Skip to content

LLVM dependency installation instructions

Certain backends/compilation flows require LLVM. This is because AdaptiveCpp needs to build a clang plugin which is then loaded into clang to provide the required compiler support for SYCL.

Generally, we recommend the latest officially released clang/LLVM versions, but older versions might also work depending on the compilation flow (see the table from the main installation instructions).

Usually, the clang/LLVM versions provided in Linux distribution repositories are sufficient, if they are recent enough. In this case, AdaptiveCpp might automatically detect and configure your LLVM installation without additional cmake arguments required. We therefore recommend to make your life easy: Check your distribution's LLVM version against the AdaptiveCpp requirements and if they match, use it.

If you are using Ubuntu or Debian, we can also recommend the package repositories at http://apt.llvm.org if you wish to obtain a newer LLVM.

Install * clang (including development headers) * LLVM (including development headers) * libomp (including development headers) * lld (only for the ROCm backend)

For example, the required steps to install clang 16 on an Ubuntu system are:

wget https://apt.llvm.org/llvm.sh #Convenience script that sets up the repositories
chmod +x llvm.sh
./llvm.sh 16 #Set up repositories for clang 16
apt install -y libclang-16-dev clang-tools-16 libomp-16-dev llvm-16-dev lld-16

It is generally not necessary to compile LLVM by yourself. However, if you wish to do this, during LLVM cmake make sure to:

  • Disable assertions as AdaptiveCpp can potentially trigger some (false positive) debug assertions in some LLVM versions: -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=OFF -DLLVM_ENABLE_DUMP=OFF
  • Generate libLLVM.so: -DLLVM_BUILD_LLVM_DYLIB=ON (only required if the SSCP compilation flow is enabled when building AdaptiveCpp, which is true by default for supported versions of LLVM)
  • Enable the correct backends for your hardware: nvptx for NVIDIA GPUs and amdgpu for AMD GPUs.

An example build of LLVM 15 from source might look like this:

git clone https://github.com/llvm/llvm-project -b release/15.x
cd llvm-project
mkdir -p build
cd build

INSTALL_PREFIX=/path/to/desired/llvm/installation/directory

cmake -DCMAKE_C_COMPILER=`which gcc` -DCMAKE_CXX_COMPILER=`which g++` \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
      -DLLVM_ENABLE_PROJECTS="clang;compiler-rt;lld;openmp" \
      -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_ASSERTIONS=OFF \
      -DLLVM_TARGETS_TO_BUILD="AMDGPU;NVPTX;X86" \
      -DCLANG_ANALYZER_ENABLE_Z3_SOLVER=0 \
      -DLLVM_INCLUDE_BENCHMARKS=0 \
      -DLLVM_INCLUDE_EXAMPLES=0 \
      -DLLVM_INCLUDE_TESTS=0 \
      -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
      -DCMAKE_INSTALL_RPATH=$INSTALL_PREFIX/lib \
      -DLLVM_ENABLE_OCAMLDOC=OFF \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=OFF \
      -DLLVM_BUILD_LLVM_DYLIB=ON \
      -DLLVM_ENABLE_DUMP=OFF  ../llvm
make install

Pointing AdaptiveCpp to the right LLVM

When invoking cmake, the AdaptiveCpp build infrastructure will attempt to find LLVM automatically (see below for how to invoke cmake).

If AdaptiveCpp does not automatically configure the build for the desired clang/LLVM installation, the following cmake variables can be used to point AdaptiveCpp to the right one: * -DLLVM_DIR=/path/to/llvm/cmake must be pointed to your LLVM installation, specifically, the subdirectory containing the LLVM cmake files. Note that different LLVM installations may have the LLVM cmake files in different subdirectories that don't necessarily end with cmake (e.g. it might also be /path/to/llvm/lib/cmake/llvm). Alternatively, you can try -DLLVM_ROOT which might be more forgiving.

Verify from the cmake that the selected clang++ and include headers match the LLVM that you have requested. Example output:

...
-- Building AdaptiveCpp against LLVM configured from /usr/lib/llvm-16/cmake/
-- Selecting clang: /usr/bin/clang++-16
-- Using clang include directory: /usr/include/clang/16.0.1/include/..
...

If AdaptiveCpp does not select the right clang++ or include directories, use the following variables to set them manually:

  • -DCLANG_EXECUTABLE_PATH=/path/to/clang++ must be pointed to the clang++ executable from this LLVM installation.
  • -DCLANG_INCLUDE_PATH=/path/to/clang-includes must be pointed to the clang internal header directory. Typically, this is something like $LLVM_INSTALL_PREFIX/include/clang/<llvm-version>/include. Newer ROCm versions will require the parent directory instead, i.e. $LLVM_INSTALL_PREFIX/include/clang/<llvm-version>. This is only important for the ROCm backend.

If clang/LLVM does not find C++ standard library headers

AdaptiveCpp relies on a working clang installation. clang in turn does not come with its own C++ standard library, but instead assumes that it can use the one from the system.

Missing packages

If it does not find C++ standard library headers, it might be because you are missing a libstdc++-dev package or similar.

If you have multiple gcc versions installed on your system, it is also possible that clang wants a specific libstdc++ version to match a gcc version that it has selected. You can use clang++ -v /dev/null to find out which gcc and libstdc++ version clang wants to use. Note: This command is expected to fail with a linker error. It should print something like "Selected GCC installation: ..." which is the information you are looking for.

GCC toolchain/C++ standard library is in a non-standard location

If the C++ standard library is in a non-standard location (this might typically be the case on a cluster), it is also possible that clang does not find it.

In that case, clang can be informed about the location of the GCC toolchain using the --gcc-toolchain=... flag. Note: This flag is very picky about the directory!. It needs to be provided with the parent directory that contains the lib/gcc/<arch>/<version> subdirectories. On a Cray system, this might e.g. be --gcc-toolchain=/opt/cray/pe/gcc/12.2.0/snos. If an incorrect path is provided, clang may silently ignore the argument. Use clang++ -v /dev/null as described above to check that it has accepted the GCC installation.

While in theory AdaptiveCpp can be made to use that flag when compiling, a simpler solution to make that change permanent is to use clang configuration files (details in the clang documentation): 1. In the directory where clang++ lives (e.g. some bin directory), create a new file <name>.cfg, replacing <name> with something of your choice. 2. Put any flags that you want clang to use by default into this file, such as the --gcc-toolchain=... flag. 3. Create a symlink to clang in the same directory that clang++ and the config file exist in: ln -s clang++ <name>-clang++, again replacing <name> with the name of your config file. 4. When invoking clang with the symlink, clang will automatically apply the configuration file. Now use <name>-clang++ in the build process of AdaptiveCpp instead of clang++, e.g. use the cmake flags -DCMAKE_CXX_COMPILER=<name>-clang++ -DCLANG_EXECUTABLE_PATH=/path/to/<name>-clang++.