Building from Source with Meson#
This chapter describes how to build HPCToolkit from source using Meson. This approach is recommended for HPCToolkit developers.
Quickstart#
Install:
meson>=1.6.0 and a working C/C++ compiler (GCC, Clang, etc.)Boost >=1.71.0
make,awk, andsedforhpcstructmeasurement directory support (see #704).(Optional but highly recommended:) ccache
(Optional:) system-wide installation of HPCToolkit’s dependencies as root
Then run:
$ meson setup builddir/
$ cd builddir/
$ meson compile # -OR- ninja
$ meson test # -OR- ninja test
Do not use meson install or ninja install.
Instead, working versions of the tools themselves are available using meson devenv. One can use meson devenv to either run an individual command, or create a subshell environment in which HPCToolkit’s commands are available, as shown below:
$ meson devenv hpcrun --version # -OR-
$ meson devenv
[builddir] $ hpcrun --version
Configuration#
Configuration arguments can be passed to the initial meson setup or later meson configure invocations with invocations as follows
meson setup [arguments] builddir/ or meson configure [arguments]. Arguments that control the build of HPCToolkit are listed below:
-Dtests=(disabled|auto|enabled): Enable unit tests withmeson test. (disabledonly disables tests that require additional dependencies.)-Dmanpages=(disabled|auto|enabled): Generate and build man pages. Requires Docutils.-Dmanual=(disabled|auto|enabled): Generate and build user manual. Requires Sphinx.-Dhpcprof_mpi=(disabled|auto|enabled): Buildhpcprof-mpiin addition tohpcprof. Requires MPI.-Dpython=(disabled|auto|enabled): Enable an (experimental) Python unwinder. Requires Python headers.-Dpapi=(disabled|auto|enabled): Enable PAPI metrics. Requires PAPI.-Dcuda=(disabled|auto|enabled): Enable CUDA metrics (-e gpu=nvidia). Requires CUDA.-Dlevel0=(disabled|auto|enabled): Enable Level Zero metrics (-e gpu=level0). Requires Level Zero.-Dgtpin=(disabled|auto|enabled): Also enable Level Zero instrumentation metrics (-e gpu=level0,inst). Requires Level Zero, IGC/IGA and GTPin.-Dopencl=(disabled|auto|enabled): Enable OpenCL metrics (-e gpu=opencl). Requires OpenCL headers.-Drocm=(disabled|auto|enabled): Enable ROCm metrics (-e gpu=amd). Requires ROCm.-Dvalgrind_annotations=(false|true): Inject annotations for debugging with Valgrind.
Note that many of the features above require additional optional dependencies when enabled.
Installing Dependencies without Root#
Meson Wraps#
If core dependencies needed to build and run HPCToolkit can be found on your system, Meson will use those. To assist you in manually providing dependencies to Meson, see the discussion about how Meson looks for dependencies later on this page.
If Meson cannot find HPCToolkit’s dependencies on your system, meson (setup|configure) will use Meson wraps to build HPCToolkit’s core dependencies. No root privileges are needed to use Meson wraps.
If you let Meson wraps provide HPCToolkit’s dependencies, then building HPCToolkit requires little more than Meson and a C/C++ compiler; any missing dependencies will be downloaded and built as subprojects. Below, we list Meson wraps that HPCToolkit will download and build if they are needed by your build configuration and they are not found on your system:
Subprojects
bzip2 : YES
dyninst : YES 347 warnings
elfutils : YES 2 warnings
libiberty : YES (from dyninst)
liblzma : YES (from elfutils)
libpfm : YES
libunwind : YES
opencl-headers: YES
tbb : YES
xed : YES
xerces-c : YES
xxhash : YES
yaml-cpp : YES
zstd : YES (from elfutils)
Meson wraps are downloaded and built only as needed. In some cases, a wrap will not be considered unless you enable a particular feature of HPCToolkit.
For instance, opencl-headers will not be downloaded unless your meson (setup|configure) command includes the configuration option -Dopencl=enabled.
If the internet is not available on the system running meson setup, you may also need to run meson subprojects download first on a system with internet to download the required sources.
If wraps are not desired, they can be disabled with meson (setup|configure) --wrap-mode=nofallback.
With this setting, all dependencies must be installed or otherwise loaded into the build environment, except for force-fallback dependencies meson (setup|configure) --force-fallback-for=dep1,dep2,....
See the official Meson documentation about wraps for more configuration options and implementation details.
Dev Containers (BETA)#
Another way to manage dependencies without root permission is to simply build and run HPCToolkit in container.
Multiple Dev Container configurations are provided for common distros and vendor software:
ubuntu20.04,rhel8,leap15,fedora39: CPU-only configurations for common distroscuda*: Ubuntu 20.04 with NVIDIA CUDA toolkit installedrocm*: Ubuntu 20.04 with AMD ROCm installedintel: Ubuntu 20.04 with Intel OneAPI Base Toolkitbare: Bare minimum dependencies to build HPCToolkit
Installing Dependencies as Root#
Debian/Ubuntu and Derivatives#
For Debian Sid/Ubuntu 23.10:
sudo apt-get install git build-essential ccache ninja-build meson cmake pkg-config python3-venv libboost-all-dev libbz2-dev libtbb-dev libelf-dev libdw-dev libunwind-dev libxerces-c-dev libiberty-dev libyaml-cpp-dev libpfm4-dev libxxhash-dev zlib1g-dev
pipx install 'meson>=1.6.0'
For older versions:
sudo apt-get install git build-essential ccache ninja-build cmake pkg-config pipx python3 python3-pip python3-venv libboost-all-dev libbz2-dev libtbb-dev libelf-dev libdw-dev libunwind-dev libxerces-c-dev libiberty-dev libyaml-cpp-dev libpfm4-dev libxxhash-dev zlib1g-dev
pipx install 'meson>=1.6.0'
Note that some dependencies may be built from wraps by default, either because they aren’t packaged in Debian/Ubuntu (e.g. Dyninst) or because the version is too old. Additional packages can be installed for optional features:
Package |
Feature option |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
Fedora/RHEL and Derivatives#
For RHEL 8:
sudo dnf install git gcc gcc-c++ ccache ninja-build cmake pkg-config python39 python39-pip boost-devel bzip2-devel tbb-devel elfutils-devel xerces-c-devel binutils-devel yaml-cpp-devel libpfm-devel xxhash-devel zlib-devel
python3.9 -m pip install pipx
pipx install 'meson>=1.6.0'
For RHEL 9:
sudo dnf install git gcc gcc-c++ ccache ninja-build cmake pkg-config python3 pipx boost-devel bzip2-devel tbb-devel elfutils-devel xerces-c-devel binutils-devel yaml-cpp-devel libpfm-devel libunwind-devel xxhash-devel zlib-devel
pipx install 'meson>=1.6.0'
For Fedora:
sudo dnf install git gcc gcc-c++ ccache ninja-build cmake pkg-config python3 meson pipx boost-devel bzip2-devel tbb-devel elfutils-devel xerces-c-devel binutils-devel yaml-cpp-devel libpfm-devel libunwind-devel xxhash-devel zlib-devel
pipx install 'meson>=1.6.0' # Optional but recommended
Note that some dependencies may be built from wraps by default, either because they aren’t packaged in Fedora/RHEL (e.g. Xed) or because the version is too old. Additional packages can be installed for optional features:
Package |
Feature option |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
SUSE Leap/SLES 15 and Derivatives#
sudo zypper install git gcc12 gcc12-c++ ccache ninja-build cmake pkg-config python311 python311-pip libboost_atomic-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_graph-devel libboost_system-devel libboost_thread-devel libboost_timer-devel libbz2-devel tbb-devel libxerces-c-devel binutils-devel yaml-cpp-devel libpfm-devel xxhash-devel zlib-devel
python3.11 -m pip install pipx
pipx install 'meson>=1.6.0'
Note that some dependencies may be built from wraps by default, either because they aren’t packaged in SUSE Leap (e.g. Xed) or because the version is too old. Additional packages can be installed for optional features:
Package |
Feature option |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
Custom Dependencies#
It is also possible to build and run HPCToolkit using custom versions of dependencies, e.g. one you have modified to fix a bug. However, to expose such dependencies to Meson, you will need some basic understanding of how Meson finds dependencies.
This section is intended as a “peek behind the curtain” of how Meson understands dependencies, and an abridged version of [Meson’s dependency() docs] for developers.
Meson fetches all dependencies from the “build environment” aka the “machine” (technically two, the build_machine and the host_machine, which are only different when cross-compiling).
Whenever Meson configures (i.e. during meson setup or automatically during meson compile/install/test/etc.), queries the “machine” as defined by various environment variables:
Finding programs (
find_program()) is done by searching thePATH,The C/C++ compilers (
CC/CXX), which are also affected byCFLAGS,CXXFLAGS,LDFLAGS,INCLUDE_PATH,LIBRARY_PATH,CRAY_*, …Dependencies are found via
pkg-config, which is affected byPKG_CONFIG_PATH(and otherPKG_CONFIG_*variables),Dependencies are found via CMake, which is affected by
CMAKE_PREFIX_PATH(and otherCMAKE_*,*_ROOTand*_ROOT_DIRvariables),Dependencies with Meson built-in functionality have their own quirks:
Boost is found under
BOOST_ROOT,The CUDA Toolkit is found under
CUDA_PATH.
These variables are frequently altered by commands designed to load software into a shell environment, for example module un/load.
Meson assumes the “machine” does not change between meson invocations, however if it does by running the above commands it is possible Meson’s cache will not match reality.
In these cases reconfiguration or later compilation may fail due to the inconsistent state between dependencies.
In some cases this can be fixed by clearing Meson’s cache (meson configure --clearcache), Meson will efficiently avoid rebuilding files if the compile command did not actually change.
If build errors persist it may be necessary to wipe the build directory completely (meson setup --wipe), it is recommended to use ccache to accelerate the subsequent rebuild.
If you want to use a custom version of a dependency library, install it first and then adjust one or more of the variables mentioned above or corresponding Meson options:
If the dependency installs a
pkg-configfile (usuallylib/pkgconfig/*.pc), append the directory containing these files toPKG_CONFIG_PATHor-Dpkg_config_path.In all other cases, append the install prefix (i.e. the directory with
include/andlib/orlib64/) toCMAKE_PREFIX_PATHor-Dcmake_prefix_path.For select dependencies (i.e. if the dependency doesn’t install
pkg-configor CMake files and there is no matchingshare/cmake-*/Modules/Find*.cmakescript in the CMake installation), you may also opt to configure the compiler instead, by:Extending
-Dc_argswith appropriate-Iinclude flags and-Dc_link_argswith-Llink flags, orExtending
CPATHwithinclude/directories andLIBRARY_PATHwithlib/orlib64/directories.
Some of these variables can be persisted as Meson built-in options (e.g. -Dpkg_config_path) or more generally [native files][meson native file].
For example, a native file to use GCC 11 with extra flags and a custom dependency search flags would look like:
# …/my-env.ini
[binaries]
c = ['ccache', 'gcc-11']
cpp = ['ccache', 'g++-11']
[built-in options]
c_args = ['-fstack-protector']
cpp_args = ['-fhardened']
cmake_prefix_path = ['/…/path/to/custom/install/', '/…/path/to/other/install/']
pkg_config_path = ['/…/path/to/custom/install/lib/pkgconfig', '/…/path/to/other/install/lib/pkgconfig']
And then can be used in a build directory by passing additional arguments to meson setup:
$ meson setup --native-file …/my-elf-dyn.ini builddir/
See [doc/developers/meson.ini] for a more complete template listing the settings available in a native file.