2 * Originally by Linus Torvalds.
3 * Smart CONFIG_* processing by Werner Almesberger, Michael Chastain.
5 * Usage: mkdep cflags -- file ...
7 * Read source files and output makefile dependency lines for them.
8 * I make simple dependency lines for #include <*.h> and #include "*.h".
9 * I also find instances of CONFIG_FOO and generate dependencies
10 * like include/config/foo.h.
12 * 1 August 1999, Michael Elizabeth Chastain, <mec@shout.net>
13 * - Keith Owens reported a bug in smart config processing. There used
14 * to be an optimization for "#define CONFIG_FOO ... #ifdef CONFIG_FOO",
15 * so that the file would not depend on CONFIG_FOO because the file defines
16 * this symbol itself. But this optimization is bogus! Consider this code:
17 * "#if 0 \n #define CONFIG_FOO \n #endif ... #ifdef CONFIG_FOO". Here
18 * the definition is inactivated, but I still used it. It turns out this
19 * actually happens a few times in the kernel source. The simple way to
20 * fix this problem is to remove this particular optimization.
22 * 2.3.99-pre1, Andrew Morton <andrewm@uow.edu.au>
23 * - Changed so that 'filename.o' depends upon 'filename.[cS]'. This is so that
24 * missing source files are noticed, rather than silently ignored.
26 * 2.4.2-pre3, Keith Owens <kaos@ocs.com.au>
27 * - Accept cflags followed by '--' followed by filenames. mkdep extracts -I
28 * options from cflags and looks in the specified directories as well as the
29 * defaults. Only -I is supported, no attempt is made to handle -idirafter,
41 #include <sys/fcntl.h>
44 #include <sys/types.h>
48 char __depname[512] = "\n\t@touch ";
49 #define depname (__depname+9)
56 struct path_struct *path_array;
60 /* Current input file */
61 static const char *g_filename;
64 * This records all the configuration options seen.
65 * In perl this would be a hash, but here it's a long string
66 * of values separated by newlines. This is simple and
69 char * str_config = NULL;
78 printf("%s:", depname);
80 printf(" %s", g_filename);
85 * Grow the configuration string to a desired length.
86 * Usually the first growth is plenty.
88 void grow_config(int len)
90 while (len_config + len > size_config) {
93 str_config = realloc(str_config, size_config *= 2);
94 if (str_config == NULL)
95 { perror("malloc config"); exit(1); }
102 * Lookup a value in the configuration string.
104 int is_defined_config(const char * name, int len)
106 const char * pconfig;
107 const char * plast = str_config + len_config - len;
108 for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
109 if (pconfig[ -1] == '\n'
110 && pconfig[len] == '\n'
111 && !memcmp(pconfig, name, len))
120 * Add a new value to the configuration string.
122 void define_config(const char * name, int len)
124 grow_config(len + 1);
126 memcpy(str_config+len_config, name, len);
128 str_config[len_config++] = '\n';
134 * Clear the set of configuration strings.
136 void clear_config(void)
139 define_config("", 0);
145 * This records all the precious .h filenames. No need for a hash,
146 * it's a long string of values enclosed in tab and newline.
148 char * str_precious = NULL;
149 int size_precious = 0;
150 int len_precious = 0;
155 * Grow the precious string to a desired length.
156 * Usually the first growth is plenty.
158 void grow_precious(int len)
160 while (len_precious + len > size_precious) {
161 if (size_precious == 0)
162 size_precious = 2048;
163 str_precious = realloc(str_precious, size_precious *= 2);
164 if (str_precious == NULL)
165 { perror("malloc"); exit(1); }
172 * Add a new value to the precious string.
174 void define_precious(const char * filename)
176 int len = strlen(filename);
177 grow_precious(len + 4);
178 *(str_precious+len_precious++) = '\t';
179 memcpy(str_precious+len_precious, filename, len);
181 memcpy(str_precious+len_precious, " \\\n", 3);
188 * Handle an #include line.
190 void handle_include(int start, const char * name, int len)
192 struct path_struct *path;
195 if (len == 14 && !memcmp(name, "linux/config.h", len))
198 if (len >= 7 && !memcmp(name, "config/", 7))
199 define_config(name+7, len-7-2);
201 for (i = start, path = path_array+start; i < paths; ++i, ++path) {
202 memcpy(path->buffer+path->len, name, len);
203 path->buffer[path->len+len] = '\0';
204 if (access(path->buffer, F_OK) == 0) {
206 printf(" \\\n %s", path->buffer);
216 * Add a path to the list of include paths.
218 void add_path(const char * name)
220 struct path_struct *path;
221 char resolved_path[PATH_MAX+1];
225 //fprintf(stderr, "mkdep.c: name is %s\n", name);
226 if (strcmp(name, ".")) {
227 name2 = realpath(name, resolved_path);
229 fprintf(stderr, "realpath(%s) failed, %m\n", name);
237 path_array = realloc(path_array, (++paths)*sizeof(*path_array));
239 fprintf(stderr, "cannot expand path_arry\n");
243 path = path_array+paths-1;
244 path->len = strlen(name2);
245 path->buffer = malloc(path->len+1+256+1);
247 fprintf(stderr, "cannot allocate path buffer\n");
250 strcpy(path->buffer, name2);
251 if (path->len && *(path->buffer+path->len-1) != '/') {
252 *(path->buffer+path->len) = '/';
253 *(path->buffer+(++(path->len))) = '\0';
260 * Record the use of a CONFIG_* word.
262 void use_config(const char * name, int len)
267 pc = path_array[paths-1].buffer + path_array[paths-1].len;
268 memcpy(pc, "config/", 7);
271 for (i = 0; i < len; i++) {
273 if (isupper((int)c)) c = tolower((int)c);
274 if (c == '_') c = '/';
279 if (is_defined_config(pc, len))
282 define_config(pc, len);
285 printf(" \\\n $(wildcard %s.h)", path_array[paths-1].buffer);
291 * Macros for stunningly fast map-based character access.
292 * __buf is a register which holds the current word of the input.
293 * Thus, there is one memory access per sizeof(unsigned long) characters.
296 #if defined(__alpha__) || defined(__i386__) || defined(__ia64__) || defined(__x86_64__) || defined(__MIPSEL__) \
302 #define next_byte(x) (x >>= 8)
303 #define current ((unsigned char) __buf)
305 #define next_byte(x) (x <<= 8)
306 #define current (__buf >> 8*(sizeof(unsigned long)-1))
311 if ((unsigned long) next % sizeof(unsigned long) == 0) { \
314 __buf = * (unsigned long *) next; \
320 * State machine macros.
322 #define CASE(c,label) if (current == c) goto label
323 #define NOTCASE(c,label) if (current != c) goto label
326 * Yet another state machine speedup.
328 #define MAX2(a,b) ((a)>(b)?(a):(b))
329 #define MIN2(a,b) ((a)<(b)?(a):(b))
330 #define MAX5(a,b,c,d,e) (MAX2(a,MAX2(b,MAX2(c,MAX2(d,e)))))
331 #define MIN5(a,b,c,d,e) (MIN2(a,MIN2(b,MIN2(c,MIN2(d,e)))))
336 * The state machine looks for (approximately) these Perl regular expressions:
342 * m|#\s*include\s*"(.*?)"|
343 * m|#\s*include\s*<(.*?>"|
344 * m|#\s*(?define|undef)\s*CONFIG_(\w*)|
347 * About 98% of the CPU time is spent here, and most of that is in
348 * the 'start' paragraph. Because the current characters are
349 * in a register, the start loop usually eats 4 or 8 characters
350 * per memory read. The MAX5 and MIN5 tests dispose of most
351 * input characters with 1 or 2 comparisons.
353 void state_machine(const char * map, const char * end)
355 const char * next = map;
356 const char * map_dot;
357 unsigned long __buf = 0;
363 if (current > MAX5('/','\'','"','#','C')) goto start;
364 if (current < MIN5('/','\'','"','#','C')) goto start;
376 NOTCASE('\\', slash_slash);
383 CASE('/', slash_slash);
384 NOTCASE('*', __start);
387 __slash_star_dot_star:
388 NOTCASE('*', slash_star_dot_star);
390 NOTCASE('/', __slash_star_dot_star);
397 NOTCASE('\\', squote);
405 NOTCASE('\\', dquote);
421 GETNEXT NOTCASE('n', __start);
422 GETNEXT NOTCASE('c', __start);
423 GETNEXT NOTCASE('l', __start);
424 GETNEXT NOTCASE('u', __start);
425 GETNEXT NOTCASE('d', __start);
426 GETNEXT NOTCASE('e', __start);
432 CASE(' ', pound_include);
433 CASE('\t', pound_include);
435 CASE('"', pound_include_dquote);
436 CASE('<', pound_include_langle);
439 /* #\s*include\s*"(.*)" */
440 pound_include_dquote:
443 NOTCASE('"', pound_include_dquote);
444 handle_include(0, map_dot, next - map_dot - 1);
447 /* #\s*include\s*<(.*)> */
448 pound_include_langle:
451 NOTCASE('>', pound_include_langle);
452 handle_include(1, map_dot, next - map_dot - 1);
457 GETNEXT NOTCASE('e', __start);
458 GETNEXT NOTCASE('f', __start);
459 GETNEXT NOTCASE('i', __start);
460 GETNEXT NOTCASE('n', __start);
461 GETNEXT NOTCASE('e', __start);
462 goto pound_define_undef;
466 GETNEXT NOTCASE('n', __start);
467 GETNEXT NOTCASE('d', __start);
468 GETNEXT NOTCASE('e', __start);
469 GETNEXT NOTCASE('f', __start);
470 goto pound_define_undef;
473 * #\s*(define|undef)\s*CONFIG_(\w*)
475 * this does not define the word, because it could be inside another
476 * conditional (#if 0). But I do parse the word so that this instance
477 * does not count as a use. -- mec
481 CASE(' ', pound_define_undef);
482 CASE('\t', pound_define_undef);
484 NOTCASE('C', __start);
485 GETNEXT NOTCASE('O', __start);
486 GETNEXT NOTCASE('N', __start);
487 GETNEXT NOTCASE('F', __start);
488 GETNEXT NOTCASE('I', __start);
489 GETNEXT NOTCASE('G', __start);
490 GETNEXT NOTCASE('_', __start);
493 pound_define_undef_CONFIG_word:
495 if (isalnum(current) || current == '_')
496 goto pound_define_undef_CONFIG_word;
501 if (next >= map+2 && (isalnum((int)next[-2]) || next[-2] == '_'))
503 GETNEXT NOTCASE('O', __start);
504 GETNEXT NOTCASE('N', __start);
505 GETNEXT NOTCASE('F', __start);
506 GETNEXT NOTCASE('I', __start);
507 GETNEXT NOTCASE('G', __start);
508 GETNEXT NOTCASE('_', __start);
513 if (isalnum(current) || current == '_')
514 goto cee_CONFIG_word;
515 use_config(map_dot, next - map_dot - 1);
523 * Generate dependencies for one file.
525 void do_depend(const char * filename, const char * command)
528 int pagesizem1 = getpagesize()-1;
533 fd = open(filename, O_RDONLY);
540 if (st.st_size == 0) {
541 fprintf(stderr,"%s is empty\n",filename);
546 mapsize = st.st_size;
547 mapsize = (mapsize+pagesizem1) & ~pagesizem1;
548 map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
549 if ((long) map == -1) {
550 perror("mkdep: mmap");
554 if ((unsigned long) map % sizeof(unsigned long) != 0)
556 fprintf(stderr, "do_depend: map not aligned\n");
562 state_machine(map, map+st.st_size);
566 define_precious(filename);
569 munmap(map, mapsize);
576 * Generate dependencies for all files.
578 int main(int argc, char **argv)
583 hpath = getenv("HPATH");
585 fputs("mkdep: HPATH not set in environment. "
586 "Don't bypass the top level Makefile.\n", stderr);
590 add_path("."); /* for #include "..." */
592 while (++argv, --argc > 0) {
593 if (strncmp(*argv, "-I", 2) == 0) {
603 else if (strcmp(*argv, "--") == 0) {
608 add_path(hpath); /* must be last entry, for config files */
611 const char * filename = *++argv;
612 const char * command = __depname;
614 len = strlen(filename);
615 memcpy(depname, filename, len+1);
616 if (len > 2 && filename[len-2] == '.') {
617 if (filename[len-1] == 'c' || filename[len-1] == 'S') {
618 depname[len-1] = 'o';
619 g_filename = filename;
623 do_depend(filename, command);
626 *(str_precious+len_precious) = '\0';
627 printf(".PRECIOUS:%s\n", str_precious);