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