Skip to content

Latest commit

 

History

History
155 lines (98 loc) · 4.7 KB

Toolchain.md

File metadata and controls

155 lines (98 loc) · 4.7 KB

Building Clang/LLVM

The bundled Clang/LLVM toolchain does not support LLVM Polly optimisations, so if you want to enable the llvm-polly-* patches then a different toolchain is required.

To build a PGO-optimised chromium (using the bundled PGO profile) a sufficiently new version of clang is required, whereby the major version (eg 18) equals or exceeds that of the bundled toolchain.

The clang/llvm packages from debian experimental often suffice, however these can be several months old. Versions of clang from stable or unstable almost always require extra patches, while the llvm repo (apt.llvm.org) offers up-to-date snapshots for both stable and unstable.

Building your own Clang/LLVM toolchain offers a certain advantages over installing from debian or apt.llvm.org :-

  • The ability to customise what gets installed (ie less bloat)
  • One can match the exact version (even the git commit) of the bundled version
  • Build an LTO, PGO and Bolt-optimised toolchain

With building chromium taking some hours on an older PC, the best argument is probably speed. As far as I know, the packages from the debian and llvm repos are not bolt-optimised (which gives a significant speed boost).

Below are the steps needed to build and install. Compilation time should be no more than a couple of hours on a cpu from the last decade or so, probably half that or less on anything relatively new.

Clone

git clone --depth 1 -b main https://github.com/llvm/llvm-project

Updating

git fetch --depth 1 --jobs=<number of threads> origin git checkout origin/main

Clean the build

git reset --hard HEAD

Configure

export LLVM_DIR=/usr/lib/llvm-16/bin

See what /usr/bin/x86_64-linux-gnu-ld points to :-

ls -l /usr/bin/x86_64-linux-gnu-ld

Note this down in case you want to change back. Now make sure that ld points at /usr/lib/llvm-16/bin/lld :-

cd /usr/bin

ln -sf $LLVM_DIR/lld x86_64-linux-gnu-ld

You can optionally add the following feature flags to the command below :-

-DLLVM_ENABLE_FFI=ON for libffi support

-DLLVM_ENABLE_RTTI=ON to enable RTTI (needed by mesa)

-DLLVM_PARALLEL_LINK_JOBS=1 if you are thread/ram limited

Now copy and edit the text below into a single line and execute inside the git root directory :-

AR=$LLVM_DIR/llvm-ar NM=$LLVM_DIR/llvm-nm RANLIB=$LLVM_DIR/llvm-ranlib CC=$LLVM_DIR/clang CXX=$LLVM_DIR/clang++ \
cmake -B build -G Ninja -S llvm -C clang/cmake/caches/BOLT-PGO.cmake -DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS='bolt;clang;lld;openmp;polly' -DLLVM_BUILD_UTILS=OFF -DLLVM_TARGETS_TO_BUILD="X86;WebAssembly" \
-DLLVM_ENABLE_CURL=OFF -DLLVM_ENABLE_LLD=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF \
-DLLVM_INCLUDE_GO_TESTS=OFF -DLLVM_USE_SPLIT_DWARF=ON -DCLANG_ENABLE_ARCMT=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF \
-DCLANG_PLUGIN_SUPPORT=OFF -DCOMPILER_RT_BUILD_BUILTINS=OFF -DCOMPILER_RT_BUILD_CRT=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
-DCOMPILER_RT_BUILD_SANITIZERS=ON -DCOMPILER_RT_BUILD_XRAY=OFF \
-DCOMPILER_RT_SANITIZERS_TO_BUILD='asan;dfsan;msan;hwasan;tsan;safestack;cfi' -DCOMPILER_RT_USE_LIBCXX=NO -DLLVM_BUILD_LLVM_DYLIB=ON \
-DLLVM_LINK_LLVM_DYLIB=ON -DBOOTSTRAP_LLVM_ENABLE_LLD=ON -DBOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_LLD=ON -DPGO_INSTRUMENT_LTO=Thin

For clarity I'll use -j4 below instead of -j<number of threads>.

If you have built before then run :-

ninja -j4 -C build -t cleandead

Compile

cd build
ninja -j4 stage2-clang-bolt

Install

Default install target is /usr/local, so do this as root :-

ninja -j4 install

(* see note about not stripping debug information)

Check for root-only permissions

Note: you need to be root to do the following.

Installing generates root-owned objects in the build directory, which interfere with subsequent builds. So after installing, do the following :-

chown -R <user>:<user> build

Permissions of 0700 won't allow users to access directories, and cause runtime errors.

Check to see if you have any :-

find /usr/local/ -type d | while read l; do [ $(stat -c %a "$l") -eq 0700 ] && ls -ld "$l"; done

Correct them with :-

find /usr/local/ -type d | while read l; do [ $(stat -c %a "$l") -eq 0700 ] && chmod 0755 "$l"; done

Uninstalling

The easiest way to uninstall is to literally delete each file/directory listed in the various install_manifest.txt files.

find -type f -name install_manifest.txt | while read l; do xargs rm -rf < $l; done
  • Normally you would strip debug information by running 'ninja -j4 install/strip', however an upstream bug means it might not be safe to do this when using BOLT. See llvm issue 56738.