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.