diff options
author | Wang Nan <wangnan0@huawei.com> | 2015-06-11 07:25:49 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-08-07 09:57:23 -0400 |
commit | 0c6d18bfd551622b438e216e4863155f47907b0d (patch) | |
tree | 5ece0f324697a75fe3e409e204cc35de3a726f2b | |
parent | d325d7887b960627dc686d70d07682e18383f9c4 (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.c | 60 |
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 | ||
249 | static 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 | |||
249 | static inline void | 275 | static inline void |
250 | get_kbuild_opts(char **kbuild_dir) | 276 | get_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 | ||
276 | int llvm__compile_bpf(const char *path, void **p_obj_buf, | 324 | int 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; |
341 | errout: | 390 | errout: |
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; |