[PATCH] kbuild: fixdep: Resync this with v4.17
Masahiro Yamada
masahiroy at kernel.org
Tue Feb 18 12:32:24 CET 2020
Hi Tom,
On Tue, Feb 18, 2020 at 11:29 AM Tom Rini <trini at konsulko.com> wrote:
>
> The previous kbuild resync
Precisely, it was "kconfig resync", not "kbuild resync".
> of e91610da7c8a ("kconfig: re-sync with Linux
> 4.17-rc4") accidentally did not sync the fixdep program.
I do not think it was accidental.
Kconfig and fixdep are separate programs.
You do not necessarily need to sync them together.
> This commit
> brings fixdep in line with the rest of that previous resync.
>
> This includes all of the following Linux kernel commits:
> fbfa9be9904e kbuild: move include/config/ksym/* to include/ksym/*
> 5b8ad96d1a44 fixdep: remove some false CONFIG_ matches
> 14a596a7e6fd fixdep: remove stale references to uml-config.h
> ab9ce9feed36 fixdep: use existing helper to check modular CONFIG options
> 87b95a81357d fixdep: refactor parse_dep_file()
> 5d1ef76f5a22 fixdep: move global variables to local variables of main()
> ccfe78873c22 fixdep: remove unneeded memcpy() in parse_dep_file()
> 4003fd80cba9 fixdep: factor out common code for reading files
> 01b5cbe7012f fixdep: use malloc() and read() to load dep_file to buffer
> 41f92cffba19 fixdep: remove unnecessary <arpa/inet.h> inclusion
> 7c2ec43a2154 fixdep: exit with error code in error branches of do_config_file()
> 4e433fc4d1a9 fixdep: trivial: typo fix and correction
> dee81e988674 fixdep: faster CONFIG_ search
> c1a95fda2a40 kbuild: add fine grained build dependencies for exported symbols
> d8329e35cc08 fixdep: accept extra dependencies on stdin
> 4c835b57b8de fixdep: constify strrcmp arguments
>
> Of note is that when applying dee81e988674 above our logic in that area
> required some careful consideration to continue to apply.
I checked it. The resync looks correct.
> We specifically do not include:
> 638e69cf2230 fixdep: do not ignore kconfig.h
> as this leads to build problems for us resulting in problems like:
> dts/.dt.dtb.o.cmd:5: *** unterminated call to function 'wildcard': missing ')'. Stop.
This is due to config_enabled(CONFIG_VAL(option##_MODULE))
in include/linux/kconfig.h
This line was unneeded in the first place
since U-Boot does not support module,
but I just wanted to make it aligned with Linux somehow.
I sent two patches.
Please choose either depending your workflow.
[A] http://patchwork.ozlabs.org/patch/1239950/
(If you want to fix the issue before re-sync)
[B] http://patchwork.ozlabs.org/patch/1239952/
(If you want to fix the issue after re-sync)
Then, you can import
638e69cf2230 fixdep: do not ignore kconfig.h
Thanks.
>
> Cc: Masahiro Yamada <masahiroy at kernel.org>'
> Signed-off-by: Tom Rini <trini at konsulko.com>
> ---
> scripts/basic/fixdep.c | 352 ++++++++++++++++++-----------------------
> 1 file changed, 151 insertions(+), 201 deletions(-)
>
> diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
> index da7fb2cd4dde..8c21dd08d9f7 100644
> --- a/scripts/basic/fixdep.c
> +++ b/scripts/basic/fixdep.c
> @@ -25,7 +25,7 @@
> *
> * So we play the same trick that "mkdep" played before. We replace
> * the dependency on autoconf.h by a dependency on every config
> - * option which is mentioned in any of the listed prequisites.
> + * option which is mentioned in any of the listed prerequisites.
> *
> * kconfig populates a tree in include/config/ with an empty file
> * for each config symbol and when the configuration is updated
> @@ -34,7 +34,7 @@
> * the config symbols are rebuilt.
> *
> * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
> - * which depend on "include/linux/config/his/driver.h" will be rebuilt,
> + * which depend on "include/config/his/driver.h" will be rebuilt,
> * so most likely only his driver ;-)
> *
> * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
> @@ -75,15 +75,14 @@
> * and then basically copies the .<target>.d file to stdout, in the
> * process filtering out the dependency on autoconf.h and adding
> * dependencies on include/config/my/option.h for every
> - * CONFIG_MY_OPTION encountered in any of the prequisites.
> + * CONFIG_MY_OPTION encountered in any of the prerequisites.
> *
> * It will also filter out all the dependencies on *.ver. We need
> * to make sure that the generated version checksum are globally up
> * to date before even starting the recursive build, so it's too late
> * at this point anyway.
> *
> - * The algorithm to grep for "CONFIG_..." is bit unusual, but should
> - * be fast ;-) We don't even try to really parse the header files, but
> + * We don't even try to really parse the header files, but
> * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
> * be picked up as well. It's not a problem with respect to
> * correctness, since that can only give too many dependencies, thus
> @@ -94,49 +93,57 @@
> * (Note: it'd be easy to port over the complete mkdep state machine,
> * but I don't think the added complexity is worth it)
> */
> -/*
> - * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
> - * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
> - * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
> - * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
> - * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
> - * those files will have correct dependencies.
> - */
>
> #include <sys/types.h>
> #include <sys/stat.h>
> -#include <sys/mman.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
> -#include <limits.h>
> #include <ctype.h>
> -#include <arpa/inet.h>
> -
> -#define INT_CONF ntohl(0x434f4e46)
> -#define INT_ONFI ntohl(0x4f4e4649)
> -#define INT_NFIG ntohl(0x4e464947)
> -#define INT_FIG_ ntohl(0x4649475f)
>
> -char *target;
> -char *depfile;
> -char *cmdline;
> int is_spl_build = 0; /* hack for U-Boot */
>
> static void usage(void)
> {
> - fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
> + fprintf(stderr, "Usage: fixdep [-e] <depfile> <target> <cmdline>\n");
> + fprintf(stderr, " -e insert extra dependencies given on stdin\n");
> exit(1);
> }
>
> /*
> - * Print out the commandline prefixed with cmd_<target filename> :=
> + * Print out a dependency path from a symbol name
> */
> -static void print_cmdline(void)
> +static void print_dep(const char *m, int slen, const char *dir)
> {
> - printf("cmd_%s := %s\n\n", target, cmdline);
> + int c, i;
> +
> + printf(" $(wildcard %s/", dir);
> + for (i = 0; i < slen; i++) {
> + c = m[i];
> + if (c == '_')
> + c = '/';
> + else
> + c = tolower(c);
> + putchar(c);
> + }
> + printf(".h) \\\n");
> +}
> +
> +static void do_extra_deps(void)
> +{
> + char buf[80];
> +
> + while (fgets(buf, sizeof(buf), stdin)) {
> + int len = strlen(buf);
> +
> + if (len < 2 || buf[len - 1] != '\n') {
> + fprintf(stderr, "fixdep: bad data on stdin\n");
> + exit(1);
> + }
> + print_dep(buf, len - 1, "include/ksym");
> + }
> }
>
> struct item {
> @@ -198,57 +205,44 @@ static void define_config(const char *name, int len, unsigned int hash)
> static void use_config(const char *m, int slen)
> {
> unsigned int hash = strhash(m, slen);
> - int c, i;
>
> if (is_defined_config(m, slen, hash))
> return;
>
> define_config(m, slen, hash);
> + print_dep(m, slen, "include/config");
> +}
>
> - printf(" $(wildcard include/config/");
> - for (i = 0; i < slen; i++) {
> - c = m[i];
> - if (c == '_')
> - c = '/';
> - else
> - c = tolower(c);
> - putchar(c);
> - }
> - printf(".h) \\\n");
> +/* test if s ends in sub */
> +static int str_ends_with(const char *s, int slen, const char *sub)
> +{
> + int sublen = strlen(sub);
> +
> + if (sublen > slen)
> + return 0;
> +
> + return !memcmp(s + slen - sublen, sub, sublen);
> }
>
> -static void parse_config_file(const char *map, size_t len)
> +static void parse_config_file(const char *p)
> {
> - const int *end = (const int *) (map + len);
> - /* start at +1, so that p can never be < map */
> - const int *m = (const int *) map + 1;
> - const char *p, *q;
> + const char *q, *r;
> + const char *start = p;
> char tmp_buf[256] = "SPL_"; /* hack for U-Boot */
>
> - for (; m < end; m++) {
> - if (*m == INT_CONF) { p = (char *) m ; goto conf; }
> - if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
> - if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
> - if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
> - continue;
> - conf:
> - if (p > map + len - 7)
> - continue;
> - if (memcmp(p, "CONFIG_", 7))
> + while ((p = strstr(p, "CONFIG_"))) {
> + if (p > start && (isalnum(p[-1]) || p[-1] == '_')) {
> + p += 7;
> continue;
> - p += 7;
> - for (q = p; q < map + len; q++) {
> - if (!(isalnum(*q) || *q == '_'))
> - goto found;
> }
> - continue;
> -
> - found:
> - if (!memcmp(q - 7, "_MODULE", 7))
> - q -= 7;
> - if (q - p < 0)
> - continue;
> -
> + p += 7;
> + q = p;
> + while (*q && (isalnum(*q) || *q == '_'))
> + q++;
> + if (str_ends_with(p, q - p, "_MODULE"))
> + r = q - 7;
> + else
> + r = q;
> /*
> * U-Boot also handles
> * CONFIG_IS_ENABLED(...)
> @@ -261,69 +255,62 @@ static void parse_config_file(const char *map, size_t len)
> (q - p == 9 && !memcmp(p, "IS_MODULE(", 10)) ||
> (q - p == 3 && !memcmp(p, "VAL(", 4))) {
> p = q + 1;
> - for (q = p; q < map + len; q++)
> - if (*q == ')')
> - goto found2;
> - continue;
> -
> - found2:
> - if (is_spl_build) {
> - memcpy(tmp_buf + 4, p, q - p);
> - q = tmp_buf + 4 + (q - p);
> + while (*q && *q != ')')
> + q++;
> + r = q;
> + if (r > p && is_spl_build) {
> + memcpy(tmp_buf + 4, p, r - p);
> + r = tmp_buf + 4 + (r - p);
> p = tmp_buf;
> }
> }
> /* end U-Boot hack */
>
> - use_config(p, q - p);
> + if (r > p)
> + use_config(p, r - p);
> + p = q;
> }
> }
>
> -/* test is s ends in sub */
> -static int strrcmp(char *s, char *sub)
> -{
> - int slen = strlen(s);
> - int sublen = strlen(sub);
> -
> - if (sublen > slen)
> - return 1;
> -
> - return memcmp(s + slen - sublen, sub, sublen);
> -}
> -
> -static void do_config_file(const char *filename)
> +static void *read_file(const char *filename)
> {
> struct stat st;
> int fd;
> - void *map;
> + char *buf;
>
> fd = open(filename, O_RDONLY);
> if (fd < 0) {
> - fprintf(stderr, "fixdep: error opening config file: ");
> + fprintf(stderr, "fixdep: error opening file: ");
> perror(filename);
> exit(2);
> }
> if (fstat(fd, &st) < 0) {
> - fprintf(stderr, "fixdep: error fstat'ing config file: ");
> + fprintf(stderr, "fixdep: error fstat'ing file: ");
> perror(filename);
> exit(2);
> }
> - if (st.st_size == 0) {
> - close(fd);
> - return;
> + buf = malloc(st.st_size + 1);
> + if (!buf) {
> + perror("fixdep: malloc");
> + exit(2);
> }
> - map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
> - if ((long) map == -1) {
> - perror("fixdep: mmap");
> - close(fd);
> - return;
> + if (read(fd, buf, st.st_size) != st.st_size) {
> + perror("fixdep: read");
> + exit(2);
> }
> + buf[st.st_size] = '\0';
> + close(fd);
>
> - parse_config_file(map, st.st_size);
> -
> - munmap(map, st.st_size);
> + return buf;
> +}
>
> - close(fd);
> +/* Ignore certain dependencies */
> +static int is_ignored_file(const char *s, int len)
> +{
> + return str_ends_with(s, len, "include/generated/autoconf.h") ||
> + str_ends_with(s, len, "include/generated/autoksyms.h") ||
> + str_ends_with(s, len, "include/linux/kconfig.h") ||
> + str_ends_with(s, len, ".ver");
> }
>
> /*
> @@ -331,70 +318,70 @@ static void do_config_file(const char *filename)
> * assignments are parsed not only by make, but also by the rather simple
> * parser in scripts/mod/sumversion.c.
> */
> -static void parse_dep_file(void *map, size_t len)
> +static void parse_dep_file(char *m, const char *target, int insert_extra_deps)
> {
> - char *m = map;
> - char *end = m + len;
> char *p;
> - char s[PATH_MAX];
> - int is_target;
> + int is_last, is_target;
> int saw_any_target = 0;
> int is_first_dep = 0;
> + void *buf;
>
> - while (m < end) {
> + while (1) {
> /* Skip any "white space" */
> - while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
> + while (*m == ' ' || *m == '\\' || *m == '\n')
> m++;
> +
> + if (!*m)
> + break;
> +
> /* Find next "white space" */
> p = m;
> - while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
> + while (*p && *p != ' ' && *p != '\\' && *p != '\n')
> p++;
> + is_last = (*p == '\0');
> /* Is the token we found a target name? */
> is_target = (*(p-1) == ':');
> /* Don't write any target names into the dependency file */
> if (is_target) {
> /* The /next/ file is the first dependency */
> is_first_dep = 1;
> - } else {
> - /* Save this token/filename */
> - memcpy(s, m, p-m);
> - s[p - m] = 0;
> -
> - /* Ignore certain dependencies */
> - if (strrcmp(s, "include/generated/autoconf.h") &&
> - strrcmp(s, "arch/um/include/uml-config.h") &&
> - strrcmp(s, "include/linux/kconfig.h") &&
> - strrcmp(s, ".ver")) {
> + } else if (!is_ignored_file(m, p - m)) {
> + *p = '\0';
> +
> + /*
> + * Do not list the source file as dependency, so that
> + * kbuild is not confused if a .c file is rewritten
> + * into .S or vice versa. Storing it in source_* is
> + * needed for modpost to compute srcversions.
> + */
> + if (is_first_dep) {
> /*
> - * Do not list the source file as dependency,
> - * so that kbuild is not confused if a .c file
> - * is rewritten into .S or vice versa. Storing
> - * it in source_* is needed for modpost to
> - * compute srcversions.
> + * If processing the concatenation of multiple
> + * dependency files, only process the first
> + * target name, which will be the original
> + * source name, and ignore any other target
> + * names, which will be intermediate temporary
> + * files.
> */
> - if (is_first_dep) {
> - /*
> - * If processing the concatenation of
> - * multiple dependency files, only
> - * process the first target name, which
> - * will be the original source name,
> - * and ignore any other target names,
> - * which will be intermediate temporary
> - * files.
> - */
> - if (!saw_any_target) {
> - saw_any_target = 1;
> - printf("source_%s := %s\n\n",
> - target, s);
> - printf("deps_%s := \\\n",
> - target);
> - }
> - is_first_dep = 0;
> - } else
> - printf(" %s \\\n", s);
> - do_config_file(s);
> + if (!saw_any_target) {
> + saw_any_target = 1;
> + printf("source_%s := %s\n\n",
> + target, m);
> + printf("deps_%s := \\\n", target);
> + }
> + is_first_dep = 0;
> + } else {
> + printf(" %s \\\n", m);
> }
> +
> + buf = read_file(m);
> + parse_config_file(buf);
> + free(buf);
> }
> +
> + if (is_last)
> + break;
> +
> /*
> * Start searching for next token immediately after the first
> * "whitespace" character that follows this token.
> @@ -407,63 +394,23 @@ static void parse_dep_file(void *map, size_t len)
> exit(1);
> }
>
> + if (insert_extra_deps)
> + do_extra_deps();
> +
> printf("\n%s: $(deps_%s)\n\n", target, target);
> printf("$(deps_%s):\n", target);
> }
>
> -static void print_deps(void)
> -{
> - struct stat st;
> - int fd;
> - void *map;
> -
> - fd = open(depfile, O_RDONLY);
> - if (fd < 0) {
> - fprintf(stderr, "fixdep: error opening depfile: ");
> - perror(depfile);
> - exit(2);
> - }
> - if (fstat(fd, &st) < 0) {
> - fprintf(stderr, "fixdep: error fstat'ing depfile: ");
> - perror(depfile);
> - exit(2);
> - }
> - if (st.st_size == 0) {
> - fprintf(stderr,"fixdep: %s is empty\n",depfile);
> - close(fd);
> - return;
> - }
> - map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
> - if ((long) map == -1) {
> - perror("fixdep: mmap");
> - close(fd);
> - return;
> - }
> -
> - parse_dep_file(map, st.st_size);
> -
> - munmap(map, st.st_size);
> -
> - close(fd);
> -}
> -
> -static void traps(void)
> -{
> - static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
> - int *p = (int *)test;
> -
> - if (*p != INT_CONF) {
> - fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n",
> - *p);
> - exit(2);
> - }
> -}
> -
> int main(int argc, char *argv[])
> {
> - traps();
> -
> - if (argc != 4)
> + const char *depfile, *target, *cmdline;
> + int insert_extra_deps = 0;
> + void *buf;
> +
> + if (argc == 5 && !strcmp(argv[1], "-e")) {
> + insert_extra_deps = 1;
> + argv++;
> + } else if (argc != 4)
> usage();
>
> depfile = argv[1];
> @@ -474,8 +421,11 @@ int main(int argc, char *argv[])
> if (!strncmp(target, "spl/", 4) || !strncmp(target, "tpl/", 4))
> is_spl_build = 1;
>
> - print_cmdline();
> - print_deps();
> + printf("cmd_%s := %s\n\n", target, cmdline);
> +
> + buf = read_file(depfile);
> + parse_dep_file(buf, target, insert_extra_deps);
> + free(buf);
>
> return 0;
> }
> --
> 2.17.1
>
--
Best Regards
Masahiro Yamada
More information about the U-Boot
mailing list