document distributed with 4.2BSD
[unix-history] / usr / src / usr.sbin / config / mkmakefile.c
CommitLineData
cd68466f
DF
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
524aa063 7#ifndef lint
349eca08 8static char sccsid[] = "@(#)mkmakefile.c 5.9 (Berkeley) %G%";
cd68466f 9#endif not lint
28061b3f 10
01d17851 11/*
28061b3f
BJ
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.
01d17851
MT
15 */
16
17#include <stdio.h>
d5429061 18#include <ctype.h>
01d17851
MT
19#include "y.tab.h"
20#include "config.h"
21
28061b3f
BJ
22#define next_word(fp, wd) \
23 { register char *word = get_word(fp); \
22d68ad0
BJ
24 if (word == (char *)EOF) \
25 return; \
28061b3f
BJ
26 else \
27 wd = word; \
28 }
01d17851 29
28061b3f 30static struct file_list *fcur;
15eb15d7 31char *tail();
01d17851
MT
32
33/*
e3dad45e 34 * Lookup a file, by name.
01d17851 35 */
28061b3f
BJ
36struct file_list *
37fl_lookup(file)
38 register char *file;
01d17851 39{
28061b3f
BJ
40 register struct file_list *fp;
41
22d68ad0 42 for (fp = ftab ; fp != 0; fp = fp->f_next) {
28061b3f
BJ
43 if (eq(fp->f_fn, file))
44 return (fp);
45 }
46 return (0);
01d17851
MT
47}
48
15eb15d7
KM
49/*
50 * Lookup a file, by final component name.
51 */
52struct file_list *
53fltail_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
01d17851 65/*
28061b3f 66 * Make a new file list entry
01d17851 67 */
28061b3f
BJ
68struct file_list *
69new_fent()
01d17851 70{
28061b3f
BJ
71 register struct file_list *fp;
72
73 fp = (struct file_list *) malloc(sizeof *fp);
22d68ad0
BJ
74 fp->f_needs = 0;
75 fp->f_next = 0;
3c812eeb
SL
76 fp->f_flags = 0;
77 fp->f_type = 0;
22d68ad0 78 if (fcur == 0)
28061b3f
BJ
79 fcur = ftab = fp;
80 else
81 fcur->f_next = fp;
82 fcur = fp;
83 return (fp);
01d17851
MT
84}
85
28061b3f 86char *COPTS;
18d7531d
SL
87static 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]))
28061b3f 95
01d17851 96/*
28061b3f 97 * Build the makefile from the skeleton
01d17851 98 */
01d17851
MT
99makefile()
100{
28061b3f
BJ
101 FILE *ifp, *ofp;
102 char line[BUFSIZ];
103 struct opt *op;
18d7531d 104 struct users *up;
28061b3f
BJ
105
106 read_files();
05b83a6c 107 strcpy(line, "../conf/Makefile.");
22d68ad0 108 (void) strcat(line, machinename);
28061b3f 109 ifp = fopen(line, "r");
22d68ad0 110 if (ifp == 0) {
28061b3f
BJ
111 perror(line);
112 exit(1);
113 }
05b83a6c 114 ofp = fopen(path("Makefile"), "w");
22d68ad0 115 if (ofp == 0) {
05b83a6c 116 perror(path("Makefile"));
28061b3f
BJ
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");
18d7531d
SL
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];
28061b3f 143 if (maxusers == 0) {
18d7531d
SL
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);
28061b3f
BJ
151 fprintf(ofp, "PARAM=-DTIMEZONE=%d -DDST=%d -DMAXUSERS=%d\n",
152 timezone, dst, maxusers);
7c1d4665
MK
153 for (op = mkopt; op; op = op->op_next)
154 fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
22d68ad0 155 while (fgets(line, BUFSIZ, ifp) != 0) {
28061b3f
BJ
156 if (*line == '%')
157 goto percent;
158 if (profiling && strncmp(line, "COPTS=", 6) == 0) {
159 register char *cp;
160
0356b29c
SL
161 fprintf(ofp,
162 "GPROF.EX=/usr/src/lib/libc/%s/csu/gmon.ex\n",
163 machinename);
28061b3f
BJ
164 cp = index(line, '\n');
165 if (cp)
166 *cp = 0;
167 cp = line + 6;
168 while (*cp && (*cp == ' ' || *cp == '\t'))
169 cp++;
22d68ad0 170 COPTS = malloc((unsigned)(strlen(cp) + 1));
28061b3f 171 if (COPTS == 0) {
f2db9eb7 172 printf("config: out of memory\n");
28061b3f
BJ
173 exit(1);
174 }
175 strcpy(COPTS, cp);
176 fprintf(ofp, "%s -pg\n", line);
177 continue;
8486638c 178 }
28061b3f 179 fprintf(ofp, "%s", line);
8486638c 180 continue;
28061b3f
BJ
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);
01d17851 194 }
73845e07
SL
195 (void) fclose(ifp);
196 (void) fclose(ofp);
01d17851
MT
197}
198
199/*
28061b3f
BJ
200 * Read in the information about files used in making the system.
201 * Store it in the ftab linked list.
01d17851 202 */
01d17851
MT
203read_files()
204{
28061b3f 205 FILE *fp;
e3dad45e 206 register struct file_list *tp, *pf;
28061b3f 207 register struct device *dp;
05b83a6c 208 register struct opt *op;
28061b3f
BJ
209 char *wd, *this, *needs, *devorprof;
210 char fname[32];
05b83a6c 211 int nreqs, first = 1, configdep, isdup;
28061b3f 212
22d68ad0
BJ
213 ftab = 0;
214 (void) strcpy(fname, "files");
28061b3f
BJ
215openit:
216 fp = fopen(fname, "r");
22d68ad0 217 if (fp == 0) {
73845e07 218 perror(fname);
28061b3f
BJ
219 exit(1);
220 }
221next:
3c812eeb
SL
222 /*
223 * filename [ standard | optional ] [ config-dependent ]
224 * [ dev* | profiling-routine ] [ device-driver]
225 */
28061b3f 226 wd = get_word(fp);
22d68ad0
BJ
227 if (wd == (char *)EOF) {
228 (void) fclose(fp);
15eb15d7 229 if (first == 1) {
22d68ad0 230 (void) sprintf(fname, "files.%s", machinename);
15eb15d7 231 first++;
28061b3f
BJ
232 goto openit;
233 }
15eb15d7
KM
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 }
28061b3f
BJ
241 return;
242 }
22d68ad0 243 if (wd == 0)
28061b3f 244 goto next;
01d17851 245 this = ns(wd);
01d17851 246 next_word(fp, wd);
22d68ad0 247 if (wd == 0) {
f2db9eb7 248 printf("%s: No type for %s.\n",
28061b3f
BJ
249 fname, this);
250 exit(1);
01d17851 251 }
e3dad45e 252 if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
05b83a6c
MK
253 isdup = 1;
254 else
255 isdup = 0;
15eb15d7
KM
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);
28061b3f
BJ
260 nreqs = 0;
261 devorprof = "";
3c812eeb 262 configdep = 0;
28061b3f
BJ
263 needs = 0;
264 if (eq(wd, "standard"))
265 goto checkdev;
266 if (!eq(wd, "optional")) {
3c812eeb 267 printf("%s: %s must be optional or standard\n", fname, this);
28061b3f
BJ
268 exit(1);
269 }
270nextopt:
271 next_word(fp, wd);
22d68ad0 272 if (wd == 0)
28061b3f 273 goto doneopt;
3c812eeb
SL
274 if (eq(wd, "config-dependent")) {
275 configdep++;
276 goto nextopt;
277 }
28061b3f 278 devorprof = wd;
73845e07
SL
279 if (eq(wd, "device-driver") || eq(wd, "profiling-routine")) {
280 next_word(fp, wd);
28061b3f 281 goto save;
73845e07 282 }
28061b3f 283 nreqs++;
05b83a6c 284 if (needs == 0 && nreqs == 1)
28061b3f 285 needs = ns(wd);
05b83a6c
MK
286 if (isdup)
287 goto invis;
22d68ad0 288 for (dp = dtab; dp != 0; dp = dp->d_next)
28061b3f
BJ
289 if (eq(dp->d_name, wd))
290 goto nextopt;
05b83a6c
MK
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 }
299invis:
22d68ad0 300 while ((wd = get_word(fp)) != 0)
28061b3f 301 ;
92a477cd
MK
302 if (tp == 0)
303 tp = new_fent();
01d17851 304 tp->f_fn = this;
28061b3f
BJ
305 tp->f_type = INVISIBLE;
306 tp->f_needs = needs;
05b83a6c 307 tp->f_flags = isdup;
28061b3f 308 goto next;
3c812eeb 309
28061b3f
BJ
310doneopt:
311 if (nreqs == 0) {
f2db9eb7 312 printf("%s: what is %s optional on?\n",
28061b3f
BJ
313 fname, this);
314 exit(1);
315 }
3c812eeb 316
28061b3f
BJ
317checkdev:
318 if (wd) {
2fcca161 319 next_word(fp, wd);
3c812eeb
SL
320 if (wd) {
321 if (eq(wd, "config-dependent")) {
322 configdep++;
323 goto checkdev;
324 }
28061b3f
BJ
325 devorprof = wd;
326 next_word(fp, wd);
2fcca161 327 }
01d17851 328 }
3c812eeb 329
28061b3f 330save:
3c812eeb 331 if (wd) {
f2db9eb7 332 printf("%s: syntax error describing %s\n",
28061b3f
BJ
333 fname, this);
334 exit(1);
2fcca161 335 }
73845e07
SL
336 if (eq(devorprof, "profiling-routine") && profiling == 0)
337 goto next;
92a477cd
MK
338 if (tp == 0)
339 tp = new_fent();
28061b3f
BJ
340 tp->f_fn = this;
341 if (eq(devorprof, "device-driver"))
3c812eeb 342 tp->f_type = DRIVER;
28061b3f
BJ
343 else if (eq(devorprof, "profiling-routine"))
344 tp->f_type = PROFILING;
345 else
346 tp->f_type = NORMAL;
3c812eeb
SL
347 tp->f_flags = 0;
348 if (configdep)
349 tp->f_flags |= CONFIGDEP;
28061b3f 350 tp->f_needs = needs;
e3dad45e
MK
351 if (pf && pf->f_type == INVISIBLE)
352 pf->f_flags = 1; /* mark as duplicate */
28061b3f 353 goto next;
01d17851
MT
354}
355
05b83a6c
MK
356opteq(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
01d17851 373do_objs(fp)
28061b3f 374 FILE *fp;
01d17851 375{
15eb15d7 376 register struct file_list *tp, *fl;
28061b3f
BJ
377 register int lpos, len;
378 register char *cp, och, *sp;
15eb15d7 379 char swapname[32];
28061b3f
BJ
380
381 fprintf(fp, "OBJS=");
382 lpos = 6;
22d68ad0 383 for (tp = ftab; tp != 0; tp = tp->f_next) {
28061b3f
BJ
384 if (tp->f_type == INVISIBLE)
385 continue;
386 sp = tail(tp->f_fn);
36edb824
SL
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);
15eb15d7
KM
391 if (eq(sp, swapname))
392 goto cont;
393 }
28061b3f
BJ
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;
36edb824
SL
404cont:
405 ;
01d17851 406 }
28061b3f
BJ
407 if (lpos != 8)
408 putc('\n', fp);
01d17851
MT
409}
410
01d17851 411do_cfiles(fp)
28061b3f 412 FILE *fp;
01d17851 413{
28061b3f
BJ
414 register struct file_list *tp;
415 register int lpos, len;
416
417 fprintf(fp, "CFILES=");
418 lpos = 8;
22d68ad0 419 for (tp = ftab; tp != 0; tp = tp->f_next) {
28061b3f
BJ
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;
01d17851 430 }
28061b3f
BJ
431 if (lpos != 8)
432 putc('\n', fp);
01d17851
MT
433}
434
28061b3f
BJ
435char *
436tail(fn)
437 char *fn;
01d17851 438{
28061b3f 439 register char *cp;
01d17851 440
28061b3f 441 cp = rindex(fn, '/');
15eb15d7
KM
442 if (cp == 0)
443 return (fn);
28061b3f 444 return (cp+1);
01d17851
MT
445}
446
447/*
28061b3f
BJ
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.
01d17851 453 */
01d17851 454do_rules(f)
28061b3f 455 FILE *f;
01d17851 456{
28061b3f
BJ
457 register char *cp, *np, och, *tp;
458 register struct file_list *ftp;
3c812eeb 459 char *extras;
01d17851 460
22d68ad0 461for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
01d17851 462 if (ftp->f_type == INVISIBLE)
28061b3f 463 continue;
01d17851
MT
464 cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
465 och = *cp;
466 *cp = '\0';
fb547c4b
MK
467 if (och == 'o') {
468 fprintf(f, "%so:\n\t-cp ../%so .\n", tail(np), np);
469 continue;
470 }
01d17851
MT
471 fprintf(f, "%so: ../%s%c\n", tail(np), np, och);
472 tp = tail(np);
28061b3f 473 if (och == 's') {
cd42919c 474 fprintf(f, "\t-ln -s ../%ss %sc\n", np, tp);
46e3cd06 475 fprintf(f, "\t${CC} -E ${COPTS} %sc | ${AS} -o %so\n",
cd42919c
KM
476 tp, tp);
477 fprintf(f, "\trm -f %sc\n\n", tp);
28061b3f 478 continue;
01d17851 479 }
3c812eeb
SL
480 if (ftp->f_flags & CONFIGDEP)
481 extras = "${PARAM} ";
482 else
483 extras = "";
28061b3f
BJ
484 switch (ftp->f_type) {
485
486 case NORMAL:
487 switch (machine) {
488
489 case MACHINE_VAX:
46e3cd06 490 fprintf(f, "\t${CC} -c -S ${COPTS} %s../%sc\n",
3c812eeb 491 extras, np);
18d7531d
SL
492 fprintf(f, "\t${C2} %ss | ${INLINE} | ${AS} -o %so\n",
493 tp, tp);
28061b3f
BJ
494 fprintf(f, "\trm -f %ss\n\n", tp);
495 break;
28061b3f
BJ
496 }
497 break;
498
3c812eeb 499 case DRIVER:
28061b3f
BJ
500 switch (machine) {
501
502 case MACHINE_VAX:
46e3cd06 503 fprintf(f, "\t${CC} -c -S ${COPTS} %s../%sc\n",
3c812eeb 504 extras, np);
18d7531d
SL
505 fprintf(f,"\t${C2} -i %ss | ${INLINE} | ${AS} -o %so\n",
506 tp, tp);
28061b3f
BJ
507 fprintf(f, "\trm -f %ss\n\n", tp);
508 break;
28061b3f
BJ
509 }
510 break;
511
512 case PROFILING:
8486638c
SL
513 if (!profiling)
514 continue;
515 if (COPTS == 0) {
516 fprintf(stderr,
28061b3f 517 "config: COPTS undefined in generic makefile");
8486638c
SL
518 COPTS = "";
519 }
28061b3f
BJ
520 switch (machine) {
521
522 case MACHINE_VAX:
46e3cd06 523 fprintf(f, "\t${CC} -c -S %s %s../%sc\n",
3c812eeb 524 COPTS, extras, np);
c7456392 525 fprintf(f, "\tex - %ss < ${GPROF.EX}\n", tp);
18d7531d 526 fprintf(f, "\t${INLINE} %ss | ${AS} -o %so\n", tp, tp);
28061b3f
BJ
527 fprintf(f, "\trm -f %ss\n\n", tp);
528 break;
28061b3f 529 }
73845e07 530 break;
28061b3f
BJ
531
532 default:
3c812eeb 533 printf("Don't know rules for %s\n", np);
28061b3f
BJ
534 break;
535 }
01d17851 536 *cp = och;
28061b3f 537}
01d17851
MT
538}
539
540/*
541 * Create the load strings
542 */
01d17851 543do_load(f)
28061b3f 544 register FILE *f;
01d17851 545{
28061b3f 546 register struct file_list *fl;
821eeaae 547 int first = 1;
36edb824 548 struct file_list *do_systemspec();
28061b3f 549
36edb824
SL
550 fl = conf_list;
551 while (fl) {
552 if (fl->f_type != SYSTEMSPEC) {
553 fl = fl->f_next;
554 continue;
28061b3f 555 }
36edb824
SL
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}
28061b3f 566
36edb824
SL
567struct file_list *
568do_systemspec(f, fl, first)
569 FILE *f;
570 register struct file_list *fl;
571 int first;
572{
28061b3f 573
05b83a6c 574 fprintf(f, "%s: Makefile", fl->f_needs);
57c2bd16 575 if (machine == MACHINE_VAX)
c9191830 576 fprintf(f, " ${INLINECMD}", machinename);
349eca08
JB
577 fprintf(f, " locore.o emulate.o ${OBJS} param.o ioconf.o swap%s.o\n",
578 fl->f_fn);
36edb824
SL
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");
190b5698 584 }
36edb824 585 switch (machine) {
28061b3f 586
36edb824
SL
587 case MACHINE_VAX:
588 fprintf(f, "\t@${LD} -n -o %s -e start -x -T 80000000 ",
589 fl->f_needs);
590 break;
36edb824 591 }
349eca08 592 fprintf(f, "locore.o emulate.o ${OBJS} vers.o ioconf.o param.o ");
36edb824
SL
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
605do_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);
46e3cd06 612 fprintf(f, "\t${CC} -c -O ${COPTS} swap%s.c\n\n", name);
36edb824
SL
613 return;
614 }
615 fprintf(f, "swapgeneric.o: ../%s/swapgeneric.c\n", machinename);
616 switch (machine) {
617
618 case MACHINE_VAX:
46e3cd06 619 fprintf(f, "\t${CC} -c -S ${COPTS} ");
36edb824 620 fprintf(f, "../%s/swapgeneric.c\n", machinename);
18d7531d 621 fprintf(f, "\t${C2} swapgeneric.s | ${INLINE}");
36edb824
SL
622 fprintf(f, " | ${AS} -o swapgeneric.o\n");
623 fprintf(f, "\trm -f swapgeneric.s\n\n");
624 break;
28061b3f 625 }
01d17851 626}
d5429061 627
22d68ad0 628char *
d5429061 629raise(str)
28061b3f 630 register char *str;
d5429061 631{
28061b3f
BJ
632 register char *cp = str;
633
634 while (*str) {
635 if (islower(*str))
636 *str = toupper(*str);
637 str++;
638 }
639 return (cp);
d5429061 640}