=============================
Advanced Build Configurations
=============================
.. contents::
:local:
Introduction
============
`CMake `_ is a cross-platform build-generator tool. CMake
does not build the project, it generates the files needed by your build tool
(GNU make, Visual Studio, etc.) for building LLVM.
If **you are a new contributor**, please start with the :doc:`GettingStarted` or
:doc:`CMake` pages. This page is intended for users doing more complex builds.
Many of the examples below are written assuming specific CMake Generators.
Unless otherwise explicitly called out these commands should work with any CMake
generator.
Bootstrap Builds
================
The Clang CMake build system supports bootstrap (aka multi-stage) builds. At a
high level a multi-stage build is a chain of builds that pass data from one
stage into the next. The most common and simple version of this is a traditional
bootstrap build.
In a simple two-stage bootstrap build, we build clang using the system compiler,
then use that just-built clang to build clang again. In CMake this simplest form
of a bootstrap build can be configured with a single option,
CLANG_ENABLE_BOOTSTRAP.
.. code-block:: console
$ cmake -G Ninja -DCLANG_ENABLE_BOOTSTRAP=On
$ ninja stage2
This command itself isn't terribly useful because it assumes default
configurations for each stage. The next series of examples utilize CMake cache
scripts to provide more complex options.
By default, only a few CMake options will be passed between stages.
The list, called _BOOTSTRAP_DEFAULT_PASSTHROUGH, is defined in clang/CMakeLists.txt.
To force the passing of the variables between stages, use the -DCLANG_BOOTSTRAP_PASSTHROUGH
CMake option, each variable separated by a ";". As example:
.. code-block:: console
$ cmake -G Ninja -DCLANG_ENABLE_BOOTSTRAP=On -DCLANG_BOOTSTRAP_PASSTHROUGH="CMAKE_INSTALL_PREFIX;CMAKE_VERBOSE_MAKEFILE"
$ ninja stage2
The clang build system refers to builds as stages. A stage1 build is a standard
build using the compiler installed on the host, and a stage2 build is built
using the stage1 compiler. This nomenclature holds up to more stages too. In
general a stage*n* build is built using the output from stage*n-1*.
Apple Clang Builds (A More Complex Bootstrap)
=============================================
Apple's Clang builds are a slightly more complicated example of the simple
bootstrapping scenario. Apple Clang is built using a 2-stage build.
The stage1 compiler is a host-only compiler with some options set. The stage1
compiler is a balance of optimization vs build time because it is a throwaway.
The stage2 compiler is the fully optimized compiler intended to ship to users.
Setting up these compilers requires a lot of options. To simplify the
configuration the Apple Clang build settings are contained in CMake Cache files.
You can build an Apple Clang compiler using the following commands:
.. code-block:: console
$ cmake -G Ninja -C /cmake/caches/Apple-stage1.cmake
$ ninja stage2-distribution
This CMake invocation configures the stage1 host compiler, and sets
CLANG_BOOTSTRAP_CMAKE_ARGS to pass the Apple-stage2.cmake cache script to the
stage2 configuration step.
When you build the stage2-distribution target it builds the minimal stage1
compiler and required tools, then configures and builds the stage2 compiler
based on the settings in Apple-stage2.cmake.
This pattern of using cache scripts to set complex settings, and specifically to
make later stage builds include cache scripts is common in our more advanced
build configurations.
Multi-stage PGO
===============
Profile-Guided Optimizations (PGO) is a really great way to optimize the code
clang generates. Our multi-stage PGO builds are a workflow for generating PGO
profiles that can be used to optimize clang.
At a high level, the way PGO works is that you build an instrumented compiler,
then you run the instrumented compiler against sample source files. While the
instrumented compiler runs it will output a bunch of files containing
performance counters (.profraw files). After generating all the profraw files
you use llvm-profdata to merge the files into a single profdata file that you
can feed into the LLVM_PROFDATA_FILE option.
Our PGO.cmake cache script automates that whole process. You can use it by
running:
.. code-block:: console
$ cmake -G Ninja -C /cmake/caches/PGO.cmake