This should hopefully fix cross compilation for the bpf programs.
# We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
bpftool = find_program('bpftool', '/usr/sbin/bpftool', required : bpf_framework_required)
- bpf_arches = ['x86_64']
deps_found = libbpf.found() and clang.found() and llvm_strip.found() and bpftool.found()
# Can build BPF program from source code in restricted C
- conf.set10('BPF_FRAMEWORK',
- bpf_arches.contains(host_machine.cpu_family()) and deps_found)
+ conf.set10('BPF_FRAMEWORK', deps_found)
endif
libmount = dependency('mount',
############################################################
-build_bpf_skel_py = find_program('tools/build-bpf-skel.py')
generate_gperfs = find_program('tools/generate-gperfs.py')
make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py')
make_directive_index_py = find_program('tools/make-directive-index.py')
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
#include "bpf-dlopen.h"
#include "bpf-link.h"
-#include "bpf/socket_bind/socket-bind.skel.h"
+#include "bpf/socket_bind/socket-bind-skel.h"
#include "bpf/socket_bind/socket-bind-api.bpf.h"
static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) {
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1+
+
+if conf.get('BPF_FRAMEWORK') == 1
+ clang_flags = [
+ '-Wno-compare-distinct-pointer-types',
+ '-O2',
+ '-target',
+ 'bpf',
+ '-g',
+ '-c',
+ ]
+
+ clang_arch_flag = '-D__@0@__'.format(host_machine.cpu_family())
+
+ if meson.version().version_compare('>= 0.58')
+ libbpf_include_dir = libbpf.get_variable('includedir')
+ else
+ libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
+ endif
+
+ bpf_o_unstripped_cmd = [
+ clang,
+ clang_flags,
+ clang_arch_flag,
+ '-I.'
+ ]
+
+ if not meson.is_cross_build()
+ target_triplet_cmd = run_command('gcc', '-dumpmachine', check: false)
+ if target_triplet_cmd.returncode() == 0
+ target_triplet = target_triplet_cmd.stdout().strip()
+ bpf_o_unstripped_cmd += [
+ '-isystem',
+ '/usr/include/@0@'.format(target_triplet)
+ ]
+ endif
+ endif
+
+ bpf_o_unstripped_cmd += [
+ '-idirafter',
+ libbpf_include_dir,
+ '@INPUT@',
+ '-o',
+ '@OUTPUT@'
+ ]
+
+ bpf_o_cmd = [
+ llvm_strip,
+ '-g',
+ '@INPUT@',
+ '-o',
+ '@OUTPUT@'
+ ]
+
+ skel_h_cmd = [
+ bpftool,
+ 'g',
+ 's',
+ '@INPUT@'
+ ]
+endif
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('BPF_FRAMEWORK') == 1
- restrict_fs_skel_h = custom_target(
- 'restrict-fs-skel.h',
+ restrict_fs_bpf_o_unstripped = custom_target(
+ 'restrict-fs.bpf.unstripped.o',
input : 'restrict-fs.bpf.c',
- output : 'restrict-fs-skel.h',
- command : [build_bpf_skel_py,
- '--clang_exec', clang.path(),
- '--llvm_strip_exec', llvm_strip.path(),
- '--bpftool_exec', bpftool.path(),
- '--arch', host_machine.cpu_family(),
- '@INPUT@', '@OUTPUT@'])
+ output : 'restrict-fs.bpf.unstripped.o',
+ command : bpf_o_unstripped_cmd)
+
+ restrict_fs_bpf_o = custom_target(
+ 'restrict-fs.bpf.o',
+ input : restrict_fs_bpf_o_unstripped,
+ output : 'restrict-fs.bpf.o',
+ command : bpf_o_cmd)
+
+ restrict_fs_skel_h = custom_target(
+ 'restrict-fs.skel.h',
+ input : restrict_fs_bpf_o,
+ output : 'restrict-fs.skel.h',
+ command : skel_h_cmd,
+ capture : true)
endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+/* The SPDX header above is actually correct in claiming this was
+ * LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
+ * compatible with GPL we will claim this to be GPL however, which should be
+ * fine given that LGPL-2.1-or-later downgrades to GPL if needed.
+ */
+
+/* libbpf is used via dlopen(), so rename symbols */
+#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
+#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
+#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
+
+#include "bpf/restrict_fs/restrict-fs.skel.h"
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('BPF_FRAMEWORK') == 1
+ restrict_ifaces_bpf_o_unstripped = custom_target(
+ 'restrict-ifaces.bpf.unstripped.o',
+ input : 'restrict-ifaces.bpf.c',
+ output : 'restrict-ifaces.bpf.unstripped.o',
+ command : bpf_o_unstripped_cmd)
+
+ restrict_ifaces_bpf_o = custom_target(
+ 'restrict-ifaces.bpf.o',
+ input : restrict_ifaces_bpf_o_unstripped,
+ output : 'restrict-ifaces.bpf.o',
+ command : bpf_o_cmd)
+
restrict_ifaces_skel_h = custom_target(
'restrict-ifaces.skel.h',
- input : 'restrict-ifaces.bpf.c',
+ input : restrict_ifaces_bpf_o,
output : 'restrict-ifaces.skel.h',
- command : [build_bpf_skel_py,
- '--clang_exec', clang.path(),
- '--llvm_strip_exec', llvm_strip.path(),
- '--bpftool_exec', bpftool.path(),
- '--arch', host_machine.cpu_family(),
- '@INPUT@', '@OUTPUT@'])
+ command : skel_h_cmd,
+ capture : true)
endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+/* The SPDX header above is actually correct in claiming this was
+ * LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
+ * compatible with GPL we will claim this to be GPL however, which should be
+ * fine given that LGPL-2.1-or-later downgrades to GPL if needed.
+ */
+
+/* libbpf is used via dlopen(), so rename symbols */
+#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
+#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
+#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
+
+#include "bpf/restrict_ifaces/restrict-ifaces.skel.h"
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('BPF_FRAMEWORK') == 1
+ socket_bind_bpf_o_unstripped = custom_target(
+ 'socket-bind.bpf.unstripped.o',
+ input : 'socket-bind.bpf.c',
+ output : 'socket-bind.bpf.unstripped.o',
+ command : bpf_o_unstripped_cmd)
+
+ socket_bind_bpf_o = custom_target(
+ 'socket-bind.bpf.o',
+ input : socket_bind_bpf_o_unstripped,
+ output : 'socket-bind.bpf.o',
+ command : bpf_o_cmd)
+
socket_bind_skel_h = custom_target(
'socket-bind.skel.h',
- input : 'socket-bind.bpf.c',
+ input : socket_bind_bpf_o,
output : 'socket-bind.skel.h',
- command : [build_bpf_skel_py,
- '--clang_exec', clang.path(),
- '--llvm_strip_exec', llvm_strip.path(),
- '--bpftool_exec', bpftool.path(),
- '--arch', host_machine.cpu_family(),
- '@INPUT@', '@OUTPUT@'])
+ command : skel_h_cmd,
+ capture : true)
endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+/* The SPDX header above is actually correct in claiming this was
+ * LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
+ * compatible with GPL we will claim this to be GPL however, which should be
+ * fine given that LGPL-2.1-or-later downgrades to GPL if needed.
+ */
+
+/* libbpf is used via dlopen(), so rename symbols */
+#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
+#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
+#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
+
+#include "bpf/socket_bind/socket-bind.skel.h"
unit.h
'''.split()
+subdir('bpf')
+
subdir('bpf/socket_bind')
if conf.get('BPF_FRAMEWORK') == 1
libcore_sources += [socket_bind_skel_h]
#include "bpf-dlopen.h"
#include "bpf-link.h"
-#include "bpf/restrict_ifaces/restrict-ifaces.skel.h"
+#include "bpf/restrict_ifaces/restrict-ifaces-skel.h"
static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) {
restrict_ifaces_bpf__destroy(obj);
+++ /dev/null
-#!/usr/bin/env python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-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)