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"}, 1543a33802SDavid du Colombier {"arm", "5c", "5l", "5", "5.out"}, 1643a33802SDavid du Colombier {"amd64", "6c", "6l", "6", "6.out"}, 1743a33802SDavid du Colombier {"386", "8c", "8l", "8", "8.out"}, 18c1b29f07SDavid du Colombier {"power64", "9c", "9l", "9", "9.out"}, 1943a33802SDavid du Colombier {"sparc", "kc", "kl", "k", "k.out"}, 207dd7cddfSDavid du Colombier {"power", "qc", "ql", "q", "q.out"}, 219acf0835SDavid du Colombier {"mips", "vc", "vl", "v", "v.out"}, 223e12c5d1SDavid du Colombier }; 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier enum { 253e12c5d1SDavid du Colombier Nobjs = (sizeof objtype)/(sizeof objtype[0]), 263e12c5d1SDavid du Colombier Maxlist = 500, 273e12c5d1SDavid du Colombier }; 283e12c5d1SDavid du Colombier 293e12c5d1SDavid du Colombier typedef struct List { 303e12c5d1SDavid du Colombier char *strings[Maxlist]; 313e12c5d1SDavid du Colombier int n; 323e12c5d1SDavid du Colombier } List; 333e12c5d1SDavid du Colombier 343e12c5d1SDavid du Colombier List srcs, objs, cpp, cc, ld, ldargs; 353e12c5d1SDavid du Colombier int cflag, vflag, Eflag, Pflag; 369acf0835SDavid du Colombier char *allos = "01245678kqv"; 373e12c5d1SDavid du Colombier 383e12c5d1SDavid du Colombier void append(List *, char *); 393e12c5d1SDavid du Colombier char *changeext(char *, char *); 403e12c5d1SDavid du Colombier void doexec(char *, List *); 413e12c5d1SDavid du Colombier void dopipe(char *, List *, char *, List *); 423e12c5d1SDavid du Colombier void fatal(char *); 433e12c5d1SDavid du Colombier Objtype *findoty(void); 443e12c5d1SDavid du Colombier void printlist(List *); 453e12c5d1SDavid du Colombier 463e12c5d1SDavid du Colombier void 473e12c5d1SDavid du Colombier main(int argc, char *argv[]) 483e12c5d1SDavid du Colombier { 493e12c5d1SDavid du Colombier Objtype *ot; 503e12c5d1SDavid du Colombier char *s, *suf, *ccpath; 513e12c5d1SDavid du Colombier char *oname; 5259cc4ca5SDavid du Colombier int i, cppn, ccn, oflag; 533e12c5d1SDavid du Colombier 5459cc4ca5SDavid du Colombier oflag = 0; 553e12c5d1SDavid du Colombier ot = findoty(); 563e12c5d1SDavid du Colombier oname = ot->oname; 573e12c5d1SDavid du Colombier append(&cpp, "cpp"); 583e12c5d1SDavid du Colombier append(&cpp, "-D__STDC__=1"); /* ANSI says so */ 593e12c5d1SDavid du Colombier append(&cpp, "-N"); /* turn off standard includes */ 603e12c5d1SDavid du Colombier append(&cc, ot->cc); 613e12c5d1SDavid du Colombier append(&ld, ot->ld); 623e12c5d1SDavid du Colombier while(argc > 0) { 633e12c5d1SDavid du Colombier ARGBEGIN { 6459cc4ca5SDavid du Colombier case '+': 659a747e4fSDavid du Colombier append(&cpp, smprint("-%c", ARGC())); 6659cc4ca5SDavid du Colombier break; 673e12c5d1SDavid du Colombier case 'c': 683e12c5d1SDavid du Colombier cflag = 1; 693e12c5d1SDavid du Colombier break; 703e12c5d1SDavid du Colombier case 'l': 719a747e4fSDavid du Colombier append(&objs, smprint("/%s/lib/ape/lib%s.a", ot->name, ARGF())); 723e12c5d1SDavid du Colombier break; 733e12c5d1SDavid du Colombier case 'o': 7459cc4ca5SDavid du Colombier oflag = 1; 753e12c5d1SDavid du Colombier oname = ARGF(); 763e12c5d1SDavid du Colombier if(!oname) 773e12c5d1SDavid du Colombier fatal("no -o argument"); 783e12c5d1SDavid du Colombier break; 793e12c5d1SDavid du Colombier case 'w': 803e12c5d1SDavid du Colombier case 'B': 8143a33802SDavid du Colombier case 'F': 823e12c5d1SDavid du Colombier case 'N': 833e12c5d1SDavid du Colombier case 'S': 8443a33802SDavid du Colombier case 'T': 857dd7cddfSDavid du Colombier case 'V': 86*62579e34SDavid du Colombier case 'W': 879a747e4fSDavid du Colombier append(&cc, smprint("-%c", ARGC())); 883e12c5d1SDavid du Colombier break; 897dd7cddfSDavid du Colombier case 's': 909a747e4fSDavid du Colombier append(&cc, smprint("-s%s", ARGF())); 917dd7cddfSDavid du Colombier break; 923e12c5d1SDavid du Colombier case 'D': 933e12c5d1SDavid du Colombier case 'I': 943e12c5d1SDavid du Colombier case 'U': 959a747e4fSDavid du Colombier append(&cpp, smprint("-%c%s", ARGC(), ARGF())); 963e12c5d1SDavid du Colombier break; 973e12c5d1SDavid du Colombier case 'v': 983e12c5d1SDavid du Colombier vflag = 1; 993e12c5d1SDavid du Colombier append(&ldargs, "-v"); 1003e12c5d1SDavid du Colombier break; 1013e12c5d1SDavid du Colombier case 'P': 1023e12c5d1SDavid du Colombier Pflag = 1; 1033e12c5d1SDavid du Colombier cflag = 1; 1043e12c5d1SDavid du Colombier break; 1053e12c5d1SDavid du Colombier case 'E': 1063e12c5d1SDavid du Colombier Eflag = 1; 1073e12c5d1SDavid du Colombier cflag = 1; 1083e12c5d1SDavid du Colombier break; 1093e12c5d1SDavid du Colombier case 'p': 1103e12c5d1SDavid du Colombier append(&ldargs, "-p"); 1113e12c5d1SDavid du Colombier break; 1129b7bf7dfSDavid du Colombier case 'f': 1139b7bf7dfSDavid du Colombier if(strcmp(ot->name, "arm") == 0) 1149b7bf7dfSDavid du Colombier append(&ldargs, "-f"); 1159b7bf7dfSDavid du Colombier break; 116*62579e34SDavid du Colombier case 'x': 117*62579e34SDavid du Colombier s = ARGF(); 118*62579e34SDavid du Colombier if(s == nil || *s == '-') 119*62579e34SDavid du Colombier fatal("no -x argument"); 120*62579e34SDavid du Colombier append(&ldargs, smprint("-x %s", s)); 121*62579e34SDavid du Colombier break; 122219b2ee8SDavid du Colombier case 'a': 123219b2ee8SDavid du Colombier /* hacky look inside ARGBEGIN insides, to see if we have -aa */ 124219b2ee8SDavid du Colombier if(*_args == 'a') { 125219b2ee8SDavid du Colombier append(&cc, "-aa"); 126219b2ee8SDavid du Colombier _args++; 127219b2ee8SDavid du Colombier } else 128219b2ee8SDavid du Colombier append(&cc, "-a"); 129219b2ee8SDavid du Colombier cflag = 1; 130219b2ee8SDavid du Colombier break; 1313e12c5d1SDavid du Colombier default: 1323e12c5d1SDavid du Colombier fprint(2, "pcc: flag -%c ignored\n", ARGC()); 1333e12c5d1SDavid du Colombier break; 1343e12c5d1SDavid du Colombier } ARGEND 1353e12c5d1SDavid du Colombier if(argc > 0) { 1363e12c5d1SDavid du Colombier s = argv[0]; 1373e12c5d1SDavid du Colombier suf = utfrrune(s, '.'); 1383e12c5d1SDavid du Colombier if(suf) { 1393e12c5d1SDavid du Colombier suf++; 1403e12c5d1SDavid du Colombier if(strcmp(suf, "c") == 0) { 1413e12c5d1SDavid du Colombier append(&srcs, s); 1423e12c5d1SDavid du Colombier append(&objs, changeext(s, ot->o)); 1433e12c5d1SDavid du Colombier } else if(strcmp(suf, ot->o) == 0 || 1443e12c5d1SDavid du Colombier strcmp(suf, "a") == 0 || 1453e12c5d1SDavid du Colombier (suf[0] == 'a' && strcmp(suf+1, ot->o) == 0)) { 1463e12c5d1SDavid du Colombier append(&objs, s); 1473e12c5d1SDavid du Colombier } else if(utfrune(allos, suf[0]) != 0) { 1483e12c5d1SDavid du Colombier fprint(2, "pcc: argument %s ignored: wrong architecture\n", 1493e12c5d1SDavid du Colombier s); 1503e12c5d1SDavid du Colombier } 1513e12c5d1SDavid du Colombier } 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier if(objs.n == 0) 1553e12c5d1SDavid du Colombier fatal("no files to compile or load"); 1569a747e4fSDavid du Colombier ccpath = smprint("/bin/%s", ot->cc); 1579a747e4fSDavid du Colombier append(&cpp, smprint("-I/%s/include/ape", ot->name)); 1583e12c5d1SDavid du Colombier append(&cpp, "-I/sys/include/ape"); 1593e12c5d1SDavid du Colombier cppn = cpp.n; 1603e12c5d1SDavid du Colombier ccn = cc.n; 1613e12c5d1SDavid du Colombier for(i = 0; i < srcs.n; i++) { 1623e12c5d1SDavid du Colombier append(&cpp, srcs.strings[i]); 1633e12c5d1SDavid du Colombier if(Pflag) 1640d35113bSDavid du Colombier append(&cpp, changeext(objs.strings[i], "i")); 1653e12c5d1SDavid du Colombier if(Eflag || Pflag) 1663e12c5d1SDavid du Colombier doexec("/bin/cpp", &cpp); 1673e12c5d1SDavid du Colombier else { 1683e12c5d1SDavid du Colombier append(&cc, "-o"); 16959cc4ca5SDavid du Colombier if(oflag && cflag) 17059cc4ca5SDavid du Colombier append(&cc, oname); 17159cc4ca5SDavid du Colombier else 17259cc4ca5SDavid du Colombier append(&cc, changeext(srcs.strings[i], ot->o)); 1733e12c5d1SDavid du Colombier dopipe("/bin/cpp", &cpp, ccpath, &cc); 1743e12c5d1SDavid du Colombier } 1753e12c5d1SDavid du Colombier cpp.n = cppn; 1763e12c5d1SDavid du Colombier cc.n = ccn; 1773e12c5d1SDavid du Colombier } 1783e12c5d1SDavid du Colombier if(!cflag) { 1793e12c5d1SDavid du Colombier append(&ld, "-o"); 1803e12c5d1SDavid du Colombier append(&ld, oname); 1813e12c5d1SDavid du Colombier for(i = 0; i < ldargs.n; i++) 1823e12c5d1SDavid du Colombier append(&ld, ldargs.strings[i]); 1833e12c5d1SDavid du Colombier for(i = 0; i < objs.n; i++) 1843e12c5d1SDavid du Colombier append(&ld, objs.strings[i]); 185fb7f0c93SDavid du Colombier append(&ld, smprint("/%s/lib/ape/libap.a", ot->name)); 1869a747e4fSDavid du Colombier doexec(smprint("/bin/%s", ot->ld), &ld); 1877dd7cddfSDavid du Colombier if(objs.n == 1){ 1887dd7cddfSDavid du Colombier /* prevent removal of a library */ 1897dd7cddfSDavid du Colombier if(strstr(objs.strings[0], ".a") == 0) 1903e12c5d1SDavid du Colombier remove(objs.strings[0]); 1913e12c5d1SDavid du Colombier } 1927dd7cddfSDavid du Colombier } 1933e12c5d1SDavid du Colombier 1943e12c5d1SDavid du Colombier exits(0); 1953e12c5d1SDavid du Colombier } 1963e12c5d1SDavid du Colombier 1973e12c5d1SDavid du Colombier void 1983e12c5d1SDavid du Colombier append(List *l, char *s) 1993e12c5d1SDavid du Colombier { 2003e12c5d1SDavid du Colombier if(l->n >= Maxlist-1) 2013e12c5d1SDavid du Colombier fatal("too many arguments"); 2023e12c5d1SDavid du Colombier l->strings[l->n++] = s; 2033e12c5d1SDavid du Colombier l->strings[l->n] = 0; 2043e12c5d1SDavid du Colombier } 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier void 2073e12c5d1SDavid du Colombier doexec(char *c, List *a) 2083e12c5d1SDavid du Colombier { 2099a747e4fSDavid du Colombier Waitmsg *w; 2103e12c5d1SDavid du Colombier 2113e12c5d1SDavid du Colombier if(vflag) { 2123e12c5d1SDavid du Colombier printlist(a); 2133e12c5d1SDavid du Colombier fprint(2, "\n"); 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier switch(fork()) { 2163e12c5d1SDavid du Colombier case -1: 2173e12c5d1SDavid du Colombier fatal("fork failed"); 2183e12c5d1SDavid du Colombier case 0: 2193e12c5d1SDavid du Colombier exec(c, a->strings); 2203e12c5d1SDavid du Colombier fatal("exec failed"); 2213e12c5d1SDavid du Colombier } 2229a747e4fSDavid du Colombier w = wait(); 2239a747e4fSDavid du Colombier if(w == nil) 2243e12c5d1SDavid du Colombier fatal("wait failed"); 2259a747e4fSDavid du Colombier if(w->msg[0]) 2269a747e4fSDavid du Colombier fatal(smprint("%s: %s", a->strings[0], w->msg)); 2279a747e4fSDavid du Colombier free(w); 2283e12c5d1SDavid du Colombier } 2293e12c5d1SDavid du Colombier 2303e12c5d1SDavid du Colombier void 2313e12c5d1SDavid du Colombier dopipe(char *c1, List *a1, char *c2, List *a2) 2323e12c5d1SDavid du Colombier { 2339a747e4fSDavid du Colombier Waitmsg *w; 2349a747e4fSDavid du Colombier int pid1, got; 2353e12c5d1SDavid du Colombier int fd[2]; 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier if(vflag) { 2383e12c5d1SDavid du Colombier printlist(a1); 2393e12c5d1SDavid du Colombier fprint(2, " | "); 2403e12c5d1SDavid du Colombier printlist(a2); 2413e12c5d1SDavid du Colombier fprint(2, "\n"); 2423e12c5d1SDavid du Colombier } 2433e12c5d1SDavid du Colombier if(pipe(fd) < 0) 2443e12c5d1SDavid du Colombier fatal("pipe failed"); 2453e12c5d1SDavid du Colombier switch((pid1 = fork())) { 2463e12c5d1SDavid du Colombier case -1: 2473e12c5d1SDavid du Colombier fatal("fork failed"); 2483e12c5d1SDavid du Colombier case 0: 2493e12c5d1SDavid du Colombier dup(fd[0], 0); 2503e12c5d1SDavid du Colombier close(fd[0]); 2513e12c5d1SDavid du Colombier close(fd[1]); 2523e12c5d1SDavid du Colombier exec(c2, a2->strings); 2533e12c5d1SDavid du Colombier fatal("exec failed"); 2543e12c5d1SDavid du Colombier } 2553e12c5d1SDavid du Colombier switch(fork()) { 2563e12c5d1SDavid du Colombier case -1: 2573e12c5d1SDavid du Colombier fatal("fork failed"); 2583e12c5d1SDavid du Colombier case 0: 2593e12c5d1SDavid du Colombier close(0); 2603e12c5d1SDavid du Colombier dup(fd[1], 1); 2613e12c5d1SDavid du Colombier close(fd[0]); 2623e12c5d1SDavid du Colombier close(fd[1]); 2633e12c5d1SDavid du Colombier exec(c1, a1->strings); 2643e12c5d1SDavid du Colombier fatal("exec failed"); 2653e12c5d1SDavid du Colombier } 2663e12c5d1SDavid du Colombier close(fd[0]); 2673e12c5d1SDavid du Colombier close(fd[1]); 2683e12c5d1SDavid du Colombier for(got = 0; got < 2; got++) { 2699a747e4fSDavid du Colombier w = wait(); 2709a747e4fSDavid du Colombier if(w == nil) 2713e12c5d1SDavid du Colombier fatal("wait failed"); 2729a747e4fSDavid du Colombier if(w->msg[0]) 2739a747e4fSDavid du Colombier fatal(smprint("%s: %s", 2749a747e4fSDavid du Colombier (w->pid == pid1) ? a1->strings[0] : a2->strings[0], w->msg)); 2759a747e4fSDavid du Colombier free(w); 2763e12c5d1SDavid du Colombier } 2773e12c5d1SDavid du Colombier } 2783e12c5d1SDavid du Colombier 2793e12c5d1SDavid du Colombier Objtype * 2803e12c5d1SDavid du Colombier findoty(void) 2813e12c5d1SDavid du Colombier { 2823e12c5d1SDavid du Colombier char *o; 2833e12c5d1SDavid du Colombier Objtype *oty; 2843e12c5d1SDavid du Colombier 2853e12c5d1SDavid du Colombier o = getenv("objtype"); 2863e12c5d1SDavid du Colombier if(!o) 2873e12c5d1SDavid du Colombier fatal("no $objtype in environment"); 2883e12c5d1SDavid du Colombier for(oty = objtype; oty < &objtype[Nobjs]; oty++) 2893e12c5d1SDavid du Colombier if(strcmp(o, oty->name) == 0) 2903e12c5d1SDavid du Colombier return oty; 2913e12c5d1SDavid du Colombier fatal("unknown $objtype"); 2923e12c5d1SDavid du Colombier return 0; /* shut compiler up */ 2933e12c5d1SDavid du Colombier } 2943e12c5d1SDavid du Colombier 2953e12c5d1SDavid du Colombier void 2963e12c5d1SDavid du Colombier fatal(char *msg) 2973e12c5d1SDavid du Colombier { 2983e12c5d1SDavid du Colombier fprint(2, "pcc: %s\n", msg); 2993e12c5d1SDavid du Colombier exits(msg); 3003e12c5d1SDavid du Colombier } 3013e12c5d1SDavid du Colombier 3023e12c5d1SDavid du Colombier /* src ends in .something; return copy of basename with .ext added */ 3033e12c5d1SDavid du Colombier char * 3043e12c5d1SDavid du Colombier changeext(char *src, char *ext) 3053e12c5d1SDavid du Colombier { 3063e12c5d1SDavid du Colombier char *b, *e, *ans; 3073e12c5d1SDavid du Colombier 3083e12c5d1SDavid du Colombier b = utfrrune(src, '/'); 3093e12c5d1SDavid du Colombier if(b) 3103e12c5d1SDavid du Colombier b++; 3113e12c5d1SDavid du Colombier else 3123e12c5d1SDavid du Colombier b = src; 3133e12c5d1SDavid du Colombier e = utfrrune(src, '.'); 3143e12c5d1SDavid du Colombier if(!e) 3153e12c5d1SDavid du Colombier return 0; 3163e12c5d1SDavid du Colombier *e = 0; 3179a747e4fSDavid du Colombier ans = smprint("%s.%s", b, ext); 3183e12c5d1SDavid du Colombier *e = '.'; 3193e12c5d1SDavid du Colombier return ans; 3203e12c5d1SDavid du Colombier } 3213e12c5d1SDavid du Colombier 3223e12c5d1SDavid du Colombier void 3233e12c5d1SDavid du Colombier printlist(List *l) 3243e12c5d1SDavid du Colombier { 3253e12c5d1SDavid du Colombier int i; 3263e12c5d1SDavid du Colombier 3273e12c5d1SDavid du Colombier for(i = 0; i < l->n; i++) { 3283e12c5d1SDavid du Colombier fprint(2, "%s", l->strings[i]); 3293e12c5d1SDavid du Colombier if(i < l->n - 1) 3303e12c5d1SDavid du Colombier fprint(2, " "); 3313e12c5d1SDavid du Colombier } 3323e12c5d1SDavid du Colombier } 333