File: | src/usr.sbin/config/mkmakefile.c |
Warning: | line 317, column 8 Although the value stored to 'fpath' is used in the enclosing expression, the value is never actually read from 'fpath' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: mkmakefile.c,v 1.48 2021/11/28 19:26:03 deraadt Exp $ */ |
2 | /* $NetBSD: mkmakefile.c,v 1.34 1997/02/02 21:12:36 thorpej Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 1992, 1993 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * This software was developed by the Computer Systems Engineering group |
9 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and |
10 | * contributed to Berkeley. |
11 | * |
12 | * All advertising materials mentioning features or use of this software |
13 | * must display the following acknowledgement: |
14 | * This product includes software developed by the University of |
15 | * California, Lawrence Berkeley Laboratories. |
16 | * |
17 | * Redistribution and use in source and binary forms, with or without |
18 | * modification, are permitted provided that the following conditions |
19 | * are met: |
20 | * 1. Redistributions of source code must retain the above copyright |
21 | * notice, this list of conditions and the following disclaimer. |
22 | * 2. Redistributions in binary form must reproduce the above copyright |
23 | * notice, this list of conditions and the following disclaimer in the |
24 | * documentation and/or other materials provided with the distribution. |
25 | * 3. Neither the name of the University nor the names of its contributors |
26 | * may be used to endorse or promote products derived from this software |
27 | * without specific prior written permission. |
28 | * |
29 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
30 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
31 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
32 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
33 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
37 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
38 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
39 | * SUCH DAMAGE. |
40 | * |
41 | * from: @(#)mkmakefile.c 8.1 (Berkeley) 6/6/93 |
42 | */ |
43 | |
44 | #include <ctype.h> |
45 | #include <err.h> |
46 | #include <errno(*__errno()).h> |
47 | #include <stdio.h> |
48 | #include <stdlib.h> |
49 | #include <string.h> |
50 | |
51 | #include "config.h" |
52 | #include "sem.h" |
53 | |
54 | /* |
55 | * Make the Makefile. |
56 | */ |
57 | |
58 | static const char *srcpath(struct files *); |
59 | |
60 | static int emitdefs(FILE *); |
61 | static int emitreconfig(FILE *); |
62 | static int emitfiles(FILE *, int); |
63 | |
64 | static int emitobjs(FILE *); |
65 | static int emitcfiles(FILE *); |
66 | static int emitsfiles(FILE *); |
67 | static int emitrules(FILE *); |
68 | static int emitload(FILE *); |
69 | |
70 | int |
71 | mkmakefile(void) |
72 | { |
73 | FILE *ifp, *ofp; |
74 | int lineno; |
75 | int (*fn)(FILE *); |
76 | char *ifname; |
77 | char line[BUFSIZ1024], buf[200]; |
78 | |
79 | (void)snprintf(buf, sizeof buf, "arch/%s/conf/Makefile.%s", |
80 | machine, machine); |
81 | ifname = sourcepath(buf); |
82 | if ((ifp = fopen(ifname, "r")) == NULL((void *)0)) { |
83 | warn("cannot read %s", ifname); |
84 | free(ifname); |
85 | return (1); |
86 | } |
87 | if ((ofp = fopen("Makefile", "w")) == NULL((void *)0)) { |
88 | warn("cannot write Makefile"); |
89 | free(ifname); |
90 | (void)fclose(ifp); |
91 | return (1); |
92 | } |
93 | if (emitdefs(ofp) != 0) |
94 | goto wrerror; |
95 | lineno = 0; |
96 | while (fgets(line, sizeof(line), ifp) != NULL((void *)0)) { |
97 | lineno++; |
98 | if (line[0] != '%') { |
99 | if (fputs(line, ofp) == EOF(-1)) |
100 | goto wrerror; |
101 | continue; |
102 | } |
103 | if (strcmp(line, "%OBJS\n") == 0) |
104 | fn = emitobjs; |
105 | else if (strcmp(line, "%CFILES\n") == 0) |
106 | fn = emitcfiles; |
107 | else if (strcmp(line, "%SFILES\n") == 0) |
108 | fn = emitsfiles; |
109 | else if (strcmp(line, "%RULES\n") == 0) |
110 | fn = emitrules; |
111 | else if (strcmp(line, "%LOAD\n") == 0) |
112 | fn = emitload; |
113 | else { |
114 | xerror(ifname, lineno, |
115 | "unknown %% construct ignored: %s", line); |
116 | continue; |
117 | } |
118 | if ((*fn)(ofp)) |
119 | goto wrerror; |
120 | } |
121 | if (startdir != NULL((void *)0)) { |
122 | if (emitreconfig(ofp) != 0) |
123 | goto wrerror; |
124 | } |
125 | if (ferror(ifp)(!__isthreaded ? (((ifp)->_flags & 0x0040) != 0) : (ferror )(ifp))) { |
126 | warn("error reading %s (at line %d)", ifname, lineno); |
127 | goto bad; |
128 | } |
129 | if (fclose(ofp) == EOF(-1)) { |
130 | ofp = NULL((void *)0); |
131 | goto wrerror; |
132 | } |
133 | (void)fclose(ifp); |
134 | free(ifname); |
135 | return (0); |
136 | wrerror: |
137 | warn("error writing Makefile"); |
138 | bad: |
139 | if (ofp != NULL((void *)0)) |
140 | (void)fclose(ofp); |
141 | /* (void)unlink("Makefile"); */ |
142 | free(ifname); |
143 | return (1); |
144 | } |
145 | |
146 | char * |
147 | expandname(const char *_nam) |
148 | { |
149 | char *ret = NULL((void *)0), *nam, *n, *s, *e, *expand; |
150 | const char *var = NULL((void *)0); |
151 | |
152 | if ((nam = n = strdup(_nam)) == NULL((void *)0)) |
153 | errx(1, "out of memory"); |
154 | |
155 | while (*n) { |
156 | /* Search for a ${name} to expand */ |
157 | if ((s = strchr(n, '$')) == NULL((void *)0)) { |
158 | if (ret == NULL((void *)0)) |
159 | break; |
160 | if (asprintf(&expand, "%s%s", ret, n) == -1) |
161 | errx(1, "out of memory"); |
162 | free(ret); |
163 | ret = expand; |
164 | break; |
165 | } |
166 | *s++ = '\0'; |
167 | if (*s != '{') |
168 | error("{"); |
169 | e = strchr(++s, '}'); |
170 | if (!e) |
171 | error("}"); |
172 | *e = '\0'; |
173 | |
174 | if (strcmp(s, "MACHINE_ARCH") == 0) |
175 | var = machinearch ? machinearch : machine; |
176 | else if (strcmp(s, "MACHINE") == 0) |
177 | var = machine; |
178 | else |
179 | error("variable `%s' not supported", s); |
180 | |
181 | if (asprintf(&expand, "%s%s", ret ? ret : nam, var) == -1) |
182 | errx(1, "out of memory"); |
183 | free(ret); |
184 | ret = expand; |
185 | n = e + 1; |
186 | } |
187 | free(nam); |
188 | return (ret); |
189 | } |
190 | |
191 | /* |
192 | * Return (possibly in a static buffer) the name of the `source' for a |
193 | * file. If we have `options source', or if the file is marked `always |
194 | * source', this is always the path from the `file' line; otherwise we |
195 | * get the .o from the obj-directory. |
196 | */ |
197 | static const char * |
198 | srcpath(struct files *fi) |
199 | { |
200 | /* Always have source, don't support object dirs for kernel builds. */ |
201 | struct nvlist *nv, *nv1; |
202 | char *expand, *source; |
203 | |
204 | /* Search path list for files we will want to use */ |
205 | if (fi->fi_nvpath->nv_next == NULL((void *)0)) { |
206 | nv = fi->fi_nvpath; |
207 | goto onlyone; |
208 | } |
209 | |
210 | for (nv = fi->fi_nvpath; nv; nv = nv->nv_next) { |
211 | expand = expandname(nv->nv_name); |
212 | source = sourcepath(expand ? expand : nv->nv_name); |
213 | if (access(source, R_OK0x04) == 0) { |
214 | if (expand) |
215 | nv->nv_name = intern(expand); |
216 | break; |
217 | } |
218 | free(expand); |
219 | free(source); |
220 | } |
221 | if (nv == NULL((void *)0)) |
222 | nv = fi->fi_nvpath; |
223 | |
224 | /* |
225 | * Now that we know which path is selected, delete all the |
226 | * other paths to skip the access() checks next time. |
227 | */ |
228 | while ((nv1 = fi->fi_nvpath)) { |
229 | nv1 = nv1->nv_next; |
230 | if (fi->fi_nvpath != nv) |
231 | nvfree(fi->fi_nvpath); |
232 | fi->fi_nvpath = nv1; |
233 | } |
234 | fi->fi_nvpath = nv; |
235 | nv->nv_next = NULL((void *)0); |
236 | onlyone: |
237 | return (nv->nv_name); |
238 | } |
239 | |
240 | static int |
241 | emitdefs(FILE *fp) |
242 | { |
243 | struct nvlist *nv; |
244 | char *sp; |
245 | |
246 | if (fputs("IDENT=", fp) == EOF(-1)) |
247 | return (1); |
248 | sp = ""; |
249 | for (nv = options; nv != NULL((void *)0); nv = nv->nv_next) { |
250 | if (ht_lookup(defopttab, nv->nv_name) != NULL((void *)0)) |
251 | continue; |
252 | if (fprintf(fp, "%s-D%s", sp, nv->nv_name) < 0) |
253 | return 1; |
254 | if (nv->nv_strnv_un.un_str) |
255 | if (fprintf(fp, "=\"%s\"", nv->nv_strnv_un.un_str) < 0) |
256 | return 1; |
257 | sp = " "; |
258 | } |
259 | if (putc('\n', fp)(!__isthreaded ? __sputc('\n', fp) : (putc)('\n', fp)) == EOF(-1)) |
260 | return (1); |
261 | if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0) |
262 | return (1); |
263 | if (fprintf(fp, "S=\t%s\n", srcdir) < 0) |
264 | return (1); |
265 | if (fprintf(fp, "_mach=%s\n", machine) < 0) |
266 | return (1); |
267 | if (fprintf(fp, "_arch=%s\n", machinearch ? machinearch : machine) < 0) |
268 | return (1); |
269 | for (nv = mkoptions; nv != NULL((void *)0); nv = nv->nv_next) |
270 | if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_strnv_un.un_str) < 0) |
271 | return (1); |
272 | return (0); |
273 | } |
274 | |
275 | static int |
276 | emitreconfig(FILE *fp) |
277 | { |
278 | if (fputs("\n" |
279 | ".PHONY: config\n" |
280 | "config:\n", fp) == EOF(-1)) |
281 | return (1); |
282 | if (fprintf(fp, "\tcd %s && config ", startdir) < 0) |
283 | return (1); |
284 | if (pflag) { |
285 | if (fputs("-p ", fp) == EOF(-1)) |
286 | return (1); |
287 | } |
288 | if (sflag) { |
289 | if (fprintf(fp, "-s %s ", sflag) < 0) |
290 | return (1); |
291 | } |
292 | if (bflag) { |
293 | if (fprintf(fp, "-b %s ", bflag) < 0) |
294 | return (1); |
295 | } |
296 | /* other options */ |
297 | if (fprintf(fp, "%s\n", conffile) < 0) |
298 | return (1); |
299 | return (0); |
300 | } |
301 | |
302 | static int |
303 | emitobjs(FILE *fp) |
304 | { |
305 | struct files *fi; |
306 | struct objects *oi; |
307 | int lpos, len, sp; |
308 | const char *fpath; |
309 | |
310 | if (fputs("OBJS=", fp) == EOF(-1)) |
311 | return (1); |
312 | sp = '\t'; |
313 | lpos = 7; |
314 | for (fi = allfiles; fi != NULL((void *)0); fi = fi->fi_next) { |
315 | if ((fi->fi_flags & FI_SEL0x01) == 0) |
316 | continue; |
317 | if ((fpath = srcpath(fi)) == NULL((void *)0)) |
Although the value stored to 'fpath' is used in the enclosing expression, the value is never actually read from 'fpath' | |
318 | return (1); |
319 | len = strlen(fi->fi_base) + 3; |
320 | if (lpos + len > 72) { |
321 | if (fputs(" \\\n", fp) == EOF(-1)) |
322 | return (1); |
323 | sp = '\t'; |
324 | lpos = 7; |
325 | } |
326 | if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0) |
327 | return (1); |
328 | lpos += len + 1; |
329 | sp = ' '; |
330 | } |
331 | for (oi = allobjects; oi != NULL((void *)0); oi = oi->oi_next) { |
332 | if ((oi->oi_flags & OI_SEL0x01) == 0) |
333 | continue; |
334 | len = strlen(oi->oi_path) + 3; |
335 | if (lpos + len > 72) { |
336 | if (fputs(" \\\n", fp) == EOF(-1)) |
337 | return (1); |
338 | sp = '\t'; |
339 | lpos = 7; |
340 | } |
341 | if (fprintf(fp, "%c$S/%s", sp, oi->oi_path) < 0) |
342 | return (1); |
343 | lpos += len + 1; |
344 | sp = ' '; |
345 | } |
346 | if (putc('\n', fp)(!__isthreaded ? __sputc('\n', fp) : (putc)('\n', fp)) == EOF(-1)) |
347 | return (1); |
348 | return (0); |
349 | } |
350 | |
351 | static int |
352 | emitcfiles(FILE *fp) |
353 | { |
354 | |
355 | return (emitfiles(fp, 'c')); |
356 | } |
357 | |
358 | static int |
359 | emitsfiles(FILE *fp) |
360 | { |
361 | |
362 | return (emitfiles(fp, 's')); |
363 | } |
364 | |
365 | static int |
366 | emitfiles(FILE *fp, int suffix) |
367 | { |
368 | struct files *fi; |
369 | int lpos, len, sp; |
370 | const char *fpath; |
371 | char uppersuffix = toupper((unsigned char)suffix); |
372 | |
373 | if (fprintf(fp, "%cFILES=", uppersuffix) < 0) |
374 | return (1); |
375 | sp = '\t'; |
376 | lpos = 7; |
377 | for (fi = allfiles; fi != NULL((void *)0); fi = fi->fi_next) { |
378 | if ((fi->fi_flags & FI_SEL0x01) == 0) |
379 | continue; |
380 | if ((fpath = srcpath(fi)) == NULL((void *)0)) |
381 | return (1); |
382 | len = strlen(fpath); |
383 | if (fpath[len - 1] != suffix && fpath[len - 1] != uppersuffix) |
384 | continue; |
385 | if (*fpath != '/') |
386 | len += 3; /* "$S/" */ |
387 | if (lpos + len > 72) { |
388 | if (fputs(" \\\n", fp) == EOF(-1)) |
389 | return (1); |
390 | sp = '\t'; |
391 | lpos = 7; |
392 | } |
393 | if (fprintf(fp, "%c%s%s", sp, *fpath != '/' ? "$S/" : "", |
394 | fpath) < 0) |
395 | return (1); |
396 | lpos += len + 1; |
397 | sp = ' '; |
398 | } |
399 | if (putc('\n', fp)(!__isthreaded ? __sputc('\n', fp) : (putc)('\n', fp)) == EOF(-1)) |
400 | return (1); |
401 | return (0); |
402 | } |
403 | |
404 | /* |
405 | * Emit the make-rules. |
406 | */ |
407 | static int |
408 | emit_1rule(FILE *fp, struct files *fi, const char *fpath, const char *suffix) |
409 | { |
410 | if (fprintf(fp, "%s%s: %s%s\n", fi->fi_base, suffix, |
411 | *fpath != '/' ? "$S/" : "", fpath) < 0) |
412 | return (1); |
413 | if (fi->fi_mkrule != NULL((void *)0)) { |
414 | if (fprintf(fp, "\t%s\n\n", fi->fi_mkrule) < 0) |
415 | return (1); |
416 | } |
417 | return (0); |
418 | } |
419 | |
420 | static int |
421 | emitrules(FILE *fp) |
422 | { |
423 | struct files *fi; |
424 | const char *fpath; |
425 | |
426 | /* write suffixes */ |
427 | if (fprintf(fp, |
428 | ".SUFFIXES:\n" |
429 | ".SUFFIXES: .s .S .c .o\n\n" |
430 | |
431 | ".PHONY: depend all install clean tags newbsd update-link\n\n" |
432 | |
433 | ".c.o:\n" |
434 | "\t${NORMAL_C}\n\n" |
435 | |
436 | ".s.o:\n" |
437 | "\t${NORMAL_S}\n\n" |
438 | |
439 | ".S.o:\n" |
440 | "\t${NORMAL_S}\n\n") < 0) |
441 | return (1); |
442 | |
443 | |
444 | for (fi = allfiles; fi != NULL((void *)0); fi = fi->fi_next) { |
445 | if ((fi->fi_flags & FI_SEL0x01) == 0) |
446 | continue; |
447 | if ((fpath = srcpath(fi)) == NULL((void *)0)) |
448 | return (1); |
449 | /* special rule: need to emit them independently */ |
450 | if (fi->fi_mkrule) { |
451 | if (emit_1rule(fp, fi, fpath, ".o")) |
452 | return (1); |
453 | /* simple default rule */ |
454 | } else { |
455 | if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base, |
456 | *fpath != '/' ? "$S/" : "", fpath) < 0) |
457 | return (1); |
458 | } |
459 | |
460 | } |
461 | return (0); |
462 | } |
463 | |
464 | /* |
465 | * Emit the load commands. |
466 | * |
467 | * This function is not to be called `spurt'. |
468 | */ |
469 | static int |
470 | emitload(FILE *fp) |
471 | { |
472 | struct config *cf; |
473 | const char *nm, *swname; |
474 | int first; |
475 | |
476 | if (fputs("all:", fp) == EOF(-1)) |
477 | return (1); |
478 | for (cf = allcf; cf != NULL((void *)0); cf = cf->cf_next) { |
479 | if (fprintf(fp, " %s", cf->cf_name) < 0) |
480 | return (1); |
481 | } |
482 | if (fputs("\n\n", fp) == EOF(-1)) |
483 | return (1); |
484 | for (first = 1, cf = allcf; cf != NULL((void *)0); cf = cf->cf_next) { |
485 | nm = cf->cf_name; |
486 | swname = |
487 | cf->cf_root != NULL((void *)0) ? cf->cf_name : "generic"; |
488 | if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0) |
489 | return (1); |
490 | if (first) { |
491 | if (fputs(" vers.o", fp) == EOF(-1)) |
492 | return (1); |
493 | first = 0; |
494 | } |
495 | if (fprintf(fp, "\n" |
496 | "\t${SYSTEM_LD_HEAD}\n" |
497 | "\t${SYSTEM_LD} swap%s.o\n" |
498 | "\t${SYSTEM_LD_TAIL}\n" |
499 | "\n" |
500 | "swap%s.o: ", swname, swname) < 0) |
501 | return (1); |
502 | if (cf->cf_root != NULL((void *)0)) { |
503 | if (fprintf(fp, "swap%s.c\n", nm) < 0) |
504 | return (1); |
505 | } else { |
506 | if (fprintf(fp, "$S/conf/swapgeneric.c\n") < 0) |
507 | return (1); |
508 | } |
509 | if (fputs("\t${NORMAL_C}\n\n", fp) == EOF(-1)) |
510 | return (1); |
511 | |
512 | if (fprintf(fp, "new%s:\n", nm) < 0) |
513 | return (1); |
514 | if (fprintf(fp, |
515 | "\t${MAKE_GAP}\n" |
516 | "\t${SYSTEM_LD_HEAD}\n" |
517 | "\t${SYSTEM_LD} swap%s.o\n" |
518 | "\t${SYSTEM_LD_TAIL}\n" |
519 | "\trm -f %s.gdb\n" |
520 | "\tmv -f new%s %s\n\n", |
521 | swname, nm, nm, nm) < 0) |
522 | return (1); |
523 | |
524 | if (fprintf(fp, "update-link:\n") < 0) |
525 | return (1); |
526 | if (fprintf(fp, |
527 | "\tmkdir -p -m 700 /usr/share/relink/kernel\n" |
528 | "\trm -rf /usr/share/relink/kernel/%s /usr/share/relink/kernel.tgz\n" |
529 | "\tmkdir /usr/share/relink/kernel/%s\n" |
530 | "\ttar -chf - Makefile makegap.sh ld.script *.o | \\\n" |
531 | "\t tar -C /usr/share/relink/kernel/%s -xf -\n\n", |
532 | last_component, last_component, last_component) < 0) |
533 | return (1); |
534 | } |
535 | return (0); |
536 | } |