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