13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier 43e12c5d1SDavid du Colombier 53e12c5d1SDavid du Colombier typedef struct Objtype { 63e12c5d1SDavid du Colombier char *name; 73e12c5d1SDavid du Colombier char *cc; 83e12c5d1SDavid du Colombier char *ld; 93e12c5d1SDavid du Colombier char *o; 103e12c5d1SDavid du Colombier char *oname; 113e12c5d1SDavid du Colombier } Objtype; 123e12c5d1SDavid du Colombier 133e12c5d1SDavid du Colombier Objtype objtype[] = { 149acf0835SDavid du Colombier {"spim", "0c", "0l", "0", "0.out"}, 159acf0835SDavid du Colombier {"68000", "1c", "1l", "1", "1.out"}, 163e12c5d1SDavid du Colombier {"68020", "2c", "2l", "2", "2.out"}, 1743a33802SDavid du Colombier {"arm", "5c", "5l", "5", "5.out"}, 1843a33802SDavid du Colombier {"amd64", "6c", "6l", "6", "6.out"}, 197dd7cddfSDavid du Colombier {"alpha", "7c", "7l", "7", "7.out"}, 2043a33802SDavid du Colombier {"386", "8c", "8l", "8", "8.out"}, 21*c1b29f07SDavid du Colombier {"power64", "9c", "9l", "9", "9.out"}, 2243a33802SDavid du Colombier {"sparc", "kc", "kl", "k", "k.out"}, 237dd7cddfSDavid du Colombier {"power", "qc", "ql", "q", "q.out"}, 249acf0835SDavid du Colombier {"mips", "vc", "vl", "v", "v.out"}, 253e12c5d1SDavid du Colombier }; 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier enum { 283e12c5d1SDavid du Colombier Nobjs = (sizeof objtype)/(sizeof objtype[0]), 293e12c5d1SDavid du Colombier Maxlist = 500, 303e12c5d1SDavid du Colombier }; 313e12c5d1SDavid du Colombier 323e12c5d1SDavid du Colombier typedef struct List { 333e12c5d1SDavid du Colombier char *strings[Maxlist]; 343e12c5d1SDavid du Colombier int n; 353e12c5d1SDavid du Colombier } List; 363e12c5d1SDavid du Colombier 373e12c5d1SDavid du Colombier List srcs, objs, cpp, cc, ld, ldargs; 383e12c5d1SDavid du Colombier int cflag, vflag, Eflag, Pflag; 399acf0835SDavid du Colombier char *allos = "01245678kqv"; 403e12c5d1SDavid du Colombier 413e12c5d1SDavid du Colombier void append(List *, char *); 423e12c5d1SDavid du Colombier char *changeext(char *, char *); 433e12c5d1SDavid du Colombier void doexec(char *, List *); 443e12c5d1SDavid du Colombier void dopipe(char *, List *, char *, List *); 453e12c5d1SDavid du Colombier void fatal(char *); 463e12c5d1SDavid du Colombier Objtype *findoty(void); 473e12c5d1SDavid du Colombier void printlist(List *); 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier void 503e12c5d1SDavid du Colombier main(int argc, char *argv[]) 513e12c5d1SDavid du Colombier { 523e12c5d1SDavid du Colombier Objtype *ot; 533e12c5d1SDavid du Colombier char *s, *suf, *ccpath; 543e12c5d1SDavid du Colombier char *oname; 5559cc4ca5SDavid du Colombier int i, cppn, ccn, oflag; 563e12c5d1SDavid du Colombier 5759cc4ca5SDavid du Colombier oflag = 0; 583e12c5d1SDavid du Colombier ot = findoty(); 593e12c5d1SDavid du Colombier oname = ot->oname; 603e12c5d1SDavid du Colombier append(&cpp, "cpp"); 613e12c5d1SDavid du Colombier append(&cpp, "-D__STDC__=1"); /* ANSI says so */ 623e12c5d1SDavid du Colombier append(&cpp, "-N"); /* turn off standard includes */ 633e12c5d1SDavid du Colombier append(&cc, ot->cc); 643e12c5d1SDavid du Colombier append(&ld, ot->ld); 653e12c5d1SDavid du Colombier while(argc > 0) { 663e12c5d1SDavid du Colombier ARGBEGIN { 6759cc4ca5SDavid du Colombier case '+': 689a747e4fSDavid du Colombier append(&cpp, smprint("-%c", ARGC())); 6959cc4ca5SDavid du Colombier break; 703e12c5d1SDavid du Colombier case 'c': 713e12c5d1SDavid du Colombier cflag = 1; 723e12c5d1SDavid du Colombier break; 733e12c5d1SDavid du Colombier case 'l': 749a747e4fSDavid du Colombier append(&objs, smprint("/%s/lib/ape/lib%s.a", ot->name, ARGF())); 753e12c5d1SDavid du Colombier break; 763e12c5d1SDavid du Colombier case 'o': 7759cc4ca5SDavid du Colombier oflag = 1; 783e12c5d1SDavid du Colombier oname = ARGF(); 793e12c5d1SDavid du Colombier if(!oname) 803e12c5d1SDavid du Colombier fatal("no -o argument"); 813e12c5d1SDavid du Colombier break; 823e12c5d1SDavid du Colombier case 'w': 833e12c5d1SDavid du Colombier case 'B': 8443a33802SDavid du Colombier case 'F': 853e12c5d1SDavid du Colombier case 'N': 863e12c5d1SDavid du Colombier case 'S': 8743a33802SDavid du Colombier case 'T': 887dd7cddfSDavid du Colombier case 'V': 899a747e4fSDavid du Colombier append(&cc, smprint("-%c", ARGC())); 903e12c5d1SDavid du Colombier break; 917dd7cddfSDavid du Colombier case 's': 929a747e4fSDavid du Colombier append(&cc, smprint("-s%s", ARGF())); 937dd7cddfSDavid du Colombier break; 943e12c5d1SDavid du Colombier case 'D': 953e12c5d1SDavid du Colombier case 'I': 963e12c5d1SDavid du Colombier case 'U': 979a747e4fSDavid du Colombier append(&cpp, smprint("-%c%s", ARGC(), ARGF())); 983e12c5d1SDavid du Colombier break; 993e12c5d1SDavid du Colombier case 'v': 1003e12c5d1SDavid du Colombier vflag = 1; 1013e12c5d1SDavid du Colombier append(&ldargs, "-v"); 1023e12c5d1SDavid du Colombier break; 1033e12c5d1SDavid du Colombier case 'P': 1043e12c5d1SDavid du Colombier Pflag = 1; 1053e12c5d1SDavid du Colombier cflag = 1; 1063e12c5d1SDavid du Colombier break; 1073e12c5d1SDavid du Colombier case 'E': 1083e12c5d1SDavid du Colombier Eflag = 1; 1093e12c5d1SDavid du Colombier cflag = 1; 1103e12c5d1SDavid du Colombier break; 1113e12c5d1SDavid du Colombier case 'p': 1123e12c5d1SDavid du Colombier append(&ldargs, "-p"); 1133e12c5d1SDavid du Colombier break; 114219b2ee8SDavid du Colombier case 'a': 115219b2ee8SDavid du Colombier /* hacky look inside ARGBEGIN insides, to see if we have -aa */ 116219b2ee8SDavid du Colombier if(*_args == 'a') { 117219b2ee8SDavid du Colombier append(&cc, "-aa"); 118219b2ee8SDavid du Colombier _args++; 119219b2ee8SDavid du Colombier } else 120219b2ee8SDavid du Colombier append(&cc, "-a"); 121219b2ee8SDavid du Colombier cflag = 1; 122219b2ee8SDavid du Colombier break; 1233e12c5d1SDavid du Colombier default: 1243e12c5d1SDavid du Colombier fprint(2, "pcc: flag -%c ignored\n", ARGC()); 1253e12c5d1SDavid du Colombier break; 1263e12c5d1SDavid du Colombier } ARGEND 1273e12c5d1SDavid du Colombier if(argc > 0) { 1283e12c5d1SDavid du Colombier s = argv[0]; 1293e12c5d1SDavid du Colombier suf = utfrrune(s, '.'); 1303e12c5d1SDavid du Colombier if(suf) { 1313e12c5d1SDavid du Colombier suf++; 1323e12c5d1SDavid du Colombier if(strcmp(suf, "c") == 0) { 1333e12c5d1SDavid du Colombier append(&srcs, s); 1343e12c5d1SDavid du Colombier append(&objs, changeext(s, ot->o)); 1353e12c5d1SDavid du Colombier } else if(strcmp(suf, ot->o) == 0 || 1363e12c5d1SDavid du Colombier strcmp(suf, "a") == 0 || 1373e12c5d1SDavid du Colombier (suf[0] == 'a' && strcmp(suf+1, ot->o) == 0)) { 1383e12c5d1SDavid du Colombier append(&objs, s); 1393e12c5d1SDavid du Colombier } else if(utfrune(allos, suf[0]) != 0) { 1403e12c5d1SDavid du Colombier fprint(2, "pcc: argument %s ignored: wrong architecture\n", 1413e12c5d1SDavid du Colombier s); 1423e12c5d1SDavid du Colombier } 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier } 1453e12c5d1SDavid du Colombier } 1463e12c5d1SDavid du Colombier if(objs.n == 0) 1473e12c5d1SDavid du Colombier fatal("no files to compile or load"); 1489a747e4fSDavid du Colombier ccpath = smprint("/bin/%s", ot->cc); 1499a747e4fSDavid du Colombier append(&cpp, smprint("-I/%s/include/ape", ot->name)); 1503e12c5d1SDavid du Colombier append(&cpp, "-I/sys/include/ape"); 1513e12c5d1SDavid du Colombier cppn = cpp.n; 1523e12c5d1SDavid du Colombier ccn = cc.n; 1533e12c5d1SDavid du Colombier for(i = 0; i < srcs.n; i++) { 1543e12c5d1SDavid du Colombier append(&cpp, srcs.strings[i]); 1553e12c5d1SDavid du Colombier if(Pflag) 1560d35113bSDavid du Colombier append(&cpp, changeext(objs.strings[i], "i")); 1573e12c5d1SDavid du Colombier if(Eflag || Pflag) 1583e12c5d1SDavid du Colombier doexec("/bin/cpp", &cpp); 1593e12c5d1SDavid du Colombier else { 1603e12c5d1SDavid du Colombier append(&cc, "-o"); 16159cc4ca5SDavid du Colombier if(oflag && cflag) 16259cc4ca5SDavid du Colombier append(&cc, oname); 16359cc4ca5SDavid du Colombier else 16459cc4ca5SDavid du Colombier append(&cc, changeext(srcs.strings[i], ot->o)); 1653e12c5d1SDavid du Colombier dopipe("/bin/cpp", &cpp, ccpath, &cc); 1663e12c5d1SDavid du Colombier } 1673e12c5d1SDavid du Colombier cpp.n = cppn; 1683e12c5d1SDavid du Colombier cc.n = ccn; 1693e12c5d1SDavid du Colombier } 1703e12c5d1SDavid du Colombier if(!cflag) { 1713e12c5d1SDavid du Colombier append(&ld, "-o"); 1723e12c5d1SDavid du Colombier append(&ld, oname); 1733e12c5d1SDavid du Colombier for(i = 0; i < ldargs.n; i++) 1743e12c5d1SDavid du Colombier append(&ld, ldargs.strings[i]); 1753e12c5d1SDavid du Colombier for(i = 0; i < objs.n; i++) 1763e12c5d1SDavid du Colombier append(&ld, objs.strings[i]); 177fb7f0c93SDavid du Colombier append(&ld, smprint("/%s/lib/ape/libap.a", ot->name)); 1789a747e4fSDavid du Colombier doexec(smprint("/bin/%s", ot->ld), &ld); 1797dd7cddfSDavid du Colombier if(objs.n == 1){ 1807dd7cddfSDavid du Colombier /* prevent removal of a library */ 1817dd7cddfSDavid du Colombier if(strstr(objs.strings[0], ".a") == 0) 1823e12c5d1SDavid du Colombier remove(objs.strings[0]); 1833e12c5d1SDavid du Colombier } 1847dd7cddfSDavid du Colombier } 1853e12c5d1SDavid du Colombier 1863e12c5d1SDavid du Colombier exits(0); 1873e12c5d1SDavid du Colombier } 1883e12c5d1SDavid du Colombier 1893e12c5d1SDavid du Colombier void 1903e12c5d1SDavid du Colombier append(List *l, char *s) 1913e12c5d1SDavid du Colombier { 1923e12c5d1SDavid du Colombier if(l->n >= Maxlist-1) 1933e12c5d1SDavid du Colombier fatal("too many arguments"); 1943e12c5d1SDavid du Colombier l->strings[l->n++] = s; 1953e12c5d1SDavid du Colombier l->strings[l->n] = 0; 1963e12c5d1SDavid du Colombier } 1973e12c5d1SDavid du Colombier 1983e12c5d1SDavid du Colombier void 1993e12c5d1SDavid du Colombier doexec(char *c, List *a) 2003e12c5d1SDavid du Colombier { 2019a747e4fSDavid du Colombier Waitmsg *w; 2023e12c5d1SDavid du Colombier 2033e12c5d1SDavid du Colombier if(vflag) { 2043e12c5d1SDavid du Colombier printlist(a); 2053e12c5d1SDavid du Colombier fprint(2, "\n"); 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier switch(fork()) { 2083e12c5d1SDavid du Colombier case -1: 2093e12c5d1SDavid du Colombier fatal("fork failed"); 2103e12c5d1SDavid du Colombier case 0: 2113e12c5d1SDavid du Colombier exec(c, a->strings); 2123e12c5d1SDavid du Colombier fatal("exec failed"); 2133e12c5d1SDavid du Colombier } 2149a747e4fSDavid du Colombier w = wait(); 2159a747e4fSDavid du Colombier if(w == nil) 2163e12c5d1SDavid du Colombier fatal("wait failed"); 2179a747e4fSDavid du Colombier if(w->msg[0]) 2189a747e4fSDavid du Colombier fatal(smprint("%s: %s", a->strings[0], w->msg)); 2199a747e4fSDavid du Colombier free(w); 2203e12c5d1SDavid du Colombier } 2213e12c5d1SDavid du Colombier 2223e12c5d1SDavid du Colombier void 2233e12c5d1SDavid du Colombier dopipe(char *c1, List *a1, char *c2, List *a2) 2243e12c5d1SDavid du Colombier { 2259a747e4fSDavid du Colombier Waitmsg *w; 2269a747e4fSDavid du Colombier int pid1, got; 2273e12c5d1SDavid du Colombier int fd[2]; 2283e12c5d1SDavid du Colombier 2293e12c5d1SDavid du Colombier if(vflag) { 2303e12c5d1SDavid du Colombier printlist(a1); 2313e12c5d1SDavid du Colombier fprint(2, " | "); 2323e12c5d1SDavid du Colombier printlist(a2); 2333e12c5d1SDavid du Colombier fprint(2, "\n"); 2343e12c5d1SDavid du Colombier } 2353e12c5d1SDavid du Colombier if(pipe(fd) < 0) 2363e12c5d1SDavid du Colombier fatal("pipe failed"); 2373e12c5d1SDavid du Colombier switch((pid1 = fork())) { 2383e12c5d1SDavid du Colombier case -1: 2393e12c5d1SDavid du Colombier fatal("fork failed"); 2403e12c5d1SDavid du Colombier case 0: 2413e12c5d1SDavid du Colombier dup(fd[0], 0); 2423e12c5d1SDavid du Colombier close(fd[0]); 2433e12c5d1SDavid du Colombier close(fd[1]); 2443e12c5d1SDavid du Colombier exec(c2, a2->strings); 2453e12c5d1SDavid du Colombier fatal("exec failed"); 2463e12c5d1SDavid du Colombier } 2473e12c5d1SDavid du Colombier switch(fork()) { 2483e12c5d1SDavid du Colombier case -1: 2493e12c5d1SDavid du Colombier fatal("fork failed"); 2503e12c5d1SDavid du Colombier case 0: 2513e12c5d1SDavid du Colombier close(0); 2523e12c5d1SDavid du Colombier dup(fd[1], 1); 2533e12c5d1SDavid du Colombier close(fd[0]); 2543e12c5d1SDavid du Colombier close(fd[1]); 2553e12c5d1SDavid du Colombier exec(c1, a1->strings); 2563e12c5d1SDavid du Colombier fatal("exec failed"); 2573e12c5d1SDavid du Colombier } 2583e12c5d1SDavid du Colombier close(fd[0]); 2593e12c5d1SDavid du Colombier close(fd[1]); 2603e12c5d1SDavid du Colombier for(got = 0; got < 2; got++) { 2619a747e4fSDavid du Colombier w = wait(); 2629a747e4fSDavid du Colombier if(w == nil) 2633e12c5d1SDavid du Colombier fatal("wait failed"); 2649a747e4fSDavid du Colombier if(w->msg[0]) 2659a747e4fSDavid du Colombier fatal(smprint("%s: %s", 2669a747e4fSDavid du Colombier (w->pid == pid1) ? a1->strings[0] : a2->strings[0], w->msg)); 2679a747e4fSDavid du Colombier free(w); 2683e12c5d1SDavid du Colombier } 2693e12c5d1SDavid du Colombier } 2703e12c5d1SDavid du Colombier 2713e12c5d1SDavid du Colombier Objtype * 2723e12c5d1SDavid du Colombier findoty(void) 2733e12c5d1SDavid du Colombier { 2743e12c5d1SDavid du Colombier char *o; 2753e12c5d1SDavid du Colombier Objtype *oty; 2763e12c5d1SDavid du Colombier 2773e12c5d1SDavid du Colombier o = getenv("objtype"); 2783e12c5d1SDavid du Colombier if(!o) 2793e12c5d1SDavid du Colombier fatal("no $objtype in environment"); 2803e12c5d1SDavid du Colombier for(oty = objtype; oty < &objtype[Nobjs]; oty++) 2813e12c5d1SDavid du Colombier if(strcmp(o, oty->name) == 0) 2823e12c5d1SDavid du Colombier return oty; 2833e12c5d1SDavid du Colombier fatal("unknown $objtype"); 2843e12c5d1SDavid du Colombier return 0; /* shut compiler up */ 2853e12c5d1SDavid du Colombier } 2863e12c5d1SDavid du Colombier 2873e12c5d1SDavid du Colombier void 2883e12c5d1SDavid du Colombier fatal(char *msg) 2893e12c5d1SDavid du Colombier { 2903e12c5d1SDavid du Colombier fprint(2, "pcc: %s\n", msg); 2913e12c5d1SDavid du Colombier exits(msg); 2923e12c5d1SDavid du Colombier } 2933e12c5d1SDavid du Colombier 2943e12c5d1SDavid du Colombier /* src ends in .something; return copy of basename with .ext added */ 2953e12c5d1SDavid du Colombier char * 2963e12c5d1SDavid du Colombier changeext(char *src, char *ext) 2973e12c5d1SDavid du Colombier { 2983e12c5d1SDavid du Colombier char *b, *e, *ans; 2993e12c5d1SDavid du Colombier 3003e12c5d1SDavid du Colombier b = utfrrune(src, '/'); 3013e12c5d1SDavid du Colombier if(b) 3023e12c5d1SDavid du Colombier b++; 3033e12c5d1SDavid du Colombier else 3043e12c5d1SDavid du Colombier b = src; 3053e12c5d1SDavid du Colombier e = utfrrune(src, '.'); 3063e12c5d1SDavid du Colombier if(!e) 3073e12c5d1SDavid du Colombier return 0; 3083e12c5d1SDavid du Colombier *e = 0; 3099a747e4fSDavid du Colombier ans = smprint("%s.%s", b, ext); 3103e12c5d1SDavid du Colombier *e = '.'; 3113e12c5d1SDavid du Colombier return ans; 3123e12c5d1SDavid du Colombier } 3133e12c5d1SDavid du Colombier 3143e12c5d1SDavid du Colombier void 3153e12c5d1SDavid du Colombier printlist(List *l) 3163e12c5d1SDavid du Colombier { 3173e12c5d1SDavid du Colombier int i; 3183e12c5d1SDavid du Colombier 3193e12c5d1SDavid du Colombier for(i = 0; i < l->n; i++) { 3203e12c5d1SDavid du Colombier fprint(2, "%s", l->strings[i]); 3213e12c5d1SDavid du Colombier if(i < l->n - 1) 3223e12c5d1SDavid du Colombier fprint(2, " "); 3233e12c5d1SDavid du Colombier } 3243e12c5d1SDavid du Colombier } 325