Browse Source

cotire 1.4.0

master
Sascha Kratky 11 years ago
parent
commit
cb1a037eb8
4 changed files with 240 additions and 91 deletions
  1. +149
    -73
      CMake/cotire.cmake
  2. +7
    -0
      HISTORY.md
  3. +81
    -16
      MANUAL.md
  4. +3
    -2
      README.md

+ 149
- 73
CMake/cotire.cmake View File

@@ -45,9 +45,10 @@ if (NOT CMAKE_SCRIPT_MODE_FILE)
endif()

set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
set (COTIRE_CMAKE_MODULE_VERSION "1.3.6")
set (COTIRE_CMAKE_MODULE_VERSION "1.4.0")

include(CMakeParseArguments)
include(ProcessorCount)

function (cotire_determine_compiler_version _language _versionPrefix)
if (NOT ${_versionPrefix}_VERSION)
@@ -1519,11 +1520,31 @@ macro (cotire_get_intermediate_dir _cotireDir)
get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
endmacro()

function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
set (_sourceFiles ${ARGN})
list (LENGTH _sourceFiles _numberOfSources)
macro (cotire_setup_file_extension_variables)
set (_unityFileExt_C ".c")
set (_unityFileExt_CXX ".cxx")
set (_prefixFileExt_C ".h")
set (_prefixFileExt_CXX ".hxx")
endmacro()

function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
cotire_setup_file_extension_variables()
if (NOT DEFINED _unityFileExt_${_language})
set (${_unityFileVar} "" PARENT_SCOPE)
return()
endif()
set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
cotire_get_intermediate_dir(_baseDir)
set (_unityFile "${_baseDir}/${_unityFileName}")
set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
if (COTIRE_DEBUG)
message(STATUS "${_unityFile}")
endif()
endfunction()

function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
cotire_setup_file_extension_variables()
if (NOT DEFINED _unityFileExt_${_language})
set (${_unityFileVar} "" PARENT_SCOPE)
return()
@@ -1533,11 +1554,13 @@ function (cotire_make_unity_source_file_paths _language _target _maxIncludes _un
set (_startIndex 0)
set (_index 0)
set (_unityFiles "")
set (_sourceFiles ${ARGN})
foreach (_sourceFile ${_sourceFiles})
get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
math (EXPR _unityFileCount "${_index} - ${_startIndex}")
if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
if (_index GREATER 0)
# start new unity file segment
math (EXPR _endIndex "${_index} - 1")
set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
@@ -1546,10 +1569,12 @@ function (cotire_make_unity_source_file_paths _language _target _maxIncludes _un
endif()
math (EXPR _index "${_index} + 1")
endforeach()
list (LENGTH _sourceFiles _numberOfSources)
if (_startIndex EQUAL 0)
set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
# there is only a single unity file
cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
elseif (_startIndex LESS _numberOfSources)
# end with final unity file segment
math (EXPR _endIndex "${_index} - 1")
set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
@@ -1560,9 +1585,21 @@ function (cotire_make_unity_source_file_paths _language _target _maxIncludes _un
endif()
endfunction()

function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
cotire_setup_file_extension_variables()
if (NOT DEFINED _unityFileExt_${_language})
set (${_prefixFileVar} "" PARENT_SCOPE)
return()
endif()
set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
endfunction()

function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
set (_prefixFileExt_C ".h")
set (_prefixFileExt_CXX ".hxx")
cotire_setup_file_extension_variables()
if (NOT _language)
set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
@@ -1811,6 +1848,43 @@ function (cotire_get_first_set_property_value _propertyValueVar _type _object)
set (${_propertyValueVar} "" PARENT_SCOPE)
endfunction()

function (cotire_setup_combine_command _sourceDir _targetScript _joinedFile _cmdsVar)
set (_files ${ARGN})
set (_filesPaths "")
foreach (_file ${_files})
if (IS_ABSOLUTE "${_file}")
set (_filePath "${_file}")
else()
get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE)
endif()
file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}")
if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.")
list (APPEND _filesPaths "${_fileRelPath}")
else()
list (APPEND _filesPaths "${_filePath}")
endif()
endforeach()
cotire_set_cmd_to_prologue(_prefixCmd)
list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
if (_targetScript)
list (APPEND _prefixCmd "${_targetScript}")
endif()
list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
if (COTIRE_DEBUG)
message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
endif()
set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
add_custom_command(
OUTPUT "${_joinedFile}"
COMMAND ${_prefixCmd}
DEPENDS ${_files}
COMMENT "Generating ${_joinedFileRelPath}"
WORKING_DIRECTORY "${_sourceDir}" VERBATIM)
list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
endfunction()

function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget)
if (XCODE)
# for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
@@ -1892,20 +1966,17 @@ function (cotire_setup_unity_generation_commands _language _targetSourceDir _tar
WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM)
list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
endforeach()
set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
endfunction()

function (cotire_setup_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar)
set (_sourceFiles ${ARGN})
list (LENGTH _unityFiles _numberOfUnityFiles)
if (_numberOfUnityFiles GREATER 1)
# create a joint unity file from all unity file segments
cotire_make_unity_source_file_paths(${_language} ${_target} 0 _unityFile ${_unityFiles})
cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
cotire_setup_combine_command("${_targetSourceDir}" "${_targetScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles})
else()
set (_unityFile "${_unityFiles}")
endif()
file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
endfunction()

function (cotire_setup_single_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar)
set (_sourceFiles ${ARGN})
set (_dependencySources "")
cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
cotire_set_cmd_to_prologue(_prefixCmd)
@@ -1914,6 +1985,7 @@ function (cotire_setup_prefix_generation_command _language _target _targetSource
if (COTIRE_DEBUG)
message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_targetScript} ${_unityFile} ${_dependencySources}")
endif()
file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
add_custom_command(
OUTPUT "${_prefixFile}" "${_prefixFile}.log"
COMMAND ${_prefixCmd}
@@ -1924,40 +1996,25 @@ function (cotire_setup_prefix_generation_command _language _target _targetSource
set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
endfunction()

function (cotire_setup_combine_command _sourceDir _targetScript _joinedFile _cmdsVar)
set (_files ${ARGN})
set (_filesPaths "")
foreach (_file ${_files})
if (IS_ABSOLUTE "${_file}")
set (_filePath "${_file}")
else()
get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE)
endif()
file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}")
if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.")
list (APPEND _filesPaths "${_fileRelPath}")
else()
list (APPEND _filesPaths "${_filePath}")
endif()
endforeach()
cotire_set_cmd_to_prologue(_prefixCmd)
list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
if (_targetScript)
list (APPEND _prefixCmd "${_targetScript}")
endif()
list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
if (COTIRE_DEBUG)
message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
function (cotire_setup_multi_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar)
set (_sourceFiles ${ARGN})
list (LENGTH _unityFiles _numberOfUnityFiles)
if (_numberOfUnityFiles GREATER 1)
set (_prefixFiles "")
foreach (_unityFile ${_unityFiles})
cotire_unity_to_prefix_file_path(${_language} ${_target} "${_unityFile}" _prefixFileSegment)
cotire_setup_single_prefix_generation_command(
${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
"${_prefixFileSegment}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles})
list (APPEND _prefixFiles "${_prefixFileSegment}")
endforeach()
# create a joint prefix header file from all prefix header segments
cotire_setup_combine_command("${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" ${_cmdsVar} ${_prefixFiles})
else()
cotire_setup_single_prefix_generation_command(
${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
"${_prefixFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
endif()
set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
add_custom_command(
OUTPUT "${_joinedFile}"
COMMAND ${_prefixCmd}
DEPENDS ${_files}
COMMENT "Generating ${_joinedFileRelPath}"
WORKING_DIRECTORY "${_sourceDir}" VERBATIM)
list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
endfunction()

@@ -2135,6 +2192,30 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag
set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
endfunction()

function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
set (_sourceFiles ${ARGN})
get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
if (_maxIncludes MATCHES "(-j|--parallel) ?([0-9]*)")
set (_numberOfThreads "${CMAKE_MATCH_2}")
if (NOT _numberOfThreads)
# use all available cores
ProcessorCount(_numberOfThreads)
endif()
list (LENGTH _sourceFiles _numberOfSources)
math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
# a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files
if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
endif()
elseif (NOT _maxIncludes MATCHES "[0-9]+")
set (_maxIncludes 0)
endif()
if (COTIRE_DEBUG)
message (STATUS "${_target} unity source max includes = ${_maxIncludes}")
endif()
set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
endfunction()

function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTargetVar _cmdsVar)
set (${_cmdsVar} "" PARENT_SCOPE)
get_target_property(_targetSourceFiles ${_target} SOURCES)
@@ -2154,10 +2235,7 @@ function (cotire_process_target_language _language _configurations _targetSource
endif()
cotire_generate_target_script(
${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript ${_unitySourceFiles})
get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
if (NOT _maxIncludes)
set (_maxIncludes 0)
endif()
cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
if (NOT _unityFiles)
return()
@@ -2171,7 +2249,7 @@ function (cotire_process_target_language _language _configurations _targetSource
if (_prefixHeaderFiles)
cotire_setup_combine_command("${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
else()
cotire_setup_prefix_generation_command(
cotire_setup_multi_prefix_generation_command(
${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles})
endif()
get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
@@ -2295,20 +2373,6 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour
endif()
# add unity source files instead
list (APPEND _unityTargetSources ${_unityFiles})
# make unity files use precompiled header if there are multiple unity files
list (LENGTH _unityFiles _numberOfUnityFiles)
if (_targetUsePCH AND _numberOfUnityFiles GREATER ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
if (_prefixFile AND _pchFile)
cotire_setup_pch_file_compilation(
${_language} "${_targetBinaryDir}" "" "${_prefixFile}" "${_pchFile}" ${_unityFiles})
cotire_setup_prefix_file_inclusion(
${_language} ${_target} FALSE "${_prefixFile}" "${_pchFile}" ${_unityFiles})
# add the prefix header to unity target sources
list (APPEND _unityTargetSources "${_prefixFile}")
endif()
endif()
endif()
endforeach()
if (COTIRE_DEBUG)
@@ -2756,7 +2820,17 @@ else()
set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING
"Minimum number of sources in target required to enable use of precompiled header.")

set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "" CACHE STRING
if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
# enable parallelization for generators that run multiple jobs by default
set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
else()
set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
endif()
endif()
set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
"Maximum number of source files to include in a single unity source file.")

if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
@@ -2842,11 +2916,13 @@ else()
CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
FULL_DOCS
"This may be set to an integer > 0."
"This may be set to an integer >= 0."
"If 0, cotire will only create a single unity source file."
"If a target contains more than that number of source files, cotire will create multiple unity source files for it."
"If not set, cotire will only create a single unity source file."
"Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
"Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
"Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
"Defaults to empty."
"Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
)

# define cotire directory properties


+ 7
- 0
HISTORY.md View File

@@ -1,3 +1,10 @@
## 1.4.0 (2013-03-11)

* one year anniversary release.
* add support for multi-core optimized unity builds for some CMake generators.
* add support for multi-core optimized prefix header generation.
* add more examples to cotire manual.

## 1.3.6 (2013-03-06)

* fix bug with prefix header initialization for generator Xcode.


+ 81
- 16
MANUAL.md View File

@@ -127,6 +127,9 @@ The unity source file uses absolute paths to include the target's source file. T
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
@@ -180,10 +183,12 @@ The generated prefix file includes the selected header files by their absolute p
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 and cannot be re-used
for a different CMake target. 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 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).

### the precompiled header

@@ -226,11 +231,24 @@ the correct precompiled header depending on the compilation language of the sour
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_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)

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.
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

@@ -281,7 +299,10 @@ 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.
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

@@ -293,23 +314,25 @@ 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)

The property can also be set to a list of header files which will then make up the contents of
the generated prefix header.

If the prefix header `stdafx.h` needs an accompanying source file (e.g., `stdafx.cpp`) in order
to be pre-compiled 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.

### 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 that
has been added in the same source directory:
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(example2 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${_prefixHeader}")
cotire(example2)
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

@@ -350,7 +373,9 @@ removed from a target source file). Cotire does not automatically recreate the p
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.
`COTIRE_DEPENDENCY` can be set to `TRUE` for those files:

set_property (SOURCE "example.cpp" PROPERTY COTIRE_DEPENDENCY "TRUE")

### fixing linkage issues

@@ -378,7 +403,7 @@ 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
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:

@@ -417,6 +442,25 @@ this property, it will complete the current unity file and start a new one. The
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

The setting `-j` will also make the automatic prefix header generation run in parallel.

### fixing macro definition clashes

Many unity build problems stem from macro definitions leaking into other target source files,
@@ -452,6 +496,22 @@ source and the prefix header for verbose builds. `COTIRE_VERBOSE` defaults to `F
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
@@ -514,6 +574,10 @@ The Intel compiler may issue incorrect warnings #672 (the command line options d
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]:http://ccache.samba.org/
[clang_pch]:http://clang.llvm.org/docs/UsersManual.html#precompiledheaders
@@ -528,3 +592,4 @@ is not compatible with those of precompiled header file) upon compilation of cot
[objlib]:http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_library
[pfh]:http://en.wikipedia.org/wiki/Prefix_header
[icc_linux]:http://software.intel.com/en-us/non-commercial-software-development
[XGE]:http://www.incredibuild.com

+ 3
- 2
README.md View File

@@ -18,7 +18,7 @@ features
* Supports console (Makefile generator) and IDE (Visual Studio and Xcode) based builds.
* Compatible with CMake single build type and CMake multi-configuration builds.
* Compatible with most CMake generators (including [Ninja][ninja]).
* Compatible with parallel builds (make -j, [jom][jom], Visual Studio, Xcode).
* Supports multi-core unity builds for some generators (make -j, [jom][jom], Visual Studio, Ninja).
* Leverages native precompiled header generation features of IDEs (Visual Studio and Xcode).
* Compatible with CMake's [cross-compiling][ccrc] support.
* Compatible with compiler wrappers like [ccache][ccch].
@@ -87,7 +87,8 @@ the original target, but does so much faster by entering:
$ make MyExecutable_unity

See the advanced usage section of the [cotire manual][manual] for information on how to
configure the cotire process (e.g., how to apply cotire to a certain build configuration only).
configure the cotire process (e.g., how to make the unity build use all available processor
cores).

The directory `Patches` contains patch files to enable cotire for some popular open sources
packages that use CMake as a build system.


Loading…
Cancel
Save