diff --git a/llvm/docs/BuildingADistribution.rst b/llvm/docs/BuildingADistribution.rst new file mode 100644 --- /dev/null +++ b/llvm/docs/BuildingADistribution.rst @@ -0,0 +1,206 @@ +=============================== +Building a Distribution of LLVM +=============================== + +.. contents:: + :local: + +Introduction +============ + +This document is geared toward people who want to build and package LLVM and any +combination of LLVM sub-project tools for distribution. This document covers +useful features of the LLVM build system as well as best practices and general +information about packaging LLVM. + +If you are new to CMake you may find the :doc:`CMake` or :doc:`CMakePrimer` +documentation useful. Some of the things covered in this document are the inner +workings of the builds described in the :doc:`AdvancedBuilds` document. + +General Distribution Guidance +============================= + +When building a distribution of a compiler it is generally advised to perform a +bootstrap build of the compiler. That means building a "stage 1" compiler with +your host toolchain, then building the "stage 2" compiler using the "stage 1" +compiler. This is done so that the compiler you distribute benefits from all the +bug fixes, performance optimizations and general improvements provided by the +new compiler. + +In deciding how to build your distribution there are a few trade-offs that you +will need to evaluate. The big two are: + +#. Compile time of the distribution against performance of the built compiler + +#. Binary size of the distribution against performance of the built compiler + +The guidance for maximizing performance of the generated compiler is to use LTO, +PGO, and statically link everything. This will result in an overall larger +distribution, and it will take longer to generate, but it provides the most +opportunity for the compiler to optimize. + +The guidance for minimizing distribution size is to dynamically link LLVM and +Clang libraries into the tools to reduce code duplication. This will come at a +substantial performance penalty to the generated binary both because it reduces +optimization opportunity, and because dynamic linking requires resolving symbols +at process launch time, which can be very slow for C++ code. + +.. _shared_libs: + +.. warning:: + One very important note: Distributions should never be built using the + *BUILD_SHARED_LIBS* CMake option. That option exists for optimizing developer + workflow only. Due to design and implementation decisions in LLVM relies on + global data which can end up being duplicated across shared libraries + resulting in bugs. As such this is not a safe way to distribute LLVM or + LLVM-based tools. + +The simplest example of building a distribution with reasonable performance is +captured in the DistributionExample CMake cache file located at +clang/cmake/caches/DistributionExample.cmake. The following command will perform +and install the distribution build: + +.. code-block:: console + + $ cmake -G Ninja -C /cmake/caches/DistributionExample.cmake + $ ninja stage2-distribution + $ ninja stage2-install-distribution + +Difference between ``install`` and ``install-distribution`` +----------------------------------------------------------- + +One subtle but important thing to note is the difference between the ``install`` +and ``install-distribution`` targets. The ``install`` target is expected to +install every part of LLVM that your build is configured to generate except the +LLVM testing tools. Alternatively the ``install-distribution`` target, which is +recommended for building distributions, only installs specific parts of LLVM as +specified at configuration time by *LLVM_DISTRIBUTION_COMPONENTS*. + +Additionally the ``install`` target can be configured to install the LLVM +testing tools as well by setting *LLVM_INSTALL_TOOLCHAIN_ONLY* to ``Off``. This +is not recommended for distributions as many of the LLVM tools are intended for +development and testing of LLVM, not for distribution. + +When building with *LLVM_DISTRIBUTION_COMPONENTS* the build system also +generates a ``distribution`` target which builds all the components specified in +the list. This is a convenience build target to allow building just the +distributed pieces without needing to build all configured targets. + +Special Notes for Library-only Distributions +-------------------------------------------- + +One of the most powerful features of LLVM is its library-first design mentality +and the way you can compose a wide variety of tools using different portions of +LLVM. Even in this situation using *BUILD_SHARED_LIBS* is not supported. If you +want to distribute LLVM as a shared library for use in a tool, the recommended +method is using *LLVM_BUILD_LLVM_DYLIB*, and you can use *LLVM_DYLIB_COMPONENTS* +to configure which LLVM components are part of libLLVM. + +Options for Optimizing LLVM +=========================== + +There are four main build optimizations that our CMake build system supports. +When performing a bootstrap build it is not beneficial to do anything other than +setting *CMAKE_BUILD_TYPE* to ``Release`` for the stage-1 compiler. This is +because the more intensive optimizations are expensive to perform and the +stage-1 compiler is thrown away. All of the further options described should be +set on the stage-2 compiler either using a CMake cache file, or by prefixing the +option with *BOOTSTRAP_*. + +The first and simplest to use is the compiler optimization level. Using CMake +the simplest way to control the optimization level is by setting the +*CMAKE_BUILD_TYPE* option. The main values of interest are ``Release`` or +``RelWithDebInfo``. By default the ``Release`` option uses the ``-O3`` +optimization level, and ``RelWithDebInfo`` uses ``-O2``. If you want to generate +debug information and use ``-O3`` you can override the +*CMAKE__FLAGS_RELWITHDEBINFO* option for C and CXX. +DistributionExample.cmake does this. + +Another easy to use option is Link-Time-Optimization. You can set the +*LLVM_ENABLE_LTO* option on your stage-2 build to ``Thin`` or ``Full`` to enable +building LLVM with LTO. These options will significantly increase link time of +the binaries in the distribution, but it will create much faster binaries. This +option should not be used if your distribution includes static archives, as the +objects inside the archive will be LLVM bitcode, which is not portable. + +The :doc:`AdvancedBuilds` documentation describes the built-in tooling for +generating LLVM profiling information to drive Profile-Guided-Optimization. The +in-tree profiling tests are very limited, and generating the profile takes a +significant amount of time, however it can have a significant improvement in +the performance of the generated binaries. + +In addition to PGO profiling we also have limited support in-tree for generating +linker order files. These files provide the linker with a suggested ordering for +functions in the final binary layout. This can measurably speed up clang by +physically grouping functions that are called temporally close to eachother. The +current tooling is only available on Darwin systems with ``dtrace(1)``. It is +worth noting that dtrace is non-deterministic, and so the order file generation +using dtrace is also non-deterministic. + +Options for Reducing Size +========================= + +.. warning:: + Any steps taken to reduce the binary size will come at a cost of runtime + performance in the generated binaries. + +The simplest and least significant way to reduce binary size is to set the +*CMAKE_BUILD_TYPE* variable to ``MinSizeRel``, which will set the compiler +optimization level to ``-Os`` which optimizes for binary size. This will have +both the least benefit to size and the least impact on performance. + +The most impactful way to reduce binary size is to dynamically link LLVM into +all the tools. This reduces code size by decreasing duplication of common code +between the LLVM-based tools. This can be done by setting the following two +CMake options to ``On``: *LLVM_BUILD_LLVM_DYLIB* and *LLVM_LINK_LLVM_DYLIB*. + +.. warning:: + Distributions should never be built using the *BUILD_SHARED_LIBS* CMake + option. (:ref:`See the warning above for more explanation `.). + +Relevant CMake Options +====================== + +This section provides documentation of the CMake options that are intended to +help construct distributions. This is not an exhaustive list, and many +additional options are documented in the :doc:`CMake` page. Some key options +that are already documented include: *LLVM_TARGETS_TO_BUILD*, +*LLVM_ENABLE_PROJECTS*, *LLVM_BUILD_LLVM_DYLIB*, and *LLVM_LINK_LLVM_DYLIB*. + +**LLVM_ENABLE_RUNTIMES**:STRING + When building a distribution that includes LLVM runtime projects (i.e. libcxx, + compiler-rt, libcxxabi, libunwind...), it is important to build those projects + with the just-built compiler. + +**LLVM_DISTRIBUTION_COMPONENTS**:STRING + This variable can be set to a semi-colon separated list of LLVM build system + components to install. All LLVM-based tools are components, as well as most + of the libraries and runtimes. Component names match the names of the build + system targets. + +**LLVM_RUNTIME_DISTRIBUTION_COMPONENTS**:STRING + This variable can be set to a semi-colon separated list of runtime library + components. This is used in conjunction with *LLVM_ENABLE_RUNTIMES* to specify + components of runtime libraries that you want to include in your distribution. + Just like with *LLVM_DISTRIBUTION_COMPONENTS*, component names match the names + of the build system targets. + +**LLVM_DYLIB_COMPONENTS**:STRING + This variable can be set to a semi-colon separated name of LLVM library + components. LLVM library components are either library names with the LLVM + prefix removed (i.e. Support, Demangle...), LLVM target names, or special + purpose component names. The special purpose component names are: + + #. ``all`` - All LLVM available component libraries + #. ``Native`` - The LLVM target for the Native system + #. ``AllTargetsAsmPrinters`` - All the included target ASM printers libraries + #. ``AllTargetsAsmParsers`` - All the included target ASM parsers libraries + #. ``AllTargetsDescs`` - All the included target descriptions libraries + #. ``AllTargetsDisassemblers`` - All the included target dissassemblers libraries + #. ``AllTargetsInfos`` - All the included target info libraries + +**LLVM_INSTALL_TOOLCHAIN_ONLY**:BOOL + This option defaults to ``On``, when set to ``Off`` it includes many of the + LLVM development and testing tools in the default ``install`` target. This is + not recommended for distributions as many of the LLVM tools are only intended + for development and testing use. diff --git a/llvm/docs/index.rst b/llvm/docs/index.rst --- a/llvm/docs/index.rst +++ b/llvm/docs/index.rst @@ -94,6 +94,7 @@ ReportingGuide Benchmarking Docker + BuildingADistribution :doc:`GettingStarted` Discusses how to get up and running quickly with the LLVM infrastructure. @@ -176,6 +177,10 @@ :doc:`Docker` A reference for using Dockerfiles provided with LLVM. +:doc:`BuildingADistribution` + A best-practices guide for using LLVM's CMake build system to package and + distribute LLVM-based tools. + Programming Documentation =========================