mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 17:51:22 +03:00
129 lines
3.5 KiB
Python
Executable File
129 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: LGPL-2.1+
|
|
|
|
import argparse
|
|
import logging
|
|
import pathlib
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
def clang_arch_flag(arch):
|
|
return '-D__{}__'.format(arch)
|
|
|
|
|
|
def target_triplet():
|
|
gcc_exec = 'gcc'
|
|
|
|
try:
|
|
return subprocess.check_output([gcc_exec, '-dumpmachine'],
|
|
universal_newlines=True).strip()
|
|
except subprocess.CalledProcessError as e:
|
|
logging.error('Failed to get target triplet: {}'.format(e))
|
|
except FileNotFoundError:
|
|
logging.error('gcc not installed')
|
|
return None
|
|
|
|
|
|
def clang_compile(clang_exec, clang_flags, src_c, out_file, target_arch,
|
|
target_triplet):
|
|
clang_args = [clang_exec, *clang_flags, target_arch, '-I.']
|
|
|
|
if target_triplet:
|
|
clang_args += [
|
|
'-isystem',
|
|
'/usr/include/{}'.format(target_triplet)]
|
|
|
|
clang_args += [
|
|
'-idirafter',
|
|
'/usr/local/include',
|
|
'-idirafter',
|
|
'/usr/include']
|
|
|
|
clang_args += [src_c, '-o', out_file]
|
|
|
|
logging.debug('{}'.format(' '.join(clang_args)))
|
|
subprocess.check_call(clang_args)
|
|
|
|
|
|
def llvm_strip(llvm_strip_exec, in_file):
|
|
llvm_strip_args = [llvm_strip_exec, '-g', in_file]
|
|
|
|
logging.debug('Stripping useless DWARF info:')
|
|
logging.debug('{}'.format(' '.join(llvm_strip_args)))
|
|
|
|
subprocess.check_call(llvm_strip_args)
|
|
|
|
|
|
def gen_bpf_skeleton(bpftool_exec, in_file, out_fd):
|
|
bpftool_args = [bpftool_exec, 'g', 's', in_file]
|
|
|
|
logging.debug('Generating BPF skeleton:')
|
|
logging.debug('{}'.format(' '.join(bpftool_args)))
|
|
skel = subprocess.check_output(bpftool_args, universal_newlines=True)
|
|
# libbpf is used via dlopen(), so rename symbols as defined
|
|
# in src/shared/bpf-dlopen.h
|
|
skel = re.sub(r'(bpf_object__\w+_skeleton)', r'sym_\1', skel)
|
|
out_fd.write(skel)
|
|
|
|
|
|
def bpf_build(args):
|
|
clang_flags = [
|
|
'-Wno-compare-distinct-pointer-types',
|
|
'-O2',
|
|
'-target',
|
|
'bpf',
|
|
'-g',
|
|
'-c',
|
|
]
|
|
|
|
clang_out_path = pathlib.Path(args.bpf_src_c).with_suffix('.o')
|
|
with clang_out_path.open(mode='w') as clang_out, \
|
|
open(args.bpf_skel_h, mode='w') as bpf_skel_h:
|
|
clang_compile(clang_exec=args.clang_exec,
|
|
clang_flags=clang_flags,
|
|
src_c=args.bpf_src_c,
|
|
out_file=clang_out.name,
|
|
target_arch=clang_arch_flag(args.arch),
|
|
target_triplet=target_triplet())
|
|
|
|
llvm_strip(llvm_strip_exec=args.llvm_strip_exec, in_file=clang_out.name)
|
|
|
|
gen_bpf_skeleton(bpftool_exec=args.bpftool_exec,
|
|
in_file=clang_out.name,
|
|
out_fd=bpf_skel_h)
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument(
|
|
'bpf_src_c',
|
|
help='Path to *.c source of BPF program in systemd source tree \
|
|
relative to the work directory')
|
|
|
|
parser.add_argument(
|
|
'bpf_skel_h',
|
|
help='Path to C header file')
|
|
|
|
parser.add_argument(
|
|
'--clang_exec',
|
|
help='Path to clang exec')
|
|
|
|
parser.add_argument(
|
|
'--llvm_strip_exec',
|
|
help='Path to llvm-strip exec')
|
|
|
|
parser.add_argument(
|
|
'--bpftool_exec',
|
|
help='Path to bpftool exec')
|
|
|
|
parser.add_argument(
|
|
'--arch',
|
|
help='Target CPU architecture',
|
|
default='x86_64')
|
|
|
|
args = parser.parse_args();
|
|
|
|
logging.basicConfig(stream=sys.stderr, level=logging.WARNING)
|
|
bpf_build(args)
|