CMake: Add ability to use system-installed libbpf rather than ExternalProject_Add #225
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.