-
Notifications
You must be signed in to change notification settings - Fork 326
CMake: Add ability to use system-installed libbpf rather than ExternalProject_Add #225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- The local cmake/FindBpf.cmake module is used to discover an installed libbpf, unless the PROCDUMP_DISABLE_SYSTEM_LIBBPF option is enabled - If system libbpf is disabled or not found, ExternalProject_Add is used to retrieve libbpf sources, build, (NEW: and install into PROJECT_BUILD_DIR/libbpf) - `LANGUAGES C CXX` added to project() command (aids CMake discovery of parameters like correct library dir name) - `GNUInstallDirs` CMake module loaded, defines CMAKE_INCLUDE_DIR and CMAKE_LIBRARY_DIR correctly relative to install prefix
The repo's CMake Find module for Bpf includes the ability to discover the location of the `bpftool` executable and provide an executable target representing its location. Use that in commands to generate the various procdump_ebpf files. Also, split out the steps to generate files using bpftool into separate add_custom_command() invocations, so that dependencies between files are tracked and each output file will be automatically tagged as `GENERATED` by CMake (and deleted by the 'clean' target).
Thanks for the contribution, much appreciated. I'll go through the PR in the next few days but as a general feedback, I would prefer the default being to build with statically linked libbpf rather than system provided. We rely on certain capabilities of libbpf that aren't available in early versions of libbpf. When we build for a lowest common dominator such as Ubuntu 20.04 it comes with a system provided libbpf (version 0.5.0 I think) which will not work. Defaulting to statically linked should still work fine as one can override and use system provided. |
@MarioHewardt your point is fair. Maybe a solution in between is to provide some way to specify where libbpf is "cached". In my case, for example, the builder does not have internet. So, ProcDump fails to compile because git cannot connect. |
I think your original approach works great (finding existing libbpf on local system), except just flipping the default to build static instead of system provided. Maybe introduce a flag USE_SYS_PROVIDED (or some such) that if defined will use the system provided approach. |
Hi @jcfaracco - No rush or anything, just checking in if you've had a chance to tweak the PR to switch the defaults? |
I just tested this PR and ..
[ 27%] Generating procdump.ebpf.o
/usr/sbin/bpftool gen object procdump.ebpf.o procdump_ebpf.o
libbpf: failed to find BTF info for object 'procdump_ebpf.o'
Error: failed to link 'procdump_ebpf.o': Invalid argument (22)
make[2]: *** [CMakeFiles/procdump_ebpf.dir/build.make:78: procdump.ebpf.o] Error 234
make[2]: *** Deleting file 'procdump.ebpf.o'
make[2]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/ProcDump-for-Linux-3.2.0/x86_64-redhat-linux-gnu' Eventually when this PR will be merged please it can close #221 |
Looks like it is not possible cleanly apply this PR on top of 3.3.0. + /usr/lib/rpm/rpmuncompress /home/tkloczko/rpmbuild/SOURCES/procdump-CMake-Add-ability-to-use-system-installed-libbpf.patch
+ /usr/bin/patch -p1 -s --fuzz=0 --no-backup-if-mismatch -f
1 out of 4 hunks FAILED -- saving rejects to file CMakeLists.txt.rej |
@MarioHewardt I have tested this PR. It requires some hacks to work with 3.3, but after that it works like a charm. For further reference, see the RPMs generated without any issue: https://koji.fedoraproject.org/koji/taskinfo?taskID=128305608 @ferdnyc can you rebase this PR on top of 3.3? |
This PR updates the project's top-level
CMakeLists.txt
to reduce assumptions about the environment in which the project will be built.bpftool / libbpf
The use of
ExternalProject_Add()
to download a copy of thelibbpf
sources and and incorporate them into theprocdump
build is now held off as a ''backup'' approach to incorporatinglibbpf
, and only used after first checking for a system-installedlibbpf
to link with. (This check can be overridden by enabling the optionPROCDUMP_DISABLE_SYSTEM_LIBBPF
when configuring the project, in which case thelibbpf
specified byExternalProject_Add()
will always be used, as before.)Dependency on the
bpftool
program being available on the system, which was previously hidden insideadd_custom_command()
scripting, is now formalized, and the location of the tool is discovered using the standard CMakefind_package()
command.To support both of these features, a CMake Find module,
cmake/FindBpf.cmake
, is added to the repo. This module supports discovery of bothlibbpf
andbpftool
as packageCOMPONENTS
. If discovery of a locallibbpf
is not disabled (see above),find_package(Bpf COMPONENTS libbpf)
will be called in an attempt to locate a usablelibbpf
to link with. In all cases,find_package(Bpf COMPONENTS bpftool)
is separately called to configure the location ofbpftool
.libbpf headers and linking
Due to the way an installed
libbpf
is meant to be consumed, the project code andExternalProject_Add
configuration forlibbpf
are slightly adjusted to be compatible.An installed
libbpf
will register its include directory as${prefix}/include
(e.g./usr/include
), and expects its header files to be included using#include <bpf/header_name.h>
. Because this layout is only created whenmake install
is called in theExternalProject
build, theINSTALL_COMMAND
argument has been added. After buildinglibbpf
, it will be installed (withDESTDIR
set to the external project's binary dir), and the library and include files will be consumed from that installed location rather than directly from the build directory. This gets the header files properly stored in abpf
subdirectory of the include dir. The#include
lines for libbpf headers inebpf/procdump_ebpf.h
are adjusted to use thebpf/
path prefix.Using bpftool
In addition to adding discovery logic for
bpftool
, the code which makes use of it in the project has been reworked to be more explicit.Previously, an
add_custom_command()
call used a long, chained command to compileprocdump_ebpf.o
and to then generate theprocdump.ebpf.o
andprocdump_ebpf.skel.h
files from it usingbpftool
.Those commands are now broken up into three
add_custom_command()
calls, each of which is responsible for generating a single output file. The dependencies between those various custom-command targets are all registered so that CMake will properly order the commands, will consider all of the resulting output files to beGENERATED
, and will automatically delete them when the project'sclean
target is built.Other dependencies
Other library dependencies of
procdump
are also discovered using standard CMakefind_package()
commands, rather than blindly linking library names on the assumption that they'll be present on the system linker paths.libz
and pthreads are now discovered usingfind_package(ZLIB)
andfind_package(Threads)
, which will use standard Find modules included in the CMake distribution.libelf
is now discovered usingfind_package(Libelf)
, which will run thecmake/FindLibelf.cmake
Find module added in this PR.System path discovery
The CMake
project()
command is now extended withLANGUAGES C CXX
arguments defining the project languages. And, the standard CMakeGNUInstallDirs
module is loaded when configuring the build. Both of these changes are made for the same reason: They activate CMake's ability to automatically detect information about the local system performing the build.For example, when
make install
is run in the downloadedlibbpf
external project, the compiled library will be installed into the standard library path inside theDESTDIR
. That path may be$DESTDIR/usr/lib/
, it may be$DESTDIR/usr/lib64/
, it may be something like$DESTDIR/usr/lib/linux-gnu-x86_64/
or$DESTDIR/usr/lib/linux-gnu-i386/
. By using$DESTDIR/usr/${CMAKE_INSTALL_LIBDIR}
as the path to the library, those details are handled automatically.(The same features would make it possible to detect 64-bit and big-endian target processors automatically, to streamline the
CLRHOSTDEF
detection code that's currently hand-coded inCMakeLists.txt
. I may submit a separate PR with those changes.)Conclusion
I believe these changes make the project's build system more robust and more usable to those who wish to build ProcDump for themselves. The ability to link with an installed
libbpf
on the system rather than downloading external code, in particular, is a requirement of most Linux packaging standards.I'm happy to answer questions about any of these changes or to make any modifications needed to meet the project's standards.