From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933693AbbI2Ik7 (ORCPT ); Tue, 29 Sep 2015 04:40:59 -0400 Received: from terminus.zytor.com ([198.137.202.10]:37651 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933283AbbI2IkJ (ORCPT ); Tue, 29 Sep 2015 04:40:09 -0400 Date: Tue, 29 Sep 2015 01:39:45 -0700 From: tip-bot for Jiri Olsa Message-ID: Cc: linux-kernel@vger.kernel.org, tglx@linutronix.de, jolsa@kernel.org, a.p.zijlstra@chello.nl, dsahern@gmail.com, mingo@kernel.org, namhyung@kernel.org, kai.germaschewski@gmx.de, acme@redhat.com, hpa@zytor.com Reply-To: jolsa@kernel.org, tglx@linutronix.de, linux-kernel@vger.kernel.org, dsahern@gmail.com, a.p.zijlstra@chello.nl, namhyung@kernel.org, mingo@kernel.org, hpa@zytor.com, acme@redhat.com, kai.germaschewski@gmx.de In-Reply-To: <1443004442-32660-4-git-send-email-jolsa@kernel.org> References: <1443004442-32660-4-git-send-email-jolsa@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] tools build: Add fixdep dependency helper Git-Commit-ID: 9f7ef9854e800bc3bab3d9a527e8f8f960eec1a6 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 9f7ef9854e800bc3bab3d9a527e8f8f960eec1a6 Gitweb: http://git.kernel.org/tip/9f7ef9854e800bc3bab3d9a527e8f8f960eec1a6 Author: Jiri Olsa AuthorDate: Wed, 23 Sep 2015 12:33:58 +0200 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 28 Sep 2015 15:50:55 -0300 tools build: Add fixdep dependency helper For dependency tracking we currently use targets that fall out of the gcc -MD command. We store this info in the .cmd file and include as makefile during the build. This format put object as target and all the c and header files as dependencies, like: util/abspath.o: util/abspath.c /usr/include/stdc-predef.h util/cache.h \ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ ... If any of those dependency header files (krava.h below) is removed the build fails on: make[1]: *** No rule to make target 'krava.h', needed by 'inc.o'. Stop. This patch adds fixdep helper, that is used by kbuild to alter the shape of the object dependencies like: source_util/abspath.o := util/abspath.c deps_util/abspath.o := \ /usr/include/stdc-predef.h \ util/cache.h \ ... util/abspath.o: $(deps_util/abspath.o) $(deps_util/abspath.o): With this format the header removal won't make the build fail, because it'll be picked up by the last empty target defined for each header. As previously mentioned the fixdep tool is taken from kbuild. It's not complete backport, only the part that alters the standard dependency info was taken, the part that adds the CONFIG_* dependency logic will be probably taken later on. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Kai Germaschewski Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1443004442-32660-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Build | 1 + tools/build/Makefile | 43 +++++++++++++ tools/build/fixdep.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+) diff --git a/tools/build/Build b/tools/build/Build new file mode 100644 index 0000000..63a6c34 --- /dev/null +++ b/tools/build/Build @@ -0,0 +1 @@ +fixdep-y := fixdep.o diff --git a/tools/build/Makefile b/tools/build/Makefile new file mode 100644 index 0000000..a930362 --- /dev/null +++ b/tools/build/Makefile @@ -0,0 +1,43 @@ +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +include $(srctree)/tools//scripts/Makefile.include + +define allow-override + $(if $(or $(findstring environment,$(origin $(1))),\ + $(findstring command line,$(origin $(1)))),,\ + $(eval $(1) = $(2))) +endef + +$(call allow-override,CC,$(CROSS_COMPILE)gcc) +$(call allow-override,LD,$(CROSS_COMPILE)ld) + +ifeq ($(V),1) + Q = +else + Q = @ +endif + +export Q srctree CC LD + +MAKEFLAGS := --no-print-directory +build := -f $(srctree)/tools/build/Makefile.build dir=. obj + +all: fixdep + +clean: + $(call QUIET_CLEAN, fixdep) + $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)rm -f fixdep + +$(OUTPUT)fixdep-in.o: FORCE + $(Q)$(MAKE) $(build)=fixdep + +$(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o + $(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $< + +FORCE: + +.PHONY: FORCE diff --git a/tools/build/fixdep.c b/tools/build/fixdep.c new file mode 100644 index 0000000..1521d36 --- /dev/null +++ b/tools/build/fixdep.c @@ -0,0 +1,168 @@ +/* + * "Optimize" a list of dependencies as spit out by gcc -MD + * for the build framework. + * + * Original author: + * Copyright 2002 by Kai Germaschewski + * + * This code has been borrowed from kbuild's fixdep (scripts/basic/fixdep.c), + * Please check it for detailed explanation. This fixdep borow only the + * base transformation of dependecies without the CONFIG mangle. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *target; +char *depfile; +char *cmdline; + +static void usage(void) +{ + fprintf(stderr, "Usage: fixdep \n"); + exit(1); +} + +/* + * Print out the commandline prefixed with cmd_ := + */ +static void print_cmdline(void) +{ + printf("cmd_%s := %s\n\n", target, cmdline); +} + +/* + * Important: The below generated source_foo.o and deps_foo.o variable + * 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) +{ + char *m = map; + char *end = m + len; + char *p; + char s[PATH_MAX]; + int is_target; + int saw_any_target = 0; + int is_first_dep = 0; + + while (m < end) { + /* Skip any "white space" */ + while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) + m++; + /* Find next "white space" */ + p = m; + while (p < end && *p != ' ' && *p != '\\' && *p != '\n') + p++; + /* 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; + + /* + * 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 + * 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); + } + /* + * Start searching for next token immediately after the first + * "whitespace" character that follows this token. + */ + m = p + 1; + } + + if (!saw_any_target) { + fprintf(stderr, "fixdep: parse error; no targets found\n"); + exit(1); + } + + 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); +} + +int main(int argc, char **argv) +{ + if (argc != 4) + usage(); + + depfile = argv[1]; + target = argv[2]; + cmdline = argv[3]; + + print_cmdline(); + print_deps(); + + return 0; +}