Commit | Line | Data |
---|---|---|
a1c56c28 | 1 | /* |
62a2aae7 KB |
2 | * Copyright (c) 1992, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
a1c56c28 CT |
4 | * |
5 | * This software was developed by the Computer Systems Engineering group | |
6 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and | |
7 | * contributed to Berkeley. | |
8 | * | |
9 | * All advertising materials mentioning features or use of this software | |
10 | * must display the following acknowledgement: | |
11 | * This product includes software developed by the University of | |
12 | * California, Lawrence Berkeley Laboratories. | |
13 | * | |
14 | * %sccs.include.redist.c% | |
15 | * | |
62a2aae7 | 16 | * @(#)mkmakefile.c 8.1 (Berkeley) %G% |
a1c56c28 CT |
17 | */ |
18 | ||
19 | #include <sys/param.h> | |
20 | #include <ctype.h> | |
21 | #include <errno.h> | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | #include "config.h" | |
26 | ||
27 | /* | |
28 | * Make the Makefile. | |
29 | */ | |
30 | ||
31 | static int emitdefs __P((FILE *)); | |
32 | static int emitobjs __P((FILE *)); | |
33 | static int emitcfiles __P((FILE *)); | |
34 | static int emitsfiles __P((FILE *)); | |
35 | static int emitfiles __P((FILE *, int)); | |
36 | static int emitrules __P((FILE *)); | |
37 | static int emitload __P((FILE *)); | |
38 | ||
39 | int | |
40 | mkmakefile() | |
41 | { | |
42 | register FILE *ifp, *ofp; | |
43 | register int lineno; | |
44 | register int (*fn) __P((FILE *)); | |
45 | register char *ofname; | |
46 | char line[BUFSIZ], ifname[200]; | |
47 | ||
48 | (void)sprintf(ifname, "Makefile.%s", machine); | |
49 | if ((ifp = fopen(ifname, "r")) == NULL) { | |
50 | (void)fprintf(stderr, "config: cannot read %s: %s\n", | |
51 | ifname, strerror(errno)); | |
52 | return (1); | |
53 | } | |
54 | ofname = path("Makefile"); | |
55 | if ((ofp = fopen(ofname, "w")) == NULL) { | |
56 | (void)fprintf(stderr, "config: cannot write %s: %s\n", | |
57 | ofname, strerror(errno)); | |
58 | free(ofname); | |
59 | return (1); | |
60 | } | |
61 | if (emitdefs(ofp) != 0) | |
62 | goto wrerror; | |
63 | lineno = 0; | |
64 | while (fgets(line, sizeof(line), ifp) != NULL) { | |
65 | lineno++; | |
66 | if (line[0] != '%') { | |
67 | if (fputs(line, ofp) < 0) | |
68 | goto wrerror; | |
69 | continue; | |
70 | } | |
71 | if (strcmp(line, "%OBJS\n") == 0) | |
72 | fn = emitobjs; | |
73 | else if (strcmp(line, "%CFILES\n") == 0) | |
74 | fn = emitcfiles; | |
75 | else if (strcmp(line, "%SFILES\n") == 0) | |
76 | fn = emitsfiles; | |
77 | else if (strcmp(line, "%RULES\n") == 0) | |
78 | fn = emitrules; | |
79 | else if (strcmp(line, "%LOAD\n") == 0) | |
80 | fn = emitload; | |
81 | else { | |
82 | xerror(ifname, lineno, | |
83 | "unknown %% construct ignored: %s", line); | |
84 | continue; | |
85 | } | |
86 | if ((*fn)(ofp)) | |
87 | goto wrerror; | |
88 | } | |
89 | if (ferror(ifp)) { | |
90 | (void)fprintf(stderr, | |
91 | "config: error reading %s (at line %d): %s\n", | |
92 | ifname, lineno, strerror(errno)); | |
93 | goto bad; | |
94 | /* (void)unlink(ofname); */ | |
95 | free(ofname); | |
96 | return (1); | |
97 | } | |
98 | if (fclose(ofp)) { | |
99 | ofp = NULL; | |
100 | goto wrerror; | |
101 | } | |
102 | (void)fclose(ifp); | |
103 | free(ofname); | |
104 | return (0); | |
105 | wrerror: | |
106 | (void)fprintf(stderr, "config: error writing %s: %s\n", | |
107 | ofname, strerror(errno)); | |
108 | bad: | |
109 | if (ofp != NULL) | |
110 | (void)fclose(ofp); | |
111 | /* (void)unlink(ofname); */ | |
112 | free(ofname); | |
113 | return (1); | |
114 | } | |
115 | ||
116 | static int | |
117 | emitdefs(fp) | |
118 | register FILE *fp; | |
119 | { | |
120 | register struct nvlist *nv; | |
121 | register char *sp; | |
122 | ||
123 | if (fputs("IDENT=", fp) < 0) | |
124 | return (1); | |
125 | sp = ""; | |
126 | for (nv = options; nv != NULL; nv = nv->nv_next) { | |
127 | if (fprintf(fp, "%s-D%s%s%s", sp, nv->nv_name, | |
128 | nv->nv_str ? "=" : "", nv->nv_str ? nv->nv_str : "") < 0) | |
129 | return (1); | |
130 | sp = " "; | |
131 | } | |
132 | if (putc('\n', fp) < 0) | |
133 | return (1); | |
134 | if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0) | |
135 | return (1); | |
136 | for (nv = mkoptions; nv != NULL; nv = nv->nv_next) | |
137 | if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0) | |
138 | return (1); | |
139 | return (0); | |
140 | } | |
141 | ||
142 | static int | |
143 | emitobjs(fp) | |
144 | register FILE *fp; | |
145 | { | |
146 | register struct files *fi; | |
147 | register int lpos, len, sp; | |
148 | ||
149 | if (fputs("OBJS=", fp) < 0) | |
150 | return (1); | |
151 | sp = '\t'; | |
152 | lpos = 7; | |
153 | for (fi = allfiles; fi != NULL; fi = fi->fi_next) { | |
154 | if ((fi->fi_flags & FI_SEL) == 0) | |
155 | continue; | |
156 | len = strlen(fi->fi_base) + 2; | |
157 | if (lpos + len > 72) { | |
158 | if (fputs(" \\\n", fp) < 0) | |
159 | return (1); | |
160 | sp = '\t'; | |
161 | lpos = 7; | |
162 | } | |
163 | if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0) | |
164 | return (1); | |
165 | lpos += len + 1; | |
166 | sp = ' '; | |
167 | } | |
168 | if (lpos != 7 && putc('\n', fp) < 0) | |
169 | return (1); | |
170 | return (0); | |
171 | } | |
172 | ||
173 | static int | |
174 | emitcfiles(fp) | |
175 | FILE *fp; | |
176 | { | |
177 | ||
178 | return (emitfiles(fp, 'c')); | |
179 | } | |
180 | ||
181 | static int | |
182 | emitsfiles(fp) | |
183 | FILE *fp; | |
184 | { | |
185 | ||
186 | return (emitfiles(fp, 's')); | |
187 | } | |
188 | ||
189 | static int | |
190 | emitfiles(fp, suffix) | |
191 | register FILE *fp; | |
192 | int suffix; | |
193 | { | |
194 | register struct files *fi; | |
195 | register struct config *cf; | |
196 | register int lpos, len, sp; | |
197 | char swapname[100]; | |
198 | ||
199 | if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0) | |
200 | return (1); | |
201 | sp = '\t'; | |
202 | lpos = 7; | |
203 | for (fi = allfiles; fi != NULL; fi = fi->fi_next) { | |
204 | if ((fi->fi_flags & FI_SEL) == 0) | |
205 | continue; | |
206 | len = strlen(fi->fi_path); | |
207 | if (fi->fi_path[len - 1] != suffix) | |
208 | continue; | |
209 | if (*fi->fi_path != '/') | |
210 | len += 3; /* "$S/" */ | |
211 | if (lpos + len > 72) { | |
212 | if (fputs(" \\\n", fp) < 0) | |
213 | return (1); | |
214 | sp = '\t'; | |
215 | lpos = 7; | |
216 | } | |
217 | if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "", | |
218 | fi->fi_path) < 0) | |
219 | return (1); | |
220 | lpos += len + 1; | |
221 | sp = ' '; | |
222 | } | |
9e5f006d CT |
223 | /* |
224 | * The allfiles list does not include the configuration-specific | |
225 | * C source files. These files should be eliminated someday, but | |
226 | * for now, we have to add them to ${CFILES} (and only ${CFILES}). | |
227 | */ | |
228 | if (suffix == 'c') { | |
229 | for (cf = allcf; cf != NULL; cf = cf->cf_next) { | |
230 | if (cf->cf_root == NULL) | |
231 | (void)sprintf(swapname, | |
232 | "$S/%s/%s/swapgeneric.c", | |
233 | machine, machine); | |
234 | else | |
235 | (void)sprintf(swapname, "swap%s.c", | |
236 | cf->cf_name); | |
237 | len = strlen(swapname); | |
238 | if (lpos + len > 72) { | |
239 | if (fputs(" \\\n", fp) < 0) | |
240 | return (1); | |
241 | sp = '\t'; | |
242 | lpos = 7; | |
243 | } | |
244 | if (fprintf(fp, "%c%s", sp, swapname) < 0) | |
a1c56c28 | 245 | return (1); |
9e5f006d CT |
246 | lpos += len + 1; |
247 | sp = ' '; | |
a1c56c28 | 248 | } |
a1c56c28 CT |
249 | } |
250 | if (lpos != 7 && putc('\n', fp) < 0) | |
251 | return (1); | |
252 | return (0); | |
253 | } | |
254 | ||
255 | /* | |
256 | * Emit the make-rules. | |
257 | */ | |
258 | static int | |
259 | emitrules(fp) | |
260 | register FILE *fp; | |
261 | { | |
262 | register struct files *fi; | |
263 | register const char *cp; | |
264 | int ch; | |
265 | char buf[200]; | |
266 | ||
267 | for (fi = allfiles; fi != NULL; fi = fi->fi_next) { | |
268 | if ((fi->fi_flags & FI_SEL) == 0) | |
269 | continue; | |
270 | if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base, | |
271 | *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0) | |
272 | return (1); | |
273 | if ((cp = fi->fi_mkrule) == NULL) { | |
274 | cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL"; | |
275 | ch = fi->fi_lastc; | |
276 | if (islower(ch)) | |
277 | ch = toupper(ch); | |
278 | (void)sprintf(buf, "${%s_%c%s}", cp, ch, | |
279 | fi->fi_flags & FI_CONFIGDEP ? "_C" : ""); | |
280 | cp = buf; | |
281 | } | |
282 | if (fprintf(fp, "\t%s\n\n", cp) < 0) | |
283 | return (1); | |
284 | } | |
285 | return (0); | |
286 | } | |
287 | ||
288 | /* | |
289 | * Emit the load commands. | |
290 | * | |
291 | * This function is not to be called `spurt'. | |
292 | */ | |
293 | static int | |
294 | emitload(fp) | |
295 | register FILE *fp; | |
296 | { | |
297 | register struct config *cf; | |
298 | register const char *nm, *swname; | |
299 | int first; | |
300 | ||
301 | if (fputs("all:", fp) < 0) | |
302 | return (1); | |
303 | for (cf = allcf; cf != NULL; cf = cf->cf_next) { | |
304 | if (fprintf(fp, " %s", cf->cf_name) < 0) | |
305 | return (1); | |
306 | } | |
307 | if (fputs("\n\n", fp) < 0) | |
308 | return (1); | |
309 | for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) { | |
310 | nm = cf->cf_name; | |
311 | swname = cf->cf_root != NULL ? cf->cf_name : "generic"; | |
312 | if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0) | |
313 | return (1); | |
314 | if (first) { | |
315 | if (fputs(" newvers", fp) < 0) | |
316 | return (1); | |
317 | first = 0; | |
318 | } | |
319 | if (fprintf(fp, "\n\ | |
320 | \t${SYSTEM_LD_HEAD}\n\ | |
321 | \t${SYSTEM_LD} swap%s.o\n\ | |
322 | \t${SYSTEM_LD_TAIL}\n\ | |
323 | \n\ | |
324 | swap%s.o: ", swname, swname) < 0) | |
325 | return (1); | |
326 | if (cf->cf_root != NULL) { | |
327 | if (fprintf(fp, "swap%s.c\n", nm) < 0) | |
328 | return (1); | |
329 | } else { | |
330 | if (fprintf(fp, "$S/%s/%s/swapgeneric.c\n", | |
331 | machine, machine) < 0) | |
332 | return (1); | |
333 | } | |
334 | if (fputs("\t${NORMAL_C}\n\n", fp) < 0) | |
335 | return (1); | |
336 | } | |
337 | return (0); | |
338 | } |