mkmakefile.c revision 152811
11573Srgrimes/* 21573Srgrimes * Copyright (c) 1993, 19801990 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 4. Neither the name of the University nor the names of its contributors 141573Srgrimes * may be used to endorse or promote products derived from this software 151573Srgrimes * without specific prior written permission. 161573Srgrimes * 171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271573Srgrimes * SUCH DAMAGE. 281573Srgrimes */ 291573Srgrimes 301573Srgrimes#ifndef lint 311573Srgrimes#if 0 321573Srgrimesstatic char sccsid[] = "@(#)mkmakefile.c 8.1 (Berkeley) 6/6/93"; 331573Srgrimes#endif 341573Srgrimesstatic const char rcsid[] = 351573Srgrimes "$FreeBSD: head/usr.sbin/config/mkmakefile.c 152811 2005-11-25 22:25:34Z ru $"; 361573Srgrimes#endif /* not lint */ 371573Srgrimes 3823668Speter/* 391573Srgrimes * Build the makefile for the system, from 4090041Sobrien * the information in the files files and the 4190041Sobrien * additional files for the machine being compiled to. 421573Srgrimes */ 431573Srgrimes 441573Srgrimes#include <ctype.h> 457615Swpaul#include <err.h> 467615Swpaul#include <stdio.h> 471573Srgrimes#include <string.h> 487615Swpaul#include <sys/param.h> 499978Swpaul#include "y.tab.h" 509978Swpaul#include "config.h" 519978Swpaul#include "configvers.h" 529978Swpaul 539978Swpaul#define next_word(fp, wd) \ 549978Swpaul { char *word = get_word(fp); \ 559978Swpaul if (word == (char *)EOF) \ 569978Swpaul return; \ 579978Swpaul else \ 589978Swpaul wd = word; \ 599978Swpaul } 609978Swpaul#define next_quoted_word(fp, wd) \ 619978Swpaul { char *word = get_quoted_word(fp); \ 629978Swpaul if (word == (char *)EOF) \ 639978Swpaul return; \ 649978Swpaul else \ 659978Swpaul wd = word; \ 669978Swpaul } 679978Swpaul 689978Swpaulstatic char *tail(char *); 699978Swpaulstatic void do_clean(FILE *); 709978Swpaulstatic void do_rules(FILE *); 719978Swpaulstatic void do_xxfiles(char *, FILE *); 729978Swpaulstatic void do_objs(FILE *); 739978Swpaulstatic void do_before_depend(FILE *); 749978Swpaulstatic int opteq(const char *, const char *); 759978Swpaulstatic void read_files(void); 769978Swpaul 779978Swpaul/* 789978Swpaul * Lookup a file, by name. 799978Swpaul */ 809978Swpaulstatic struct file_list * 819978Swpaulfl_lookup(char *file) 829978Swpaul{ 839978Swpaul struct file_list *fp; 849978Swpaul 859978Swpaul STAILQ_FOREACH(fp, &ftab, f_next) { 869978Swpaul if (eq(fp->f_fn, file)) 8730288Swpaul return (fp); 887615Swpaul } 897615Swpaul return (0); 907615Swpaul} 919978Swpaul 929978Swpaul/* 939978Swpaul * Make a new file list entry 949978Swpaul */ 959978Swpaulstatic struct file_list * 9610521Swpaulnew_fent(void) 977615Swpaul{ 989978Swpaul struct file_list *fp; 997615Swpaul 1007615Swpaul fp = (struct file_list *) malloc(sizeof *fp); 1019978Swpaul bzero(fp, sizeof *fp); 1021573Srgrimes STAILQ_INSERT_TAIL(&ftab, fp, f_next); 1039978Swpaul return (fp); 1041573Srgrimes} 1051573Srgrimes 1061573Srgrimes/* 1071573Srgrimes * Build the makefile from the skeleton 1081573Srgrimes */ 1091573Srgrimesvoid 1101573Srgrimesmakefile(void) 1111573Srgrimes{ 1121573Srgrimes FILE *ifp, *ofp; 1131573Srgrimes char line[BUFSIZ]; 1141573Srgrimes struct opt *op; 1151573Srgrimes int versreq; 1161573Srgrimes char *s; 1171573Srgrimes 1181573Srgrimes read_files(); 1191573Srgrimes snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename); 1201573Srgrimes ifp = fopen(line, "r"); 1211573Srgrimes if (ifp == 0) { 1221573Srgrimes snprintf(line, sizeof(line), "Makefile.%s", machinename); 1231573Srgrimes ifp = fopen(line, "r"); 1241573Srgrimes } 1251573Srgrimes if (ifp == 0) 1261573Srgrimes err(1, "%s", line); 1271573Srgrimes 1281573Srgrimes /* XXX this check seems to be misplaced. */ 1291573Srgrimes if (SLIST_EMPTY(&cputype)) { 1301573Srgrimes printf("cpu type must be specified\n"); 1311573Srgrimes exit(1); 1321573Srgrimes } 1331573Srgrimes 1341573Srgrimes ofp = fopen(path("Makefile.new"), "w"); 1351573Srgrimes if (ofp == 0) 1361573Srgrimes err(1, "%s", path("Makefile.new")); 1371573Srgrimes fprintf(ofp, "KERN_IDENT=%s\n", ident); 1381573Srgrimes SLIST_FOREACH(op, &mkopt, op_next) 1391573Srgrimes fprintf(ofp, "%s=%s\n", op->op_name, op->op_value); 1401573Srgrimes if (debugging) 1411573Srgrimes fprintf(ofp, "DEBUG=-g\n"); 1421573Srgrimes if (profiling) 1431573Srgrimes fprintf(ofp, "PROFLEVEL=%d\n", profiling); 1441573Srgrimes if (*srcdir != '\0') 1451573Srgrimes fprintf(ofp,"S=%s\n", srcdir); 1461573Srgrimes while (fgets(line, BUFSIZ, ifp) != 0) { 1471573Srgrimes if (*line != '%') { 1481573Srgrimes fprintf(ofp, "%s", line); 1491573Srgrimes continue; 1501573Srgrimes } 1511573Srgrimes if (eq(line, "%BEFORE_DEPEND\n")) 1521573Srgrimes do_before_depend(ofp); 1531573Srgrimes else if (eq(line, "%OBJS\n")) 1541573Srgrimes do_objs(ofp); 1559978Swpaul else if (strncmp(line, "%FILES.", 7) == 0) 1569978Swpaul do_xxfiles(line, ofp); 1579978Swpaul else if (eq(line, "%RULES\n")) 1589978Swpaul do_rules(ofp); 1599978Swpaul else if (eq(line, "%CLEAN\n")) 1607336Swpaul do_clean(ofp); 1617289Swpaul else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 0) { 1627336Swpaul versreq = atoi(line + sizeof("%VERSREQ=") - 1); 1637289Swpaul if (versreq != CONFIGVERS) { 1647336Swpaul fprintf(stderr, "ERROR: version of config(8) does not match kernel!\n"); 1651573Srgrimes fprintf(stderr, "config version = %d, ", CONFIGVERS); 1661573Srgrimes fprintf(stderr, "version required = %d\n\n", versreq); 1671573Srgrimes fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n"); 1689978Swpaul fprintf(stderr, "with your /usr/src/sys and install a new config binary\n"); 16910521Swpaul fprintf(stderr, "before trying this again.\n\n"); 17010521Swpaul fprintf(stderr, "If running the new config fails check your config\n"); 1719978Swpaul fprintf(stderr, "file against the GENERIC or LINT config files for\n"); 17215264Swpaul fprintf(stderr, "changes in config syntax, or option/device naming\n"); 1739978Swpaul fprintf(stderr, "conventions\n\n"); 1749978Swpaul exit(1); 1759978Swpaul } 1769978Swpaul } else 1779978Swpaul fprintf(stderr, 1789978Swpaul "Unknown %% construct in generic makefile: %s", 1799978Swpaul line); 1809978Swpaul } 1819978Swpaul (void) fclose(ifp); 1829978Swpaul (void) fclose(ofp); 1839978Swpaul moveifchanged(path("Makefile.new"), path("Makefile")); 1849978Swpaul 1859978Swpaul /* XXX makefile() should make the Makefile, not hints.c. */ 1869978Swpaul if (hints) { 1879978Swpaul ifp = fopen(hints, "r"); 1889978Swpaul if (ifp == NULL) 1899978Swpaul err(1, "%s", hints); 1909978Swpaul } else { 1919978Swpaul ifp = NULL; 1929978Swpaul } 1939978Swpaul ofp = fopen(path("hints.c.new"), "w"); 1949978Swpaul if (ofp == NULL) 19510521Swpaul err(1, "%s", path("hints.c.new")); 19610521Swpaul fprintf(ofp, "#include <sys/types.h>\n"); 19712585Swpaul fprintf(ofp, "#include <sys/systm.h>\n"); 19812585Swpaul fprintf(ofp, "\n"); 1999978Swpaul fprintf(ofp, "int hintmode = %d;\n", hintmode); 20010521Swpaul fprintf(ofp, "char static_hints[] = {\n"); 2019978Swpaul if (ifp) { 2021573Srgrimes while (fgets(line, BUFSIZ, ifp) != 0) { 2039978Swpaul /* zap trailing CR and/or LF */ 2041573Srgrimes while ((s = rindex(line, '\n')) != NULL) 2051573Srgrimes *s = '\0'; 2061573Srgrimes while ((s = rindex(line, '\r')) != NULL) 2071573Srgrimes *s = '\0'; 2081573Srgrimes /* remove # comments */ 2091573Srgrimes s = index(line, '#'); 2101573Srgrimes if (s) 2119978Swpaul *s = '\0'; 2129978Swpaul /* remove any whitespace and " characters */ 2131573Srgrimes s = line; 2141573Srgrimes while (*s) { 2151573Srgrimes if (*s == ' ' || *s == '\t' || *s == '"') { 2161573Srgrimes while (*s) { 2171573Srgrimes s[0] = s[1]; 2181573Srgrimes s++; 2191573Srgrimes } 2201573Srgrimes /* start over */ 2211573Srgrimes s = line; 2221573Srgrimes continue; 2231573Srgrimes } 2241573Srgrimes s++; 2259978Swpaul } 2269978Swpaul /* anything left? */ 2279978Swpaul if (*line == '\0') 2281573Srgrimes continue; 2291573Srgrimes fprintf(ofp, "\"%s\\0\"\n", line); 2301573Srgrimes } 2311573Srgrimes } 2321573Srgrimes fprintf(ofp, "\"\\0\"\n};\n"); 2331573Srgrimes if (ifp) 2341573Srgrimes fclose(ifp); 2351573Srgrimes fclose(ofp); 2361573Srgrimes moveifchanged(path("hints.c.new"), path("hints.c")); 2371573Srgrimes 2381573Srgrimes /* XXX makefile() should make the Makefile, not env.c. */ 2391573Srgrimes if (env) { 2401573Srgrimes ifp = fopen(env, "r"); 2411573Srgrimes if (ifp == NULL) 2421573Srgrimes err(1, "%s", env); 2431573Srgrimes } else { 2441573Srgrimes ifp = NULL; 24590041Sobrien } 24690041Sobrien ofp = fopen(path("env.c.new"), "w"); 2471573Srgrimes if (ofp == NULL) 2481573Srgrimes err(1, "%s", path("env.c.new")); 2491573Srgrimes fprintf(ofp, "#include <sys/types.h>\n"); 2501573Srgrimes fprintf(ofp, "#include <sys/systm.h>\n"); 2511573Srgrimes fprintf(ofp, "\n"); 2521573Srgrimes fprintf(ofp, "int envmode = %d;\n", envmode); 2531573Srgrimes fprintf(ofp, "char static_env[] = {\n"); 2541573Srgrimes if (ifp) { 2551573Srgrimes while (fgets(line, BUFSIZ, ifp) != 0) { 2561573Srgrimes /* zap trailing CR and/or LF */ 2571573Srgrimes while ((s = rindex(line, '\n')) != NULL) 2581573Srgrimes *s = '\0'; 2591573Srgrimes while ((s = rindex(line, '\r')) != NULL) 2601573Srgrimes *s = '\0'; 2611573Srgrimes /* remove # comments */ 2621573Srgrimes s = index(line, '#'); 2631573Srgrimes if (s) 2641573Srgrimes *s = '\0'; 2651573Srgrimes /* remove any whitespace and " characters */ 2661573Srgrimes s = line; 2671573Srgrimes while (*s) { 2681573Srgrimes if (*s == ' ' || *s == '\t' || *s == '"') { 2691573Srgrimes while (*s) { 2701573Srgrimes s[0] = s[1]; 2711573Srgrimes s++; 2721573Srgrimes } 2731573Srgrimes /* start over */ 2747149Swpaul s = line; 2757223Swpaul continue; 2767149Swpaul } 2771573Srgrimes s++; 2781573Srgrimes } 2799978Swpaul /* anything left? */ 2809998Swpaul if (*line == '\0') 28131180Swpaul continue; 28231180Swpaul fprintf(ofp, "\"%s\\0\"\n", line); 2839978Swpaul } 28431180Swpaul } 28531180Swpaul fprintf(ofp, "\"\\0\"\n};\n"); 2869978Swpaul if (ifp) 28731180Swpaul fclose(ifp); 28852856Sache fclose(ofp); 28931180Swpaul moveifchanged(path("env.c.new"), path("env.c")); 29015264Swpaul} 29133950Ssteve 29233950Sstevestatic void 29352856Sacheread_file(char *fname) 29433950Ssteve{ 29533950Ssteve FILE *fp; 29615839Swpaul struct file_list *tp; 29752856Sache struct device *dp; 29833950Ssteve struct opt *op; 29915839Swpaul char *wd, *this, *compilewith, *depends, *clean, *warning; 30015839Swpaul int nreqs, devfound, std, filetype, 3019978Swpaul imp_rule, no_obj, before_depend, mandatory, nowerror; 3029978Swpaul 3039978Swpaul fp = fopen(fname, "r"); 3049978Swpaul if (fp == 0) 3059978Swpaul err(1, "%s", fname); 3069978Swpaulnext: 3079978Swpaul /* 3089978Swpaul * filename [ standard | mandatory | optional ] 3099978Swpaul * [ dev* | profiling-routine ] [ no-obj ] 3109978Swpaul * [ compile-with "compile rule" [no-implicit-rule] ] 3119978Swpaul * [ dependency "dependency-list"] [ before-depend ] 3129978Swpaul * [ clean "file-list"] [ warning "text warning" ] 3139978Swpaul */ 3149978Swpaul wd = get_word(fp); 3159978Swpaul if (wd == (char *)EOF) { 3169978Swpaul (void) fclose(fp); 3179978Swpaul return; 3189978Swpaul } 3199978Swpaul if (wd == 0) 3209978Swpaul goto next; 3219978Swpaul if (wd[0] == '#') 3229978Swpaul { 3239978Swpaul while (((wd = get_word(fp)) != (char *)EOF) && wd) 3249978Swpaul ; 3251573Srgrimes goto next; 3261573Srgrimes } 3271573Srgrimes this = ns(wd); 3281573Srgrimes next_word(fp, wd); 3291573Srgrimes if (wd == 0) { 33017141Sjkh printf("%s: No type for %s.\n", 3311573Srgrimes fname, this); 3321573Srgrimes exit(1); 3339978Swpaul } 3349978Swpaul tp = fl_lookup(this); 3359978Swpaul nreqs = 0; 33615264Swpaul compilewith = 0; 3379978Swpaul depends = 0; 3387336Swpaul clean = 0; 3399287Swpaul warning = 0; 3407336Swpaul std = mandatory = 0; 3417336Swpaul imp_rule = 0; 3427336Swpaul no_obj = 0; 3439978Swpaul before_depend = 0; 3449978Swpaul nowerror = 0; 3459978Swpaul filetype = NORMAL; 3461573Srgrimes if (eq(wd, "standard")) { 3479978Swpaul std = 1; 34815264Swpaul /* 3499978Swpaul * If an entry is marked "mandatory", config will abort if it's 3509978Swpaul * not called by a configuration line in the config file. Apart 3519978Swpaul * from this, the device is handled like one marked "optional". 3529978Swpaul */ 3539978Swpaul } else if (eq(wd, "mandatory")) { 3549978Swpaul mandatory = 1; 35530390Swpaul } else if (!eq(wd, "optional")) { 3569978Swpaul printf("%s: %s must be optional, mandatory or standard\n", 3579978Swpaul fname, this); 3589978Swpaul exit(1); 35920161Sjkh } 36030390Swpaulnextparam: 3619978Swpaul next_word(fp, wd); 36230390Swpaul if (wd == 0) { 36330390Swpaul if (tp != NULL) 36430390Swpaul goto next; 36530390Swpaul goto doneparam; 36630390Swpaul } 36730390Swpaul if (eq(wd, "no-obj")) { 36830390Swpaul no_obj++; 36930390Swpaul goto nextparam; 37030390Swpaul } 37130390Swpaul if (eq(wd, "no-implicit-rule")) { 37215264Swpaul if (compilewith == 0) { 37315264Swpaul printf("%s: alternate rule required when " 37415264Swpaul "\"no-implicit-rule\" is specified.\n", 3759978Swpaul fname); 37615264Swpaul } 37715264Swpaul imp_rule++; 3789978Swpaul goto nextparam; 3799978Swpaul } 38030390Swpaul if (eq(wd, "before-depend")) { 38130390Swpaul before_depend++; 38230390Swpaul goto nextparam; 38330390Swpaul } 38430390Swpaul if (eq(wd, "dependency")) { 38530390Swpaul next_quoted_word(fp, wd); 38630390Swpaul if (wd == 0) { 38730390Swpaul printf("%s: %s missing compile command string.\n", 38830390Swpaul fname, this); 38930390Swpaul exit(1); 39030390Swpaul } 3919978Swpaul depends = ns(wd); 39230390Swpaul goto nextparam; 3939978Swpaul } 3949978Swpaul if (eq(wd, "clean")) { 39530390Swpaul next_quoted_word(fp, wd); 3961573Srgrimes if (wd == 0) { 3979978Swpaul printf("%s: %s missing clean file list.\n", 3989978Swpaul fname, this); 3999978Swpaul exit(1); 4001573Srgrimes } 4011573Srgrimes clean = ns(wd); 4021573Srgrimes goto nextparam; 4031573Srgrimes } 4041573Srgrimes if (eq(wd, "compile-with")) { 4051573Srgrimes next_quoted_word(fp, wd); 4061573Srgrimes if (wd == 0) { 4071573Srgrimes printf("%s: %s missing compile command string.\n", 4081573Srgrimes fname, this); 4091573Srgrimes exit(1); 4101573Srgrimes } 4111573Srgrimes compilewith = ns(wd); 4121573Srgrimes goto nextparam; 4131573Srgrimes } 41490041Sobrien if (eq(wd, "warning")) { 41590041Sobrien next_quoted_word(fp, wd); 4169287Swpaul if (wd == 0) { 41790041Sobrien printf("%s: %s missing warning text string.\n", 4189287Swpaul fname, this); 4191573Srgrimes exit(1); 4201573Srgrimes } 4211573Srgrimes warning = ns(wd); 4221573Srgrimes goto nextparam; 4231573Srgrimes } 4241573Srgrimes nreqs++; 4251573Srgrimes if (eq(wd, "local")) { 4261573Srgrimes filetype = LOCAL; 4271573Srgrimes goto nextparam; 4281573Srgrimes } 4291573Srgrimes if (eq(wd, "no-depend")) { 4301573Srgrimes filetype = NODEPEND; 4311573Srgrimes goto nextparam; 4321573Srgrimes } 4331573Srgrimes if (eq(wd, "profiling-routine")) { 4341573Srgrimes filetype = PROFILING; 4359287Swpaul goto nextparam; 4369287Swpaul } 4379287Swpaul if (eq(wd, "nowerror")) { 4389287Swpaul nowerror = 1; 4399287Swpaul goto nextparam; 4409287Swpaul } 4419287Swpaul devfound = 0; /* XXX duplicate device entries */ 4421573Srgrimes STAILQ_FOREACH(dp, &dtab, d_next) 4439287Swpaul if (eq(dp->d_name, wd)) { 4441573Srgrimes dp->d_done |= DEVDONE; 4451573Srgrimes devfound = 1; 4461573Srgrimes } 4471573Srgrimes if (devfound) 4487149Swpaul goto nextparam; 4497149Swpaul if (tp != NULL) 4501573Srgrimes goto skip; 4511573Srgrimes if (mandatory) { 4521573Srgrimes printf("%s: mandatory device \"%s\" not found\n", 4531573Srgrimes fname, wd); 4541573Srgrimes exit(1); 4551573Srgrimes } 4561573Srgrimes if (std) { 4579287Swpaul printf("standard entry %s has a device keyword - %s!\n", 4589287Swpaul this, wd); 4599287Swpaul exit(1); 4601573Srgrimes } 4619978Swpaul SLIST_FOREACH(op, &opt, op_next) 4629287Swpaul if (op->op_value == 0 && opteq(op->op_name, wd)) 4639287Swpaul goto nextparam; 4649287Swpaulskip: 4651573Srgrimes while ((wd = get_word(fp)) != 0) 4661573Srgrimes ; 4679978Swpaul goto next; 4681573Srgrimes 4691573Srgrimesdoneparam: 4701573Srgrimes if (std == 0 && nreqs == 0) { 4711573Srgrimes printf("%s: what is %s optional on?\n", 4721573Srgrimes fname, this); 4731573Srgrimes exit(1); 4741573Srgrimes } 4751573Srgrimes 4761573Srgrimes if (wd) { 4771573Srgrimes printf("%s: syntax error describing %s\n", 4789287Swpaul fname, this); 4799287Swpaul exit(1); 4809287Swpaul } 4819287Swpaul if (filetype == PROFILING && profiling == 0) 4829287Swpaul goto next; 4839287Swpaul tp = new_fent(); 4849287Swpaul tp->f_fn = this; 4859287Swpaul tp->f_type = filetype; 4869287Swpaul if (imp_rule) 4871573Srgrimes tp->f_flags |= NO_IMPLCT_RULE; 4889287Swpaul if (no_obj) 4899287Swpaul tp->f_flags |= NO_OBJ; 4909287Swpaul if (before_depend) 4919287Swpaul tp->f_flags |= BEFORE_DEPEND; 4929287Swpaul if (nowerror) 4939287Swpaul tp->f_flags |= NOWERROR; 4949287Swpaul tp->f_compilewith = compilewith; 4959287Swpaul tp->f_depends = depends; 4969287Swpaul tp->f_clean = clean; 4979287Swpaul tp->f_warn = warning; 4989287Swpaul goto next; 4999287Swpaul} 5009287Swpaul 5019287Swpaul/* 5029287Swpaul * Read in the information about files used in making the system. 5039287Swpaul * Store it in the ftab linked list. 5041573Srgrimes */ 5051573Srgrimesstatic void 5061573Srgrimesread_files(void) 5077175Swpaul{ 5081573Srgrimes char fname[MAXPATHLEN]; 50923668Speter struct files_name *nl, *tnl; 51023668Speter 51123668Speter if (ident == NULL) { 51223668Speter printf("no ident line specified\n"); 5131573Srgrimes exit(1); 5141573Srgrimes } 5151573Srgrimes (void) snprintf(fname, sizeof(fname), "../../conf/files"); 5161573Srgrimes read_file(fname); 5171573Srgrimes (void) snprintf(fname, sizeof(fname), 5181573Srgrimes "../../conf/files.%s", machinename); 5191573Srgrimes read_file(fname); 5201573Srgrimes for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) { 5211573Srgrimes read_file(nl->f_name); 5221573Srgrimes tnl = STAILQ_NEXT(nl, f_next); 5231573Srgrimes free(nl->f_name); 5241573Srgrimes free(nl); 52590041Sobrien } 52690041Sobrien} 5271573Srgrimes 5281573Srgrimesstatic int 52920957Swpaulopteq(const char *cp, const char *dp) 5307149Swpaul{ 5317149Swpaul char c, d; 5327149Swpaul 5331573Srgrimes for (; ; cp++, dp++) { 5347149Swpaul if (*cp != *dp) { 5357149Swpaul c = isupper(*cp) ? tolower(*cp) : *cp; 5367149Swpaul d = isupper(*dp) ? tolower(*dp) : *dp; 5377223Swpaul if (c != d) 5387149Swpaul return (0); 5397223Swpaul } 5407223Swpaul if (*cp == 0) 5417223Swpaul return (1); 5429978Swpaul } 5439978Swpaul} 5449978Swpaul 5459978Swpaulstatic void 5469978Swpauldo_before_depend(FILE *fp) 5479978Swpaul{ 5487149Swpaul struct file_list *tp; 54920957Swpaul int lpos, len; 5507149Swpaul 5517149Swpaul fputs("BEFORE_DEPEND=", fp); 5527149Swpaul lpos = 15; 5531573Srgrimes STAILQ_FOREACH(tp, &ftab, f_next) 5547149Swpaul if (tp->f_flags & BEFORE_DEPEND) { 5557149Swpaul len = strlen(tp->f_fn); 5567149Swpaul if ((len = 3 + len) + lpos > 72) { 5577149Swpaul lpos = 8; 5587149Swpaul fputs("\\\n\t", fp); 5597149Swpaul } 5607149Swpaul if (tp->f_flags & NO_IMPLCT_RULE) 5617149Swpaul fprintf(fp, "%s ", tp->f_fn); 5621573Srgrimes else 5631573Srgrimes fprintf(fp, "$S/%s ", tp->f_fn); 5641573Srgrimes lpos += len + 1; 5651573Srgrimes } 5661573Srgrimes if (lpos != 8) 5671573Srgrimes putc('\n', fp); 5681573Srgrimes} 5691573Srgrimes 5701573Srgrimesstatic void 5711573Srgrimesdo_objs(FILE *fp) 5721573Srgrimes{ 5731573Srgrimes struct file_list *tp; 5741573Srgrimes int lpos, len; 5751573Srgrimes char *cp, och, *sp; 5761573Srgrimes 5771573Srgrimes fprintf(fp, "OBJS="); 5781573Srgrimes lpos = 6; 5791573Srgrimes STAILQ_FOREACH(tp, &ftab, f_next) { 5801573Srgrimes if (tp->f_flags & NO_OBJ) 5811573Srgrimes continue; 5821573Srgrimes sp = tail(tp->f_fn); 5831573Srgrimes cp = sp + (len = strlen(sp)) - 1; 5841573Srgrimes och = *cp; 5851573Srgrimes *cp = 'o'; 5861573Srgrimes if (len + lpos > 72) { 5871573Srgrimes lpos = 8; 5881573Srgrimes fprintf(fp, "\\\n\t"); 5891573Srgrimes } 5901573Srgrimes fprintf(fp, "%s ", sp); 5911573Srgrimes lpos += len + 1; 5921573Srgrimes *cp = och; 5931573Srgrimes } 5941573Srgrimes if (lpos != 8) 5951573Srgrimes putc('\n', fp); 5961573Srgrimes} 5971573Srgrimes 5981573Srgrimesstatic void 5991573Srgrimesdo_xxfiles(char *tag, FILE *fp) 6001573Srgrimes{ 6011573Srgrimes struct file_list *tp; 6021573Srgrimes int lpos, len, slen; 6031573Srgrimes char *suff, *SUFF; 6041573Srgrimes 6051573Srgrimes if (tag[strlen(tag) - 1] == '\n') 6061573Srgrimes tag[strlen(tag) - 1] = '\0'; 6071573Srgrimes 6081573Srgrimes suff = ns(tag + 7); 6091573Srgrimes SUFF = ns(suff); 6101573Srgrimes raisestr(SUFF); 6111573Srgrimes slen = strlen(suff); 6121573Srgrimes 6131573Srgrimes fprintf(fp, "%sFILES=", SUFF); 6141573Srgrimes lpos = 8; 6151573Srgrimes STAILQ_FOREACH(tp, &ftab, f_next) 6161573Srgrimes if (tp->f_type != NODEPEND) { 6171573Srgrimes len = strlen(tp->f_fn); 6181573Srgrimes if (tp->f_fn[len - slen - 1] != '.') 6191573Srgrimes continue; 6201573Srgrimes if (strcasecmp(&tp->f_fn[len - slen], suff) != 0) 6211573Srgrimes continue; 6221573Srgrimes if ((len = 3 + len) + lpos > 72) { 6239978Swpaul lpos = 8; 6249978Swpaul fputs("\\\n\t", fp); 6259978Swpaul } 6269978Swpaul if (tp->f_type != LOCAL) 6279978Swpaul fprintf(fp, "$S/%s ", tp->f_fn); 6289978Swpaul else 6299978Swpaul fprintf(fp, "%s ", tp->f_fn); 6309978Swpaul lpos += len + 1; 6319978Swpaul } 6329978Swpaul if (lpos != 8) 6331573Srgrimes putc('\n', fp); 6341573Srgrimes} 635 636static char * 637tail(char *fn) 638{ 639 char *cp; 640 641 cp = rindex(fn, '/'); 642 if (cp == 0) 643 return (fn); 644 return (cp+1); 645} 646 647/* 648 * Create the makerules for each file 649 * which is part of the system. 650 */ 651static void 652do_rules(FILE *f) 653{ 654 char *cp, *np, och, *tp; 655 struct file_list *ftp; 656 char *compilewith; 657 658 STAILQ_FOREACH(ftp, &ftab, f_next) { 659 if (ftp->f_warn) 660 printf("WARNING: %s\n", ftp->f_warn); 661 cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; 662 och = *cp; 663 if (ftp->f_flags & NO_IMPLCT_RULE) { 664 if (ftp->f_depends) 665 fprintf(f, "%s: %s\n", np, ftp->f_depends); 666 else 667 fprintf(f, "%s: \n", np); 668 } 669 else { 670 *cp = '\0'; 671 if (och == 'o') { 672 fprintf(f, "%so:\n\t-cp $S/%so .\n\n", 673 tail(np), np); 674 continue; 675 } 676 if (ftp->f_depends) { 677 fprintf(f, "%sln: $S/%s%c %s\n", tail(np), 678 np, och, ftp->f_depends); 679 fprintf(f, "\t${NORMAL_LINT}\n\n"); 680 fprintf(f, "%so: $S/%s%c %s\n", tail(np), 681 np, och, ftp->f_depends); 682 } 683 else { 684 fprintf(f, "%sln: $S/%s%c\n", tail(np), 685 np, och); 686 fprintf(f, "\t${NORMAL_LINT}\n\n"); 687 fprintf(f, "%so: $S/%s%c\n", tail(np), 688 np, och); 689 } 690 } 691 tp = tail(np); 692 compilewith = ftp->f_compilewith; 693 if (compilewith == 0) { 694 const char *ftype = NULL; 695 static char cmd[128]; 696 697 switch (ftp->f_type) { 698 699 case NORMAL: 700 ftype = "NORMAL"; 701 break; 702 703 case PROFILING: 704 if (!profiling) 705 continue; 706 ftype = "PROFILE"; 707 break; 708 709 default: 710 printf("config: don't know rules for %s\n", np); 711 break; 712 } 713 snprintf(cmd, sizeof(cmd), "${%s_%c%s}", ftype, 714 toupper(och), 715 ftp->f_flags & NOWERROR ? "_NOWERROR" : ""); 716 compilewith = cmd; 717 } 718 *cp = och; 719 fprintf(f, "\t%s\n\n", compilewith); 720 } 721} 722 723static void 724do_clean(FILE *fp) 725{ 726 struct file_list *tp; 727 int lpos, len; 728 729 fputs("CLEAN=", fp); 730 lpos = 7; 731 STAILQ_FOREACH(tp, &ftab, f_next) 732 if (tp->f_clean) { 733 len = strlen(tp->f_clean); 734 if (len + lpos > 72) { 735 lpos = 8; 736 fputs("\\\n\t", fp); 737 } 738 fprintf(fp, "%s ", tp->f_clean); 739 lpos += len + 1; 740 } 741 if (lpos != 8) 742 putc('\n', fp); 743} 744 745char * 746raisestr(char *str) 747{ 748 char *cp = str; 749 750 while (*str) { 751 if (islower(*str)) 752 *str = toupper(*str); 753 str++; 754 } 755 return (cp); 756} 757