]> git.saurik.com Git - apple/xnu.git/blame - SETUP/config/mkmakefile.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / SETUP / config / mkmakefile.c
CommitLineData
6d2010ae 1/*
39037602 2 * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
6d2010ae
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
39037602 5 *
6d2010ae
A
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
39037602 13 *
6d2010ae
A
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
39037602 21 *
6d2010ae
A
22 * @APPLE_LICENSE_HEADER_END@
23 */
39037602 24/*
6d2010ae
A
25 * Mach Operating System
26 * Copyright (c) 1990 Carnegie-Mellon University
27 * Copyright (c) 1989 Carnegie-Mellon University
28 * Copyright (c) 1988 Carnegie-Mellon University
29 * Copyright (c) 1987 Carnegie-Mellon University
30 * All rights reserved. The CMU software License Agreement specifies
31 * the terms and conditions for use and redistribution.
32 */
33
34/*
35 * Copyright (c) 1980 Regents of the University of California.
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms are permitted
39 * provided that the above copyright notice and this paragraph are
40 * duplicated in all such forms and that any documentation,
41 * advertising materials, and other materials related to such
42 * distribution and use acknowledge that the software was developed
43 * by the University of California, Berkeley. The name of the
44 * University may not be used to endorse or promote products derived
45 * from this software without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
48 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
49 */
50
51#ifndef lint
52static char sccsid[] __attribute__((used)) = "@(#)mkmakefile.c 5.21 (Berkeley) 6/18/88";
53#endif /* not lint */
54
55/*
56 * Build the makefile for the system, from
57 * the information in the files files and the
58 * additional files for the machine being compiled to.
59 */
60
61#include <stdio.h>
0a7de745 62#include <unistd.h> /* for unlink */
6d2010ae
A
63#include <ctype.h>
64#include "parser.h"
65#include "config.h"
66
0a7de745
A
67void read_files(void);
68void do_objs(FILE *fp, const char *msg, int ext);
69void do_files(FILE *fp, const char *msg, char ext);
70void do_machdep(FILE *ofp);
71void do_rules(FILE *f);
72void copy_dependencies(FILE *makin, FILE *makout);
6d2010ae 73
6d2010ae
A
74struct file_list *fl_lookup(char *file);
75struct file_list *fltail_lookup(char *file);
76struct file_list *new_fent(void);
77
0a7de745 78void put_source_file_name(FILE *fp, struct file_list *tp);
6d2010ae
A
79
80
6d2010ae 81#define next_word(fp, wd) \
39037602 82 { const char *word = get_word(fp); \
6d2010ae 83 if (word == (char *)EOF) \
0a7de745 84 return; \
6d2010ae 85 else \
0a7de745 86 wd = word; \
6d2010ae
A
87 }
88
0a7de745 89static struct file_list *fcur;
6d2010ae
A
90const char *tail(const char *fn);
91char *allCaps(char *str);
92
93/*
94 * Lookup a file, by name.
95 */
96struct file_list *
97fl_lookup(char *file)
98{
39037602 99 struct file_list *fp;
6d2010ae 100
0a7de745
A
101 for (fp = ftab; fp != 0; fp = fp->f_next) {
102 if (eq(fp->f_fn, file)) {
103 return fp;
104 }
6d2010ae 105 }
0a7de745 106 return 0;
6d2010ae
A
107}
108
109/*
110 * Lookup a file, by final component name.
111 */
112struct file_list *
113fltail_lookup(char *file)
114{
39037602 115 struct file_list *fp;
6d2010ae 116
0a7de745
A
117 for (fp = ftab; fp != 0; fp = fp->f_next) {
118 if (eq(tail(fp->f_fn), tail(file))) {
119 return fp;
120 }
6d2010ae 121 }
0a7de745 122 return 0;
6d2010ae
A
123}
124
125/*
126 * Make a new file list entry
127 */
128struct file_list *
129new_fent(void)
130{
39037602 131 struct file_list *fp;
6d2010ae
A
132
133 fp = (struct file_list *) malloc(sizeof *fp);
134 fp->f_needs = 0;
135 fp->f_next = 0;
136 fp->f_flags = 0;
137 fp->f_type = 0;
138 fp->f_extra = (char *) 0;
0a7de745 139 if (fcur == 0) {
6d2010ae 140 fcur = ftab = fp;
0a7de745 141 } else {
6d2010ae 142 fcur->f_next = fp;
0a7de745 143 }
6d2010ae 144 fcur = fp;
0a7de745 145 return fp;
6d2010ae
A
146}
147
0a7de745 148char *COPTS;
6d2010ae
A
149
150const char *
151get_VPATH(void)
152{
0a7de745 153 static char *vpath = NULL;
6d2010ae 154
0a7de745
A
155 if ((vpath == NULL) &&
156 ((vpath = getenv("VPATH")) != NULL) &&
157 (*vpath != ':')) {
158 char *buf = malloc((unsigned)(strlen(vpath) + 2));
6d2010ae 159
0a7de745
A
160 vpath = strcat(strcpy(buf, ":"), vpath);
161 }
6d2010ae 162
0a7de745 163 return vpath ? vpath : "";
6d2010ae
A
164}
165
166
167/*
168 * Build the makefile from the skeleton
169 */
170void
171makefile(void)
172{
173 FILE *ifp, *ofp;
174 FILE *dfp;
175 char pname[BUFSIZ];
176 char line[BUFSIZ];
177 struct opt *op;
6d2010ae
A
178
179 read_files();
180 (void) sprintf(line, "%s/Makefile.template", config_directory);
181 ifp = fopenp(VPATH, line, pname, "r");
182 if (ifp == 0) {
183 perror(line);
184 exit(1);
185 }
186 dfp = fopen(path("Makefile"), "r");
187 rename(path("Makefile"), path("Makefile.old"));
188 unlink(path("Makefile.old"));
6d2010ae
A
189 ofp = fopen(path("Makefile"), "w");
190 if (ofp == 0) {
191 perror(path("Makefile"));
192 exit(1);
193 }
194 fprintf(ofp, "SOURCE_DIR=%s\n", source_directory);
195
fe8ab488 196 fprintf(ofp, "export CONFIG_DEFINES =");
0a7de745 197 if (profiling) {
6d2010ae 198 fprintf(ofp, " -DGPROF");
0a7de745 199 }
6d2010ae 200
0a7de745
A
201 for (op = opt; op; op = op->op_next) {
202 if (op->op_value) {
6d2010ae 203 fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value);
0a7de745 204 } else {
6d2010ae 205 fprintf(ofp, " -D%s", op->op_name);
0a7de745
A
206 }
207 }
6d2010ae 208 fprintf(ofp, "\n");
0a7de745
A
209 for (op = mkopt; op; op = op->op_next) {
210 if (op->op_value) {
6d2010ae 211 fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
0a7de745 212 } else {
6d2010ae 213 fprintf(ofp, "%s\n", op->op_name);
0a7de745
A
214 }
215 }
6d2010ae
A
216
217 while (fgets(line, BUFSIZ, ifp) != 0) {
0a7de745 218 if (*line == '%') {
6d2010ae 219 goto percent;
0a7de745 220 }
6d2010ae 221 if (profiling && strncmp(line, "COPTS=", 6) == 0) {
39037602 222 char *cp;
fe8ab488 223 fprintf(ofp,
0a7de745 224 "GPROF.EX=$(SOURCE_DIR)/machdep/%s/gmon.ex\n", machinename);
6d2010ae 225 cp = index(line, '\n');
0a7de745 226 if (cp) {
6d2010ae 227 *cp = 0;
0a7de745 228 }
6d2010ae 229 cp = line + 6;
0a7de745 230 while (*cp && (*cp == ' ' || *cp == '\t')) {
6d2010ae 231 cp++;
0a7de745 232 }
6d2010ae
A
233 COPTS = malloc((unsigned)(strlen(cp) + 1));
234 if (COPTS == 0) {
235 printf("config: out of memory\n");
236 exit(1);
237 }
238 strcpy(COPTS, cp);
fe8ab488 239 fprintf(ofp, "%s -pg\n", line);
6d2010ae
A
240 continue;
241 }
242 fprintf(ofp, "%s", line);
243 continue;
0a7de745 244percent:
6d2010ae
A
245 if (eq(line, "%OBJS\n")) {
246 do_objs(ofp, "OBJS=", -1);
247 } else if (eq(line, "%CFILES\n")) {
248 do_files(ofp, "CFILES=", 'c');
249 do_objs(ofp, "COBJS=", 'c');
fe8ab488
A
250 } else if (eq(line, "%CXXFILES\n")) {
251 do_files(ofp, "CXXFILES=", 'p');
252 do_objs(ofp, "CXXOBJS=", 'p');
6d2010ae
A
253 } else if (eq(line, "%SFILES\n")) {
254 do_files(ofp, "SFILES=", 's');
255 do_objs(ofp, "SOBJS=", 's');
39236c6e 256 } else if (eq(line, "%MACHDEP\n")) {
6d2010ae 257 do_machdep(ofp);
0a7de745 258 } else if (eq(line, "%RULES\n")) {
6d2010ae 259 do_rules(ofp);
0a7de745 260 } else {
6d2010ae
A
261 fprintf(stderr,
262 "Unknown %% construct in generic makefile: %s",
263 line);
0a7de745 264 }
6d2010ae 265 }
0a7de745 266 if (dfp != NULL) {
6d2010ae
A
267 copy_dependencies(dfp, ofp);
268 (void) fclose(dfp);
269 }
270 (void) fclose(ifp);
271 (void) fclose(ofp);
272}
273
274/*
275 * Read in the information about files used in making the system.
276 * Store it in the ftab linked list.
277 */
278void
279read_files(void)
280{
281 FILE *fp;
39037602
A
282 struct file_list *tp, *pf;
283 struct device *dp;
284 struct opt *op;
6d2010ae
A
285 const char *wd;
286 char *this, *needs;
287 const char *devorprof;
288 int options;
289 int not_option;
6d2010ae
A
290 char pname[BUFSIZ];
291 char fname[1024];
292 char *rest = (char *) 0;
6d2010ae
A
293 int nreqs, first = 1, isdup;
294
295 ftab = 0;
296 (void) sprintf(fname, "%s/files", config_directory);
297openit:
298 fp = fopenp(VPATH, fname, pname, "r");
299 if (fp == 0) {
300 perror(fname);
301 exit(1);
302 }
303next:
304 options = 0;
305 rest = (char *) 0;
306 /*
307 * filename [ standard | optional ]
308 * [ dev* | profiling-routine ] [ device-driver]
309 */
6d2010ae
A
310 wd = get_word(fp);
311 if (wd == (char *)EOF) {
312 (void) fclose(fp);
313 if (first == 1) {
314 (void) sprintf(fname, "%s/files.%s", config_directory, machinename);
315 first++;
316 goto openit;
317 }
6d2010ae
A
318 return;
319 }
0a7de745 320 if (wd == 0) {
6d2010ae 321 goto next;
0a7de745 322 }
6d2010ae
A
323 /*
324 * Allow comment lines beginning witha '#' character.
325 */
0a7de745
A
326 if (*wd == '#') {
327 while ((wd = get_word(fp)) && wd != (char *)EOF) {
6d2010ae 328 ;
0a7de745 329 }
6d2010ae
A
330 goto next;
331 }
332
333 this = ns(wd);
334 next_word(fp, wd);
335 if (wd == 0) {
336 printf("%s: No type for %s.\n",
337 fname, this);
338 exit(1);
339 }
0a7de745 340 if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags)) {
6d2010ae 341 isdup = 1;
0a7de745 342 } else {
6d2010ae 343 isdup = 0;
0a7de745 344 }
6d2010ae 345 tp = 0;
6d2010ae
A
346 nreqs = 0;
347 devorprof = "";
6d2010ae 348 needs = 0;
0a7de745 349 if (eq(wd, "standard")) {
6d2010ae 350 goto checkdev;
0a7de745 351 }
6d2010ae
A
352 if (!eq(wd, "optional")) {
353 printf("%s: %s must be optional or standard\n", fname, this);
354 exit(1);
355 }
0a7de745 356 if (strncmp(this, "OPTIONS/", 8) == 0) {
6d2010ae 357 options++;
0a7de745 358 }
6d2010ae
A
359 not_option = 0;
360nextopt:
361 next_word(fp, wd);
0a7de745 362 if (wd == 0) {
6d2010ae 363 goto doneopt;
0a7de745 364 }
6d2010ae
A
365 if (eq(wd, "not")) {
366 not_option = !not_option;
367 goto nextopt;
368 }
369 devorprof = wd;
370 if (eq(wd, "device-driver") || eq(wd, "profiling-routine")) {
371 next_word(fp, wd);
372 goto save;
373 }
374 nreqs++;
0a7de745 375 if (needs == 0 && nreqs == 1) {
6d2010ae 376 needs = ns(wd);
0a7de745
A
377 }
378 if (isdup) {
6d2010ae 379 goto invis;
0a7de745
A
380 }
381 if (options) {
6d2010ae
A
382 struct opt *lop = 0;
383 struct device tdev;
384
385 /*
386 * Allocate a pseudo-device entry which we will insert into
387 * the device list below. The flags field is set non-zero to
388 * indicate an internal entry rather than one generated from
389 * the configuration file. The slave field is set to define
390 * the corresponding symbol as 0 should we fail to find the
391 * option in the option list.
392 */
393 init_dev(&tdev);
394 tdev.d_name = ns(wd);
395 tdev.d_type = PSEUDO_DEVICE;
396 tdev.d_flags++;
397 tdev.d_slave = 0;
398
0a7de745 399 for (op = opt; op; lop = op, op = op->op_next) {
6d2010ae
A
400 char *od = allCaps(ns(wd));
401
402 /*
403 * Found an option which matches the current device
404 * dependency identifier. Set the slave field to
405 * define the option in the header file.
406 */
0a7de745 407 if (strcmp(op->op_name, od) == 0) {
6d2010ae 408 tdev.d_slave = 1;
0a7de745 409 if (lop == 0) {
6d2010ae 410 opt = op->op_next;
0a7de745 411 } else {
6d2010ae 412 lop->op_next = op->op_next;
0a7de745 413 }
6d2010ae
A
414 free(op);
415 op = 0;
0a7de745 416 }
6d2010ae 417 free(od);
0a7de745 418 if (op == 0) {
6d2010ae 419 break;
0a7de745 420 }
6d2010ae
A
421 }
422 newdev(&tdev);
423 }
0a7de745 424 for (dp = dtab; dp != 0; dp = dp->d_next) {
6d2010ae 425 if (eq(dp->d_name, wd) && (dp->d_type != PSEUDO_DEVICE || dp->d_slave)) {
0a7de745
A
426 if (not_option) {
427 goto invis; /* dont want file if option present */
428 } else {
6d2010ae 429 goto nextopt;
0a7de745 430 }
6d2010ae
A
431 }
432 }
0a7de745
A
433 if (not_option) {
434 goto nextopt; /* want file if option missing */
435 }
436 for (op = opt; op != 0; op = op->op_next) {
6d2010ae
A
437 if (op->op_value == 0 && opteq(op->op_name, wd)) {
438 if (nreqs == 1) {
439 free(needs);
440 needs = 0;
441 }
442 goto nextopt;
443 }
0a7de745 444 }
6d2010ae 445
6d2010ae 446invis:
0a7de745 447 while ((wd = get_word(fp)) != 0) {
6d2010ae 448 ;
0a7de745
A
449 }
450 if (tp == 0) {
6d2010ae 451 tp = new_fent();
0a7de745 452 }
6d2010ae
A
453 tp->f_fn = this;
454 tp->f_type = INVISIBLE;
455 tp->f_needs = needs;
456 tp->f_flags = isdup;
457 goto next;
458
459doneopt:
460 if (nreqs == 0) {
461 printf("%s: what is %s optional on?\n",
462 fname, this);
463 exit(1);
464 }
465
466checkdev:
467 if (wd) {
0a7de745 468 if (*wd == '|') {
6d2010ae 469 goto getrest;
0a7de745 470 }
6d2010ae
A
471 next_word(fp, wd);
472 if (wd) {
6d2010ae
A
473 devorprof = wd;
474 next_word(fp, wd);
475 }
476 }
477
478save:
479getrest:
480 if (wd) {
481 if (*wd == '|') {
482 rest = ns(get_rest(fp));
483 } else {
484 printf("%s: syntax error describing %s\n",
0a7de745 485 fname, this);
6d2010ae
A
486 exit(1);
487 }
488 }
0a7de745 489 if (eq(devorprof, "profiling-routine") && profiling == 0) {
6d2010ae 490 goto next;
0a7de745
A
491 }
492 if (tp == 0) {
6d2010ae 493 tp = new_fent();
0a7de745 494 }
6d2010ae
A
495 tp->f_fn = this;
496 tp->f_extra = rest;
0a7de745 497 if (options) {
6d2010ae 498 tp->f_type = INVISIBLE;
0a7de745 499 } else if (eq(devorprof, "device-driver")) {
6d2010ae 500 tp->f_type = DRIVER;
0a7de745 501 } else if (eq(devorprof, "profiling-routine")) {
6d2010ae 502 tp->f_type = PROFILING;
0a7de745 503 } else {
6d2010ae 504 tp->f_type = NORMAL;
0a7de745 505 }
6d2010ae 506 tp->f_flags = 0;
6d2010ae 507 tp->f_needs = needs;
0a7de745
A
508 if (pf && pf->f_type == INVISIBLE) {
509 pf->f_flags = 1; /* mark as duplicate */
510 }
6d2010ae
A
511 goto next;
512}
513
514int
515opteq(const char *cp, const char *dp)
516{
517 char c, d;
518
0a7de745 519 for (;; cp++, dp++) {
6d2010ae
A
520 if (*cp != *dp) {
521 c = isupper(*cp) ? tolower(*cp) : *cp;
522 d = isupper(*dp) ? tolower(*dp) : *dp;
0a7de745
A
523 if (c != d) {
524 return 0;
525 }
526 }
527 if (*cp == 0) {
528 return 1;
6d2010ae 529 }
6d2010ae
A
530 }
531}
532
533void
534put_source_file_name(FILE *fp, struct file_list *tp)
535{
0a7de745 536 if ((tp->f_fn[0] == '.') && (tp->f_fn[1] == '/')) {
6d2010ae 537 fprintf(fp, "%s ", tp->f_fn);
0a7de745 538 } else {
6d2010ae 539 fprintf(fp, "$(SOURCE_DIR)/%s ", tp->f_fn);
0a7de745 540 }
6d2010ae
A
541}
542
543void
544do_objs(FILE *fp, const char *msg, int ext)
545{
39037602
A
546 struct file_list *tp;
547 int lpos, len;
6d2010ae
A
548 char *cp;
549 char och;
550 const char *sp;
6d2010ae
A
551
552 fprintf(fp, "%s", msg);
553 lpos = strlen(msg);
554 for (tp = ftab; tp != 0; tp = tp->f_next) {
0a7de745 555 if (tp->f_type == INVISIBLE) {
6d2010ae 556 continue;
0a7de745 557 }
6d2010ae
A
558
559 /*
560 * Check for '.o' file in list
561 */
562 cp = tp->f_fn + (len = strlen(tp->f_fn)) - 1;
0a7de745 563 if (ext != -1 && *cp != ext) {
6d2010ae 564 continue;
0a7de745 565 } else if (*cp == 'o') {
6d2010ae
A
566 if (len + lpos > 72) {
567 lpos = 8;
568 fprintf(fp, "\\\n\t");
569 }
570 put_source_file_name(fp, tp);
571 fprintf(fp, " ");
572 lpos += len + 1;
573 continue;
574 }
575 sp = tail(tp->f_fn);
6d2010ae
A
576 cp = (char *)sp + (len = strlen(sp)) - 1;
577 och = *cp;
578 *cp = 'o';
579 if (len + lpos > 72) {
580 lpos = 8;
581 fprintf(fp, "\\\n\t");
582 }
583 fprintf(fp, "%s ", sp);
584 lpos += len + 1;
585 *cp = och;
6d2010ae 586 }
fe8ab488 587 putc('\n', fp);
6d2010ae
A
588}
589
590void
591do_files(FILE *fp, const char *msg, char ext)
592{
39037602 593 struct file_list *tp;
0a7de745 594 int lpos, len = 0; /* dvw: init to 0 */
6d2010ae
A
595
596 fprintf(fp, "%s", msg);
597 lpos = 8;
598 for (tp = ftab; tp != 0; tp = tp->f_next) {
0a7de745 599 if (tp->f_type == INVISIBLE) {
6d2010ae 600 continue;
0a7de745
A
601 }
602 if (tp->f_fn[strlen(tp->f_fn) - 1] != ext) {
6d2010ae 603 continue;
0a7de745 604 }
6d2010ae
A
605 /*
606 * Always generate a newline.
607 * Our Makefile's aren't readable anyway.
608 */
609
610 lpos = 8;
611 fprintf(fp, "\\\n\t");
612 put_source_file_name(fp, tp);
613 lpos += len + 1;
614 }
fe8ab488 615 putc('\n', fp);
6d2010ae
A
616}
617
618/*
619 * Include machine dependent makefile in output
620 */
621
622void
623do_machdep(FILE *ofp)
624{
625 FILE *ifp;
626 char pname[BUFSIZ];
627 char line[BUFSIZ];
628
629 (void) sprintf(line, "%s/Makefile.%s", config_directory, machinename);
630 ifp = fopenp(VPATH, line, pname, "r");
631 if (ifp == 0) {
632 perror(line);
633 exit(1);
634 }
635 while (fgets(line, BUFSIZ, ifp) != 0) {
0a7de745
A
636 if (profiling && (strncmp(line, "LIBS=", 5) == 0)) {
637 fprintf(ofp, "LIBS=${LIBS_P}\n");
638 } else {
6d2010ae 639 fputs(line, ofp);
0a7de745 640 }
6d2010ae
A
641 }
642 fclose(ifp);
643}
644
6d2010ae
A
645const char *
646tail(const char *fn)
647{
39037602 648 const char *cp;
6d2010ae
A
649
650 cp = rindex(fn, '/');
0a7de745
A
651 if (cp == 0) {
652 return fn;
653 }
654 return cp + 1;
6d2010ae
A
655}
656
657/*
658 * Create the makerules for each file
659 * which is part of the system.
660 * Devices are processed with the special c2 option -i
661 * which avoids any problem areas with i/o addressing
662 * (e.g. for the VAX); assembler files are processed by as.
663 */
664void
665do_rules(FILE *f)
666{
667 char *cp;
668 char *np, och;
669 const char *tp;
39037602 670 struct file_list *ftp;
6d2010ae
A
671 const char *extras = ""; /* dvw: init to "" */
672 char *source_dir;
673 char och_upper;
674 const char *nl = "";
675
676 for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
0a7de745 677 if (ftp->f_type == INVISIBLE) {
6d2010ae 678 continue;
0a7de745 679 }
6d2010ae
A
680 cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
681 och = *cp;
682 /*
0a7de745
A
683 * Don't compile '.o' files
684 */
685 if (och == 'o') {
6d2010ae 686 continue;
0a7de745 687 }
6d2010ae 688 /*
0a7de745
A
689 * Determine where sources should come from
690 */
6d2010ae
A
691 if ((np[0] == '.') && (np[1] == '/')) {
692 source_dir = "";
693 np += 2;
0a7de745 694 } else {
6d2010ae 695 source_dir = "$(SOURCE_DIR)/";
0a7de745 696 }
6d2010ae 697 *cp = '\0';
0a7de745 698 tp = tail(np); /* dvw: init tp before 'if' */
39236c6e 699 fprintf(f, "-include %sd\n", tp);
6d2010ae
A
700 fprintf(f, "%so: %s%s%c\n", tp, source_dir, np, och);
701 if (och == 's') {
fe8ab488
A
702 fprintf(f, "\t${S_RULE_0}\n");
703 fprintf(f, "\t${S_RULE_1A}%s%.*s${S_RULE_1B}%s\n",
0a7de745 704 source_dir, (int)(tp - np), np, nl);
fe8ab488 705 fprintf(f, "\t${S_RULE_2}%s\n", nl);
6d2010ae
A
706 continue;
707 }
6d2010ae
A
708 extras = "";
709 switch (ftp->f_type) {
6d2010ae 710 case NORMAL:
fe8ab488 711 goto common;
6d2010ae 712 break;
0a7de745 713
6d2010ae 714 case DRIVER:
fe8ab488
A
715 extras = "_D";
716 goto common;
6d2010ae 717 break;
0a7de745 718
6d2010ae 719 case PROFILING:
0a7de745 720 if (!profiling) {
6d2010ae 721 continue;
0a7de745 722 }
6d2010ae
A
723 if (COPTS == 0) {
724 fprintf(stderr,
0a7de745 725 "config: COPTS undefined in generic makefile");
6d2010ae
A
726 COPTS = "";
727 }
fe8ab488
A
728 extras = "_P";
729 goto common;
0a7de745
A
730
731common:
6d2010ae 732 och_upper = och + 'A' - 'a';
39236c6e 733 fprintf(f, "\t${%c_RULE_0%s}\n", och_upper, extras);
6d2010ae 734 fprintf(f, "\t${%c_RULE_1A%s}", och_upper, extras);
0a7de745 735 if (ftp->f_extra) {
6d2010ae 736 fprintf(f, "%s", ftp->f_extra);
0a7de745 737 }
6d2010ae 738 fprintf(f, "%s%.*s${%c_RULE_1B%s}%s\n",
0a7de745 739 source_dir, (int)(tp - np), np, och_upper, extras, nl);
39236c6e 740
6d2010ae 741 fprintf(f, "\t${%c_RULE_2%s}%s\n", och_upper, extras, nl);
39037602 742 fprintf(f, "\t${%c_RULE_3%s}%s\n", och_upper, extras, nl);
cb323159
A
743 fprintf(f, "\t$(if ${%c_RULE_4A%s},${%c_RULE_4A%s}",
744 och_upper, extras, och_upper, extras);
0a7de745 745 if (ftp->f_extra) {
39037602 746 fprintf(f, "%s", ftp->f_extra);
0a7de745 747 }
cb323159 748 fprintf(f, "%s%.*s${%c_RULE_4B%s}%s)\n",
0a7de745 749 source_dir, (int)(tp - np), np, och_upper, extras, nl);
6d2010ae 750 break;
0a7de745 751
6d2010ae
A
752 default:
753 printf("Don't know rules for %s\n", np);
754 break;
755 }
756 *cp = och;
757 }
758}
759
6d2010ae 760char *
39037602 761allCaps(char *str)
6d2010ae 762{
39037602 763 char *cp = str;
6d2010ae
A
764
765 while (*str) {
0a7de745 766 if (islower(*str)) {
6d2010ae 767 *str = toupper(*str);
0a7de745 768 }
6d2010ae
A
769 str++;
770 }
0a7de745 771 return cp;
6d2010ae
A
772}
773
774#define OLDSALUTATION "# DO NOT DELETE THIS LINE"
775
776#define LINESIZE 1024
0a7de745 777static char makbuf[LINESIZE]; /* one line buffer for makefile */
6d2010ae
A
778
779void
780copy_dependencies(FILE *makin, FILE *makout)
781{
39037602 782 int oldlen = (sizeof OLDSALUTATION - 1);
6d2010ae
A
783
784 while (fgets(makbuf, LINESIZE, makin) != NULL) {
0a7de745 785 if (!strncmp(makbuf, OLDSALUTATION, oldlen)) {
6d2010ae 786 break;
0a7de745 787 }
6d2010ae
A
788 }
789 while (fgets(makbuf, LINESIZE, makin) != NULL) {
0a7de745
A
790 if (oldlen != 0) {
791 if (makbuf[0] == '\n') {
6d2010ae 792 continue;
0a7de745 793 } else {
6d2010ae 794 oldlen = 0;
0a7de745 795 }
6d2010ae
A
796 }
797 fputs(makbuf, makout);
798 }
799}