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; |
