1*22433fc5SMasahiro Yamada /* 2*22433fc5SMasahiro Yamada * "Optimize" a list of dependencies as spit out by gcc -MD 3*22433fc5SMasahiro Yamada * for the kernel build 4*22433fc5SMasahiro Yamada * =========================================================================== 5*22433fc5SMasahiro Yamada * 6*22433fc5SMasahiro Yamada * Author Kai Germaschewski 7*22433fc5SMasahiro Yamada * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de> 8*22433fc5SMasahiro Yamada * 9*22433fc5SMasahiro Yamada * This software may be used and distributed according to the terms 10*22433fc5SMasahiro Yamada * of the GNU General Public License, incorporated herein by reference. 11*22433fc5SMasahiro Yamada * 12*22433fc5SMasahiro Yamada * 13*22433fc5SMasahiro Yamada * Introduction: 14*22433fc5SMasahiro Yamada * 15*22433fc5SMasahiro Yamada * gcc produces a very nice and correct list of dependencies which 16*22433fc5SMasahiro Yamada * tells make when to remake a file. 17*22433fc5SMasahiro Yamada * 18*22433fc5SMasahiro Yamada * To use this list as-is however has the drawback that virtually 19*22433fc5SMasahiro Yamada * every file in the kernel includes autoconf.h. 20*22433fc5SMasahiro Yamada * 21*22433fc5SMasahiro Yamada * If the user re-runs make *config, autoconf.h will be 22*22433fc5SMasahiro Yamada * regenerated. make notices that and will rebuild every file which 23*22433fc5SMasahiro Yamada * includes autoconf.h, i.e. basically all files. This is extremely 24*22433fc5SMasahiro Yamada * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. 25*22433fc5SMasahiro Yamada * 26*22433fc5SMasahiro Yamada * So we play the same trick that "mkdep" played before. We replace 27*22433fc5SMasahiro Yamada * the dependency on autoconf.h by a dependency on every config 28*22433fc5SMasahiro Yamada * option which is mentioned in any of the listed prequisites. 29*22433fc5SMasahiro Yamada * 30*22433fc5SMasahiro Yamada * kconfig populates a tree in include/config/ with an empty file 31*22433fc5SMasahiro Yamada * for each config symbol and when the configuration is updated 32*22433fc5SMasahiro Yamada * the files representing changed config options are touched 33*22433fc5SMasahiro Yamada * which then let make pick up the changes and the files that use 34*22433fc5SMasahiro Yamada * the config symbols are rebuilt. 35*22433fc5SMasahiro Yamada * 36*22433fc5SMasahiro Yamada * So if the user changes his CONFIG_HIS_DRIVER option, only the objects 37*22433fc5SMasahiro Yamada * which depend on "include/linux/config/his/driver.h" will be rebuilt, 38*22433fc5SMasahiro Yamada * so most likely only his driver ;-) 39*22433fc5SMasahiro Yamada * 40*22433fc5SMasahiro Yamada * The idea above dates, by the way, back to Michael E Chastain, AFAIK. 41*22433fc5SMasahiro Yamada * 42*22433fc5SMasahiro Yamada * So to get dependencies right, there are two issues: 43*22433fc5SMasahiro Yamada * o if any of the files the compiler read changed, we need to rebuild 44*22433fc5SMasahiro Yamada * o if the command line given to the compile the file changed, we 45*22433fc5SMasahiro Yamada * better rebuild as well. 46*22433fc5SMasahiro Yamada * 47*22433fc5SMasahiro Yamada * The former is handled by using the -MD output, the later by saving 48*22433fc5SMasahiro Yamada * the command line used to compile the old object and comparing it 49*22433fc5SMasahiro Yamada * to the one we would now use. 50*22433fc5SMasahiro Yamada * 51*22433fc5SMasahiro Yamada * Again, also this idea is pretty old and has been discussed on 52*22433fc5SMasahiro Yamada * kbuild-devel a long time ago. I don't have a sensibly working 53*22433fc5SMasahiro Yamada * internet connection right now, so I rather don't mention names 54*22433fc5SMasahiro Yamada * without double checking. 55*22433fc5SMasahiro Yamada * 56*22433fc5SMasahiro Yamada * This code here has been based partially based on mkdep.c, which 57*22433fc5SMasahiro Yamada * says the following about its history: 58*22433fc5SMasahiro Yamada * 59*22433fc5SMasahiro Yamada * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>. 60*22433fc5SMasahiro Yamada * This is a C version of syncdep.pl by Werner Almesberger. 61*22433fc5SMasahiro Yamada * 62*22433fc5SMasahiro Yamada * 63*22433fc5SMasahiro Yamada * It is invoked as 64*22433fc5SMasahiro Yamada * 65*22433fc5SMasahiro Yamada * fixdep <depfile> <target> <cmdline> 66*22433fc5SMasahiro Yamada * 67*22433fc5SMasahiro Yamada * and will read the dependency file <depfile> 68*22433fc5SMasahiro Yamada * 69*22433fc5SMasahiro Yamada * The transformed dependency snipped is written to stdout. 70*22433fc5SMasahiro Yamada * 71*22433fc5SMasahiro Yamada * It first generates a line 72*22433fc5SMasahiro Yamada * 73*22433fc5SMasahiro Yamada * cmd_<target> = <cmdline> 74*22433fc5SMasahiro Yamada * 75*22433fc5SMasahiro Yamada * and then basically copies the .<target>.d file to stdout, in the 76*22433fc5SMasahiro Yamada * process filtering out the dependency on autoconf.h and adding 77*22433fc5SMasahiro Yamada * dependencies on include/config/my/option.h for every 78*22433fc5SMasahiro Yamada * CONFIG_MY_OPTION encountered in any of the prequisites. 79*22433fc5SMasahiro Yamada * 80*22433fc5SMasahiro Yamada * It will also filter out all the dependencies on *.ver. We need 81*22433fc5SMasahiro Yamada * to make sure that the generated version checksum are globally up 82*22433fc5SMasahiro Yamada * to date before even starting the recursive build, so it's too late 83*22433fc5SMasahiro Yamada * at this point anyway. 84*22433fc5SMasahiro Yamada * 85*22433fc5SMasahiro Yamada * The algorithm to grep for "CONFIG_..." is bit unusual, but should 86*22433fc5SMasahiro Yamada * be fast ;-) We don't even try to really parse the header files, but 87*22433fc5SMasahiro Yamada * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will 88*22433fc5SMasahiro Yamada * be picked up as well. It's not a problem with respect to 89*22433fc5SMasahiro Yamada * correctness, since that can only give too many dependencies, thus 90*22433fc5SMasahiro Yamada * we cannot miss a rebuild. Since people tend to not mention totally 91*22433fc5SMasahiro Yamada * unrelated CONFIG_ options all over the place, it's not an 92*22433fc5SMasahiro Yamada * efficiency problem either. 93*22433fc5SMasahiro Yamada * 94*22433fc5SMasahiro Yamada * (Note: it'd be easy to port over the complete mkdep state machine, 95*22433fc5SMasahiro Yamada * but I don't think the added complexity is worth it) 96*22433fc5SMasahiro Yamada */ 97*22433fc5SMasahiro Yamada /* 98*22433fc5SMasahiro Yamada * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto 99*22433fc5SMasahiro Yamada * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not 100*22433fc5SMasahiro Yamada * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as 101*22433fc5SMasahiro Yamada * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h, 102*22433fc5SMasahiro Yamada * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that 103*22433fc5SMasahiro Yamada * those files will have correct dependencies. 104*22433fc5SMasahiro Yamada */ 105*22433fc5SMasahiro Yamada 106*22433fc5SMasahiro Yamada #include <sys/types.h> 107*22433fc5SMasahiro Yamada #include <sys/stat.h> 108*22433fc5SMasahiro Yamada #include <sys/mman.h> 109*22433fc5SMasahiro Yamada #include <unistd.h> 110*22433fc5SMasahiro Yamada #include <fcntl.h> 111*22433fc5SMasahiro Yamada #include <string.h> 112*22433fc5SMasahiro Yamada #include <stdlib.h> 113*22433fc5SMasahiro Yamada #include <stdio.h> 114*22433fc5SMasahiro Yamada #include <limits.h> 115*22433fc5SMasahiro Yamada #include <ctype.h> 116*22433fc5SMasahiro Yamada #include <arpa/inet.h> 117*22433fc5SMasahiro Yamada 118*22433fc5SMasahiro Yamada #define INT_CONF ntohl(0x434f4e46) 119*22433fc5SMasahiro Yamada #define INT_ONFI ntohl(0x4f4e4649) 120*22433fc5SMasahiro Yamada #define INT_NFIG ntohl(0x4e464947) 121*22433fc5SMasahiro Yamada #define INT_FIG_ ntohl(0x4649475f) 122*22433fc5SMasahiro Yamada 123*22433fc5SMasahiro Yamada char *target; 124*22433fc5SMasahiro Yamada char *depfile; 125*22433fc5SMasahiro Yamada char *cmdline; 126*22433fc5SMasahiro Yamada 127*22433fc5SMasahiro Yamada static void usage(void) 128*22433fc5SMasahiro Yamada { 129*22433fc5SMasahiro Yamada fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); 130*22433fc5SMasahiro Yamada exit(1); 131*22433fc5SMasahiro Yamada } 132*22433fc5SMasahiro Yamada 133*22433fc5SMasahiro Yamada /* 134*22433fc5SMasahiro Yamada * Print out the commandline prefixed with cmd_<target filename> := 135*22433fc5SMasahiro Yamada */ 136*22433fc5SMasahiro Yamada static void print_cmdline(void) 137*22433fc5SMasahiro Yamada { 138*22433fc5SMasahiro Yamada printf("cmd_%s := %s\n\n", target, cmdline); 139*22433fc5SMasahiro Yamada } 140*22433fc5SMasahiro Yamada 141*22433fc5SMasahiro Yamada struct item { 142*22433fc5SMasahiro Yamada struct item *next; 143*22433fc5SMasahiro Yamada unsigned int len; 144*22433fc5SMasahiro Yamada unsigned int hash; 145*22433fc5SMasahiro Yamada char name[0]; 146*22433fc5SMasahiro Yamada }; 147*22433fc5SMasahiro Yamada 148*22433fc5SMasahiro Yamada #define HASHSZ 256 149*22433fc5SMasahiro Yamada static struct item *hashtab[HASHSZ]; 150*22433fc5SMasahiro Yamada 151*22433fc5SMasahiro Yamada static unsigned int strhash(const char *str, unsigned int sz) 152*22433fc5SMasahiro Yamada { 153*22433fc5SMasahiro Yamada /* fnv32 hash */ 154*22433fc5SMasahiro Yamada unsigned int i, hash = 2166136261U; 155*22433fc5SMasahiro Yamada 156*22433fc5SMasahiro Yamada for (i = 0; i < sz; i++) 157*22433fc5SMasahiro Yamada hash = (hash ^ str[i]) * 0x01000193; 158*22433fc5SMasahiro Yamada return hash; 159*22433fc5SMasahiro Yamada } 160*22433fc5SMasahiro Yamada 161*22433fc5SMasahiro Yamada /* 162*22433fc5SMasahiro Yamada * Lookup a value in the configuration string. 163*22433fc5SMasahiro Yamada */ 164*22433fc5SMasahiro Yamada static int is_defined_config(const char *name, int len, unsigned int hash) 165*22433fc5SMasahiro Yamada { 166*22433fc5SMasahiro Yamada struct item *aux; 167*22433fc5SMasahiro Yamada 168*22433fc5SMasahiro Yamada for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { 169*22433fc5SMasahiro Yamada if (aux->hash == hash && aux->len == len && 170*22433fc5SMasahiro Yamada memcmp(aux->name, name, len) == 0) 171*22433fc5SMasahiro Yamada return 1; 172*22433fc5SMasahiro Yamada } 173*22433fc5SMasahiro Yamada return 0; 174*22433fc5SMasahiro Yamada } 175*22433fc5SMasahiro Yamada 176*22433fc5SMasahiro Yamada /* 177*22433fc5SMasahiro Yamada * Add a new value to the configuration string. 178*22433fc5SMasahiro Yamada */ 179*22433fc5SMasahiro Yamada static void define_config(const char *name, int len, unsigned int hash) 180*22433fc5SMasahiro Yamada { 181*22433fc5SMasahiro Yamada struct item *aux = malloc(sizeof(*aux) + len); 182*22433fc5SMasahiro Yamada 183*22433fc5SMasahiro Yamada if (!aux) { 184*22433fc5SMasahiro Yamada perror("fixdep:malloc"); 185*22433fc5SMasahiro Yamada exit(1); 186*22433fc5SMasahiro Yamada } 187*22433fc5SMasahiro Yamada memcpy(aux->name, name, len); 188*22433fc5SMasahiro Yamada aux->len = len; 189*22433fc5SMasahiro Yamada aux->hash = hash; 190*22433fc5SMasahiro Yamada aux->next = hashtab[hash % HASHSZ]; 191*22433fc5SMasahiro Yamada hashtab[hash % HASHSZ] = aux; 192*22433fc5SMasahiro Yamada } 193*22433fc5SMasahiro Yamada 194*22433fc5SMasahiro Yamada /* 195*22433fc5SMasahiro Yamada * Clear the set of configuration strings. 196*22433fc5SMasahiro Yamada */ 197*22433fc5SMasahiro Yamada static void clear_config(void) 198*22433fc5SMasahiro Yamada { 199*22433fc5SMasahiro Yamada struct item *aux, *next; 200*22433fc5SMasahiro Yamada unsigned int i; 201*22433fc5SMasahiro Yamada 202*22433fc5SMasahiro Yamada for (i = 0; i < HASHSZ; i++) { 203*22433fc5SMasahiro Yamada for (aux = hashtab[i]; aux; aux = next) { 204*22433fc5SMasahiro Yamada next = aux->next; 205*22433fc5SMasahiro Yamada free(aux); 206*22433fc5SMasahiro Yamada } 207*22433fc5SMasahiro Yamada hashtab[i] = NULL; 208*22433fc5SMasahiro Yamada } 209*22433fc5SMasahiro Yamada } 210*22433fc5SMasahiro Yamada 211*22433fc5SMasahiro Yamada /* 212*22433fc5SMasahiro Yamada * Record the use of a CONFIG_* word. 213*22433fc5SMasahiro Yamada */ 214*22433fc5SMasahiro Yamada static void use_config(const char *m, int slen) 215*22433fc5SMasahiro Yamada { 216*22433fc5SMasahiro Yamada unsigned int hash = strhash(m, slen); 217*22433fc5SMasahiro Yamada int c, i; 218*22433fc5SMasahiro Yamada 219*22433fc5SMasahiro Yamada if (is_defined_config(m, slen, hash)) 220*22433fc5SMasahiro Yamada return; 221*22433fc5SMasahiro Yamada 222*22433fc5SMasahiro Yamada define_config(m, slen, hash); 223*22433fc5SMasahiro Yamada 224*22433fc5SMasahiro Yamada printf(" $(wildcard include/config/"); 225*22433fc5SMasahiro Yamada for (i = 0; i < slen; i++) { 226*22433fc5SMasahiro Yamada c = m[i]; 227*22433fc5SMasahiro Yamada if (c == '_') 228*22433fc5SMasahiro Yamada c = '/'; 229*22433fc5SMasahiro Yamada else 230*22433fc5SMasahiro Yamada c = tolower(c); 231*22433fc5SMasahiro Yamada putchar(c); 232*22433fc5SMasahiro Yamada } 233*22433fc5SMasahiro Yamada printf(".h) \\\n"); 234*22433fc5SMasahiro Yamada } 235*22433fc5SMasahiro Yamada 236*22433fc5SMasahiro Yamada static void parse_config_file(const char *map, size_t len) 237*22433fc5SMasahiro Yamada { 238*22433fc5SMasahiro Yamada const int *end = (const int *) (map + len); 239*22433fc5SMasahiro Yamada /* start at +1, so that p can never be < map */ 240*22433fc5SMasahiro Yamada const int *m = (const int *) map + 1; 241*22433fc5SMasahiro Yamada const char *p, *q; 242*22433fc5SMasahiro Yamada 243*22433fc5SMasahiro Yamada for (; m < end; m++) { 244*22433fc5SMasahiro Yamada if (*m == INT_CONF) { p = (char *) m ; goto conf; } 245*22433fc5SMasahiro Yamada if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } 246*22433fc5SMasahiro Yamada if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } 247*22433fc5SMasahiro Yamada if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } 248*22433fc5SMasahiro Yamada continue; 249*22433fc5SMasahiro Yamada conf: 250*22433fc5SMasahiro Yamada if (p > map + len - 7) 251*22433fc5SMasahiro Yamada continue; 252*22433fc5SMasahiro Yamada if (memcmp(p, "CONFIG_", 7)) 253*22433fc5SMasahiro Yamada continue; 254*22433fc5SMasahiro Yamada for (q = p + 7; q < map + len; q++) { 255*22433fc5SMasahiro Yamada if (!(isalnum(*q) || *q == '_')) 256*22433fc5SMasahiro Yamada goto found; 257*22433fc5SMasahiro Yamada } 258*22433fc5SMasahiro Yamada continue; 259*22433fc5SMasahiro Yamada 260*22433fc5SMasahiro Yamada found: 261*22433fc5SMasahiro Yamada if (!memcmp(q - 7, "_MODULE", 7)) 262*22433fc5SMasahiro Yamada q -= 7; 263*22433fc5SMasahiro Yamada if( (q-p-7) < 0 ) 264*22433fc5SMasahiro Yamada continue; 265*22433fc5SMasahiro Yamada use_config(p+7, q-p-7); 266*22433fc5SMasahiro Yamada } 267*22433fc5SMasahiro Yamada } 268*22433fc5SMasahiro Yamada 269*22433fc5SMasahiro Yamada /* test is s ends in sub */ 270*22433fc5SMasahiro Yamada static int strrcmp(char *s, char *sub) 271*22433fc5SMasahiro Yamada { 272*22433fc5SMasahiro Yamada int slen = strlen(s); 273*22433fc5SMasahiro Yamada int sublen = strlen(sub); 274*22433fc5SMasahiro Yamada 275*22433fc5SMasahiro Yamada if (sublen > slen) 276*22433fc5SMasahiro Yamada return 1; 277*22433fc5SMasahiro Yamada 278*22433fc5SMasahiro Yamada return memcmp(s + slen - sublen, sub, sublen); 279*22433fc5SMasahiro Yamada } 280*22433fc5SMasahiro Yamada 281*22433fc5SMasahiro Yamada static void do_config_file(const char *filename) 282*22433fc5SMasahiro Yamada { 283*22433fc5SMasahiro Yamada struct stat st; 284*22433fc5SMasahiro Yamada int fd; 285*22433fc5SMasahiro Yamada void *map; 286*22433fc5SMasahiro Yamada 287*22433fc5SMasahiro Yamada fd = open(filename, O_RDONLY); 288*22433fc5SMasahiro Yamada if (fd < 0) { 289*22433fc5SMasahiro Yamada fprintf(stderr, "fixdep: error opening config file: "); 290*22433fc5SMasahiro Yamada perror(filename); 291*22433fc5SMasahiro Yamada exit(2); 292*22433fc5SMasahiro Yamada } 293*22433fc5SMasahiro Yamada fstat(fd, &st); 294*22433fc5SMasahiro Yamada if (st.st_size == 0) { 295*22433fc5SMasahiro Yamada close(fd); 296*22433fc5SMasahiro Yamada return; 297*22433fc5SMasahiro Yamada } 298*22433fc5SMasahiro Yamada map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 299*22433fc5SMasahiro Yamada if ((long) map == -1) { 300*22433fc5SMasahiro Yamada perror("fixdep: mmap"); 301*22433fc5SMasahiro Yamada close(fd); 302*22433fc5SMasahiro Yamada return; 303*22433fc5SMasahiro Yamada } 304*22433fc5SMasahiro Yamada 305*22433fc5SMasahiro Yamada parse_config_file(map, st.st_size); 306*22433fc5SMasahiro Yamada 307*22433fc5SMasahiro Yamada munmap(map, st.st_size); 308*22433fc5SMasahiro Yamada 309*22433fc5SMasahiro Yamada close(fd); 310*22433fc5SMasahiro Yamada } 311*22433fc5SMasahiro Yamada 312*22433fc5SMasahiro Yamada /* 313*22433fc5SMasahiro Yamada * Important: The below generated source_foo.o and deps_foo.o variable 314*22433fc5SMasahiro Yamada * assignments are parsed not only by make, but also by the rather simple 315*22433fc5SMasahiro Yamada * parser in scripts/mod/sumversion.c. 316*22433fc5SMasahiro Yamada */ 317*22433fc5SMasahiro Yamada static void parse_dep_file(void *map, size_t len) 318*22433fc5SMasahiro Yamada { 319*22433fc5SMasahiro Yamada char *m = map; 320*22433fc5SMasahiro Yamada char *end = m + len; 321*22433fc5SMasahiro Yamada char *p; 322*22433fc5SMasahiro Yamada char s[PATH_MAX]; 323*22433fc5SMasahiro Yamada int is_target; 324*22433fc5SMasahiro Yamada int saw_any_target = 0; 325*22433fc5SMasahiro Yamada int is_first_dep = 0; 326*22433fc5SMasahiro Yamada 327*22433fc5SMasahiro Yamada clear_config(); 328*22433fc5SMasahiro Yamada 329*22433fc5SMasahiro Yamada while (m < end) { 330*22433fc5SMasahiro Yamada /* Skip any "white space" */ 331*22433fc5SMasahiro Yamada while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) 332*22433fc5SMasahiro Yamada m++; 333*22433fc5SMasahiro Yamada /* Find next "white space" */ 334*22433fc5SMasahiro Yamada p = m; 335*22433fc5SMasahiro Yamada while (p < end && *p != ' ' && *p != '\\' && *p != '\n') 336*22433fc5SMasahiro Yamada p++; 337*22433fc5SMasahiro Yamada /* Is the token we found a target name? */ 338*22433fc5SMasahiro Yamada is_target = (*(p-1) == ':'); 339*22433fc5SMasahiro Yamada /* Don't write any target names into the dependency file */ 340*22433fc5SMasahiro Yamada if (is_target) { 341*22433fc5SMasahiro Yamada /* The /next/ file is the first dependency */ 342*22433fc5SMasahiro Yamada is_first_dep = 1; 343*22433fc5SMasahiro Yamada } else { 344*22433fc5SMasahiro Yamada /* Save this token/filename */ 345*22433fc5SMasahiro Yamada memcpy(s, m, p-m); 346*22433fc5SMasahiro Yamada s[p - m] = 0; 347*22433fc5SMasahiro Yamada 348*22433fc5SMasahiro Yamada /* Ignore certain dependencies */ 349*22433fc5SMasahiro Yamada if (strrcmp(s, "include/generated/autoconf.h") && 350*22433fc5SMasahiro Yamada strrcmp(s, "arch/um/include/uml-config.h") && 351*22433fc5SMasahiro Yamada strrcmp(s, "include/linux/kconfig.h") && 352*22433fc5SMasahiro Yamada strrcmp(s, ".ver")) { 353*22433fc5SMasahiro Yamada /* 354*22433fc5SMasahiro Yamada * Do not list the source file as dependency, 355*22433fc5SMasahiro Yamada * so that kbuild is not confused if a .c file 356*22433fc5SMasahiro Yamada * is rewritten into .S or vice versa. Storing 357*22433fc5SMasahiro Yamada * it in source_* is needed for modpost to 358*22433fc5SMasahiro Yamada * compute srcversions. 359*22433fc5SMasahiro Yamada */ 360*22433fc5SMasahiro Yamada if (is_first_dep) { 361*22433fc5SMasahiro Yamada /* 362*22433fc5SMasahiro Yamada * If processing the concatenation of 363*22433fc5SMasahiro Yamada * multiple dependency files, only 364*22433fc5SMasahiro Yamada * process the first target name, which 365*22433fc5SMasahiro Yamada * will be the original source name, 366*22433fc5SMasahiro Yamada * and ignore any other target names, 367*22433fc5SMasahiro Yamada * which will be intermediate temporary 368*22433fc5SMasahiro Yamada * files. 369*22433fc5SMasahiro Yamada */ 370*22433fc5SMasahiro Yamada if (!saw_any_target) { 371*22433fc5SMasahiro Yamada saw_any_target = 1; 372*22433fc5SMasahiro Yamada printf("source_%s := %s\n\n", 373*22433fc5SMasahiro Yamada target, s); 374*22433fc5SMasahiro Yamada printf("deps_%s := \\\n", 375*22433fc5SMasahiro Yamada target); 376*22433fc5SMasahiro Yamada } 377*22433fc5SMasahiro Yamada is_first_dep = 0; 378*22433fc5SMasahiro Yamada } else 379*22433fc5SMasahiro Yamada printf(" %s \\\n", s); 380*22433fc5SMasahiro Yamada do_config_file(s); 381*22433fc5SMasahiro Yamada } 382*22433fc5SMasahiro Yamada } 383*22433fc5SMasahiro Yamada /* 384*22433fc5SMasahiro Yamada * Start searching for next token immediately after the first 385*22433fc5SMasahiro Yamada * "whitespace" character that follows this token. 386*22433fc5SMasahiro Yamada */ 387*22433fc5SMasahiro Yamada m = p + 1; 388*22433fc5SMasahiro Yamada } 389*22433fc5SMasahiro Yamada 390*22433fc5SMasahiro Yamada if (!saw_any_target) { 391*22433fc5SMasahiro Yamada fprintf(stderr, "fixdep: parse error; no targets found\n"); 392*22433fc5SMasahiro Yamada exit(1); 393*22433fc5SMasahiro Yamada } 394*22433fc5SMasahiro Yamada 395*22433fc5SMasahiro Yamada printf("\n%s: $(deps_%s)\n\n", target, target); 396*22433fc5SMasahiro Yamada printf("$(deps_%s):\n", target); 397*22433fc5SMasahiro Yamada } 398*22433fc5SMasahiro Yamada 399*22433fc5SMasahiro Yamada static void print_deps(void) 400*22433fc5SMasahiro Yamada { 401*22433fc5SMasahiro Yamada struct stat st; 402*22433fc5SMasahiro Yamada int fd; 403*22433fc5SMasahiro Yamada void *map; 404*22433fc5SMasahiro Yamada 405*22433fc5SMasahiro Yamada fd = open(depfile, O_RDONLY); 406*22433fc5SMasahiro Yamada if (fd < 0) { 407*22433fc5SMasahiro Yamada fprintf(stderr, "fixdep: error opening depfile: "); 408*22433fc5SMasahiro Yamada perror(depfile); 409*22433fc5SMasahiro Yamada exit(2); 410*22433fc5SMasahiro Yamada } 411*22433fc5SMasahiro Yamada if (fstat(fd, &st) < 0) { 412*22433fc5SMasahiro Yamada fprintf(stderr, "fixdep: error fstat'ing depfile: "); 413*22433fc5SMasahiro Yamada perror(depfile); 414*22433fc5SMasahiro Yamada exit(2); 415*22433fc5SMasahiro Yamada } 416*22433fc5SMasahiro Yamada if (st.st_size == 0) { 417*22433fc5SMasahiro Yamada fprintf(stderr,"fixdep: %s is empty\n",depfile); 418*22433fc5SMasahiro Yamada close(fd); 419*22433fc5SMasahiro Yamada return; 420*22433fc5SMasahiro Yamada } 421*22433fc5SMasahiro Yamada map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 422*22433fc5SMasahiro Yamada if ((long) map == -1) { 423*22433fc5SMasahiro Yamada perror("fixdep: mmap"); 424*22433fc5SMasahiro Yamada close(fd); 425*22433fc5SMasahiro Yamada return; 426*22433fc5SMasahiro Yamada } 427*22433fc5SMasahiro Yamada 428*22433fc5SMasahiro Yamada parse_dep_file(map, st.st_size); 429*22433fc5SMasahiro Yamada 430*22433fc5SMasahiro Yamada munmap(map, st.st_size); 431*22433fc5SMasahiro Yamada 432*22433fc5SMasahiro Yamada close(fd); 433*22433fc5SMasahiro Yamada } 434*22433fc5SMasahiro Yamada 435*22433fc5SMasahiro Yamada static void traps(void) 436*22433fc5SMasahiro Yamada { 437*22433fc5SMasahiro Yamada static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; 438*22433fc5SMasahiro Yamada int *p = (int *)test; 439*22433fc5SMasahiro Yamada 440*22433fc5SMasahiro Yamada if (*p != INT_CONF) { 441*22433fc5SMasahiro Yamada fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n", 442*22433fc5SMasahiro Yamada *p); 443*22433fc5SMasahiro Yamada exit(2); 444*22433fc5SMasahiro Yamada } 445*22433fc5SMasahiro Yamada } 446*22433fc5SMasahiro Yamada 447*22433fc5SMasahiro Yamada int main(int argc, char *argv[]) 448*22433fc5SMasahiro Yamada { 449*22433fc5SMasahiro Yamada traps(); 450*22433fc5SMasahiro Yamada 451*22433fc5SMasahiro Yamada if (argc != 4) 452*22433fc5SMasahiro Yamada usage(); 453*22433fc5SMasahiro Yamada 454*22433fc5SMasahiro Yamada depfile = argv[1]; 455*22433fc5SMasahiro Yamada target = argv[2]; 456*22433fc5SMasahiro Yamada cmdline = argv[3]; 457*22433fc5SMasahiro Yamada 458*22433fc5SMasahiro Yamada print_cmdline(); 459*22433fc5SMasahiro Yamada print_deps(); 460*22433fc5SMasahiro Yamada 461*22433fc5SMasahiro Yamada return 0; 462*22433fc5SMasahiro Yamada } 463