]> git.ipfire.org Git - thirdparty/systemd.git/blame - tools/build-bpf-skel.py
tree-wide: fix SPDX short identifier for LGPL-2.1-or-later
[thirdparty/systemd.git] / tools / build-bpf-skel.py
CommitLineData
cf4f9a57 1#!/usr/bin/env python3
948def4a 2# SPDX-License-Identifier: LGPL-2.1-or-later
cf4f9a57
JK
3
4import argparse
5import logging
6import pathlib
c5fd89ad 7import re
cf4f9a57
JK
8import subprocess
9import sys
10
11def clang_arch_flag(arch):
12 return '-D__{}__'.format(arch)
13
14
15def target_triplet():
16 gcc_exec = 'gcc'
17
18 try:
19 return subprocess.check_output([gcc_exec, '-dumpmachine'],
20 universal_newlines=True).strip()
21 except subprocess.CalledProcessError as e:
22 logging.error('Failed to get target triplet: {}'.format(e))
23 except FileNotFoundError:
24 logging.error('gcc not installed')
25 return None
26
27
28def clang_compile(clang_exec, clang_flags, src_c, out_file, target_arch,
29 target_triplet):
30 clang_args = [clang_exec, *clang_flags, target_arch, '-I.']
31
32 if target_triplet:
33 clang_args += [
34 '-isystem',
35 '/usr/include/{}'.format(target_triplet)]
36
37 clang_args += [
38 '-idirafter',
39 '/usr/local/include',
40 '-idirafter',
41 '/usr/include']
42
43 clang_args += [src_c, '-o', out_file]
44
45 logging.debug('{}'.format(' '.join(clang_args)))
46 subprocess.check_call(clang_args)
47
48
49def llvm_strip(llvm_strip_exec, in_file):
50 llvm_strip_args = [llvm_strip_exec, '-g', in_file]
51
52 logging.debug('Stripping useless DWARF info:')
53 logging.debug('{}'.format(' '.join(llvm_strip_args)))
54
55 subprocess.check_call(llvm_strip_args)
56
57
58def gen_bpf_skeleton(bpftool_exec, in_file, out_fd):
59 bpftool_args = [bpftool_exec, 'g', 's', in_file]
60
61 logging.debug('Generating BPF skeleton:')
62 logging.debug('{}'.format(' '.join(bpftool_args)))
c5fd89ad
LB
63 skel = subprocess.check_output(bpftool_args, universal_newlines=True)
64 # libbpf is used via dlopen(), so rename symbols as defined
65 # in src/shared/bpf-dlopen.h
66 skel = re.sub(r'(bpf_object__\w+_skeleton)', r'sym_\1', skel)
67 out_fd.write(skel)
cf4f9a57
JK
68
69
70def bpf_build(args):
71 clang_flags = [
72 '-Wno-compare-distinct-pointer-types',
73 '-O2',
74 '-target',
75 'bpf',
76 '-g',
77 '-c',
78 ]
79
80 clang_out_path = pathlib.Path(args.bpf_src_c).with_suffix('.o')
81 with clang_out_path.open(mode='w') as clang_out, \
82 open(args.bpf_skel_h, mode='w') as bpf_skel_h:
83 clang_compile(clang_exec=args.clang_exec,
84 clang_flags=clang_flags,
85 src_c=args.bpf_src_c,
86 out_file=clang_out.name,
87 target_arch=clang_arch_flag(args.arch),
88 target_triplet=target_triplet())
89
90 llvm_strip(llvm_strip_exec=args.llvm_strip_exec, in_file=clang_out.name)
91
92 gen_bpf_skeleton(bpftool_exec=args.bpftool_exec,
93 in_file=clang_out.name,
94 out_fd=bpf_skel_h)
95
96if __name__ == '__main__':
97 parser = argparse.ArgumentParser()
98
99 parser.add_argument(
100 'bpf_src_c',
101 help='Path to *.c source of BPF program in systemd source tree \
102 relative to the work directory')
103
104 parser.add_argument(
105 'bpf_skel_h',
106 help='Path to C header file')
107
108 parser.add_argument(
109 '--clang_exec',
110 help='Path to clang exec')
111
112 parser.add_argument(
113 '--llvm_strip_exec',
114 help='Path to llvm-strip exec')
115
116 parser.add_argument(
117 '--bpftool_exec',
118 help='Path to bpftool exec')
119
120 parser.add_argument(
121 '--arch',
122 help='Target CPU architecture',
123 default='x86_64')
124
125 args = parser.parse_args();
126
127 logging.basicConfig(stream=sys.stderr, level=logging.WARNING)
128 bpf_build(args)