122433fc5SMasahiro Yamada /* 222433fc5SMasahiro Yamada * "Optimize" a list of dependencies as spit out by gcc -MD 322433fc5SMasahiro Yamada * for the kernel build 422433fc5SMasahiro Yamada * =========================================================================== 522433fc5SMasahiro Yamada * 622433fc5SMasahiro Yamada * Author Kai Germaschewski 722433fc5SMasahiro Yamada * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de> 822433fc5SMasahiro Yamada * 922433fc5SMasahiro Yamada * This software may be used and distributed according to the terms 1022433fc5SMasahiro Yamada * of the GNU General Public License, incorporated herein by reference. 1122433fc5SMasahiro Yamada * 1222433fc5SMasahiro Yamada * 1322433fc5SMasahiro Yamada * Introduction: 1422433fc5SMasahiro Yamada * 1522433fc5SMasahiro Yamada * gcc produces a very nice and correct list of dependencies which 1622433fc5SMasahiro Yamada * tells make when to remake a file. 1722433fc5SMasahiro Yamada * 1822433fc5SMasahiro Yamada * To use this list as-is however has the drawback that virtually 1922433fc5SMasahiro Yamada * every file in the kernel includes autoconf.h. 2022433fc5SMasahiro Yamada * 2122433fc5SMasahiro Yamada * If the user re-runs make *config, autoconf.h will be 2222433fc5SMasahiro Yamada * regenerated. make notices that and will rebuild every file which 2322433fc5SMasahiro Yamada * includes autoconf.h, i.e. basically all files. This is extremely 2422433fc5SMasahiro Yamada * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. 2522433fc5SMasahiro Yamada * 2622433fc5SMasahiro Yamada * So we play the same trick that "mkdep" played before. We replace 2722433fc5SMasahiro Yamada * the dependency on autoconf.h by a dependency on every config 2822433fc5SMasahiro Yamada * option which is mentioned in any of the listed prequisites. 2922433fc5SMasahiro Yamada * 3022433fc5SMasahiro Yamada * kconfig populates a tree in include/config/ with an empty file 3122433fc5SMasahiro Yamada * for each config symbol and when the configuration is updated 3222433fc5SMasahiro Yamada * the files representing changed config options are touched 3322433fc5SMasahiro Yamada * which then let make pick up the changes and the files that use 3422433fc5SMasahiro Yamada * the config symbols are rebuilt. 3522433fc5SMasahiro Yamada * 3622433fc5SMasahiro Yamada * So if the user changes his CONFIG_HIS_DRIVER option, only the objects 3722433fc5SMasahiro Yamada * which depend on "include/linux/config/his/driver.h" will be rebuilt, 3822433fc5SMasahiro Yamada * so most likely only his driver ;-) 3922433fc5SMasahiro Yamada * 4022433fc5SMasahiro Yamada * The idea above dates, by the way, back to Michael E Chastain, AFAIK. 4122433fc5SMasahiro Yamada * 4222433fc5SMasahiro Yamada * So to get dependencies right, there are two issues: 4322433fc5SMasahiro Yamada * o if any of the files the compiler read changed, we need to rebuild 4422433fc5SMasahiro Yamada * o if the command line given to the compile the file changed, we 4522433fc5SMasahiro Yamada * better rebuild as well. 4622433fc5SMasahiro Yamada * 4722433fc5SMasahiro Yamada * The former is handled by using the -MD output, the later by saving 4822433fc5SMasahiro Yamada * the command line used to compile the old object and comparing it 4922433fc5SMasahiro Yamada * to the one we would now use. 5022433fc5SMasahiro Yamada * 5122433fc5SMasahiro Yamada * Again, also this idea is pretty old and has been discussed on 5222433fc5SMasahiro Yamada * kbuild-devel a long time ago. I don't have a sensibly working 5322433fc5SMasahiro Yamada * internet connection right now, so I rather don't mention names 5422433fc5SMasahiro Yamada * without double checking. 5522433fc5SMasahiro Yamada * 5622433fc5SMasahiro Yamada * This code here has been based partially based on mkdep.c, which 5722433fc5SMasahiro Yamada * says the following about its history: 5822433fc5SMasahiro Yamada * 5922433fc5SMasahiro Yamada * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>. 6022433fc5SMasahiro Yamada * This is a C version of syncdep.pl by Werner Almesberger. 6122433fc5SMasahiro Yamada * 6222433fc5SMasahiro Yamada * 6322433fc5SMasahiro Yamada * It is invoked as 6422433fc5SMasahiro Yamada * 6522433fc5SMasahiro Yamada * fixdep <depfile> <target> <cmdline> 6622433fc5SMasahiro Yamada * 6722433fc5SMasahiro Yamada * and will read the dependency file <depfile> 6822433fc5SMasahiro Yamada * 6922433fc5SMasahiro Yamada * The transformed dependency snipped is written to stdout. 7022433fc5SMasahiro Yamada * 7122433fc5SMasahiro Yamada * It first generates a line 7222433fc5SMasahiro Yamada * 7322433fc5SMasahiro Yamada * cmd_<target> = <cmdline> 7422433fc5SMasahiro Yamada * 7522433fc5SMasahiro Yamada * and then basically copies the .<target>.d file to stdout, in the 7622433fc5SMasahiro Yamada * process filtering out the dependency on autoconf.h and adding 7722433fc5SMasahiro Yamada * dependencies on include/config/my/option.h for every 7822433fc5SMasahiro Yamada * CONFIG_MY_OPTION encountered in any of the prequisites. 7922433fc5SMasahiro Yamada * 8022433fc5SMasahiro Yamada * It will also filter out all the dependencies on *.ver. We need 8122433fc5SMasahiro Yamada * to make sure that the generated version checksum are globally up 8222433fc5SMasahiro Yamada * to date before even starting the recursive build, so it's too late 8322433fc5SMasahiro Yamada * at this point anyway. 8422433fc5SMasahiro Yamada * 8522433fc5SMasahiro Yamada * The algorithm to grep for "CONFIG_..." is bit unusual, but should 8622433fc5SMasahiro Yamada * be fast ;-) We don't even try to really parse the header files, but 8722433fc5SMasahiro Yamada * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will 8822433fc5SMasahiro Yamada * be picked up as well. It's not a problem with respect to 8922433fc5SMasahiro Yamada * correctness, since that can only give too many dependencies, thus 9022433fc5SMasahiro Yamada * we cannot miss a rebuild. Since people tend to not mention totally 9122433fc5SMasahiro Yamada * unrelated CONFIG_ options all over the place, it's not an 9222433fc5SMasahiro Yamada * efficiency problem either. 9322433fc5SMasahiro Yamada * 9422433fc5SMasahiro Yamada * (Note: it'd be easy to port over the complete mkdep state machine, 9522433fc5SMasahiro Yamada * but I don't think the added complexity is worth it) 9622433fc5SMasahiro Yamada */ 9722433fc5SMasahiro Yamada /* 9822433fc5SMasahiro Yamada * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto 9922433fc5SMasahiro Yamada * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not 10022433fc5SMasahiro Yamada * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as 10122433fc5SMasahiro Yamada * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h, 10222433fc5SMasahiro Yamada * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that 10322433fc5SMasahiro Yamada * those files will have correct dependencies. 10422433fc5SMasahiro Yamada */ 10522433fc5SMasahiro Yamada 10622433fc5SMasahiro Yamada #include <sys/types.h> 10722433fc5SMasahiro Yamada #include <sys/stat.h> 10822433fc5SMasahiro Yamada #include <sys/mman.h> 10922433fc5SMasahiro Yamada #include <unistd.h> 11022433fc5SMasahiro Yamada #include <fcntl.h> 11122433fc5SMasahiro Yamada #include <string.h> 11222433fc5SMasahiro Yamada #include <stdlib.h> 11322433fc5SMasahiro Yamada #include <stdio.h> 11422433fc5SMasahiro Yamada #include <limits.h> 11522433fc5SMasahiro Yamada #include <ctype.h> 11622433fc5SMasahiro Yamada #include <arpa/inet.h> 11722433fc5SMasahiro Yamada 11822433fc5SMasahiro Yamada #define INT_CONF ntohl(0x434f4e46) 11922433fc5SMasahiro Yamada #define INT_ONFI ntohl(0x4f4e4649) 12022433fc5SMasahiro Yamada #define INT_NFIG ntohl(0x4e464947) 12122433fc5SMasahiro Yamada #define INT_FIG_ ntohl(0x4649475f) 12222433fc5SMasahiro Yamada 12322433fc5SMasahiro Yamada char *target; 12422433fc5SMasahiro Yamada char *depfile; 12522433fc5SMasahiro Yamada char *cmdline; 12622433fc5SMasahiro Yamada 12722433fc5SMasahiro Yamada static void usage(void) 12822433fc5SMasahiro Yamada { 12922433fc5SMasahiro Yamada fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); 13022433fc5SMasahiro Yamada exit(1); 13122433fc5SMasahiro Yamada } 13222433fc5SMasahiro Yamada 13322433fc5SMasahiro Yamada /* 13422433fc5SMasahiro Yamada * Print out the commandline prefixed with cmd_<target filename> := 13522433fc5SMasahiro Yamada */ 13622433fc5SMasahiro Yamada static void print_cmdline(void) 13722433fc5SMasahiro Yamada { 13822433fc5SMasahiro Yamada printf("cmd_%s := %s\n\n", target, cmdline); 13922433fc5SMasahiro Yamada } 14022433fc5SMasahiro Yamada 14122433fc5SMasahiro Yamada struct item { 14222433fc5SMasahiro Yamada struct item *next; 14322433fc5SMasahiro Yamada unsigned int len; 14422433fc5SMasahiro Yamada unsigned int hash; 14522433fc5SMasahiro Yamada char name[0]; 14622433fc5SMasahiro Yamada }; 14722433fc5SMasahiro Yamada 14822433fc5SMasahiro Yamada #define HASHSZ 256 14922433fc5SMasahiro Yamada static struct item *hashtab[HASHSZ]; 15022433fc5SMasahiro Yamada 15122433fc5SMasahiro Yamada static unsigned int strhash(const char *str, unsigned int sz) 15222433fc5SMasahiro Yamada { 15322433fc5SMasahiro Yamada /* fnv32 hash */ 15422433fc5SMasahiro Yamada unsigned int i, hash = 2166136261U; 15522433fc5SMasahiro Yamada 15622433fc5SMasahiro Yamada for (i = 0; i < sz; i++) 15722433fc5SMasahiro Yamada hash = (hash ^ str[i]) * 0x01000193; 15822433fc5SMasahiro Yamada return hash; 15922433fc5SMasahiro Yamada } 16022433fc5SMasahiro Yamada 16122433fc5SMasahiro Yamada /* 16222433fc5SMasahiro Yamada * Lookup a value in the configuration string. 16322433fc5SMasahiro Yamada */ 16422433fc5SMasahiro Yamada static int is_defined_config(const char *name, int len, unsigned int hash) 16522433fc5SMasahiro Yamada { 16622433fc5SMasahiro Yamada struct item *aux; 16722433fc5SMasahiro Yamada 16822433fc5SMasahiro Yamada for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { 16922433fc5SMasahiro Yamada if (aux->hash == hash && aux->len == len && 17022433fc5SMasahiro Yamada memcmp(aux->name, name, len) == 0) 17122433fc5SMasahiro Yamada return 1; 17222433fc5SMasahiro Yamada } 17322433fc5SMasahiro Yamada return 0; 17422433fc5SMasahiro Yamada } 17522433fc5SMasahiro Yamada 17622433fc5SMasahiro Yamada /* 17722433fc5SMasahiro Yamada * Add a new value to the configuration string. 17822433fc5SMasahiro Yamada */ 17922433fc5SMasahiro Yamada static void define_config(const char *name, int len, unsigned int hash) 18022433fc5SMasahiro Yamada { 18122433fc5SMasahiro Yamada struct item *aux = malloc(sizeof(*aux) + len); 18222433fc5SMasahiro Yamada 18322433fc5SMasahiro Yamada if (!aux) { 18422433fc5SMasahiro Yamada perror("fixdep:malloc"); 18522433fc5SMasahiro Yamada exit(1); 18622433fc5SMasahiro Yamada } 18722433fc5SMasahiro Yamada memcpy(aux->name, name, len); 18822433fc5SMasahiro Yamada aux->len = len; 18922433fc5SMasahiro Yamada aux->hash = hash; 19022433fc5SMasahiro Yamada aux->next = hashtab[hash % HASHSZ]; 19122433fc5SMasahiro Yamada hashtab[hash % HASHSZ] = aux; 19222433fc5SMasahiro Yamada } 19322433fc5SMasahiro Yamada 19422433fc5SMasahiro Yamada /* 19522433fc5SMasahiro Yamada * Clear the set of configuration strings. 19622433fc5SMasahiro Yamada */ 19722433fc5SMasahiro Yamada static void clear_config(void) 19822433fc5SMasahiro Yamada { 19922433fc5SMasahiro Yamada struct item *aux, *next; 20022433fc5SMasahiro Yamada unsigned int i; 20122433fc5SMasahiro Yamada 20222433fc5SMasahiro Yamada for (i = 0; i < HASHSZ; i++) { 20322433fc5SMasahiro Yamada for (aux = hashtab[i]; aux; aux = next) { 20422433fc5SMasahiro Yamada next = aux->next; 20522433fc5SMasahiro Yamada free(aux); 20622433fc5SMasahiro Yamada } 20722433fc5SMasahiro Yamada hashtab[i] = NULL; 20822433fc5SMasahiro Yamada } 20922433fc5SMasahiro Yamada } 21022433fc5SMasahiro Yamada 21122433fc5SMasahiro Yamada /* 21222433fc5SMasahiro Yamada * Record the use of a CONFIG_* word. 21322433fc5SMasahiro Yamada */ 21422433fc5SMasahiro Yamada static void use_config(const char *m, int slen) 21522433fc5SMasahiro Yamada { 21622433fc5SMasahiro Yamada unsigned int hash = strhash(m, slen); 21722433fc5SMasahiro Yamada int c, i; 21822433fc5SMasahiro Yamada 21922433fc5SMasahiro Yamada if (is_defined_config(m, slen, hash)) 22022433fc5SMasahiro Yamada return; 22122433fc5SMasahiro Yamada 22222433fc5SMasahiro Yamada define_config(m, slen, hash); 22322433fc5SMasahiro Yamada 224fc196d0eSMasahiro Yamada printf(" $(wildcard include/config/"); 22522433fc5SMasahiro Yamada for (i = 0; i < slen; i++) { 22622433fc5SMasahiro Yamada c = m[i]; 22722433fc5SMasahiro Yamada if (c == '_') 22822433fc5SMasahiro Yamada c = '/'; 22922433fc5SMasahiro Yamada else 23022433fc5SMasahiro Yamada c = tolower(c); 23122433fc5SMasahiro Yamada putchar(c); 23222433fc5SMasahiro Yamada } 23322433fc5SMasahiro Yamada printf(".h) \\\n"); 23422433fc5SMasahiro Yamada } 23522433fc5SMasahiro Yamada 23622433fc5SMasahiro Yamada static void parse_config_file(const char *map, size_t len) 23722433fc5SMasahiro Yamada { 23822433fc5SMasahiro Yamada const int *end = (const int *) (map + len); 23922433fc5SMasahiro Yamada /* start at +1, so that p can never be < map */ 24022433fc5SMasahiro Yamada const int *m = (const int *) map + 1; 24122433fc5SMasahiro Yamada const char *p, *q; 24222433fc5SMasahiro Yamada 24322433fc5SMasahiro Yamada for (; m < end; m++) { 24422433fc5SMasahiro Yamada if (*m == INT_CONF) { p = (char *) m ; goto conf; } 24522433fc5SMasahiro Yamada if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } 24622433fc5SMasahiro Yamada if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } 24722433fc5SMasahiro Yamada if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } 24822433fc5SMasahiro Yamada continue; 24922433fc5SMasahiro Yamada conf: 25022433fc5SMasahiro Yamada if (p > map + len - 7) 25122433fc5SMasahiro Yamada continue; 25222433fc5SMasahiro Yamada if (memcmp(p, "CONFIG_", 7)) 25322433fc5SMasahiro Yamada continue; 254*29974f77SMasahiro Yamada p += 7; 255*29974f77SMasahiro Yamada for (q = p; q < map + len; q++) { 25622433fc5SMasahiro Yamada if (!(isalnum(*q) || *q == '_')) 25722433fc5SMasahiro Yamada goto found; 25822433fc5SMasahiro Yamada } 25922433fc5SMasahiro Yamada continue; 26022433fc5SMasahiro Yamada 26122433fc5SMasahiro Yamada found: 26222433fc5SMasahiro Yamada if (!memcmp(q - 7, "_MODULE", 7)) 26322433fc5SMasahiro Yamada q -= 7; 264*29974f77SMasahiro Yamada if (q - p < 0) 26522433fc5SMasahiro Yamada continue; 266*29974f77SMasahiro Yamada use_config(p, q - p); 26722433fc5SMasahiro Yamada } 26822433fc5SMasahiro Yamada } 26922433fc5SMasahiro Yamada 27022433fc5SMasahiro Yamada /* test is s ends in sub */ 27122433fc5SMasahiro Yamada static int strrcmp(char *s, char *sub) 27222433fc5SMasahiro Yamada { 27322433fc5SMasahiro Yamada int slen = strlen(s); 27422433fc5SMasahiro Yamada int sublen = strlen(sub); 27522433fc5SMasahiro Yamada 27622433fc5SMasahiro Yamada if (sublen > slen) 27722433fc5SMasahiro Yamada return 1; 27822433fc5SMasahiro Yamada 27922433fc5SMasahiro Yamada return memcmp(s + slen - sublen, sub, sublen); 28022433fc5SMasahiro Yamada } 28122433fc5SMasahiro Yamada 28222433fc5SMasahiro Yamada static void do_config_file(const char *filename) 28322433fc5SMasahiro Yamada { 28422433fc5SMasahiro Yamada struct stat st; 28522433fc5SMasahiro Yamada int fd; 28622433fc5SMasahiro Yamada void *map; 28722433fc5SMasahiro Yamada 28822433fc5SMasahiro Yamada fd = open(filename, O_RDONLY); 28922433fc5SMasahiro Yamada if (fd < 0) { 29022433fc5SMasahiro Yamada fprintf(stderr, "fixdep: error opening config file: "); 29122433fc5SMasahiro Yamada perror(filename); 29222433fc5SMasahiro Yamada exit(2); 29322433fc5SMasahiro Yamada } 29422433fc5SMasahiro Yamada fstat(fd, &st); 29522433fc5SMasahiro Yamada if (st.st_size == 0) { 29622433fc5SMasahiro Yamada close(fd); 29722433fc5SMasahiro Yamada return; 29822433fc5SMasahiro Yamada } 29922433fc5SMasahiro Yamada map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 30022433fc5SMasahiro Yamada if ((long) map == -1) { 30122433fc5SMasahiro Yamada perror("fixdep: mmap"); 30222433fc5SMasahiro Yamada close(fd); 30322433fc5SMasahiro Yamada return; 30422433fc5SMasahiro Yamada } 30522433fc5SMasahiro Yamada 30622433fc5SMasahiro Yamada parse_config_file(map, st.st_size); 30722433fc5SMasahiro Yamada 30822433fc5SMasahiro Yamada munmap(map, st.st_size); 30922433fc5SMasahiro Yamada 31022433fc5SMasahiro Yamada close(fd); 31122433fc5SMasahiro Yamada } 31222433fc5SMasahiro Yamada 31322433fc5SMasahiro Yamada /* 31422433fc5SMasahiro Yamada * Important: The below generated source_foo.o and deps_foo.o variable 31522433fc5SMasahiro Yamada * assignments are parsed not only by make, but also by the rather simple 31622433fc5SMasahiro Yamada * parser in scripts/mod/sumversion.c. 31722433fc5SMasahiro Yamada */ 31822433fc5SMasahiro Yamada static void parse_dep_file(void *map, size_t len) 31922433fc5SMasahiro Yamada { 32022433fc5SMasahiro Yamada char *m = map; 32122433fc5SMasahiro Yamada char *end = m + len; 32222433fc5SMasahiro Yamada char *p; 32322433fc5SMasahiro Yamada char s[PATH_MAX]; 32422433fc5SMasahiro Yamada int is_target; 32522433fc5SMasahiro Yamada int saw_any_target = 0; 32622433fc5SMasahiro Yamada int is_first_dep = 0; 32722433fc5SMasahiro Yamada 32822433fc5SMasahiro Yamada clear_config(); 32922433fc5SMasahiro Yamada 33022433fc5SMasahiro Yamada while (m < end) { 33122433fc5SMasahiro Yamada /* Skip any "white space" */ 33222433fc5SMasahiro Yamada while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) 33322433fc5SMasahiro Yamada m++; 33422433fc5SMasahiro Yamada /* Find next "white space" */ 33522433fc5SMasahiro Yamada p = m; 33622433fc5SMasahiro Yamada while (p < end && *p != ' ' && *p != '\\' && *p != '\n') 33722433fc5SMasahiro Yamada p++; 33822433fc5SMasahiro Yamada /* Is the token we found a target name? */ 33922433fc5SMasahiro Yamada is_target = (*(p-1) == ':'); 34022433fc5SMasahiro Yamada /* Don't write any target names into the dependency file */ 34122433fc5SMasahiro Yamada if (is_target) { 34222433fc5SMasahiro Yamada /* The /next/ file is the first dependency */ 34322433fc5SMasahiro Yamada is_first_dep = 1; 34422433fc5SMasahiro Yamada } else { 34522433fc5SMasahiro Yamada /* Save this token/filename */ 34622433fc5SMasahiro Yamada memcpy(s, m, p-m); 34722433fc5SMasahiro Yamada s[p - m] = 0; 34822433fc5SMasahiro Yamada 34922433fc5SMasahiro Yamada /* Ignore certain dependencies */ 35022433fc5SMasahiro Yamada if (strrcmp(s, "include/generated/autoconf.h") && 35122433fc5SMasahiro Yamada strrcmp(s, "arch/um/include/uml-config.h") && 35222433fc5SMasahiro Yamada strrcmp(s, "include/linux/kconfig.h") && 35322433fc5SMasahiro Yamada strrcmp(s, ".ver")) { 35422433fc5SMasahiro Yamada /* 35522433fc5SMasahiro Yamada * Do not list the source file as dependency, 35622433fc5SMasahiro Yamada * so that kbuild is not confused if a .c file 35722433fc5SMasahiro Yamada * is rewritten into .S or vice versa. Storing 35822433fc5SMasahiro Yamada * it in source_* is needed for modpost to 35922433fc5SMasahiro Yamada * compute srcversions. 36022433fc5SMasahiro Yamada */ 36122433fc5SMasahiro Yamada if (is_first_dep) { 36222433fc5SMasahiro Yamada /* 36322433fc5SMasahiro Yamada * If processing the concatenation of 36422433fc5SMasahiro Yamada * multiple dependency files, only 36522433fc5SMasahiro Yamada * process the first target name, which 36622433fc5SMasahiro Yamada * will be the original source name, 36722433fc5SMasahiro Yamada * and ignore any other target names, 36822433fc5SMasahiro Yamada * which will be intermediate temporary 36922433fc5SMasahiro Yamada * files. 37022433fc5SMasahiro Yamada */ 37122433fc5SMasahiro Yamada if (!saw_any_target) { 37222433fc5SMasahiro Yamada saw_any_target = 1; 37322433fc5SMasahiro Yamada printf("source_%s := %s\n\n", 37422433fc5SMasahiro Yamada target, s); 37522433fc5SMasahiro Yamada printf("deps_%s := \\\n", 37622433fc5SMasahiro Yamada target); 37722433fc5SMasahiro Yamada } 37822433fc5SMasahiro Yamada is_first_dep = 0; 37922433fc5SMasahiro Yamada } else 38022433fc5SMasahiro Yamada printf(" %s \\\n", s); 38122433fc5SMasahiro Yamada do_config_file(s); 38222433fc5SMasahiro Yamada } 38322433fc5SMasahiro Yamada } 38422433fc5SMasahiro Yamada /* 38522433fc5SMasahiro Yamada * Start searching for next token immediately after the first 38622433fc5SMasahiro Yamada * "whitespace" character that follows this token. 38722433fc5SMasahiro Yamada */ 38822433fc5SMasahiro Yamada m = p + 1; 38922433fc5SMasahiro Yamada } 39022433fc5SMasahiro Yamada 39122433fc5SMasahiro Yamada if (!saw_any_target) { 39222433fc5SMasahiro Yamada fprintf(stderr, "fixdep: parse error; no targets found\n"); 39322433fc5SMasahiro Yamada exit(1); 39422433fc5SMasahiro Yamada } 39522433fc5SMasahiro Yamada 39622433fc5SMasahiro Yamada printf("\n%s: $(deps_%s)\n\n", target, target); 39722433fc5SMasahiro Yamada printf("$(deps_%s):\n", target); 39822433fc5SMasahiro Yamada } 39922433fc5SMasahiro Yamada 40022433fc5SMasahiro Yamada static void print_deps(void) 40122433fc5SMasahiro Yamada { 40222433fc5SMasahiro Yamada struct stat st; 40322433fc5SMasahiro Yamada int fd; 40422433fc5SMasahiro Yamada void *map; 40522433fc5SMasahiro Yamada 40622433fc5SMasahiro Yamada fd = open(depfile, O_RDONLY); 40722433fc5SMasahiro Yamada if (fd < 0) { 40822433fc5SMasahiro Yamada fprintf(stderr, "fixdep: error opening depfile: "); 40922433fc5SMasahiro Yamada perror(depfile); 41022433fc5SMasahiro Yamada exit(2); 41122433fc5SMasahiro Yamada } 41222433fc5SMasahiro Yamada if (fstat(fd, &st) < 0) { 41322433fc5SMasahiro Yamada fprintf(stderr, "fixdep: error fstat'ing depfile: "); 41422433fc5SMasahiro Yamada perror(depfile); 41522433fc5SMasahiro Yamada exit(2); 41622433fc5SMasahiro Yamada } 41722433fc5SMasahiro Yamada if (st.st_size == 0) { 41822433fc5SMasahiro Yamada fprintf(stderr,"fixdep: %s is empty\n",depfile); 41922433fc5SMasahiro Yamada close(fd); 42022433fc5SMasahiro Yamada return; 42122433fc5SMasahiro Yamada } 42222433fc5SMasahiro Yamada map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 42322433fc5SMasahiro Yamada if ((long) map == -1) { 42422433fc5SMasahiro Yamada perror("fixdep: mmap"); 42522433fc5SMasahiro Yamada close(fd); 42622433fc5SMasahiro Yamada return; 42722433fc5SMasahiro Yamada } 42822433fc5SMasahiro Yamada 42922433fc5SMasahiro Yamada parse_dep_file(map, st.st_size); 43022433fc5SMasahiro Yamada 43122433fc5SMasahiro Yamada munmap(map, st.st_size); 43222433fc5SMasahiro Yamada 43322433fc5SMasahiro Yamada close(fd); 43422433fc5SMasahiro Yamada } 43522433fc5SMasahiro Yamada 43622433fc5SMasahiro Yamada static void traps(void) 43722433fc5SMasahiro Yamada { 43822433fc5SMasahiro Yamada static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; 43922433fc5SMasahiro Yamada int *p = (int *)test; 44022433fc5SMasahiro Yamada 44122433fc5SMasahiro Yamada if (*p != INT_CONF) { 44222433fc5SMasahiro Yamada fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n", 44322433fc5SMasahiro Yamada *p); 44422433fc5SMasahiro Yamada exit(2); 44522433fc5SMasahiro Yamada } 44622433fc5SMasahiro Yamada } 44722433fc5SMasahiro Yamada 44822433fc5SMasahiro Yamada int main(int argc, char *argv[]) 44922433fc5SMasahiro Yamada { 45022433fc5SMasahiro Yamada traps(); 45122433fc5SMasahiro Yamada 45222433fc5SMasahiro Yamada if (argc != 4) 45322433fc5SMasahiro Yamada usage(); 45422433fc5SMasahiro Yamada 45522433fc5SMasahiro Yamada depfile = argv[1]; 45622433fc5SMasahiro Yamada target = argv[2]; 45722433fc5SMasahiro Yamada cmdline = argv[3]; 45822433fc5SMasahiro Yamada 45922433fc5SMasahiro Yamada print_cmdline(); 46022433fc5SMasahiro Yamada print_deps(); 46122433fc5SMasahiro Yamada 46222433fc5SMasahiro Yamada return 0; 46322433fc5SMasahiro Yamada } 464