|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)mkmakefile.c 5.9 (Berkeley) 5/6/86";
9: #endif not lint
10:
11: /*
12: * Build the makefile for the system, from
13: * the information in the files files and the
14: * additional files for the machine being compiled to.
15: */
16:
17: #include <stdio.h>
18: #include <ctype.h>
19: #include "y.tab.h"
20: #include "config.h"
21:
22: #define next_word(fp, wd) \
23: { register char *word = get_word(fp); \
24: if (word == (char *)EOF) \
25: return; \
26: else \
27: wd = word; \
28: }
29:
30: static struct file_list *fcur;
31: char *tail();
32:
33: /*
34: * Lookup a file, by name.
35: */
36: struct file_list *
37: fl_lookup(file)
38: register char *file;
39: {
40: register struct file_list *fp;
41:
42: for (fp = ftab ; fp != 0; fp = fp->f_next) {
43: if (eq(fp->f_fn, file))
44: return (fp);
45: }
46: return (0);
47: }
48:
49: /*
50: * Lookup a file, by final component name.
51: */
52: struct file_list *
53: fltail_lookup(file)
54: register char *file;
55: {
56: register struct file_list *fp;
57:
58: for (fp = ftab ; fp != 0; fp = fp->f_next) {
59: if (eq(tail(fp->f_fn), tail(file)))
60: return (fp);
61: }
62: return (0);
63: }
64:
65: /*
66: * Make a new file list entry
67: */
68: struct file_list *
69: new_fent()
70: {
71: register struct file_list *fp;
72:
73: fp = (struct file_list *) malloc(sizeof *fp);
74: fp->f_needs = 0;
75: fp->f_next = 0;
76: fp->f_flags = 0;
77: fp->f_type = 0;
78: if (fcur == 0)
79: fcur = ftab = fp;
80: else
81: fcur->f_next = fp;
82: fcur = fp;
83: return (fp);
84: }
85:
86: char *COPTS;
87: static struct users {
88: int u_default;
89: int u_min;
90: int u_max;
91: } users[] = {
92: { 24, 8, 1024 }, /* MACHINE_VAX */
93: };
94: #define NUSERS (sizeof (users) / sizeof (users[0]))
95:
96: /*
97: * Build the makefile from the skeleton
98: */
99: makefile()
100: {
101: FILE *ifp, *ofp;
102: char line[BUFSIZ];
103: struct opt *op;
104: struct users *up;
105:
106: read_files();
107: strcpy(line, "../conf/Makefile.");
108: (void) strcat(line, machinename);
109: ifp = fopen(line, "r");
110: if (ifp == 0) {
111: perror(line);
112: exit(1);
113: }
114: ofp = fopen(path("Makefile"), "w");
115: if (ofp == 0) {
116: perror(path("Makefile"));
117: exit(1);
118: }
119: fprintf(ofp, "IDENT=-D%s", raise(ident));
120: if (profiling)
121: fprintf(ofp, " -DGPROF");
122: if (cputype == 0) {
123: printf("cpu type must be specified\n");
124: exit(1);
125: }
126: { struct cputype *cp;
127: for (cp = cputype; cp; cp = cp->cpu_next)
128: fprintf(ofp, " -D%s", cp->cpu_name);
129: }
130: for (op = opt; op; op = op->op_next)
131: if (op->op_value)
132: fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value);
133: else
134: fprintf(ofp, " -D%s", op->op_name);
135: fprintf(ofp, "\n");
136: if (hadtz == 0)
137: printf("timezone not specified; gmt assumed\n");
138: if ((unsigned)machine > NUSERS) {
139: printf("maxusers config info isn't present, using vax\n");
140: up = &users[MACHINE_VAX-1];
141: } else
142: up = &users[machine-1];
143: if (maxusers == 0) {
144: printf("maxusers not specified; %d assumed\n", up->u_default);
145: maxusers = up->u_default;
146: } else if (maxusers < up->u_min) {
147: printf("minimum of %d maxusers assumed\n", up->u_min);
148: maxusers = up->u_min;
149: } else if (maxusers > up->u_max)
150: printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers);
151: fprintf(ofp, "PARAM=-DTIMEZONE=%d -DDST=%d -DMAXUSERS=%d\n",
152: timezone, dst, maxusers);
153: for (op = mkopt; op; op = op->op_next)
154: fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
155: while (fgets(line, BUFSIZ, ifp) != 0) {
156: if (*line == '%')
157: goto percent;
158: if (profiling && strncmp(line, "COPTS=", 6) == 0) {
159: register char *cp;
160:
161: fprintf(ofp,
162: "GPROF.EX=/usr/src/lib/libc/%s/csu/gmon.ex\n",
163: machinename);
164: cp = index(line, '\n');
165: if (cp)
166: *cp = 0;
167: cp = line + 6;
168: while (*cp && (*cp == ' ' || *cp == '\t'))
169: cp++;
170: COPTS = malloc((unsigned)(strlen(cp) + 1));
171: if (COPTS == 0) {
172: printf("config: out of memory\n");
173: exit(1);
174: }
175: strcpy(COPTS, cp);
176: fprintf(ofp, "%s -pg\n", line);
177: continue;
178: }
179: fprintf(ofp, "%s", line);
180: continue;
181: percent:
182: if (eq(line, "%OBJS\n"))
183: do_objs(ofp);
184: else if (eq(line, "%CFILES\n"))
185: do_cfiles(ofp);
186: else if (eq(line, "%RULES\n"))
187: do_rules(ofp);
188: else if (eq(line, "%LOAD\n"))
189: do_load(ofp);
190: else
191: fprintf(stderr,
192: "Unknown %% construct in generic makefile: %s",
193: line);
194: }
195: (void) fclose(ifp);
196: (void) fclose(ofp);
197: }
198:
199: /*
200: * Read in the information about files used in making the system.
201: * Store it in the ftab linked list.
202: */
203: read_files()
204: {
205: FILE *fp;
206: register struct file_list *tp, *pf;
207: register struct device *dp;
208: register struct opt *op;
209: char *wd, *this, *needs, *devorprof;
210: char fname[32];
211: int nreqs, first = 1, configdep, isdup;
212:
213: ftab = 0;
214: (void) strcpy(fname, "files");
215: openit:
216: fp = fopen(fname, "r");
217: if (fp == 0) {
218: perror(fname);
219: exit(1);
220: }
221: next:
222: /*
223: * filename [ standard | optional ] [ config-dependent ]
224: * [ dev* | profiling-routine ] [ device-driver]
225: */
226: wd = get_word(fp);
227: if (wd == (char *)EOF) {
228: (void) fclose(fp);
229: if (first == 1) {
230: (void) sprintf(fname, "files.%s", machinename);
231: first++;
232: goto openit;
233: }
234: if (first == 2) {
235: (void) sprintf(fname, "files.%s", raise(ident));
236: first++;
237: fp = fopen(fname, "r");
238: if (fp != 0)
239: goto next;
240: }
241: return;
242: }
243: if (wd == 0)
244: goto next;
245: this = ns(wd);
246: next_word(fp, wd);
247: if (wd == 0) {
248: printf("%s: No type for %s.\n",
249: fname, this);
250: exit(1);
251: }
252: if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
253: isdup = 1;
254: else
255: isdup = 0;
256: tp = 0;
257: if (first == 3 && (tp = fltail_lookup(this)) != 0)
258: printf("%s: Local file %s overrides %s.\n",
259: fname, this, tp->f_fn);
260: nreqs = 0;
261: devorprof = "";
262: configdep = 0;
263: needs = 0;
264: if (eq(wd, "standard"))
265: goto checkdev;
266: if (!eq(wd, "optional")) {
267: printf("%s: %s must be optional or standard\n", fname, this);
268: exit(1);
269: }
270: nextopt:
271: next_word(fp, wd);
272: if (wd == 0)
273: goto doneopt;
274: if (eq(wd, "config-dependent")) {
275: configdep++;
276: goto nextopt;
277: }
278: devorprof = wd;
279: if (eq(wd, "device-driver") || eq(wd, "profiling-routine")) {
280: next_word(fp, wd);
281: goto save;
282: }
283: nreqs++;
284: if (needs == 0 && nreqs == 1)
285: needs = ns(wd);
286: if (isdup)
287: goto invis;
288: for (dp = dtab; dp != 0; dp = dp->d_next)
289: if (eq(dp->d_name, wd))
290: goto nextopt;
291: for (op = opt; op != 0; op = op->op_next)
292: if (op->op_value == 0 && opteq(op->op_name, wd)) {
293: if (nreqs == 1) {
294: free(needs);
295: needs = 0;
296: }
297: goto nextopt;
298: }
299: invis:
300: while ((wd = get_word(fp)) != 0)
301: ;
302: if (tp == 0)
303: tp = new_fent();
304: tp->f_fn = this;
305: tp->f_type = INVISIBLE;
306: tp->f_needs = needs;
307: tp->f_flags = isdup;
308: goto next;
309:
310: doneopt:
311: if (nreqs == 0) {
312: printf("%s: what is %s optional on?\n",
313: fname, this);
314: exit(1);
315: }
316:
317: checkdev:
318: if (wd) {
319: next_word(fp, wd);
320: if (wd) {
321: if (eq(wd, "config-dependent")) {
322: configdep++;
323: goto checkdev;
324: }
325: devorprof = wd;
326: next_word(fp, wd);
327: }
328: }
329:
330: save:
331: if (wd) {
332: printf("%s: syntax error describing %s\n",
333: fname, this);
334: exit(1);
335: }
336: if (eq(devorprof, "profiling-routine") && profiling == 0)
337: goto next;
338: if (tp == 0)
339: tp = new_fent();
340: tp->f_fn = this;
341: if (eq(devorprof, "device-driver"))
342: tp->f_type = DRIVER;
343: else if (eq(devorprof, "profiling-routine"))
344: tp->f_type = PROFILING;
345: else
346: tp->f_type = NORMAL;
347: tp->f_flags = 0;
348: if (configdep)
349: tp->f_flags |= CONFIGDEP;
350: tp->f_needs = needs;
351: if (pf && pf->f_type == INVISIBLE)
352: pf->f_flags = 1; /* mark as duplicate */
353: goto next;
354: }
355:
356: opteq(cp, dp)
357: char *cp, *dp;
358: {
359: char c, d;
360:
361: for (; ; cp++, dp++) {
362: if (*cp != *dp) {
363: c = isupper(*cp) ? tolower(*cp) : *cp;
364: d = isupper(*dp) ? tolower(*dp) : *dp;
365: if (c != d)
366: return (0);
367: }
368: if (*cp == 0)
369: return (1);
370: }
371: }
372:
373: do_objs(fp)
374: FILE *fp;
375: {
376: register struct file_list *tp, *fl;
377: register int lpos, len;
378: register char *cp, och, *sp;
379: char swapname[32];
380:
381: fprintf(fp, "OBJS=");
382: lpos = 6;
383: for (tp = ftab; tp != 0; tp = tp->f_next) {
384: if (tp->f_type == INVISIBLE)
385: continue;
386: sp = tail(tp->f_fn);
387: for (fl = conf_list; fl; fl = fl->f_next) {
388: if (fl->f_type != SWAPSPEC)
389: continue;
390: sprintf(swapname, "swap%s.c", fl->f_fn);
391: if (eq(sp, swapname))
392: goto cont;
393: }
394: cp = sp + (len = strlen(sp)) - 1;
395: och = *cp;
396: *cp = 'o';
397: if (len + lpos > 72) {
398: lpos = 8;
399: fprintf(fp, "\\\n\t");
400: }
401: fprintf(fp, "%s ", sp);
402: lpos += len + 1;
403: *cp = och;
404: cont:
405: ;
406: }
407: if (lpos != 8)
408: putc('\n', fp);
409: }
410:
411: do_cfiles(fp)
412: FILE *fp;
413: {
414: register struct file_list *tp;
415: register int lpos, len;
416:
417: fprintf(fp, "CFILES=");
418: lpos = 8;
419: for (tp = ftab; tp != 0; tp = tp->f_next) {
420: if (tp->f_type == INVISIBLE)
421: continue;
422: if (tp->f_fn[strlen(tp->f_fn)-1] != 'c')
423: continue;
424: if ((len = 3 + strlen(tp->f_fn)) + lpos > 72) {
425: lpos = 8;
426: fprintf(fp, "\\\n\t");
427: }
428: fprintf(fp, "../%s ", tp->f_fn);
429: lpos += len + 1;
430: }
431: if (lpos != 8)
432: putc('\n', fp);
433: }
434:
435: char *
436: tail(fn)
437: char *fn;
438: {
439: register char *cp;
440:
441: cp = rindex(fn, '/');
442: if (cp == 0)
443: return (fn);
444: return (cp+1);
445: }
446:
447: /*
448: * Create the makerules for each file
449: * which is part of the system.
450: * Devices are processed with the special c2 option -i
451: * which avoids any problem areas with i/o addressing
452: * (e.g. for the VAX); assembler files are processed by as.
453: */
454: do_rules(f)
455: FILE *f;
456: {
457: register char *cp, *np, och, *tp;
458: register struct file_list *ftp;
459: char *extras;
460:
461: for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
462: if (ftp->f_type == INVISIBLE)
463: continue;
464: cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
465: och = *cp;
466: *cp = '\0';
467: if (och == 'o') {
468: fprintf(f, "%so:\n\t-cp ../%so .\n", tail(np), np);
469: continue;
470: }
471: fprintf(f, "%so: ../%s%c\n", tail(np), np, och);
472: tp = tail(np);
473: if (och == 's') {
474: fprintf(f, "\t-ln -s ../%ss %sc\n", np, tp);
475: fprintf(f, "\t${CC} -E ${COPTS} %sc | ${AS} -o %so\n",
476: tp, tp);
477: fprintf(f, "\trm -f %sc\n\n", tp);
478: continue;
479: }
480: if (ftp->f_flags & CONFIGDEP)
481: extras = "${PARAM} ";
482: else
483: extras = "";
484: switch (ftp->f_type) {
485:
486: case NORMAL:
487: switch (machine) {
488:
489: case MACHINE_VAX:
490: fprintf(f, "\t${CC} -c -S ${COPTS} %s../%sc\n",
491: extras, np);
492: fprintf(f, "\t${C2} %ss | ${INLINE} | ${AS} -o %so\n",
493: tp, tp);
494: fprintf(f, "\trm -f %ss\n\n", tp);
495: break;
496: }
497: break;
498:
499: case DRIVER:
500: switch (machine) {
501:
502: case MACHINE_VAX:
503: fprintf(f, "\t${CC} -c -S ${COPTS} %s../%sc\n",
504: extras, np);
505: fprintf(f,"\t${C2} -i %ss | ${INLINE} | ${AS} -o %so\n",
506: tp, tp);
507: fprintf(f, "\trm -f %ss\n\n", tp);
508: break;
509: }
510: break;
511:
512: case PROFILING:
513: if (!profiling)
514: continue;
515: if (COPTS == 0) {
516: fprintf(stderr,
517: "config: COPTS undefined in generic makefile");
518: COPTS = "";
519: }
520: switch (machine) {
521:
522: case MACHINE_VAX:
523: fprintf(f, "\t${CC} -c -S %s %s../%sc\n",
524: COPTS, extras, np);
525: fprintf(f, "\tex - %ss < ${GPROF.EX}\n", tp);
526: fprintf(f, "\t${INLINE} %ss | ${AS} -o %so\n", tp, tp);
527: fprintf(f, "\trm -f %ss\n\n", tp);
528: break;
529: }
530: break;
531:
532: default:
533: printf("Don't know rules for %s\n", np);
534: break;
535: }
536: *cp = och;
537: }
538: }
539:
540: /*
541: * Create the load strings
542: */
543: do_load(f)
544: register FILE *f;
545: {
546: register struct file_list *fl;
547: int first = 1;
548: struct file_list *do_systemspec();
549:
550: fl = conf_list;
551: while (fl) {
552: if (fl->f_type != SYSTEMSPEC) {
553: fl = fl->f_next;
554: continue;
555: }
556: fl = do_systemspec(f, fl, first);
557: if (first)
558: first = 0;
559: }
560: fprintf(f, "all:");
561: for (fl = conf_list; fl != 0; fl = fl->f_next)
562: if (fl->f_type == SYSTEMSPEC)
563: fprintf(f, " %s", fl->f_needs);
564: fprintf(f, "\n");
565: }
566:
567: struct file_list *
568: do_systemspec(f, fl, first)
569: FILE *f;
570: register struct file_list *fl;
571: int first;
572: {
573:
574: fprintf(f, "%s: Makefile", fl->f_needs);
575: if (machine == MACHINE_VAX)
576: fprintf(f, " ${INLINECMD}", machinename);
577: fprintf(f, " locore.o emulate.o ${OBJS} param.o ioconf.o swap%s.o\n",
578: fl->f_fn);
579: fprintf(f, "\t@echo loading %s\n\t@rm -f %s\n",
580: fl->f_needs, fl->f_needs);
581: if (first) {
582: fprintf(f, "\t@sh ../conf/newvers.sh\n");
583: fprintf(f, "\t@${CC} $(CFLAGS) -c vers.c\n");
584: }
585: switch (machine) {
586:
587: case MACHINE_VAX:
588: fprintf(f, "\t@${LD} -n -o %s -e start -x -T 80000000 ",
589: fl->f_needs);
590: break;
591: }
592: fprintf(f, "locore.o emulate.o ${OBJS} vers.o ioconf.o param.o ");
593: fprintf(f, "swap%s.o\n", fl->f_fn);
594: fprintf(f, "\t@echo rearranging symbols\n");
595: fprintf(f, "\t@-symorder ../%s/symbols.sort %s\n",
596: machinename, fl->f_needs);
597: fprintf(f, "\t@size %s\n", fl->f_needs);
598: fprintf(f, "\t@chmod 755 %s\n\n", fl->f_needs);
599: do_swapspec(f, fl->f_fn);
600: for (fl = fl->f_next; fl->f_type == SWAPSPEC; fl = fl->f_next)
601: ;
602: return (fl);
603: }
604:
605: do_swapspec(f, name)
606: FILE *f;
607: register char *name;
608: {
609:
610: if (!eq(name, "generic")) {
611: fprintf(f, "swap%s.o: swap%s.c\n", name, name);
612: fprintf(f, "\t${CC} -c -O ${COPTS} swap%s.c\n\n", name);
613: return;
614: }
615: fprintf(f, "swapgeneric.o: ../%s/swapgeneric.c\n", machinename);
616: switch (machine) {
617:
618: case MACHINE_VAX:
619: fprintf(f, "\t${CC} -c -S ${COPTS} ");
620: fprintf(f, "../%s/swapgeneric.c\n", machinename);
621: fprintf(f, "\t${C2} swapgeneric.s | ${INLINE}");
622: fprintf(f, " | ${AS} -o swapgeneric.o\n");
623: fprintf(f, "\trm -f swapgeneric.s\n\n");
624: break;
625: }
626: }
627:
628: char *
629: raise(str)
630: register char *str;
631: {
632: register char *cp = str;
633:
634: while (*str) {
635: if (islower(*str))
636: *str = toupper(*str);
637: str++;
638: }
639: return (cp);
640: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.