aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-07-14 02:40:02 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-07 09:57:16 -0400
commitd325d7887b960627dc686d70d07682e18383f9c4 (patch)
treeb0ac46a5e263ed9e1af09adf7853b6262bcfdc38
parent4cea3a9cb30a962fa759fcb081fb83351113d9c4 (diff)
perf tools: Auto detecting kernel build directory
This patch detects kernel build directory by checking the existence of include/generated/autoconf.h. clang working directory is changed to kbuild directory if it is found, to help user use relative include path. Following patch will detect kernel include directory, which contains relative include patch so this workdir changing is needed. Users are allowed to set 'kbuild-dir = ""' manually to disable this checking. 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/n/tip-owyfwfbemrjn0tlj6tgk2nf5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/llvm-utils.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 5ae11249baad..6bfcb2dd3161 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <sys/utsname.h>
7#include "util.h" 8#include "util.h"
8#include "debug.h" 9#include "debug.h"
9#include "llvm-utils.h" 10#include "llvm-utils.h"
@@ -204,6 +205,74 @@ version_notice(void)
204); 205);
205} 206}
206 207
208static int detect_kbuild_dir(char **kbuild_dir)
209{
210 const char *test_dir = llvm_param.kbuild_dir;
211 const char *prefix_dir = "";
212 const char *suffix_dir = "";
213
214 char *autoconf_path;
215 struct utsname utsname;
216
217 int err;
218
219 if (!test_dir) {
220 err = uname(&utsname);
221 if (err) {
222 pr_warning("uname failed: %s\n", strerror(errno));
223 return -EINVAL;
224 }
225
226 test_dir = utsname.release;
227 prefix_dir = "/lib/modules/";
228 suffix_dir = "/build";
229 }
230
231 err = asprintf(&autoconf_path, "%s%s%s/include/generated/autoconf.h",
232 prefix_dir, test_dir, suffix_dir);
233 if (err < 0)
234 return -ENOMEM;
235
236 if (access(autoconf_path, R_OK) == 0) {
237 free(autoconf_path);
238
239 err = asprintf(kbuild_dir, "%s%s%s", prefix_dir, test_dir,
240 suffix_dir);
241 if (err < 0)
242 return -ENOMEM;
243 return 0;
244 }
245 free(autoconf_path);
246 return -ENOENT;
247}
248
249static inline void
250get_kbuild_opts(char **kbuild_dir)
251{
252 int err;
253
254 if (!kbuild_dir)
255 return;
256
257 *kbuild_dir = NULL;
258
259 if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
260 pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n");
261 pr_debug("Skip kbuild options detection.\n");
262 return;
263 }
264
265 err = detect_kbuild_dir(kbuild_dir);
266 if (err) {
267 pr_warning(
268"WARNING:\tunable to get correct kernel building directory.\n"
269"Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n"
270" \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n"
271" \tdetection.\n\n");
272 return;
273 }
274}
275
207int llvm__compile_bpf(const char *path, void **p_obj_buf, 276int llvm__compile_bpf(const char *path, void **p_obj_buf,
208 size_t *p_obj_buf_sz) 277 size_t *p_obj_buf_sz)
209{ 278{
@@ -211,6 +280,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
211 char clang_path[PATH_MAX]; 280 char clang_path[PATH_MAX];
212 const char *clang_opt = llvm_param.clang_opt; 281 const char *clang_opt = llvm_param.clang_opt;
213 const char *template = llvm_param.clang_bpf_cmd_template; 282 const char *template = llvm_param.clang_bpf_cmd_template;
283 char *kbuild_dir = NULL;
214 void *obj_buf = NULL; 284 void *obj_buf = NULL;
215 size_t obj_buf_sz; 285 size_t obj_buf_sz;
216 286
@@ -228,10 +298,16 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
228 return -ENOENT; 298 return -ENOENT;
229 } 299 }
230 300
301 /*
302 * This is an optional work. Even it fail we can continue our
303 * work. Needn't to check error return.
304 */
305 get_kbuild_opts(&kbuild_dir);
306
231 force_set_env("CLANG_EXEC", clang_path); 307 force_set_env("CLANG_EXEC", clang_path);
232 force_set_env("CLANG_OPTIONS", clang_opt); 308 force_set_env("CLANG_OPTIONS", clang_opt);
233 force_set_env("KERNEL_INC_OPTIONS", NULL); 309 force_set_env("KERNEL_INC_OPTIONS", NULL);
234 force_set_env("WORKING_DIR", "."); 310 force_set_env("WORKING_DIR", kbuild_dir ? : ".");
235 311
236 /* 312 /*
237 * Since we may reset clang's working dir, path of source file 313 * Since we may reset clang's working dir, path of source file
@@ -253,6 +329,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
253 goto errout; 329 goto errout;
254 } 330 }
255 331
332 free(kbuild_dir);
256 if (!p_obj_buf) 333 if (!p_obj_buf)
257 free(obj_buf); 334 free(obj_buf);
258 else 335 else
@@ -262,6 +339,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
262 *p_obj_buf_sz = obj_buf_sz; 339 *p_obj_buf_sz = obj_buf_sz;
263 return 0; 340 return 0;
264errout: 341errout:
342 free(kbuild_dir);
265 free(obj_buf); 343 free(obj_buf);
266 if (p_obj_buf) 344 if (p_obj_buf)
267 *p_obj_buf = NULL; 345 *p_obj_buf = NULL;