aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-06-11 07:25:49 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-07 09:57:23 -0400
commit0c6d18bfd551622b438e216e4863155f47907b0d (patch)
tree5ece0f324697a75fe3e409e204cc35de3a726f2b
parentd325d7887b960627dc686d70d07682e18383f9c4 (diff)
perf tools: Auto detecting kernel include options
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 <wangnan0@huawei.com> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: David Ahern <dsahern@gmail.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kaixu Xia <xiakaixu@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1436445342-1402-16-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/llvm-utils.c60
1 files changed, 55 insertions, 5 deletions
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 6bfcb2dd3161..5887bb8c1243 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -246,15 +246,42 @@ static int detect_kbuild_dir(char **kbuild_dir)
246 return -ENOENT; 246 return -ENOENT;
247} 247}
248 248
249static const char *kinc_fetch_script =
250"#!/usr/bin/env sh\n"
251"if ! test -d \"$KBUILD_DIR\"\n"
252"then\n"
253" exit -1\n"
254"fi\n"
255"if ! test -f \"$KBUILD_DIR/include/generated/autoconf.h\"\n"
256"then\n"
257" exit -1\n"
258"fi\n"
259"TMPDIR=`mktemp -d`\n"
260"if test -z \"$TMPDIR\"\n"
261"then\n"
262" exit -1\n"
263"fi\n"
264"cat << EOF > $TMPDIR/Makefile\n"
265"obj-y := dummy.o\n"
266"\\$(obj)/%.o: \\$(src)/%.c\n"
267"\t@echo -n \"\\$(NOSTDINC_FLAGS) \\$(LINUXINCLUDE) \\$(EXTRA_CFLAGS)\"\n"
268"EOF\n"
269"touch $TMPDIR/dummy.c\n"
270"make -s -C $KBUILD_DIR M=$TMPDIR $KBUILD_OPTS dummy.o 2>/dev/null\n"
271"RET=$?\n"
272"rm -rf $TMPDIR\n"
273"exit $RET\n";
274
249static inline void 275static inline void
250get_kbuild_opts(char **kbuild_dir) 276get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
251{ 277{
252 int err; 278 int err;
253 279
254 if (!kbuild_dir) 280 if (!kbuild_dir || !kbuild_include_opts)
255 return; 281 return;
256 282
257 *kbuild_dir = NULL; 283 *kbuild_dir = NULL;
284 *kbuild_include_opts = NULL;
258 285
259 if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) { 286 if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
260 pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n"); 287 pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n");
@@ -271,6 +298,27 @@ get_kbuild_opts(char **kbuild_dir)
271" \tdetection.\n\n"); 298" \tdetection.\n\n");
272 return; 299 return;
273 } 300 }
301
302 pr_debug("Kernel build dir is set to %s\n", *kbuild_dir);
303 force_set_env("KBUILD_DIR", *kbuild_dir);
304 force_set_env("KBUILD_OPTS", llvm_param.kbuild_opts);
305 err = read_from_pipe(kinc_fetch_script,
306 (void **)kbuild_include_opts,
307 NULL);
308 if (err) {
309 pr_warning(
310"WARNING:\tunable to get kernel include directories from '%s'\n"
311"Hint:\tTry set clang include options using 'clang-bpf-cmd-template'\n"
312" \toption in [llvm] section of ~/.perfconfig and set 'kbuild-dir'\n"
313" \toption in [llvm] to \"\" to suppress this detection.\n\n",
314 *kbuild_dir);
315
316 free(*kbuild_dir);
317 *kbuild_dir = NULL;
318 return;
319 }
320
321 pr_debug("include option is set to %s\n", *kbuild_include_opts);
274} 322}
275 323
276int llvm__compile_bpf(const char *path, void **p_obj_buf, 324int llvm__compile_bpf(const char *path, void **p_obj_buf,
@@ -280,7 +328,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
280 char clang_path[PATH_MAX]; 328 char clang_path[PATH_MAX];
281 const char *clang_opt = llvm_param.clang_opt; 329 const char *clang_opt = llvm_param.clang_opt;
282 const char *template = llvm_param.clang_bpf_cmd_template; 330 const char *template = llvm_param.clang_bpf_cmd_template;
283 char *kbuild_dir = NULL; 331 char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
284 void *obj_buf = NULL; 332 void *obj_buf = NULL;
285 size_t obj_buf_sz; 333 size_t obj_buf_sz;
286 334
@@ -302,11 +350,11 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
302 * This is an optional work. Even it fail we can continue our 350 * This is an optional work. Even it fail we can continue our
303 * work. Needn't to check error return. 351 * work. Needn't to check error return.
304 */ 352 */
305 get_kbuild_opts(&kbuild_dir); 353 get_kbuild_opts(&kbuild_dir, &kbuild_include_opts);
306 354
307 force_set_env("CLANG_EXEC", clang_path); 355 force_set_env("CLANG_EXEC", clang_path);
308 force_set_env("CLANG_OPTIONS", clang_opt); 356 force_set_env("CLANG_OPTIONS", clang_opt);
309 force_set_env("KERNEL_INC_OPTIONS", NULL); 357 force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts);
310 force_set_env("WORKING_DIR", kbuild_dir ? : "."); 358 force_set_env("WORKING_DIR", kbuild_dir ? : ".");
311 359
312 /* 360 /*
@@ -330,6 +378,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
330 } 378 }
331 379
332 free(kbuild_dir); 380 free(kbuild_dir);
381 free(kbuild_include_opts);
333 if (!p_obj_buf) 382 if (!p_obj_buf)
334 free(obj_buf); 383 free(obj_buf);
335 else 384 else
@@ -340,6 +389,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
340 return 0; 389 return 0;
341errout: 390errout:
342 free(kbuild_dir); 391 free(kbuild_dir);
392 free(kbuild_include_opts);
343 free(obj_buf); 393 free(obj_buf);
344 if (p_obj_buf) 394 if (p_obj_buf)
345 *p_obj_buf = NULL; 395 *p_obj_buf = NULL;