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