kbuild: fixdep: Resync this with v4.17
The previous kbuild resync of e91610da7c ("kconfig: re-sync with Linux
4.17-rc4") accidentally did not sync the fixdep program.  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.
[Fold in bugfix to allow us to include 638e69cf2230 from upstream]
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
[Merge everything to U-Boot, rework dee81e988674]
Signed-off-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Masahiro Yamada <masahiroy@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									8a266e5800
								
							
						
					
					
						commit
						67f2ee86cc
					
				|  | @ -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); | ||||
| 
 | ||||
| 	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"); | ||||
| 	print_dep(m, slen, "include/config"); | ||||
| } | ||||
| 
 | ||||
| static void parse_config_file(const char *map, size_t len) | ||||
| /* test if s ends in sub */ | ||||
| static int str_ends_with(const char *s, int slen, const char *sub) | ||||
| { | ||||
| 	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; | ||||
| 	int sublen = strlen(sub); | ||||
| 
 | ||||
| 	if (sublen > slen) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return !memcmp(s + slen - sublen, sub, sublen); | ||||
| } | ||||
| 
 | ||||
| static void parse_config_file(const char *p) | ||||
| { | ||||
| 	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)) | ||||
| 			continue; | ||||
| 	while ((p = strstr(p, "CONFIG_"))) { | ||||
| 		if (p > start && (isalnum(p[-1]) || p[-1] == '_')) { | ||||
| 			p += 7; | ||||
| 		for (q = p; q < map + len; q++) { | ||||
| 			if (!(isalnum(*q) || *q == '_')) | ||||
| 				goto found; | ||||
| 			continue; | ||||
| 		} | ||||
| 		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,61 @@ 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 (!(isalnum(*q) || *q == '_')) | ||||
| 					goto found2; | ||||
| 			continue; | ||||
| 
 | ||||
| 		found2: | ||||
| 			if (is_spl_build) { | ||||
| 				memcpy(tmp_buf + 4, p, q - p); | ||||
| 				q = tmp_buf + 4 + (q - p); | ||||
| 			while (isalnum(*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"); | ||||
| 	if (read(fd, buf, st.st_size) != st.st_size) { | ||||
| 		perror("fixdep: read"); | ||||
| 		exit(2); | ||||
| 	} | ||||
| 	buf[st.st_size] = '\0'; | ||||
| 	close(fd); | ||||
| 		return; | ||||
| 
 | ||||
| 	return buf; | ||||
| } | ||||
| 
 | ||||
| 	parse_config_file(map, st.st_size); | ||||
| 
 | ||||
| 	munmap(map, st.st_size); | ||||
| 
 | ||||
| 	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, ".ver"); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -331,70 +317,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; | ||||
| 		} else if (!is_ignored_file(m, p - m)) { | ||||
| 			*p = '\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")) { | ||||
| 			/*
 | ||||
| 				 * 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. | ||||
| 			 * 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) { | ||||
| 				/*
 | ||||
| 					 * 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 | ||||
| 				 * 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); | ||||
| 					       target, m); | ||||
| 					printf("deps_%s := \\\n", target); | ||||
| 				} | ||||
| 				is_first_dep = 0; | ||||
| 				} else | ||||
| 					printf("  %s \\\n", s); | ||||
| 				do_config_file(s); | ||||
| 			} 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 +393,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(); | ||||
| 	const char *depfile, *target, *cmdline; | ||||
| 	int insert_extra_deps = 0; | ||||
| 	void *buf; | ||||
| 
 | ||||
| 	if (argc != 4) | ||||
| 	if (argc == 5 && !strcmp(argv[1], "-e")) { | ||||
| 		insert_extra_deps = 1; | ||||
| 		argv++; | ||||
| 	} else if (argc != 4) | ||||
| 		usage(); | ||||
| 
 | ||||
| 	depfile = argv[1]; | ||||
|  | @ -474,8 +420,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; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue