Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
 
4
 
5
typedef struct Objtype {
6
	char	*name;
7
	char	*cc;
8
	char	*ld;
9
	char	*o;
10
	char	*oname;
11
} Objtype;
12
 
13
/* sync with /sys/src/ape/cmd/cc.c */
14
Objtype objtype[] = {
15
	{"spim",	"0c", "0l", "0", "0.out"},
16
	{"arm",		"5c", "5l", "5", "5.out"},
17
	{"amd64",	"6c", "6l", "6", "6.out"},
18
	{"386",		"8c", "8l", "8", "8.out"},
19
	{"power64",	"9c", "9l", "9", "9.out"},
20
	{"sparc",	"kc", "kl", "k", "k.out"},
21
	{"power",	"qc", "ql", "q", "q.out"},
22
	{"mips",	"vc", "vl", "v", "v.out"},
23
};
24
char	*allos = "05689kqv";
25
 
26
enum {
27
	Nobjs = (sizeof objtype)/(sizeof objtype[0]),
28
	Maxlist = 2000,
29
};
30
 
31
typedef struct List {
32
	char	*strings[Maxlist];
33
	int	n;
34
} List;
35
 
36
List	srcs, objs, cpp, cc, ld, ldargs;
37
int	cflag, vflag, Eflag, Pflag;
38
 
39
void	append(List *, char *);
40
char	*changeext(char *, char *);
41
void	doexec(char *, List *);
42
void	dopipe(char *, List *, char *, List *);
43
void	fatal(char *);
44
Objtype	*findoty(void);
45
void	printlist(List *);
46
 
47
void
48
main(int argc, char *argv[])
49
{
50
	Objtype *ot;
51
	char *s, *suf, *ccpath;
52
	char *oname;
53
	int i, cppn, ccn, oflag;
54
 
55
	oflag = 0;
56
	ot = findoty();
57
	oname = ot->oname;
58
	append(&cpp, "cpp");
59
	append(&cpp, "-D__STDC__=1");	/* ANSI says so */
60
	append(&cpp, "-N");		/* turn off standard includes */
61
	append(&cc, ot->cc);
62
	append(&ld, ot->ld);
63
	while(argc > 0) {
64
		ARGBEGIN {
65
		case '+':
66
			append(&cpp, smprint("-%c", ARGC()));
67
			break;
68
		case 'c':
69
			cflag = 1;
70
			break;
71
		case 'l':
72
			append(&objs, smprint("/%s/lib/ape/lib%s.a", ot->name, ARGF()));
73
			break;
74
		case 'o':
75
			oflag = 1;
76
			oname = ARGF();
77
			if(!oname)
78
				fatal("no -o argument");
79
			break;
80
		case 'w':
81
		case 'B':
82
		case 'F':
83
		case 'N':
84
		case 'S':
85
		case 'T':
86
		case 'V':
87
		case 'W':
88
			append(&cc, smprint("-%c", ARGC()));
89
			break;
90
		case 's':
91
			append(&cc, smprint("-s%s", ARGF()));
92
			break;
93
		case 'D':
94
		case 'I':
95
		case 'U':
96
			append(&cpp, smprint("-%c%s", ARGC(), ARGF()));
97
			break;
98
		case 'v':
99
			vflag = 1;
100
			append(&ldargs, "-v");
101
			break;
102
		case 'P':
103
			Pflag = 1;
104
			cflag = 1;
105
			break;
106
		case 'E':
107
			Eflag = 1;
108
			cflag = 1;
109
			break;
110
		case 'p':
111
			append(&ldargs, "-p");
112
			break;
113
		case 'f':
114
			if(strcmp(ot->name, "arm") == 0)
115
				append(&ldargs, "-f");
116
			break;
117
		case 'x':
118
			s = ARGF();
119
			if(s == nil || *s == '-')
120
				fatal("no -x argument");
121
			append(&ldargs, smprint("-x %s", s));
122
			break;
123
		case 'a':
124
			/* hacky look inside ARGBEGIN insides, to see if we have -aa */
125
			if(*_args == 'a') {
126
				append(&cc, "-aa");
127
				_args++;
128
			} else
129
				append(&cc, "-a");
130
			cflag = 1;
131
			break;
132
		default:
133
			fprint(2, "pcc: flag -%c ignored\n", ARGC());
134
			break;
135
		} ARGEND
136
		if(argc > 0) {
137
			s = argv[0];
138
			suf = utfrrune(s, '.');
139
			if(suf) {
140
				suf++;
141
				if(strcmp(suf, "c") == 0) {
142
					append(&srcs, s);
143
					append(&objs, changeext(s, ot->o));
144
				} else if(strcmp(suf, ot->o) == 0 ||
145
					  strcmp(suf, "a") == 0 ||
146
					  (suf[0] == 'a' && strcmp(suf+1, ot->o) == 0)) {
147
					append(&objs, s);
148
				} else if(utfrune(allos, suf[0]) != 0) {
149
					fprint(2, "pcc: argument %s ignored: wrong architecture\n",
150
						s);
151
				}
152
			}
153
		}
154
	}
155
	if(objs.n == 0)
156
		fatal("no files to compile or load");
157
	ccpath = smprint("/bin/%s", ot->cc);
158
	append(&cpp, smprint("-I/%s/include/ape", ot->name));
159
	append(&cpp, "-I/sys/include/ape");
160
	cppn = cpp.n;
161
	ccn = cc.n;
162
	for(i = 0; i < srcs.n; i++) {
163
		append(&cpp, srcs.strings[i]);
164
		if(Pflag)
165
			append(&cpp, changeext(objs.strings[i], "i"));
166
		if(Eflag || Pflag)
167
			doexec("/bin/cpp", &cpp);
168
		else {
169
			append(&cc, "-o");
170
			if(oflag && cflag)
171
				append(&cc, oname);
172
			else
173
				append(&cc, changeext(srcs.strings[i], ot->o));
174
			dopipe("/bin/cpp", &cpp, ccpath, &cc);
175
		}
176
		cpp.n = cppn;
177
		cc.n = ccn;
178
	}
179
	if(!cflag) {
180
		append(&ld, "-o");
181
		append(&ld, oname);
182
		for(i = 0; i < ldargs.n; i++)
183
			append(&ld, ldargs.strings[i]);
184
		for(i = 0; i < objs.n; i++)
185
			append(&ld, objs.strings[i]);
186
		append(&ld, smprint("/%s/lib/ape/libap.a", ot->name));
187
		doexec(smprint("/bin/%s", ot->ld), &ld);
188
		if(objs.n == 1){
189
			/* prevent removal of a library */
190
			if(strstr(objs.strings[0], ".a") == 0)
191
				remove(objs.strings[0]);
192
		}
193
	}
194
 
195
	exits(0);
196
}
197
 
198
void
199
append(List *l, char *s)
200
{
201
	if(l->n >= Maxlist-1)
202
		fatal("too many arguments");
203
	l->strings[l->n++] = s;
204
	l->strings[l->n] = 0;
205
}
206
 
207
void
208
doexec(char *c, List *a)
209
{
210
	Waitmsg *w;
211
 
212
	if(vflag) {
213
		printlist(a);
214
		fprint(2, "\n");
215
	}
216
	switch(fork()) {
217
	case -1:
218
		fatal("fork failed");
219
	case 0:
220
		exec(c, a->strings);
221
		fatal("exec failed");
222
	}
223
	w = wait();
224
	if(w == nil)
225
		fatal("wait failed");
226
	if(w->msg[0])
227
		fatal(smprint("%s: %s", a->strings[0], w->msg));
228
	free(w);
229
}
230
 
231
void
232
dopipe(char *c1, List *a1, char *c2, List *a2)
233
{
234
	Waitmsg *w;
235
	int pid1, got;
236
	int fd[2];
237
 
238
	if(vflag) {
239
		printlist(a1);
240
		fprint(2, " | ");
241
		printlist(a2);
242
		fprint(2, "\n");
243
	}
244
	if(pipe(fd) < 0)
245
		fatal("pipe failed");
246
	switch((pid1 = fork())) {
247
	case -1:
248
		fatal("fork failed");
249
	case 0:
250
		dup(fd[0], 0);
251
		close(fd[0]);
252
		close(fd[1]);
253
		exec(c2, a2->strings);
254
		fatal("exec failed");
255
	}
256
	switch(fork()) {
257
	case -1:
258
		fatal("fork failed");
259
	case 0:
260
		close(0);
261
		dup(fd[1], 1);
262
		close(fd[0]);
263
		close(fd[1]);
264
		exec(c1, a1->strings);
265
		fatal("exec failed");
266
	}
267
	close(fd[0]);
268
	close(fd[1]);
269
	for(got = 0; got < 2; got++) {
270
		w = wait();
271
		if(w == nil)
272
			fatal("wait failed");
273
		if(w->msg[0])
274
			fatal(smprint("%s: %s",
275
			   (w->pid == pid1) ? a1->strings[0] : a2->strings[0], w->msg));
276
		free(w);
277
	}
278
}
279
 
280
Objtype *
281
findoty(void)
282
{
283
	char *o;
284
	Objtype *oty;
285
 
286
	o = getenv("objtype");
287
	if(!o)
288
		fatal("no $objtype in environment");
289
	for(oty = objtype; oty < &objtype[Nobjs]; oty++)
290
		if(strcmp(o, oty->name) == 0)
291
			return oty;
292
	fatal("unknown $objtype");
293
	return 0;			/* shut compiler up */
294
}
295
 
296
void
297
fatal(char *msg)
298
{
299
	fprint(2, "pcc: %s\n", msg);
300
	exits(msg);
301
}
302
 
303
/* src ends in .something; return copy of basename with .ext added */
304
char *
305
changeext(char *src, char *ext)
306
{
307
	char *b, *e, *ans;
308
 
309
	b = utfrrune(src, '/');
310
	if(b)
311
		b++;
312
	else
313
		b = src;
314
	e = utfrrune(src, '.');
315
	if(!e)
316
		return 0;
317
	*e = 0;
318
	ans = smprint("%s.%s", b, ext);
319
	*e = '.';
320
	return ans;
321
}
322
 
323
void
324
printlist(List *l)
325
{
326
	int i;
327
 
328
	for(i = 0; i < l->n; i++) {
329
		fprint(2, "%s", l->strings[i]);
330
		if(i < l->n - 1)
331
			fprint(2, " ");
332
	}
333
}