Commit fcacd8ce authored by Craig Scott's avatar Craig Scott

Help: Improve readability and fix inaccuracies in unity build docs

parent 929d7a45
SKIP_UNITY_BUILD_INCLUSION
--------------------------
Is this source file skipped by :prop_tgt:`UNITY_BUILD` feature.
Setting this property to true ensures the source file will be skipped by
unity builds when its associated target has its :prop_tgt:`UNITY_BUILD`
property set to true. The source file will instead be compiled on its own
in the same way as it would with unity builds disabled.
This property helps with "ODR (One definition rule)" problems
that one would run into when using an :prop_tgt:`UNITY_BUILD`.
This property helps with "ODR (One definition rule)" problems where combining
a particular source file with others might lead to build errors or other
unintended side effects.
UNITY_BUILD
-----------
Should the target source files be processed into batches for
faster compilation. This feature is known as "Unity build",
or "Jumbo build".
The ``C`` and ``CXX`` source files are grouped separately.
This property is initialized by the value of the
:variable:`CMAKE_UNITY_BUILD` variable if it is set when
a target is created.
.. note::
It's not recommended to directly set :prop_tgt:`UNITY_BUILD`
to ``ON``, but to instead set :variable:`CMAKE_UNITY_BUILD` from
the command line. However, it IS recommended to set
:prop_tgt:`UNITY_BUILD` to ``OFF`` if you need to ensure that a
target doesn't get a unity build.
The batch size can be specified by setting
:prop_tgt:`UNITY_BUILD_BATCH_SIZE`.
The batching of source files is done by adding new sources files
which will ``#include`` the source files, and exclude them from
building by setting :prop_sf:`HEADER_FILE_ONLY` to ``ON``.
When this property is set to true, the target source files will be combined
into batches for faster compilation. This is done by creating a (set of)
unity sources which ``#include`` the original sources, then compiling these
unity sources instead of the originals. This is known as a *Unity* or *Jumbo*
build. The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper
limit on how many sources can be combined per unity source file.
Unity builds are not currently supported for all languages. CMake version
|release| supports combining ``C`` and ``CXX`` source files. For targets that
mix source files from more than one language, CMake will separate the languages
such that each generated unity source file only contains sources for a single
language.
This property is initialized by the value of the :variable:`CMAKE_UNITY_BUILD`
variable when a target is created.
.. note::
Marking the original sources with :prop_sf:`HEADER_FILE_ONLY`
is considered an implementation detail that may change in the
future because it does not work well in combination with
the :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` variable.
Projects should not directly set the ``UNITY_BUILD`` property or its
associated :variable:`CMAKE_UNITY_BUILD` variable to true. Depending
on the capabilities of the build machine and compiler used, it might or
might not be appropriate to enable unity builds. Therefore, this feature
should be under developer control, which would normally be through the
developer choosing whether or not to set the :variable:`CMAKE_UNITY_BUILD`
variable on the :manual:`cmake(1)` command line or some other equivalent
method. However, it IS recommended to set the ``UNITY_BUILD`` target
property to false if it is known that enabling unity builds for the
target can lead to problems.
ODR (One definition rule) errors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since multiple source files are included into one source file,
it can lead to ODR errors. This section contains properties
which help fixing these errors.
The source files marked by :prop_sf:`SKIP_UNITY_BUILD_INCLUSION`
will be skipped from unity build.
The source files that have :prop_sf:`COMPILE_OPTIONS`,
:prop_sf:`COMPILE_DEFINITIONS`, :prop_sf:`COMPILE_FLAGS`, or
:prop_sf:`INCLUDE_DIRECTORIES` will also be skipped.
With the :prop_tgt:`UNITY_BUILD_CODE_BEFORE_INCLUDE` and
:prop_tgt:`UNITY_BUILD_CODE_AFTER_INCLUDE` one can specify code
to be injected in the unity source file before and after every
``#include`` statement.
.. note::
The order of source files defined in the ``CMakeLists.txt`` will
be preserved into the generated unity source files. This can
be used to manually enforce a specific grouping based on the
:prop_tgt:`UNITY_BUILD_BATCH_SIZE` target property.
When multiple source files are included into one source file, as is done
for unity builds, it can potentially lead to ODR errors. CMake provides
a number of measures to help address such problems:
* Any source file that has a non-empty :prop_sf:`COMPILE_OPTIONS`,
:prop_sf:`COMPILE_DEFINITIONS`, :prop_sf:`COMPILE_FLAGS`, or
:prop_sf:`INCLUDE_DIRECTORIES` source property will not be combined
into a unity source.
* Projects can prevent an individual source file from being combined into
a unity source by setting its :prop_sf:`SKIP_UNITY_BUILD_INCLUSION`
source property to true. This can be a more effective way to prevent
problems with specific files than disabling unity builds for an entire
target.
* The :prop_tgt:`UNITY_BUILD_CODE_BEFORE_INCLUDE` and
:prop_tgt:`UNITY_BUILD_CODE_AFTER_INCLUDE` target properties can be used
to inject code into the unity source files before and after every
``#include`` statement.
* The order of source files added to the target via commands like
:command:`add_library`, :command:`add_executable` or
:command:`target_sources` will be preserved in the generated unity source
files. This can be used to manually enforce a specific grouping based on
the :prop_tgt:`UNITY_BUILD_BATCH_SIZE` target property.
UNITY_BUILD_BATCH_SIZE
----------------------
Specifies how many source code files will be included into a
:prop_tgt:`UNITY_BUILD` source file.
Specifies the maximum number of source files that can be combined into any one
unity source file when unity builds are enabled by the :prop_tgt:`UNITY_BUILD`
target property. The original source files will be distributed across as many
unity source files as necessary to honor this limit.
If the property is not set, CMake will use the value provided
by :variable:`CMAKE_UNITY_BUILD_BATCH_SIZE`.
The initial value for this property is taken from the
:variable:`CMAKE_UNITY_BUILD_BATCH_SIZE` variable when the target is created.
If that variable has not been set, the initial value will be 8.
By setting it to value `0` the generated unity source file will
contain all the source files that would otherwise be split
into multiple batches. It is not recommended to do so, since it
would affect performance.
The batch size needs to be selected carefully. If set too high, the size of
the combined source files could result in the compiler using excessive memory
or hitting other similar limits. In extreme cases, this can even result in
build failure. On the other hand, if the batch size is too low, there will be
little gain in build performance.
Although strongly discouraged, the batch size may be set to a value of 0 to
combine all the sources for the target into a single unity file, regardless of
how many sources are involved. This runs the risk of creating an excessively
large unity source file and negatively impacting the build performance, so
a value of 0 is not generally recommended.
......@@ -2,7 +2,18 @@ UNITY_BUILD_CODE_AFTER_INCLUDE
------------------------------
Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
feature just after the `#include` statement of the targeted source
files.
feature just after every ``#include`` statement in the generated unity
source files. For example:
This could be something like `#undef NOMINMAX`.
.. code-block:: cmake
set(after [[
#if defined(NOMINMAX)
#undef NOMINMAX
#endif
]])
set_target_properties(myTarget PROPERTIES
UNITY_BUILD_CODE_AFTER_INCLUDE "${after}"
)
See also :prop_tgt:`UNITY_BUILD_CODE_BEFORE_INCLUDE`.
......@@ -2,7 +2,18 @@ UNITY_BUILD_CODE_BEFORE_INCLUDE
-------------------------------
Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
feature just before the `#include` statement of the targeted source
files.
feature just before every ``#include`` statement in the generated unity
source files. For example:
This could be something like `#define NOMINMAX`.
.. code-block:: cmake
set(before [[
#if !defined(NOMINMAX)
#define NOMINMAX
#endif
]])
set_target_properties(myTarget PROPERTIES
UNITY_BUILD_CODE_BEFORE_INCLUDE "${before}"
)
See also :prop_tgt:`UNITY_BUILD_CODE_AFTER_INCLUDE`.
CMAKE_UNITY_BUILD
-----------------
Initializes the :prop_tgt:`UNITY_BUILD` target property on targets
as they are created. Set to ``ON`` to batch compilation of multiple
sources within each target. This feature is known as "Unity build",
or "Jumbo build". By default this variable is not set and so does
not enable unity builds on targets.
This variable is used to initialize the :prop_tgt:`UNITY_BUILD`
property of targets when they are created. Setting it to true
enables batch compilation of multiple sources within each target.
This feature is known as a *Unity* or *Jumbo* build.
Projects should not set this variable, it is intended as a developer
control to be set on the :manual:`cmake(1)` command line or other
equivalent methods. The developer must have the ability to enable or
disable unity builds according to the capabilities of their own machine
and compiler.
By default, this variable is not set, which will result in unity builds
being disabled.
.. note::
This option currently does not work well in combination with
......
CMAKE_UNITY_BUILD_BATCH_SIZE
----------------------------
Default value for :prop_tgt:`UNITY_BUILD_BATCH_SIZE` of targets.
By default ``CMAKE_UNITY_BUILD_BATCH_SIZE`` is set to ``8``.
This variable is used to initialize the :prop_tgt:`UNITY_BUILD_BATCH_SIZE`
property of targets when they are created. It specifies the default upper
limit on the number of source files that may be combined in any one unity
source file when unity builds are enabled for a target.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment