mkmakefile.c revision 269825
1299425Smm/* 2299425Smm * Copyright (c) 1980, 1990, 1993 3299425Smm * The Regents of the University of California. All rights reserved. 4299425Smm * 5299425Smm * Redistribution and use in source and binary forms, with or without 6299425Smm * modification, are permitted provided that the following conditions 7299425Smm * are met: 8299425Smm * 1. Redistributions of source code must retain the above copyright 9299425Smm * notice, this list of conditions and the following disclaimer. 10299425Smm * 2. Redistributions in binary form must reproduce the above copyright 11299425Smm * notice, this list of conditions and the following disclaimer in the 12299425Smm * documentation and/or other materials provided with the distribution. 13299425Smm * 4. Neither the name of the University nor the names of its contributors 14299425Smm * may be used to endorse or promote products derived from this software 15299425Smm * without specific prior written permission. 16299425Smm * 17299425Smm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18299425Smm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19299425Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20299425Smm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21299425Smm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22299425Smm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23299425Smm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24299425Smm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25299425Smm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26299425Smm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27299425Smm * SUCH DAMAGE. 28299425Smm */ 29299425Smm 30299425Smm#ifndef lint 31299425Smm#if 0 32313571Smmstatic char sccsid[] = "@(#)mkmakefile.c 8.1 (Berkeley) 6/6/93"; 33313571Smm#endif 34299425Smmstatic const char rcsid[] = 35299425Smm "$FreeBSD: stable/10/usr.sbin/config/mkmakefile.c 269825 2014-08-11 18:42:20Z imp $"; 36299425Smm#endif /* not lint */ 37299425Smm 38299425Smm/* 39299425Smm * Build the makefile for the system, from 40299425Smm * the information in the files files and the 41299425Smm * additional files for the machine being compiled to. 42299425Smm */ 43299425Smm 44299425Smm#include <ctype.h> 45299425Smm#include <err.h> 46299425Smm#include <stdarg.h> 47299425Smm#include <stdio.h> 48299425Smm#include <string.h> 49299425Smm#include <sys/param.h> 50299425Smm#include "y.tab.h" 51299425Smm#include "config.h" 52299425Smm#include "configvers.h" 53299425Smm 54299425Smmstatic char *tail(char *); 55299425Smmstatic void do_clean(FILE *); 56299425Smmstatic void do_rules(FILE *); 57299425Smmstatic void do_xxfiles(char *, FILE *); 58299425Smmstatic void do_objs(FILE *); 59299425Smmstatic void do_before_depend(FILE *); 60299425Smmstatic int opteq(const char *, const char *); 61299425Smmstatic void read_files(void); 62299425Smm 63299425Smmstatic void errout(const char *fmt, ...) 64313571Smm{ 65299425Smm va_list ap; 66299425Smm 67299425Smm va_start(ap, fmt); 68299425Smm vfprintf(stderr, fmt, ap); 69299425Smm va_end(ap); 70299425Smm exit(1); 71299425Smm} 72299425Smm 73299425Smm/* 74299425Smm * Lookup a file, by name. 75299425Smm */ 76299425Smmstatic struct file_list * 77299425Smmfl_lookup(char *file) 78299425Smm{ 79299425Smm struct file_list *fp; 80299425Smm 81299425Smm STAILQ_FOREACH(fp, &ftab, f_next) { 82299425Smm if (eq(fp->f_fn, file)) 83299425Smm return (fp); 84299425Smm } 85299425Smm return (0); 86299425Smm} 87299425Smm 88299425Smm/* 89299425Smm * Make a new file list entry 90299425Smm */ 91299425Smmstatic struct file_list * 92299425Smmnew_fent(void) 93299425Smm{ 94299425Smm struct file_list *fp; 95299425Smm 96299425Smm fp = (struct file_list *) calloc(1, sizeof *fp); 97299425Smm if (fp == NULL) 98299425Smm err(EXIT_FAILURE, "calloc"); 99299425Smm STAILQ_INSERT_TAIL(&ftab, fp, f_next); 100299425Smm return (fp); 101299425Smm} 102299425Smm 103299425Smm/* 104299425Smm * Open the correct Makefile and return it, or error out. 105299425Smm */ 106299425SmmFILE * 107299425Smmopen_makefile_template(void) 108299425Smm{ 109299425Smm FILE *ifp; 110299425Smm char line[BUFSIZ]; 111299425Smm 112299425Smm snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename); 113299425Smm ifp = fopen(line, "r"); 114299425Smm if (ifp == 0) { 115299425Smm snprintf(line, sizeof(line), "Makefile.%s", machinename); 116299425Smm ifp = fopen(line, "r"); 117299425Smm } 118299425Smm if (ifp == 0) 119299425Smm err(1, "%s", line); 120299425Smm return (ifp); 121299425Smm} 122299425Smm 123299425Smm/* 124299425Smm * Build the makefile from the skeleton 125299425Smm */ 126299425Smmvoid 127299425Smmmakefile(void) 128299425Smm{ 129299425Smm FILE *ifp, *ofp; 130299425Smm char line[BUFSIZ]; 131299425Smm struct opt *op, *t; 132299425Smm 133299425Smm read_files(); 134299425Smm ifp = open_makefile_template(); 135299425Smm ofp = fopen(path("Makefile.new"), "w"); 136299425Smm if (ofp == 0) 137299425Smm err(1, "%s", path("Makefile.new")); 138299425Smm fprintf(ofp, "KERN_IDENT=%s\n", ident); 139299425Smm fprintf(ofp, "MACHINE=%s\n", machinename); 140299425Smm fprintf(ofp, "MACHINE_ARCH=%s\n", machinearch); 141299425Smm SLIST_FOREACH_SAFE(op, &mkopt, op_next, t) { 142299425Smm fprintf(ofp, "%s=%s", op->op_name, op->op_value); 143299425Smm while ((op = SLIST_NEXT(op, op_append)) != NULL) 144299425Smm fprintf(ofp, " %s", op->op_value); 145299425Smm fprintf(ofp, "\n"); 146299425Smm } 147299425Smm if (debugging) 148318483Smm fprintf(ofp, "DEBUG=-g\n"); 149299425Smm if (profiling) 150318483Smm fprintf(ofp, "PROFLEVEL=%d\n", profiling); 151318483Smm if (*srcdir != '\0') 152318483Smm fprintf(ofp,"S=%s\n", srcdir); 153318483Smm while (fgets(line, BUFSIZ, ifp) != NULL) { 154318483Smm if (*line != '%') { 155318483Smm fprintf(ofp, "%s", line); 156318483Smm continue; 157318483Smm } 158299425Smm if (eq(line, "%BEFORE_DEPEND\n")) 159299425Smm do_before_depend(ofp); 160299425Smm else if (eq(line, "%OBJS\n")) 161299425Smm do_objs(ofp); 162299425Smm else if (strncmp(line, "%FILES.", 7) == 0) 163299425Smm do_xxfiles(line, ofp); 164299425Smm else if (eq(line, "%RULES\n")) 165299425Smm do_rules(ofp); 166299425Smm else if (eq(line, "%CLEAN\n")) 167299425Smm do_clean(ofp); 168299425Smm else if (strncmp(line, "%VERSREQ=", 9) == 0) 169299425Smm line[0] = '\0'; /* handled elsewhere */ 170299425Smm else 171299425Smm fprintf(stderr, 172299425Smm "Unknown %% construct in generic makefile: %s", 173299425Smm line); 174299425Smm } 175299425Smm (void) fclose(ifp); 176299425Smm (void) fclose(ofp); 177299425Smm moveifchanged(path("Makefile.new"), path("Makefile")); 178299425Smm} 179299425Smm 180299425Smm/* 181299425Smm * Build hints.c from the skeleton 182299425Smm */ 183299425Smmvoid 184299425Smmmakehints(void) 185299425Smm{ 186299425Smm FILE *ifp, *ofp; 187299425Smm char line[BUFSIZ]; 188299425Smm char *s; 189299425Smm struct hint *hint; 190299425Smm 191299425Smm ofp = fopen(path("hints.c.new"), "w"); 192299425Smm if (ofp == NULL) 193299425Smm err(1, "%s", path("hints.c.new")); 194299425Smm fprintf(ofp, "#include <sys/types.h>\n"); 195299425Smm fprintf(ofp, "#include <sys/systm.h>\n"); 196299425Smm fprintf(ofp, "\n"); 197299425Smm fprintf(ofp, "int hintmode = %d;\n", hintmode); 198299425Smm fprintf(ofp, "char static_hints[] = {\n"); 199299425Smm STAILQ_FOREACH(hint, &hints, hint_next) { 200299425Smm ifp = fopen(hint->hint_name, "r"); 201299425Smm if (ifp == NULL) 202299425Smm err(1, "%s", hint->hint_name); 203299425Smm while (fgets(line, BUFSIZ, ifp) != NULL) { 204299425Smm /* zap trailing CR and/or LF */ 205299425Smm while ((s = strrchr(line, '\n')) != NULL) 206299425Smm *s = '\0'; 207299425Smm while ((s = strrchr(line, '\r')) != NULL) 208299425Smm *s = '\0'; 209299425Smm /* remove # comments */ 210299425Smm s = strchr(line, '#'); 211299425Smm if (s) 212299425Smm *s = '\0'; 213299425Smm /* remove any whitespace and " characters */ 214299425Smm s = line; 215299425Smm while (*s) { 216299425Smm if (*s == ' ' || *s == '\t' || *s == '"') { 217299425Smm while (*s) { 218299425Smm s[0] = s[1]; 219299425Smm s++; 220299425Smm } 221299425Smm /* start over */ 222299425Smm s = line; 223299425Smm continue; 224299425Smm } 225299425Smm s++; 226299425Smm } 227299425Smm /* anything left? */ 228299425Smm if (*line == '\0') 229299425Smm continue; 230299425Smm fprintf(ofp, "\"%s\\0\"\n", line); 231299425Smm } 232299425Smm fclose(ifp); 233299425Smm } 234299425Smm fprintf(ofp, "\"\\0\"\n};\n"); 235299425Smm fclose(ofp); 236299425Smm moveifchanged(path("hints.c.new"), path("hints.c")); 237299425Smm} 238299425Smm 239299425Smm/* 240299425Smm * Build env.c from the skeleton 241299425Smm */ 242299425Smmvoid 243299425Smmmakeenv(void) 244299425Smm{ 245299425Smm FILE *ifp, *ofp; 246299425Smm char line[BUFSIZ]; 247299425Smm char *s; 248299425Smm 249299425Smm if (env) { 250299425Smm ifp = fopen(env, "r"); 251299425Smm if (ifp == NULL) 252299425Smm err(1, "%s", env); 253299425Smm } else { 254299425Smm ifp = NULL; 255299425Smm } 256299425Smm ofp = fopen(path("env.c.new"), "w"); 257299425Smm if (ofp == NULL) 258299425Smm err(1, "%s", path("env.c.new")); 259299425Smm fprintf(ofp, "#include <sys/types.h>\n"); 260299425Smm fprintf(ofp, "#include <sys/systm.h>\n"); 261299425Smm fprintf(ofp, "\n"); 262299425Smm fprintf(ofp, "int envmode = %d;\n", envmode); 263299425Smm fprintf(ofp, "char static_env[] = {\n"); 264299425Smm if (ifp) { 265299425Smm while (fgets(line, BUFSIZ, ifp) != NULL) { 266299425Smm /* zap trailing CR and/or LF */ 267299425Smm while ((s = strrchr(line, '\n')) != NULL) 268299425Smm *s = '\0'; 269299425Smm while ((s = strrchr(line, '\r')) != NULL) 270299425Smm *s = '\0'; 271299425Smm /* remove # comments */ 272299425Smm s = strchr(line, '#'); 273299425Smm if (s) 274299425Smm *s = '\0'; 275299425Smm /* remove any whitespace and " characters */ 276299425Smm s = line; 277299425Smm while (*s) { 278299425Smm if (*s == ' ' || *s == '\t' || *s == '"') { 279299425Smm while (*s) { 280299425Smm s[0] = s[1]; 281299425Smm s++; 282299425Smm } 283299425Smm /* start over */ 284299425Smm s = line; 285299425Smm continue; 286299425Smm } 287299425Smm s++; 288299425Smm } 289299425Smm /* anything left? */ 290299425Smm if (*line == '\0') 291299425Smm continue; 292299425Smm fprintf(ofp, "\"%s\\0\"\n", line); 293299425Smm } 294299425Smm } 295299425Smm fprintf(ofp, "\"\\0\"\n};\n"); 296299425Smm if (ifp) 297299425Smm fclose(ifp); 298299425Smm fclose(ofp); 299299425Smm moveifchanged(path("env.c.new"), path("env.c")); 300299425Smm} 301299425Smm 302299425Smmstatic void 303299425Smmread_file(char *fname) 304299425Smm{ 305299425Smm char ifname[MAXPATHLEN]; 306299425Smm FILE *fp; 307299425Smm struct file_list *tp; 308299425Smm struct device *dp; 309299425Smm struct opt *op; 310299425Smm char *wd, *this, *compilewith, *depends, *clean, *warning; 311299425Smm const char *objprefix; 312299425Smm int compile, match, nreqs, std, filetype, not, 313299425Smm imp_rule, no_obj, before_depend, nowerror; 314299425Smm 315299425Smm fp = fopen(fname, "r"); 316299425Smm if (fp == 0) 317299425Smm err(1, "%s", fname); 318299425Smmnext: 319299425Smm /* 320299425Smm * include "filename" 321299425Smm * filename [ standard | optional ] 322299425Smm * [ dev* [ | dev* ... ] | profiling-routine ] [ no-obj ] 323299425Smm * [ compile-with "compile rule" [no-implicit-rule] ] 324299425Smm * [ dependency "dependency-list"] [ before-depend ] 325299425Smm * [ clean "file-list"] [ warning "text warning" ] 326299425Smm * [ obj-prefix "file prefix"] 327299425Smm */ 328299425Smm wd = get_word(fp); 329299425Smm if (wd == (char *)EOF) { 330299425Smm (void) fclose(fp); 331299425Smm return; 332299425Smm } 333299425Smm if (wd == 0) 334299425Smm goto next; 335299425Smm if (wd[0] == '#') 336299425Smm { 337299425Smm while (((wd = get_word(fp)) != (char *)EOF) && wd) 338299425Smm ; 339299425Smm goto next; 340299425Smm } 341299425Smm if (eq(wd, "include")) { 342299425Smm wd = get_quoted_word(fp); 343299425Smm if (wd == (char *)EOF || wd == 0) 344299425Smm errout("%s: missing include filename.\n", fname); 345299425Smm (void) snprintf(ifname, sizeof(ifname), "../../%s", wd); 346299425Smm read_file(ifname); 347299425Smm while (((wd = get_word(fp)) != (char *)EOF) && wd) 348299425Smm ; 349299425Smm goto next; 350299425Smm } 351299425Smm this = ns(wd); 352299425Smm wd = get_word(fp); 353299425Smm if (wd == (char *)EOF) 354299425Smm return; 355299425Smm if (wd == 0) 356299425Smm errout("%s: No type for %s.\n", fname, this); 357299425Smm tp = fl_lookup(this); 358299425Smm compile = 0; 359299425Smm match = 1; 360299425Smm nreqs = 0; 361299425Smm compilewith = 0; 362299425Smm depends = 0; 363299425Smm clean = 0; 364299425Smm warning = 0; 365299425Smm std = 0; 366299425Smm imp_rule = 0; 367299425Smm no_obj = 0; 368299425Smm before_depend = 0; 369299425Smm nowerror = 0; 370299425Smm not = 0; 371299425Smm filetype = NORMAL; 372299425Smm objprefix = ""; 373299425Smm if (eq(wd, "standard")) 374299425Smm std = 1; 375299425Smm else if (!eq(wd, "optional")) 376299425Smm errout("%s: \"%s\" %s must be optional or standard\n", 377299425Smm fname, wd, this); 378299425Smm for (wd = get_word(fp); wd; wd = get_word(fp)) { 379299425Smm if (wd == (char *)EOF) 380299425Smm return; 381299425Smm if (eq(wd, "!")) { 382299425Smm not = 1; 383299425Smm continue; 384299425Smm } 385299425Smm if (eq(wd, "|")) { 386299425Smm if (nreqs == 0) 387299425Smm errout("%s: syntax error describing %s\n", 388299425Smm fname, this); 389299425Smm if (not) 390299425Smm compile += !match; 391299425Smm else 392299425Smm compile += match; 393299425Smm match = 1; 394299425Smm nreqs = 0; 395299425Smm not = 0; 396299425Smm continue; 397299425Smm } 398299425Smm if (eq(wd, "no-obj")) { 399299425Smm no_obj++; 400299425Smm continue; 401299425Smm } 402299425Smm if (eq(wd, "no-implicit-rule")) { 403299425Smm if (compilewith == 0) 404299425Smm errout("%s: alternate rule required when " 405299425Smm "\"no-implicit-rule\" is specified for" 406299425Smm " %s.\n", 407299425Smm fname, this); 408299425Smm imp_rule++; 409299425Smm continue; 410299425Smm } 411299425Smm if (eq(wd, "before-depend")) { 412299425Smm before_depend++; 413299425Smm continue; 414299425Smm } 415299425Smm if (eq(wd, "dependency")) { 416299425Smm wd = get_quoted_word(fp); 417299425Smm if (wd == (char *)EOF || wd == 0) 418299425Smm errout("%s: %s missing dependency string.\n", 419299425Smm fname, this); 420299425Smm depends = ns(wd); 421299425Smm continue; 422299425Smm } 423299425Smm if (eq(wd, "clean")) { 424299425Smm wd = get_quoted_word(fp); 425299425Smm if (wd == (char *)EOF || wd == 0) 426299425Smm errout("%s: %s missing clean file list.\n", 427299425Smm fname, this); 428299425Smm clean = ns(wd); 429299425Smm continue; 430299425Smm } 431299425Smm if (eq(wd, "compile-with")) { 432299425Smm wd = get_quoted_word(fp); 433299425Smm if (wd == (char *)EOF || wd == 0) 434299425Smm errout("%s: %s missing compile command string.\n", 435299425Smm fname, this); 436299425Smm compilewith = ns(wd); 437299425Smm continue; 438299425Smm } 439299425Smm if (eq(wd, "warning")) { 440299425Smm wd = get_quoted_word(fp); 441299425Smm if (wd == (char *)EOF || wd == 0) 442299425Smm errout("%s: %s missing warning text string.\n", 443299425Smm fname, this); 444299425Smm warning = ns(wd); 445299425Smm continue; 446299425Smm } 447299425Smm if (eq(wd, "obj-prefix")) { 448299425Smm wd = get_quoted_word(fp); 449299425Smm if (wd == (char *)EOF || wd == 0) 450299425Smm errout("%s: %s missing object prefix string.\n", 451299425Smm fname, this); 452299425Smm objprefix = ns(wd); 453299425Smm continue; 454299425Smm } 455299425Smm if (eq(wd, "nowerror")) { 456299425Smm nowerror = 1; 457299425Smm continue; 458299425Smm } 459299425Smm if (eq(wd, "local")) { 460299425Smm filetype = LOCAL; 461299425Smm continue; 462299425Smm } 463299425Smm if (eq(wd, "no-depend")) { 464299425Smm filetype = NODEPEND; 465299425Smm continue; 466299425Smm } 467299425Smm nreqs++; 468299425Smm if (eq(wd, "profiling-routine")) { 469299425Smm filetype = PROFILING; 470299425Smm continue; 471299425Smm } 472299425Smm if (std) 473299425Smm errout("standard entry %s has optional inclusion specifier %s!\n", 474299425Smm this, wd); 475299425Smm STAILQ_FOREACH(dp, &dtab, d_next) 476299425Smm if (eq(dp->d_name, wd)) { 477299425Smm dp->d_done |= DEVDONE; 478299425Smm goto nextparam; 479299425Smm } 480299425Smm SLIST_FOREACH(op, &opt, op_next) 481299425Smm if (op->op_value == 0 && opteq(op->op_name, wd)) 482299425Smm goto nextparam; 483299425Smm match = 0; 484299425Smmnextparam:; 485299425Smm } 486299425Smm if (not) 487299425Smm compile += !match; 488299425Smm else 489299425Smm compile += match; 490299425Smm if (compile && tp == NULL) { 491299425Smm if (std == 0 && nreqs == 0) 492299425Smm errout("%s: what is %s optional on?\n", 493299425Smm fname, this); 494299425Smm if (filetype == PROFILING && profiling == 0) 495299425Smm goto next; 496299425Smm tp = new_fent(); 497299425Smm tp->f_fn = this; 498299425Smm tp->f_type = filetype; 499299425Smm if (imp_rule) 500299425Smm tp->f_flags |= NO_IMPLCT_RULE; 501299425Smm if (no_obj) 502299425Smm tp->f_flags |= NO_OBJ; 503299425Smm if (before_depend) 504299425Smm tp->f_flags |= BEFORE_DEPEND; 505299425Smm if (nowerror) 506299425Smm tp->f_flags |= NOWERROR; 507299425Smm tp->f_compilewith = compilewith; 508299425Smm tp->f_depends = depends; 509299425Smm tp->f_clean = clean; 510299425Smm tp->f_warn = warning; 511299425Smm tp->f_objprefix = objprefix; 512299425Smm } 513299425Smm goto next; 514299425Smm} 515299425Smm 516299425Smm/* 517299425Smm * Read in the information about files used in making the system. 518299425Smm * Store it in the ftab linked list. 519299425Smm */ 520299425Smmstatic void 521299425Smmread_files(void) 522{ 523 char fname[MAXPATHLEN]; 524 struct files_name *nl, *tnl; 525 526 (void) snprintf(fname, sizeof(fname), "../../conf/files"); 527 read_file(fname); 528 (void) snprintf(fname, sizeof(fname), 529 "../../conf/files.%s", machinename); 530 read_file(fname); 531 for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) { 532 read_file(nl->f_name); 533 tnl = STAILQ_NEXT(nl, f_next); 534 free(nl->f_name); 535 free(nl); 536 } 537} 538 539static int 540opteq(const char *cp, const char *dp) 541{ 542 char c, d; 543 544 for (; ; cp++, dp++) { 545 if (*cp != *dp) { 546 c = isupper(*cp) ? tolower(*cp) : *cp; 547 d = isupper(*dp) ? tolower(*dp) : *dp; 548 if (c != d) 549 return (0); 550 } 551 if (*cp == 0) 552 return (1); 553 } 554} 555 556static void 557do_before_depend(FILE *fp) 558{ 559 struct file_list *tp; 560 int lpos, len; 561 562 fputs("BEFORE_DEPEND=", fp); 563 lpos = 15; 564 STAILQ_FOREACH(tp, &ftab, f_next) 565 if (tp->f_flags & BEFORE_DEPEND) { 566 len = strlen(tp->f_fn); 567 if ((len = 3 + len) + lpos > 72) { 568 lpos = 8; 569 fputs("\\\n\t", fp); 570 } 571 if (tp->f_flags & NO_IMPLCT_RULE) 572 fprintf(fp, "%s ", tp->f_fn); 573 else 574 fprintf(fp, "$S/%s ", tp->f_fn); 575 lpos += len + 1; 576 } 577 if (lpos != 8) 578 putc('\n', fp); 579} 580 581static void 582do_objs(FILE *fp) 583{ 584 struct file_list *tp; 585 int lpos, len; 586 char *cp, och, *sp; 587 588 fprintf(fp, "OBJS="); 589 lpos = 6; 590 STAILQ_FOREACH(tp, &ftab, f_next) { 591 if (tp->f_flags & NO_OBJ) 592 continue; 593 sp = tail(tp->f_fn); 594 cp = sp + (len = strlen(sp)) - 1; 595 och = *cp; 596 *cp = 'o'; 597 len += strlen(tp->f_objprefix); 598 if (len + lpos > 72) { 599 lpos = 8; 600 fprintf(fp, "\\\n\t"); 601 } 602 fprintf(fp, "%s%s ", tp->f_objprefix, sp); 603 lpos += len + 1; 604 *cp = och; 605 } 606 if (lpos != 8) 607 putc('\n', fp); 608} 609 610static void 611do_xxfiles(char *tag, FILE *fp) 612{ 613 struct file_list *tp; 614 int lpos, len, slen; 615 char *suff, *SUFF; 616 617 if (tag[strlen(tag) - 1] == '\n') 618 tag[strlen(tag) - 1] = '\0'; 619 620 suff = ns(tag + 7); 621 SUFF = ns(suff); 622 raisestr(SUFF); 623 slen = strlen(suff); 624 625 fprintf(fp, "%sFILES=", SUFF); 626 lpos = 8; 627 STAILQ_FOREACH(tp, &ftab, f_next) 628 if (tp->f_type != NODEPEND) { 629 len = strlen(tp->f_fn); 630 if (tp->f_fn[len - slen - 1] != '.') 631 continue; 632 if (strcasecmp(&tp->f_fn[len - slen], suff) != 0) 633 continue; 634 if ((len = 3 + len) + lpos > 72) { 635 lpos = 8; 636 fputs("\\\n\t", fp); 637 } 638 if (tp->f_type != LOCAL) 639 fprintf(fp, "$S/%s ", tp->f_fn); 640 else 641 fprintf(fp, "%s ", tp->f_fn); 642 lpos += len + 1; 643 } 644 if (lpos != 8) 645 putc('\n', fp); 646} 647 648static char * 649tail(char *fn) 650{ 651 char *cp; 652 653 cp = strrchr(fn, '/'); 654 if (cp == 0) 655 return (fn); 656 return (cp+1); 657} 658 659/* 660 * Create the makerules for each file 661 * which is part of the system. 662 */ 663static void 664do_rules(FILE *f) 665{ 666 char *cp, *np, och; 667 struct file_list *ftp; 668 char *compilewith; 669 char cmd[128]; 670 671 STAILQ_FOREACH(ftp, &ftab, f_next) { 672 if (ftp->f_warn) 673 fprintf(stderr, "WARNING: %s\n", ftp->f_warn); 674 cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; 675 och = *cp; 676 if (ftp->f_flags & NO_IMPLCT_RULE) { 677 if (ftp->f_depends) 678 fprintf(f, "%s%s: %s\n", 679 ftp->f_objprefix, np, ftp->f_depends); 680 else 681 fprintf(f, "%s%s: \n", ftp->f_objprefix, np); 682 } 683 else { 684 *cp = '\0'; 685 if (och == 'o') { 686 fprintf(f, "%s%so:\n\t-cp $S/%so .\n\n", 687 ftp->f_objprefix, tail(np), np); 688 continue; 689 } 690 if (ftp->f_depends) { 691 fprintf(f, "%s%sln: $S/%s%c %s\n", 692 ftp->f_objprefix, tail(np), np, och, 693 ftp->f_depends); 694 fprintf(f, "\t${NORMAL_LINT}\n\n"); 695 fprintf(f, "%s%so: $S/%s%c %s\n", 696 ftp->f_objprefix, tail(np), np, och, 697 ftp->f_depends); 698 } 699 else { 700 fprintf(f, "%s%sln: $S/%s%c\n", 701 ftp->f_objprefix, tail(np), np, och); 702 fprintf(f, "\t${NORMAL_LINT}\n\n"); 703 fprintf(f, "%s%so: $S/%s%c\n", 704 ftp->f_objprefix, tail(np), np, och); 705 } 706 } 707 compilewith = ftp->f_compilewith; 708 if (compilewith == 0) { 709 const char *ftype = NULL; 710 711 switch (ftp->f_type) { 712 case NORMAL: 713 ftype = "NORMAL"; 714 break; 715 case PROFILING: 716 if (!profiling) 717 continue; 718 ftype = "PROFILE"; 719 break; 720 default: 721 fprintf(stderr, 722 "config: don't know rules for %s\n", np); 723 break; 724 } 725 snprintf(cmd, sizeof(cmd), 726 "${%s_%c%s}", ftype, 727 toupper(och), 728 ftp->f_flags & NOWERROR ? "_NOWERROR" : ""); 729 compilewith = cmd; 730 } 731 *cp = och; 732 if (strlen(ftp->f_objprefix)) 733 fprintf(f, "\t%s $S/%s\n", compilewith, np); 734 else 735 fprintf(f, "\t%s\n", compilewith); 736 737 if (!(ftp->f_flags & NO_OBJ)) 738 fprintf(f, "\t${NORMAL_CTFCONVERT}\n\n"); 739 else 740 fprintf(f, "\n"); 741 } 742} 743 744static void 745do_clean(FILE *fp) 746{ 747 struct file_list *tp; 748 int lpos, len; 749 750 fputs("CLEAN=", fp); 751 lpos = 7; 752 STAILQ_FOREACH(tp, &ftab, f_next) 753 if (tp->f_clean) { 754 len = strlen(tp->f_clean); 755 if (len + lpos > 72) { 756 lpos = 8; 757 fputs("\\\n\t", fp); 758 } 759 fprintf(fp, "%s ", tp->f_clean); 760 lpos += len + 1; 761 } 762 if (lpos != 8) 763 putc('\n', fp); 764} 765 766char * 767raisestr(char *str) 768{ 769 char *cp = str; 770 771 while (*str) { 772 if (islower(*str)) 773 *str = toupper(*str); 774 str++; 775 } 776 return (cp); 777} 778