X Tutup
Skip to content

Commit 2ab8a99

Browse files
committed
kbuild: fixdep: support concatenated dep files
The current use-case for fixdep is: a source file is run through a single processing step, which creates a single dependency file as a side-effect, which fixdep transforms into the file used by the kernel build process. In order to transparently run the C pre-processor on device-tree files, we wish to run both gcc -E and dtc on a source file in a single rule. This generates two dependency files, which must be transformed together into the file used by the kernel build process. This change modifies fixdep so it can process the concatenation of multiple separate input dependency files, and produce a correct unified output. The code changes have the slight benefit of transforming the loop in parse_dep_file() into more of a lexer/tokenizer, with the loop body being more of a parser. Previously, some of this logic was mixed together before the loop. I also added some comments, which I hope are useful. Benchmarking shows that on a cross-compiled ARM tegra_defconfig build, there is less than 0.5 seconds speed decrease with this change, on top of a build time of ~2m24s. This is probably within the noise. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Rob Herring <rob.herring@calxeda.com>
1 parent c58299a commit 2ab8a99

File tree

1 file changed

+61
-32
lines changed

1 file changed

+61
-32
lines changed

scripts/basic/fixdep.c

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -320,49 +320,78 @@ static void parse_dep_file(void *map, size_t len)
320320
char *end = m + len;
321321
char *p;
322322
char s[PATH_MAX];
323-
int first;
324-
325-
p = strchr(m, ':');
326-
if (!p) {
327-
fprintf(stderr, "fixdep: parse error\n");
328-
exit(1);
329-
}
330-
memcpy(s, m, p-m); s[p-m] = 0;
331-
m = p+1;
323+
int is_target;
324+
int saw_any_target = 0;
325+
int is_first_dep = 0;
332326

333327
clear_config();
334328

335-
first = 1;
336329
while (m < end) {
330+
/* Skip any "white space" */
337331
while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
338332
m++;
333+
/* Find next "white space" */
339334
p = m;
340-
while (p < end && *p != ' ') p++;
341-
if (p == end) {
342-
do p--; while (!isalnum(*p));
335+
while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
343336
p++;
337+
/* Is the token we found a target name? */
338+
is_target = (*(p-1) == ':');
339+
/* Don't write any target names into the dependency file */
340+
if (is_target) {
341+
/* The /next/ file is the first dependency */
342+
is_first_dep = 1;
343+
} else {
344+
/* Save this token/filename */
345+
memcpy(s, m, p-m);
346+
s[p - m] = 0;
347+
348+
/* Ignore certain dependencies */
349+
if (strrcmp(s, "include/generated/autoconf.h") &&
350+
strrcmp(s, "arch/um/include/uml-config.h") &&
351+
strrcmp(s, "include/linux/kconfig.h") &&
352+
strrcmp(s, ".ver")) {
353+
/*
354+
* Do not list the source file as dependency,
355+
* so that kbuild is not confused if a .c file
356+
* is rewritten into .S or vice versa. Storing
357+
* it in source_* is needed for modpost to
358+
* compute srcversions.
359+
*/
360+
if (is_first_dep) {
361+
/*
362+
* If processing the concatenation of
363+
* multiple dependency files, only
364+
* process the first target name, which
365+
* will be the original source name,
366+
* and ignore any other target names,
367+
* which will be intermediate temporary
368+
* files.
369+
*/
370+
if (!saw_any_target) {
371+
saw_any_target = 1;
372+
printf("source_%s := %s\n\n",
373+
target, s);
374+
printf("deps_%s := \\\n",
375+
target);
376+
}
377+
is_first_dep = 0;
378+
} else
379+
printf(" %s \\\n", s);
380+
do_config_file(s);
381+
}
344382
}
345-
memcpy(s, m, p-m); s[p-m] = 0;
346-
if (strrcmp(s, "include/generated/autoconf.h") &&
347-
strrcmp(s, "arch/um/include/uml-config.h") &&
348-
strrcmp(s, "include/linux/kconfig.h") &&
349-
strrcmp(s, ".ver")) {
350-
/*
351-
* Do not list the source file as dependency, so that
352-
* kbuild is not confused if a .c file is rewritten
353-
* into .S or vice versa. Storing it in source_* is
354-
* needed for modpost to compute srcversions.
355-
*/
356-
if (first) {
357-
printf("source_%s := %s\n\n", target, s);
358-
printf("deps_%s := \\\n", target);
359-
} else
360-
printf(" %s \\\n", s);
361-
do_config_file(s);
362-
}
363-
first = 0;
383+
/*
384+
* Start searching for next token immediately after the first
385+
* "whitespace" character that follows this token.
386+
*/
364387
m = p + 1;
365388
}
389+
390+
if (!saw_any_target) {
391+
fprintf(stderr, "fixdep: parse error; no targets found\n");
392+
exit(1);
393+
}
394+
366395
printf("\n%s: $(deps_%s)\n\n", target, target);
367396
printf("$(deps_%s):\n", target);
368397
}

0 commit comments

Comments
 (0)
X Tutup