From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965007AbbGHNP0 (ORCPT ); Wed, 8 Jul 2015 09:15:26 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:56854 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964938AbbGHNPT (ORCPT ); Wed, 8 Jul 2015 09:15:19 -0400 From: Wang Nan To: , CC: , , , , Subject: [PATCH v11 26/39] perf tools: Auto detecting kernel include options Date: Wed, 8 Jul 2015 13:14:15 +0000 Message-ID: <1436361268-234530-27-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1436361268-234530-1-git-send-email-wangnan0@huawei.com> References: <1436361268-234530-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.200] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To help user find correct kernel include options, this patch extracts them from kbuild system by an embedded script kinc_fetch_script, which creates a temporary directory, generates Makefile and an empty dummy.o then use the Makefile to fetch $(NOSTDINC_FLAGS), $(LINUXINCLUDE) and $(EXTRA_CFLAGS) options. The result is passed to compiler script using 'KERNEL_INC_OPTIONS' environment variable. Because options from kbuild contains relative path like 'Iinclude/generated/uapi', the work directory must be changed. This is done by previous patch. Signed-off-by: Wang Nan --- tools/perf/util/llvm-utils.c | 59 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 2ca2bd6..b658896 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -218,15 +218,42 @@ static const char *kbuild_detector = "fi\n" "exit -1\n"; +static const char *kinc_fetch_script = +"#!/usr/bin/env sh\n" +"if ! test -d \"$KBUILD_DIR\"\n" +"then\n" +" exit -1\n" +"fi\n" +"if ! test -f \"$KBUILD_DIR/include/generated/autoconf.h\"\n" +"then\n" +" exit -1\n" +"fi\n" +"TMPDIR=`mktemp -d`\n" +"if test -z \"$TMPDIR\"\n" +"then\n" +" exit -1\n" +"fi\n" +"cat << EOF > $TMPDIR/Makefile\n" +"obj-y := dummy.o\n" +"\\$(obj)/%.o: \\$(src)/%.c\n" +"\t@echo -n \"\\$(NOSTDINC_FLAGS) \\$(LINUXINCLUDE) \\$(EXTRA_CFLAGS)\"\n" +"EOF\n" +"touch $TMPDIR/dummy.c\n" +"make -s -C $KBUILD_DIR M=$TMPDIR $KBUILD_OPTS dummy.o 2>/dev/null\n" +"RET=$?\n" +"rm -rf $TMPDIR\n" +"exit $RET\n"; + static inline void -get_kbuild_opts(char **kbuild_dir) +get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) { int err; - if (!kbuild_dir) + if (!kbuild_dir || !kbuild_include_opts) return; *kbuild_dir = NULL; + *kbuild_include_opts = NULL; if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) { pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n"); @@ -247,6 +274,26 @@ get_kbuild_opts(char **kbuild_dir) " \tdetection.\n\n"); return; } + + pr_debug("Kernel build dir is set to %s\n", *kbuild_dir); + force_set_env("KBUILD_DIR", *kbuild_dir); + err = read_from_pipe(kinc_fetch_script, + (void **)kbuild_include_opts, + NULL); + if (err) { + pr_warning( +"WARNING:\tunable to get kernel include directories from '%s'\n" +"Hint:\tTry set clang include options using 'clang-bpf-cmd-template'\n" +" \toption in [llvm] section of ~/.perfconfig and set 'kbuild-dir'\n" +" \toption in [llvm] to \"\" to suppress this detection.\n\n", + *kbuild_dir); + + free(*kbuild_dir); + *kbuild_dir = NULL; + return; + } + + pr_debug("include option is set to %s\n", *kbuild_include_opts); } int llvm__compile_bpf(const char *path, void **p_obj_buf, @@ -256,7 +303,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, char clang_path[PATH_MAX]; const char *clang_opt = llvm_param.clang_opt; const char *template = llvm_param.clang_bpf_cmd_template; - char *kbuild_dir = NULL; + char *kbuild_dir = NULL, *kbuild_include_opts = NULL; void *obj_buf = NULL; size_t obj_buf_sz; @@ -278,11 +325,11 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, * This is an optional work. Even it fail we can continue our * work. Needn't to check error return. */ - get_kbuild_opts(&kbuild_dir); + get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); force_set_env("CLANG_EXEC", clang_path); force_set_env("CLANG_OPTIONS", clang_opt); - force_set_env("KERNEL_INC_OPTIONS", NULL); + force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts); force_set_env("WORKING_DIR", kbuild_dir ? : "."); /* @@ -305,6 +352,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, } free(kbuild_dir); + free(kbuild_include_opts); if (!p_obj_buf) free(obj_buf); else @@ -315,6 +363,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, return 0; errout: free(kbuild_dir); + free(kbuild_include_opts); free(obj_buf); if (p_obj_buf) *p_obj_buf = NULL; -- 1.8.3.4