2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 static const char copyright[] =
36 "@(#) Copyright (c) 1980, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
42 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
44 static const char rcsid[] =
48 #include <sys/types.h>
52 #include <sys/param.h>
70 #define CDIR "../compile/"
73 char destdir[MAXPATHLEN];
74 char srcdir[MAXPATHLEN];
79 static void configfile(void);
80 static void get_srcdir(void);
81 static void usage(void);
82 static void cleanheaders(char *);
86 struct hdr_list *h_next;
90 * Config builds a set of files for building a UNIX
91 * system given a description of the desired system.
94 main(int argc, char **argv)
100 char xxx[MAXPATHLEN];
102 while ((ch = getopt(argc, argv, "d:gp")) != -1)
105 if (*destdir == '\0')
106 strlcpy(destdir, optarg, sizeof(destdir));
108 errx(2, "directory already set");
126 if (freopen(PREFIX = *argv, "r", stdin) == NULL)
127 err(2, "%s", PREFIX);
129 if (*destdir != '\0') {
130 len = strlen(destdir);
131 while (len > 1 && destdir[len - 1] == '/')
132 destdir[--len] = '\0';
135 strlcpy(destdir, CDIR, sizeof(destdir));
136 strlcat(destdir, PREFIX, sizeof(destdir));
139 p = path((char *)NULL);
144 else if ((buf.st_mode & S_IFMT) != S_IFDIR)
145 errx(2, "%s isn't a directory", p);
151 if (machinename == NULL) {
152 printf("Specify machine type, e.g. ``machine i386''\n");
156 * make symbolic links in compilation directory
157 * for "sys" (to make genassym.c work along with #include <sys/xxx>)
158 * and similarly for "machine".
161 (void)snprintf(xxx, sizeof(xxx), "../../include");
163 (void)snprintf(xxx, sizeof(xxx), "%s/%s/include",
164 srcdir, machinename);
165 (void) unlink(path("machine"));
166 (void) symlink(xxx, path("machine"));
167 options(); /* make options .h files */
168 makefile(); /* build Makefile */
169 headers(); /* make a lot of .h files */
170 configfile(); /* put config file into kernel*/
172 printf("Kernel build directory is %s\n", p);
173 printf("Don't forget to do a ``make depend''\n");
179 * determine the root of the kernel source tree
180 * and save that in srcdir.
186 if (realpath("../..", srcdir) == NULL)
187 errx(2, "Unable to find root of source tree");
193 fprintf(stderr, "usage: config [-gp] [-d destdir] sysname\n");
199 * returns EOF on end of file
200 * NULL on end of line
201 * pointer to the word otherwise
206 static char line[80];
212 while ((ch = getc(fp)) != EOF)
213 if (ch != ' ' && ch != '\t')
216 return ((char *)EOF);
231 while ((ch = getc(fp)) != EOF) {
238 return ((char *)EOF);
239 (void) ungetc(ch, fp);
245 * like get_word but will accept something in double or single quotes
246 * (to allow embedded spaces).
249 get_quoted_word(FILE *fp)
251 static char line[256];
257 while ((ch = getc(fp)) != EOF)
258 if (ch != ' ' && ch != '\t')
261 return ((char *)EOF);
275 if (ch == '"' || ch == '\'') {
278 while ((ch = getc(fp)) != EOF) {
283 printf("config: missing quote reading `%s'\n",
291 while ((ch = getc(fp)) != EOF) {
297 (void) ungetc(ch, fp);
301 return ((char *)EOF);
306 * prepend the path to a filename
309 path(const char *file)
314 asprintf(&cp, "%s/%s", destdir, file);
316 cp = strdup(destdir);
327 fi = fopen(PREFIX, "r");
329 err(2, "%s", PREFIX);
330 fo = fopen(p=path("config.c.new"), "w");
333 fprintf(fo, "#include \"opt_config.h\"\n");
334 fprintf(fo, "#ifdef INCLUDE_CONFIG_FILE \n");
335 fprintf(fo, "static const char config[] = \"\\\n");
336 fprintf(fo, "START CONFIG FILE %s\\n\\\n___", PREFIX);
337 while (EOF != (i=getc(fi))) {
339 fprintf(fo, "\\n\\\n___");
340 } else if (i == '\"') {
342 } else if (i == '\\') {
348 fprintf(fo, "\\n\\\nEND CONFIG FILE %s\\n\\\n", PREFIX);
349 fprintf(fo, "\";\n");
350 fprintf(fo, "\n#endif /* INCLUDE_CONFIG_FILE */\n");
353 moveifchanged(path("config.c.new"), path("config.c"));
358 * compare two files; rename if changed.
361 moveifchanged(const char *from_name, const char *to_name)
366 struct stat from_sb, to_sb;
371 if ((from_fd = open(from_name, O_RDONLY)) < 0)
372 err(EX_OSERR, "moveifchanged open(%s)", from_name);
374 if ((to_fd = open(to_name, O_RDONLY)) < 0)
377 if (!changed && fstat(from_fd, &from_sb) < 0)
378 err(EX_OSERR, "moveifchanged fstat(%s)", from_name);
380 if (!changed && fstat(to_fd, &to_sb) < 0)
381 err(EX_OSERR, "moveifchanged fstat(%s)", to_name);
383 if (!changed && from_sb.st_size != to_sb.st_size)
386 tsize = (size_t)from_sb.st_size;
389 p = mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
391 #define MAP_FAILED ((caddr_t) -1)
394 err(EX_OSERR, "mmap %s", from_name);
395 q = mmap(NULL, tsize, PROT_READ, MAP_SHARED, to_fd, (off_t)0);
397 err(EX_OSERR, "mmap %s", to_name);
399 changed = memcmp(p, q, tsize);
404 if (rename(from_name, to_name) < 0)
405 err(EX_OSERR, "rename(%s, %s)", from_name, to_name);
407 if (unlink(from_name) < 0)
408 err(EX_OSERR, "unlink(%s)", from_name);
413 cleanheaders(char *p)
417 struct file_list *fl;
422 remember("setdefs.h");
423 for (fl = ftab; fl != NULL; fl = fl->f_next)
427 * Scan the build directory and clean out stuff that looks like
428 * it might have been a leftover NFOO header, etc.
431 while ((dp = readdir(dirp)) != NULL) {
432 i = dp->d_namlen - 2;
433 /* Skip non-headers */
434 if (dp->d_name[i] != '.' || dp->d_name[i + 1] != 'h')
436 /* Skip special stuff, eg: bus_if.h, but check opt_*.h */
437 if (index(dp->d_name, '_') &&
438 strncmp(dp->d_name, "opt_", 4) != 0)
440 /* Check if it is a target file */
441 for (hl = htab; hl != NULL; hl = hl->h_next) {
442 if (strcmp(dp->d_name, hl->h_name) == 0) {
448 printf("Removing stale header: %s\n", dp->d_name);
449 unlink(path(dp->d_name));
451 (void)closedir(dirp);
455 remember(const char *file)
460 if ((s = strrchr(file, '/')) != NULL)
465 if (index(s, '_') && strncmp(s, "opt_", 4) != 0) {
469 for (hl = htab; hl != NULL; hl = hl->h_next) {
470 if (strcmp(s, hl->h_name) == 0) {
475 hl = malloc(sizeof(*hl));
476 bzero(hl, sizeof(*hl));