diff options
Diffstat (limited to 'dep/cotire/MANUAL.md')
-rw-r--r-- | dep/cotire/MANUAL.md | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/dep/cotire/MANUAL.md b/dep/cotire/MANUAL.md new file mode 100644 index 00000000000..af1f1fed03a --- /dev/null +++ b/dep/cotire/MANUAL.md @@ -0,0 +1,795 @@ +cotire manual +============= + +Cotire (compile time reducer) is a CMake module that speeds up the build process of CMake based +build systems by fully automating techniques as [precompiled header][pch] usage and +[single compilation unit][scu] builds for C and C++. + +motivation +---------- + +Cotire was born out of a dissatisfaction with the existing CMake solutions for adding +[precompiled header][1260] support and unity build support to CMake based build systems. +The design of cotire tries to adhere to the following principles: + +#### as automatic as possible + +[Precompiled header][pch] and [unity builds][scu] are good ideas in principle, but in reality +they do not work if the burden of maintaining the required additional source files (a +[prefix header][pfh] and a unity source file) is put on the developer. A modern build system +like CMake provides enough context information to have the build system generate and update +these files automatically. + +#### non-intrusive + +The configuration of precompiled headers usage and single computation unit builds belongs to the +build system and not in the source code. Nobody wants to litter one's source files with `hdrstop` +pragmas or be forced to add an include directive to every file. Source code should build properly +when a precompiled header isn't used and should build faster when a precompiled header is used. + +#### minimal interface + +Maintaining a build system over time is enough work and the CMake language may often get in your +way. Thus the solution should only add few public CMake functions. It should be easy to integrate +it into an existing CMake based build system and it should be just as easy to remove it again. + +#### lazy file creation + +The additional source files needed for precompiled header support and unity build support should +only be created when they are required for the compilation of a target. Thus the solution should +not create these files upon configuring the project, but should set up custom build commands for +the creation of these files that only kick in when the files are required to exist by the build +process. + +#### cross-platform + +C/C++ Compilers and IDEs on different platforms vary widely in how the implement precompiled +header support. The solution should hide these implementation details and present a uniform +interface to the developer on all supported platforms. + +cotire basic usage +------------------ + +Cotire consists of a single CMake module file, which can be easily added to an existing CMake +project. + +The file `CMake/cotire.cmake` needs to be copied to the module directory of a CMake project. In the +top-level `CMakeList.txt` file, the module directory needs to be added to the CMake module search +path: + + set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake") + +To use cotire in a CMake project, one adds the following include directive to the beginning of the +top-level `CMakeList.txt`: + + include(cotire) + +To speed the build process of a CMake library or executable target, the `cotire` function is +applied to a CMake target. From the example project that ships with cotire: + + add_executable(example main.cpp example.cpp log.cpp log.h example.h) + ... + cotire(example) + +Cotire looks at the properties of the target provided by CMake (e.g., target type, source files, +compile flags, preprocessor defines, include directories, ...) and modifies the target's build +process in the following way: + +1. cotire adds a custom build rule to produce a unity source file from the target's sources. +2. cotire adds a custom build rule to produce a prefix header file by tracking the header files + included by the target's sources. +3. cotire adds a custom build rule to produce a precompiled header from the prefix header. +4. cotire modifies the target's compile flags to make use of the generated precompiled header. +5. cotire adds a couple of new targets. + +For makefile based build systems, running `make help` in the terminal reveals the new targets: + + $ make help + ... + ... all_pch + ... all_unity + ... clean_cotire + ... example + ... example_pch + ... example_unity + +The `example_pch` target triggers the compilation of the precompiled header and as a side effect +the generation of the unity source and the prefix header. The target `clean_cotire` cleans up all +files generated by cotire. The `example_unity` target produces the same output as the original +`example` target, but does so by performing a unity build. The `all_pch` and `all_unity` serve as +pool targets for all cotired project targets. + +By default, the `example_unity` target inherits all build settings from the original target +`example` including linked libraries and target dependencies. + +cotire generated files +---------------------- + +For a target that has been cotired, three files will be generated as part of the build process: + +### the unity source + +The unity source file is generated from the target by querying the target's `SOURCES` property. +It consists of preprocessor include directives for each of the target source files. The files +are included in the same order that is used in the CMake `add_executable` or `add_library` call. +Header files are omitted. + +This is a unity source generated for the example project under OS X: + + #ifdef __cplusplus + #include "/Users/sakra/Documents/cotire/src/main.cpp" + #include "/Users/sakra/Documents/cotire/src/example.cpp" + #include "/Users/sakra/Documents/cotire/src/log.cpp" + #endif + +The unity source file uses absolute paths to include the target's source file. The file is not +intended to be portable across different build folders or machines. It is an intermediate file +tied to the build folder that is automatically recreated by the build system if it is missing. + +For multi-core machines cotire can be configured to generate multiple unity file segments that +can be built in parallel by the chosen CMake generator (see below). + +### the prefix header + +The prefix header is produced from the unity source file by running the unity file through the +preprocessor and keeping track of each header file used (this is done by using option `-H` with +GCC / Clang and `/showIncludes` with Visual Studio C++). The path of each used header file is +compared against an exclude directory list and an include directory list to decide if the header +file should be added to the prefix header. + +By default the include directory list is empty and the exclude directory list is initialized to +`"${CMAKE_SOURCE_DIR};${CMAKE_BINARY_DIR}"`. This default setting guarantees that project headers +which are likely to be changed frequently are not added to the prefix header. + +Upon generation of the prefix header cotire makes sure that target compile options, include path +settings and preprocessor defines (e.g., `NDEBUG`) that affect the outcome of the preprocessor +are correctly set up. + +Generating the prefix header from the unity source is much faster than running each individual +target source file through the preprocessor, because the coalesced unity source will make the +preprocessor process most header files only once. + +This is a prefix header produced for the example project with Visual Studio 2013 under Windows 7: + + #pragma warning(push, 0) + #ifdef __cplusplus + #include "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\string" + #include "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\algorithm" + #include "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\iostream" + #endif + #pragma warning(pop) + +Generating the prefix file under Ubuntu 12.04 with GCC 4.6 yields the following result: + + #pragma GCC system_header + #ifdef __cplusplus + #include "/usr/include/c++/4.6/string" + #include "/usr/include/c++/4.6/algorithm" + #include "/usr/include/c++/4.6/iterator" + #include "/usr/include/c++/4.6/iostream" + #endif + +Using Xcode 5.1 under OS X 10.9, this is the resulting prefix header: + + #pragma clang system_header + #ifdef __cplusplus + #include "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/string" + #include "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/iostream" + #endif + +Besides include directives, cotire also adds compiler specific pragmas to the generated prefix +header to suppress compiler warnings upon inclusion. + +Cotire attempts to produce a minimal list of header files by omitting header files indirectly +included by a header that is already part of the prefix header. Header files with nonstandard +file extensions like `.inl`, `.inc` of `.ipp` are omitted by default. + +The generated prefix file includes the selected header files by their absolute paths. This speeds +up the precompiling of the prefix header because the compiler does not have to search for header +files in include directories again. + +The prefix header is tailored to the CMake target that it is generated for. It is tied to the +compiler environment of the local machine and is not portable across different compilers or +machines. It is automatically recreated by the build system if it goes missing. + +The generated prefix header can be applied to a different target added in the same source directory +(see below). + +Optionally, cotire will also create a prefix source file that consists of a single include directive +for the prefix header. This file is needed for pre-compiling the prefix header with Clang or GCC +to make both compilers handle the `system_header` pragma correctly. + +### the precompiled header + +The precompiled header is produced from the generated prefix header by using the proprietary +precompiling mechanism depending on the compiler used. For GCC and Clang cotire sets up a custom +build rule and generates the precompiled header as described in the documentation for +[GCC][gcc_pch] and [Clang][clang_pch]. Cotire then modifies the `COMPILE_FLAGS` property of the +target to force the inclusion of the prefix header. + +Visual Studio C++ and Intel C++ use a [different approach][msvc_pch] to pre-compiling. Both +compilers require a host source file to generate the precompiled header as a side effect of +producing an object file. Cotire modifies the `COMPILE_FLAGS` of the first target source file to +[generate][msvc_pch_create] the precompiled header and then modifies the `COMPILE_FLAGS` of the +remaining target source files to [include][msvc_pch_use] the generated precompiled header. + +For Xcode projects generated with CMake, cotire completely hands off the pre-compilation of +the prefix header and the inclusion of the precompiled header to the IDE. Cotire attaches a +pre-build action to the target which generates the unity source file and the prefix header. +Cotire then modifies Xcode attributes of the generated Xcode project to have Xcode precompile the +the generated prefix header with the Xcode build steps `ProcessPCH` for C sources and +`ProcessPCH++` for C++ sources. + +For precompiled headers creation flags must match use flags exactly. Cotire uses the same flags, +include directories and preprocessor defines that are used for the compilation of source files +for the generation of the precompiled header. Thus the resulting precompiled header binary is only +usable for the target and cannot be re-used for a different CMake target. + +cotire advanced usage +--------------------- + +### applying cotire to multiple targets at the same time + +The `cotire` function can be applied to multiple targets added in the same source directory in one +call: + + add_library(libA STATIC ...) + add_library(libB SHARED ...) + add_executable(example ...) + ... + cotire(example libA libB) + +### mixed-language targets + +Cotire is able to speed up the build process of mixed language targets, consisting of both C and +C++ sources. It generates a separate set of unity source files, prefix headers and precompiled +headers for both languages and modifies the `COMPILE_FLAGS` of each target source file to include +the correct precompiled header depending on the compilation language of the source file. + +### obtaining the names of the generated files and targets + +For a cotired target the target properties `COTIRE_<LANG>_UNITY_SOURCE`, +`COTIRE_<LANG>_PREFIX_HEADER`, `COTIRE_<LANG>_PRECOMPILED_HEADER` will be set to the paths of the +generated files (`<LANG>` can be set to `CXX` or `C`). The target property +`COTIRE_UNITY_TARGET_NAME` will be set to the name of the generated unity target: + + cotire(example) + ... + get_target_property(_unitySource example COTIRE_CXX_UNITY_SOURCE) + get_target_property(_prefixHeader example COTIRE_CXX_PREFIX_HEADER) + get_target_property(_precompiledHeader example COTIRE_CXX_PRECOMPILED_HEADER) + get_target_property(_unityTargetName example COTIRE_UNITY_TARGET_NAME) + +If a source file's `COMPILE_FLAGS` are modified by cotire, it sets the source file property +`COTIRE_TARGET` to the name of the target, that the source file's build command has been +altered for: + + cotire(example) + ... + get_source_file_property(_cotireTargetName "example.cpp" COTIRE_TARGET) + if (_cotireTargetName) + message(STATUS "example.cpp has been cotired for target ${_cotireTargetName}") + endif() + +### changing the name of the generated unity build target + +By default cotire uses the name of the the original target with the suffix `_unity` appended +for the name of the generated unity build target. To create the unity build target under a +different name, set the `COTIRE_UNITY_TARGET_NAME` property: + + add_executable(example_template main.cpp example.cpp log.cpp log.h example.h) + set_target_properties(example_template PROPERTIES COTIRE_UNITY_TARGET_NAME "example") + ... + cotire(example_template) + +Invoking the `example` target will then run the unity build. + +### restricting cotire to certain build configurations + +To restrict the cotire related modifications to the build process to certain build configurations, +the `CONFIGURATIONS` parameter can be added to the `cotire` call. + + cotire(example CONFIGURATIONS Release MinSizeRel) + +For single build type builds the selected configuration will be checked at configure time, for +multi-configuration builds the check will be done at build time. + +It is recommended to have at least one build configuration that does not make use of cotire to +ensure that the project builds properly without cotire. + +### disabling precompiled headers and unity builds + +If the target's build process should not be modified to make use of the generated precompiled +header, the target property `COTIRE_ENABLE_PRECOMPILED_HEADER` can be set to `FALSE`: + + set_target_properties(example PROPERTIES COTIRE_ENABLE_PRECOMPILED_HEADER FALSE) + cotire(example) + +If a unity build target should not be added by cotire, the target property +`COTIRE_ADD_UNITY_BUILD` can be set to `FALSE`: + + set_target_properties(example PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE) + cotire(example) + +The property `COTIRE_ADD_UNITY_BUILD` only affects the addition of the unity build target. Custom +build rules for the generation of the unity source file will always be set up, because the +unity source file is needed for the generation of the prefix header. + +Both properties default to `TRUE`. If both are set to `FALSE`, cotire will only set up custom build +rules for the generation of the unity source and the prefix header. + +The properties `COTIRE_ENABLE_PRECOMPILED_HEADER` and `COTIRE_ADD_UNITY_BUILD` can also be set on +directories. A target inherits the property value from its enclosing directory. + +### disabling precompiled headers for small targets + +The cache variable `COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES` can be set to the minimum number of +source files required to enable the use of a precompiled header. It defaults to 3. To override the +default, run `cmake` with the following options: + + $ cmake -D COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES=5 <path-to-source> + +### using a manually maintained prefix header instead of the automatically generated one + +cotire can be configured to use an existing manually maintained prefix header (e.g., Visual Studio +projects often use a prefix header named `stdafx.h`) instead of the automatically generated one. +Set the target property `COTIRE_CXX_PREFIX_HEADER_INIT` to the path of the existing prefix header +file. The path is interpreted relative to the target source directory: + + set_target_properties(example PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "stdafx.h") + cotire(example) + +If the prefix header `stdafx.h` needs an accompanying source file (e.g., `stdafx.cpp`) in order +to be precompiled properly, that source file needs to be the first one on the list of source +files in the target's `add_executable` or `add_library` call. + +The property `COTIRE_CXX_PREFIX_HEADER_INIT` can also be set to a list of header files which will +then make up the contents of the generated prefix header. + +A manually maintained prefix header will always be applied to the corresponding target, +even if the target contains too few sources to enable the use of a precompiled header. + +### using a generated prefix header for multiple targets + +A prefix header that is generated for a cotired target can be applied to a different target +added in the same source directory: + + cotire(example) + get_target_property(_prefixHeader example COTIRE_CXX_PREFIX_HEADER) + ... + set_target_properties(other_target PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${_prefixHeader}") + cotire(other_target) + +The compilation of either target will trigger the generation of the prefix header. + +### configuring the generation of the prefix header + +There are multiple target properties which affect the generation of the prefix header: + +* `COTIRE_PREFIX_HEADER_IGNORE_PATH` can be set to a semicolon separated list of directories. If a +header file is found in one of these directories or sub-directories, it will be excluded from the +generated prefix header. + +* `COTIRE_PREFIX_HEADER_INCLUDE_PATH` can be set to a semicolon separated list of directories. If +a header file is included from one of these directories or sub-directories, it will be included +in the generated prefix header. + +If a header file is matched by both `COTIRE_PREFIX_HEADER_IGNORE_PATH` and +`COTIRE_PREFIX_HEADER_INCLUDE_PATH`, the option which yields the closer relative path match wins. +For example, if third-party libraries are part of the source tree in a directory called `Libs`, +the following setting will make cotire select header files from the third-party directory, but +ignore other project related headers in `CMAKE_SOURCE_DIR`: + + set_target_properties(example PROPERTIES + COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}" + COTIRE_PREFIX_HEADER_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/Libs") + +The properties `COTIRE_PREFIX_HEADER_IGNORE_PATH` and `COTIRE_PREFIX_HEADER_INCLUDE_PATH` can +also be set on directories. + +The following cache variables also affect the selection of prefix headers: + +* Directory paths in `COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH` will be added to the list of +ignored directories when the prefix header file is created. + +* `COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS` can be used to ignore header files by file +extension. It defaults to the CMake list `inc;inl;ipp`. + +During development, changes to the project source files may affect the list of header files that +should be selected for inclusion in the prefix header (e.g., a standard include may be added or +removed from a target source file). Cotire does not automatically recreate the prefix header, +when a target source file is changed, because this would always trigger a re-compilation of the +precompiled header and would result in a rebuild of the whole target. To make the prefix header +creation dependent on changes to certain target source files, the source file property +`COTIRE_DEPENDENCY` can be set to `TRUE` for those files: + + set_property (SOURCE "example.cpp" PROPERTY COTIRE_DEPENDENCY "TRUE") + +### fixing linkage issues + +When a C++ program uses `extern "C"` on a system header file, cotire will not be able to detect +that the include file needs C linkage and will include the file with C++ linkage in the generated +prefix header instead. For example, the C interface to BLAS `cblas.h` usually has to be included +as `extern "C"` in a C++ program: + + extern "C" { + #include <cblas.h> + } + +The presence of `extern "C"` includes will prevent cotired targets from being linked successfully +because of unresolved function references using the wrong linkage. To work around the problem, +the property `COTIRE_PREFIX_HEADER_IGNORE_PATH` can also include the full path of header files +besides directories. Here is an example: + + set_property(DIRECTORY + PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH + "${ATLAS_INCLUDE_DIR}/cblas.h" + "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") + +That way `cblas.h` will not be included in the generated prefix header and will not cause problems +upon linking. + +### using a manually maintained unity source instead of the automatically generated one + +Cotire can be configured to use an existing manually maintained unity source file instead of the +automatically generated one. Set the target property `COTIRE_CXX_UNITY_SOURCE_INIT` to the path +of the existing unity source file. Its path is interpreted relative to the target source directory: + + set_target_properties(example PROPERTIES COTIRE_CXX_UNITY_SOURCE_INIT "example-all.cpp") + cotire(example) + +The property can also be set to a list of source files which will then make up the contents of +the generated unity source file. + +### configuring the generation of the unity source + +By default cotire adds all target source files to the generated unity source. In most cases a +unity build will not work out of the box, because unity builds [break][EoUB] the use of some C +and C++ language features. Unity build problems can be tackled in the following way: + +* Change the order of the source files in the `add_executable` or `add_library` calls. +Problematic source files should be moved towards the end. + +* Set the source file property `COTIRE_EXCLUDED` on problematic source files. The source file +will not be included in the unity source file and will be compiled separately when the unity build +is performed. + +* `COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS` can be used to exclude source files by file extension +from inclusion in the generated unity source. It defaults to the CMake list `m;mm`. + +* If the unity source file is too large and the compilation process runs into a compiler limit, +the target property `COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES` can be set. If the target +contains more than that number of source files, cotire will create multiple unity source files +for it. Each unity source file is compiled separately when the unity build is performed. +The property is initialized by value of the cache variable +`COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES`. + +* Another way to break up a large unity source file is to set the source file property +`COTIRE_START_NEW_UNITY_SOURCE` to `TRUE` on selected target source files. If cotire encounters +this property, it will complete the current unity file and start a new one. The new unity source +file will include the source file as the first one. This property essentially works as a separator +for unity source files. + +### optimizing the build process for multiple processor cores + +To make use of all the machine's CPU cores for the unity compilation of a target, the target +property `COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES` can be set to the string `-j`. Cotire +will then create as many unity file segments as there are CPU cores on the machine. Because +the unity file segments do not depend on each other, a multi-core aware build process can compile +the file segments in parallel. + +To explicitly specify the number of cores, append the number after `-j`, e.g. `-j 4` or `-j4`. + +For CMake generators that are multi-core aware by default (i.e., Visual Studio, JOM, Ninja), cotire +will automatically initialize the property to `-j`. For makefile based generators, this has to be +done explicitly by setting the cache variable `COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES`, i.e.: + + $ cmake -D COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES=-j4 <path-to-source> + $ make -j 4 + +### fixing macro definition clashes + +Many unity build problems stem from macro definitions leaking into other target source files, +where they may conflict with other definitions of the same name. Cotire adds the properties +`COTIRE_UNITY_SOURCE_PRE_UNDEFS` and `COTIRE_UNITY_SOURCE_POST_UNDEFS` to fix macro definition +clashes. + +As an example, if these properties are set on a source file of the example project: + + set_source_files_properties (example.cpp PROPERTIES + COTIRE_UNITY_SOURCE_PRE_UNDEFS "max;min" + COTIRE_UNITY_SOURCE_POST_UNDEFS "DEBUG_TYPE") + +This will make cotire add undefs to the generated unity source file. + + #ifdef __cplusplus + #include "/Users/sakra/Documents/cotire/src/main.cpp" + #undef min + #undef max + #include "/Users/sakra/Documents/cotire/src/example.cpp" + #undef DEBUG_TYPE + #include "/Users/sakra/Documents/cotire/src/log.cpp" + #endif + +The properties `COTIRE_UNITY_SOURCE_PRE_UNDEFS` and `COTIRE_UNITY_SOURCE_POST_UNDEFS` can also be +set on targets. Cotire will add `#undef` directives for each source file in the unity source then. + +### enabling verbose builds + +The cache variable `COTIRE_VERBOSE` can be set to `TRUE` to see all compile commands used when +generating the cotire related files. Cotire will also print the contents of the generated unity +source and the prefix header for verbose builds. `COTIRE_VERBOSE` defaults to `FALSE`. +When using a Makefile generator `COTIRE_VERBOSE` defaults to the value of the makefile variable +`VERBOSE` (i.e., `make VERBOSE=1`). + +### conditionally loading cotire + +To make a `CMakeLists.txt` robust against a missing `cotire.cmake` module, the following strategy +can be applied to using cotire: + + include(cotire OPTIONAL) + ... + add_executable(example main.cpp example.cpp log.cpp log.h example.h) + ... + if (COMMAND cotire) + cotire(example) + endif() + +The `include(cotire OPTIONAL)` will prevent CMake from raising an error if cotire cannot be +found. The actual calls to cotire need to be guarded by `if (COMMAND cotire)` blocks. + +### using cotire with compiler wrappers + +Cotire is compatible with CMake compiler wrappers. For example, the use of [ccache][ccch] may be +enabled in the following way upon configuring the project: + + $ export CC="/usr/local/bin/ccache /usr/bin/gcc" + $ export CXX="/usr/local/bin/ccache /usr/bin/g++" + $ export CCACHE_SLOPPINESS=pch_defines,time_macros + $ cmake .. + +Alternatively, for CMake 3.4 or later compiler wrappers can be enabled by pointing the CMake +variable `CMAKE_CXX_COMPILER_LAUNCHER` to the compiler wrapper executable upon configuring: + + $ cmake -D CMAKE_CXX_COMPILER_LAUNCHER=/usr/local/bin/ccache <path-to-source> + +Note that with ccache in order for precompiled headers to work properly, it is necessary to set +the environment variable `CCACHE_SLOPPINESS` to `pch_defines,time_macros`. Otherwise the build +process may abort with the following error message: + + fatal error: file 'example_CXX_prefix.hxx' has been modified since the precompiled header + 'example_CXX_prefix.hxx.gch' was built + +Also see the [ccache manual][ccch_pch]. + +### applying cotire to object library targets + +CMake 2.8.8 introduced a new type of library target called [object library][objlib]. An object +library is a convenience target that compiles multiple source files but does not create a linked +target library for them, e.g.: + + add_library(myLib OBJECT lib1.cpp lib2.cpp lib3.cpp) + add_executable(exeA $<TARGET_OBJECTS:myLib> mainA.cpp) + add_executable(exeB $<TARGET_OBJECTS:myLib> mainB.cpp) + +The `cotire` function can be applied to an object library target in a familiar fashion: + + add_library(myLib OBJECT lib1.cpp lib2.cpp lib3.cpp) + cotire(myLib) + # use unity object library for executables + add_executable(exeA $<TARGET_OBJECTS:myLib_unity> mainA.cpp) + add_executable(exeB $<TARGET_OBJECTS:myLib_unity> mainB.cpp) + +Because object library targets do not support `PRE_BUILD` actions, precompiled header usage cannot +be enabled for them for Xcode projects generated with CMake. Unity builds work as expected, though. + +### automatically setting up linked libraries in the unity target + +The setting of the target property `COTIRE_UNITY_LINK_LIBRARIES_INIT` controls the linking +strategy for the generated unit target. + +If this property is empty or set to `NONE`, the generated unity target's link libraries have to be +set up manually with subsequent `target_link_libraries` calls: + + set_target_properties(example PROPERTIES COTIRE_UNITY_LINK_LIBRARIES_INIT "NONE") + ... + cotire(example) + target_link_libraries(MyExecutable_unity ${MyExecutableLibraries}) + +If this property is set to `COPY`, the unity target's link libraries will be copied from the +original target. + +If this property is set to `COPY_UNITY`, the unity target's link libraries will be copied from the +original target but instead of copying a linked target verbatim, the target's corresponding unity +target will be preferred, provided one exists. This also applies to object libraries, which have +been added to the original target with a `TARGET_OBJECTS` generator expression. + +As of cotire 1.7.0, the default linking strategy for unit targets is `COPY_UNITY`. + +The property `COTIRE_UNITY_LINK_LIBRARIES_INIT` can also be set on directories. A target inherits +the property value from its enclosing directory. To make all targets in the project use the +`COPY` strategy, the directory property can be set in the outermost `CMakeList.txt` file: + + include(cotire) + ... + set_property(DIRECTORY PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY") + +### using cotire with Qt + +Cotire is compatible with both Qt4 and Qt5 projects that use CMake as build system. + +If a CMake target's `AUTOMOC` or `AUTOUIC` properties are set, the generated unity target will +automatically add a dependency to the implicitly generated `<targetname>_automoc` target to ensure +that `moc` and `uic` are run on the individual source files. + +The unity target will also include the implicitly generated `<targetname>_automoc.cpp` source file. + +The `Patches` directory contains examples for the [Qt4][fsedit_qt4] and [Qt5][fsedit_qt5] based +variants of the *FSEditor* sample Qt application. + +### installing files generated by unity targets + +Cotire cannot set up a `install_unity` target that mimics the `install` target automatically, +because CMake does not provide the necessary information about the existing install rules +programmatically. + +When using a Makefile generator, you can use the following workaround (thanks to peterhuene): + + $ make all_unity + $ make install/fast + +The `install/fast` does not trigger a build, but will use the binaries built by the `all_unity` +target. + +For other generators, set up an `install_unity` target manually. First set up install rules for +all unity targets, that mimic the install rules for the original targets: + + install(TARGETS example_unity RUNTIME DESTINATION "bin" OPTIONAL COMPONENT "unity") + +This installs the `example` executable built by the unity target to the `bin` folder. The install +rules for unity targets must use a custom install component. Then add a global `install_unity` +target that performs the installation of all unity targets: + + add_custom_target(install_unity + COMMAND ${CMAKE_COMMAND} -DCOMPONENT=unity -P cmake_install.cmake + COMMENT "Install the unity-built project..." + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + add_dependencies(unity_install example_unity) + +The global `install_unity` target must depend on all unity targets that should be installed. + +### customized inclusion of system headers + +If a system header ends up in a precompiled header, it is not possible to customize the inclusion +of that header in a source file through preprocessor defines. + +For example, under Windows one may want to include `Windows.h` with `NOMINMAX` defined to prevent +the definition of the `min` and `max` macros: + + #define NOMINMAX + #include <Windows.h> + +The dependency of `Windows.h` on the preprocessor define `NOMINMAX` will not be picked up by cotire +automatically upon adding `Windows.h` to the prefix header. To work around the problem, make the +dependency explicit by using `add_definitions` in the corresponding `CMakeLists.txt`: + + if (WIN32) + # prevent definition of min and max macros through inclusion of Windows.h + add_definitions("-DNOMINMAX") + endif() + +That way, the preprocessor define `NOMINMAX` will be picked up by cotire and applied to the +pre-compilation of the prefix header. + +### organize includes added to the prefix header + +Sometimes the order of the includes in the automatically generated prefix header may result in +compilation errors due to subtile header dependencies. + +To work around the problem, the target property `COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH` +can be set to a list of directories. Header files whose path matches one of these directories will +be inserted at the beginning of generated prefix header. Header files are sorted according to +the order of the directories in the property. Headers not matching one of these directories are +left untouched. + +The property `COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH` can also be set on directories. A target +inherits the property value from its enclosing directory. + +common pitfalls +--------------- + +### include the `cotire.cmake` module correctly + +If CMake issues the message `Unknown CMake command "cotire"`, double check that the cotire module +has been included correctly in your project. See the manual section "cotire basic usage". + +### do not modify a target's build related properties after applying cotire + +Cotire only considers build related settings of a target at the time of the `cotire` function call. +If target properties that control the build are changed after the call to the `cotire` function, +the build rules set up by cotire for the precompiled header and unity build may not work correctly. + +Don't do this: + + add_executable(example main.cpp example.cpp log.cpp log.h example.h) + cotire(example) + ... + set_target_properties(example PROPERTIES POSITION_INDEPENDENT_CODE ON) # affects build + + +### always apply cotire in the same source directory where a target has been added + +CMake targets are globally visible. Nevertheless, it is important that the `cotire` function is +called for a target in the exact same directory that creates the target with `add_library` or +`add_executable`. + +Don't do this: + + add_subdirectory(src) + ... + cotire(mytarget) # mytarget added in src directory + +Cotire may fail to inspect the target's source files correctly, if the target has been added in a +different directory and you may get odd messages about missing source files. + +known issues +------------ + +### Ninja compatibility + +Under Ninja indirect prefix header dependencies are ignored by the generated build system. Cotire +uses the `IMPLICIT_DEPENDS` option of `add_custom_command` to make the precompiled header depend +on header files indirectly included by the prefix header. The `IMPLICIT_DEPENDS` option is not +supported by CMake's Ninja generator. See [CMake issue][ninja_issue]. + +### using source files for multiple targets + +When the same set of source files is used for different targets (e.g., for producing a static +and a shared library variant from the same sources), using a precompiled header may not work. +Under certain circumstances, cotire cannot enable the precompiled header usage by changing the +`COMPILE_FLAGS` property of the whole target, but must set the `COMPILE_FLAGS` properties of +individual target source files instead. This will break the usage of the source file for multiple +targets. + +### multi-architecture builds under Mac OS X + +Neither GCC nor Clang support the use of precompiled headers when performing a Mac OS X +multi-architecture build (e.g., using option `-DCMAKE_OSX_ARCHITECTURES=i386;x86_64`). + +### Objective-C + +CMake targets that contain Objective-C or Objective-C++ source files cannot be cotired. Source +files ending with .m and .mm are excluded by default through the initial default setting of +`COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS`. + +### Intel C++ + +Intel C++ support has only been tested with [Intel C++ Composer XE 2013 for Linux][icc_linux] and +may not work with other platforms or versions. + +The Intel compiler may issue incorrect warnings #672 (the command line options do not match those +used when precompiled header was created) or #673 (the initial sequence of preprocessing directives +is not compatible with those of precompiled header file) upon compilation of cotired targets. + +### IncrediBuild + +Cotire is not compatible with [Xoreax IncrediBuild][XGE]. + +[1260]:http://www.cmake.org/Bug/view.php?id=1260 +[ccch]:https://ccache.samba.org/ +[ccch_pch]:https://ccache.samba.org/manual.html#_precompiled_headers +[clang_pch]:http://clang.llvm.org/docs/UsersManual.html#precompiled-headers +[fsedit_qt4]:http://www.vikingsoft.eu/fseditor.html +[fsedit_qt5]:https://github.com/joonhwan/fsedit-qt5 +[gcc_pch]:https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html +[msvc_pch]:https://msdn.microsoft.com/en-us/library/szfdksca(v=vs.90).aspx +[msvc_pch_create]:https://msdn.microsoft.com/en-us/library/7zc28563(v=vs.90).aspx +[msvc_pch_use]:https://msdn.microsoft.com/en-us/library/z0atkd6c(v=vs.90).aspx +[ninja_issue]:https://cmake.org/Bug/view.php?id=13234 +[EoUB]:https://engineering-game-dev.com/2009/12/15/the-evils-of-unity-builds/ +[pch]:https://en.wikipedia.org/wiki/Precompiled_header +[scu]:https://en.wikipedia.org/wiki/Single_Compilation_Unit +[objlib]:https://cmake.org/cmake/help/v2.8.12/cmake.html#command:add_library +[pfh]:https://en.wikipedia.org/wiki/Prefix_header +[icc_linux]:https://software.intel.com/en-us/c-compilers/ipsxe-support +[XGE]:https://www.incredibuild.com/ |