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