1 # - cotire (compile time reducer)
3 # See the cotire manual for usage hints.
5 #=============================================================================
6 # Copyright 2012-2014 Sascha Kratky
8 # Permission is hereby granted, free of charge, to any person
9 # obtaining a copy of this software and associated documentation
10 # files (the "Software"), to deal in the Software without
11 # restriction, including without limitation the rights to use,
12 # copy, modify, merge, publish, distribute, sublicense, and/or sell
13 # copies of the Software, and to permit persons to whom the
14 # Software is furnished to do so, subject to the following
17 # The above copyright notice and this permission notice shall be
18 # included in all copies or substantial portions of the Software.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 # OTHER DEALINGS IN THE SOFTWARE.
28 #=============================================================================
33 set(__COTIRE_INCLUDED TRUE)
35 # call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode
36 # cmake_minimum_required also sets the policy version as a side effect, which we have to avoid
37 if (NOT CMAKE_SCRIPT_MODE_FILE)
40 # we need the CMake variables CMAKE_SCRIPT_MODE_FILE and CMAKE_ARGV available since 2.8.5
41 # we need APPEND_STRING option for set_property available since 2.8.6
42 cmake_minimum_required(VERSION 2.8.6)
43 if (NOT CMAKE_SCRIPT_MODE_FILE)
47 set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
48 set (COTIRE_CMAKE_MODULE_VERSION "1.6.6")
50 include(CMakeParseArguments)
51 include(ProcessorCount)
53 function (cotire_determine_compiler_version _language _versionPrefix)
54 if (NOT ${_versionPrefix}_VERSION)
55 # use CMake's predefined compiler version variable (available since CMake 2.8.8)
56 if (DEFINED CMAKE_${_language}_COMPILER_VERSION)
57 set (${_versionPrefix}_VERSION "${CMAKE_${_language}_COMPILER_VERSION}")
59 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
60 unset (ENV{VS_UNICODE_OUTPUT})
61 string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1)
63 COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1}
64 ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10)
65 string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}")
67 # assume GCC like command line interface
68 string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1)
70 COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion"
71 OUTPUT_VARIABLE ${_versionPrefix}_VERSION
72 RESULT_VARIABLE _result
73 OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10)
75 set (${_versionPrefix}_VERSION "")
78 if (${_versionPrefix}_VERSION)
79 set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" CACHE INTERNAL "${_language} compiler version")
81 set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" PARENT_SCOPE)
83 message (STATUS "${CMAKE_${_language}_COMPILER} version ${${_versionPrefix}_VERSION}")
88 function (cotire_get_source_file_extension _sourceFile _extVar)
89 # get_filename_component returns extension from first occurrence of . in file name
90 # this function computes the extension from last occurrence of . in file name
91 string (FIND "${_sourceFile}" "." _index REVERSE)
92 if (_index GREATER -1)
93 math (EXPR _index "${_index} + 1")
94 string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
98 set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
101 macro (cotire_check_is_path_relative_to _path _isRelativeVar)
102 set (${_isRelativeVar} FALSE)
103 if (IS_ABSOLUTE "${_path}")
104 foreach (_dir ${ARGN})
105 file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
106 if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
107 set (${_isRelativeVar} TRUE)
114 function (cotire_filter_language_source_files _language _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
115 set (_sourceFiles "")
116 set (_excludedSourceFiles "")
117 set (_cotiredSourceFiles "")
118 if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
119 set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
121 set (_languageExtensions "")
123 if (CMAKE_${_language}_IGNORE_EXTENSIONS)
124 set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}")
126 set (_ignoreExtensions "")
128 if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS)
129 set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}")
131 set (_excludeExtensions "")
134 message (STATUS "${_language} source file extensions: ${_languageExtensions}")
135 message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}")
136 message (STATUS "${_language} exclude extensions: ${_excludeExtensions}")
138 foreach (_sourceFile ${ARGN})
139 get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY)
140 get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT)
141 get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC)
142 get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE)
143 set (_sourceIsFiltered FALSE)
144 if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic)
145 cotire_get_source_file_extension("${_sourceFile}" _sourceExt)
147 list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex)
148 if (_ignoreIndex LESS 0)
149 list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex)
150 if (_excludeIndex GREATER -1)
151 list (APPEND _excludedSourceFiles "${_sourceFile}")
153 list (FIND _languageExtensions "${_sourceExt}" _sourceIndex)
154 if (_sourceIndex GREATER -1)
155 set (_sourceIsFiltered TRUE)
156 elseif ("${_sourceLanguage}" STREQUAL "${_language}")
157 # add to excluded sources, if file is not ignored and has correct language without having the correct extension
158 list (APPEND _excludedSourceFiles "${_sourceFile}")
165 message (STATUS "${_sourceFile} filtered=${_sourceIsFiltered} language=${_sourceLanguage} header=${_sourceIsHeaderOnly}")
167 if (_sourceIsFiltered)
168 get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED)
169 get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET)
170 get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS)
172 message (STATUS "${_sourceFile} excluded=${_sourceIsExcluded} cotired=${_sourceIsCotired} compileFlags=${_sourceCompileFlags}")
174 if (_sourceIsCotired)
175 list (APPEND _cotiredSourceFiles "${_sourceFile}")
176 elseif (_sourceIsExcluded OR _sourceCompileFlags)
177 list (APPEND _excludedSourceFiles "${_sourceFile}")
179 list (APPEND _sourceFiles "${_sourceFile}")
184 message (STATUS "All: ${ARGN}")
185 message (STATUS "${_language}: ${_sourceFiles}")
186 message (STATUS "Excluded: ${_excludedSourceFiles}")
187 message (STATUS "Cotired: ${_cotiredSourceFiles}")
189 set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE)
190 set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE)
191 set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE)
194 function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
195 set (_filteredObjects "")
196 foreach (_object ${ARGN})
197 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
199 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
201 list (APPEND _filteredObjects "${_object}")
205 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
208 function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
209 set (_filteredObjects "")
210 foreach (_object ${ARGN})
211 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
213 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
214 if (NOT _propertyValue)
215 list (APPEND _filteredObjects "${_object}")
219 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
222 function (cotire_get_source_file_property_values _valuesVar _property)
224 foreach (_sourceFile ${ARGN})
225 get_source_file_property(_propertyValue "${_sourceFile}" ${_property})
227 list (APPEND _values "${_propertyValue}")
230 set (${_valuesVar} ${_values} PARENT_SCOPE)
233 function (cotire_resolve_config_properties _configurations _propertiesVar)
235 foreach (_property ${ARGN})
236 if ("${_property}" MATCHES "<CONFIG>")
237 foreach (_config ${_configurations})
238 string (TOUPPER "${_config}" _upperConfig)
239 string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}")
240 list (APPEND _properties ${_configProperty})
243 list (APPEND _properties ${_property})
246 set (${_propertiesVar} ${_properties} PARENT_SCOPE)
249 function (cotire_copy_set_properties _configurations _type _source _target)
250 cotire_resolve_config_properties("${_configurations}" _properties ${ARGN})
251 foreach (_property ${_properties})
252 get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
254 get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
255 set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
260 function (cotire_get_target_link_libraries_for_usage_requirements _target _targetLinkLibrariesVar)
261 set (_targetLinkLibraries "")
262 get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES)
263 while (_librariesToProcess)
265 list (GET _librariesToProcess 0 _library)
266 list (REMOVE_AT _librariesToProcess 0)
267 list (FIND _targetLinkLibraries ${_library} _index)
269 list (APPEND _targetLinkLibraries ${_library})
270 # process transitive libraries
271 if (TARGET ${_library})
272 get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES)
274 list (APPEND _librariesToProcess ${_libraries})
279 set (${_targetLinkLibrariesVar} ${_targetLinkLibraries} PARENT_SCOPE)
282 function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar)
283 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
284 set (_flagPrefix "[/-]")
286 set (_flagPrefix "--?")
289 set (_matchedOptions "")
290 set (_unmatchedOptions "")
291 foreach (_compileFlag ${ARGN})
293 if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}")
294 # option with separate argument
295 list (APPEND _matchedOptions "${_compileFlag}")
297 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$")
299 set (_optionFlag "${CMAKE_MATCH_2}")
300 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$")
301 # option with joined argument
302 list (APPEND _matchedOptions "${CMAKE_MATCH_3}")
305 # flush remembered option
307 list (APPEND _matchedOptions "${_optionFlag}")
310 # add to unfiltered options
311 list (APPEND _unmatchedOptions "${_compileFlag}")
316 list (APPEND _matchedOptions "${_optionFlag}")
319 message (STATUS "Filter ${_flagFilter}")
321 message (STATUS "Matched ${_matchedOptions}")
323 if (_unmatchedOptions)
324 message (STATUS "Unmatched ${_unmatchedOptions}")
327 set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE)
328 set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE)
331 function (cotire_get_target_compile_flags _config _language _directory _target _flagsVar)
332 string (TOUPPER "${_config}" _upperConfig)
333 # collect options from CMake language variables
334 set (_compileFlags "")
335 if (CMAKE_${_language}_FLAGS)
336 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
338 if (CMAKE_${_language}_FLAGS_${_upperConfig})
339 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}")
342 # add option from CMake target type variable
343 get_target_property(_targetType ${_target} TYPE)
345 # handle POSITION_INDEPENDENT_CODE property introduced with CMake 2.8.9 if policy CMP0018 is turned on
346 cmake_policy(GET CMP0018 _PIC_Policy)
348 # default to old behavior
349 set (_PIC_Policy "OLD")
352 message(STATUS "CMP0018=${_PIC_Policy}")
354 if (_PIC_Policy STREQUAL "NEW")
355 # NEW behavior: honor the POSITION_INDEPENDENT_CODE target property
356 get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE)
358 if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE)
359 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIE}")
360 elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC)
361 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIC}")
365 # OLD behavior or policy not set: use the value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS
366 if (_targetType STREQUAL "MODULE_LIBRARY")
367 # flags variable for module library uses different name SHARED_MODULE
368 # (e.g., CMAKE_SHARED_MODULE_C_FLAGS)
369 set (_targetType SHARED_MODULE)
371 if (CMAKE_${_targetType}_${_language}_FLAGS)
372 set (_compileFlags "${_compileFlags} ${CMAKE_${_targetType}_${_language}_FLAGS}")
377 # add_definitions may have been used to add flags to the compiler command
378 get_directory_property(_dirDefinitions DIRECTORY "${_directory}" DEFINITIONS)
380 set (_compileFlags "${_compileFlags} ${_dirDefinitions}")
384 # add target compile options
385 get_target_property(_targetflags ${_target} COMPILE_FLAGS)
387 set (_compileFlags "${_compileFlags} ${_targetflags}")
389 get_target_property(_targetOptions ${_target} COMPILE_OPTIONS)
391 set (_compileFlags "${_compileFlags} ${_targetOptions}")
393 # interface compile options from linked library targets
394 cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries)
395 foreach (_library ${_linkLibraries})
396 if (TARGET ${_library})
397 get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS)
399 set (_compileFlags "${_compileFlags} ${_targetOptions}")
405 separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}")
407 separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}")
409 separate_arguments(_compileFlags)
411 # platform specific flags
413 get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig})
414 if (NOT _architectures)
415 get_target_property(_architectures ${_target} OSX_ARCHITECTURES)
418 foreach (_arch ${_architectures})
419 list (APPEND _compileFlags "-arch" "${_arch}")
422 if (CMAKE_OSX_SYSROOT)
423 if (CMAKE_${_language}_SYSROOT_FLAG)
424 list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}")
426 list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}")
429 if (CMAKE_OSX_DEPLOYMENT_TARGET)
430 if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG)
431 list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
433 list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
437 if (COTIRE_DEBUG AND _compileFlags)
438 message (STATUS "Target ${_target} compile flags ${_compileFlags}")
440 set (${_flagsVar} ${_compileFlags} PARENT_SCOPE)
443 function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar _systemIncludeDirsVar)
444 set (_includeDirs "")
445 set (_systemIncludeDirs "")
446 # default include dirs
447 if (CMAKE_INCLUDE_CURRENT_DIR)
448 list (APPEND _includeDirs "${_targetBinaryDir}")
449 list (APPEND _includeDirs "${_targetSourceDir}")
451 # parse additional include directories from target compile flags
452 set (_targetFlags "")
453 cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags)
454 cotire_filter_compile_flags("${_language}" "I" _dirs _ignore ${_targetFlags})
456 list (APPEND _includeDirs ${_dirs})
458 # target include directories
459 get_directory_property(_dirs DIRECTORY "${_targetSourceDir}" INCLUDE_DIRECTORIES)
461 get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES)
463 list (APPEND _dirs ${_targetDirs})
465 get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
467 list (APPEND _systemIncludeDirs ${_targetDirs})
470 # interface include directories from linked library targets
471 cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries)
472 foreach (_library ${_linkLibraries})
473 if (TARGET ${_library})
474 get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES)
476 list (APPEND _dirs ${_targetDirs})
478 get_target_property(_targetDirs ${_library} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
480 list (APPEND _systemIncludeDirs ${_targetDirs})
486 list (REMOVE_DUPLICATES _dirs)
488 list (LENGTH _includeDirs _projectInsertIndex)
489 foreach (_dir ${_dirs})
490 if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE)
491 cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
493 list (LENGTH _includeDirs _len)
494 if (_len EQUAL _projectInsertIndex)
495 list (APPEND _includeDirs "${_dir}")
497 list (INSERT _includeDirs _projectInsertIndex "${_dir}")
499 math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1")
501 list (APPEND _includeDirs "${_dir}")
504 list (APPEND _includeDirs "${_dir}")
507 list (REMOVE_DUPLICATES _includeDirs)
508 list (REMOVE_DUPLICATES _systemIncludeDirs)
509 if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES)
510 list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES})
512 if (COTIRE_DEBUG AND _includeDirs)
513 message (STATUS "Target ${_target} include dirs ${_includeDirs}")
515 set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE)
516 if (COTIRE_DEBUG AND _systemIncludeDirs)
517 message (STATUS "Target ${_target} system include dirs ${_systemIncludeDirs}")
519 set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE)
522 macro (cotire_make_C_identifier _identifierVar _str)
523 if (CMAKE_VERSION VERSION_LESS "2.8.12")
524 # mimic CMake SystemTools::MakeCindentifier behavior
525 if ("${_str}" MATCHES "^[0-9].+$")
528 string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}")
530 string (MAKE_C_IDENTIFIER "${_str}" "${_identifierVar}")
534 function (cotire_get_target_export_symbol _target _exportSymbolVar)
535 set (_exportSymbol "")
536 get_target_property(_targetType ${_target} TYPE)
537 get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
538 if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
539 (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
540 get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
541 if (NOT _exportSymbol)
542 set (_exportSymbol "${_target}_EXPORTS")
544 cotire_make_C_identifier(_exportSymbol "${_exportSymbol}")
546 set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
549 function (cotire_get_target_compile_definitions _config _language _directory _target _definitionsVar)
550 string (TOUPPER "${_config}" _upperConfig)
551 set (_configDefinitions "")
552 # CMAKE_INTDIR for multi-configuration build systems
553 if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
554 list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
556 # target export define symbol
557 cotire_get_target_export_symbol("${_target}" _defineSymbol)
559 list (APPEND _configDefinitions "${_defineSymbol}")
561 # directory compile definitions
562 get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS)
564 list (APPEND _configDefinitions ${_definitions})
566 get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS_${_upperConfig})
568 list (APPEND _configDefinitions ${_definitions})
570 # target compile definitions
571 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS)
573 list (APPEND _configDefinitions ${_definitions})
575 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig})
577 list (APPEND _configDefinitions ${_definitions})
579 # interface compile definitions from linked library targets
580 cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries)
581 foreach (_library ${_linkLibraries})
582 if (TARGET ${_library})
583 get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS)
585 list (APPEND _configDefinitions ${_definitions})
589 # parse additional compile definitions from target compile flags
590 # and don't look at directory compile definitions, which we already handled
591 set (_targetFlags "")
592 cotire_get_target_compile_flags("${_config}" "${_language}" "" "${_target}" _targetFlags)
593 cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags})
595 list (APPEND _configDefinitions ${_definitions})
597 list (REMOVE_DUPLICATES _configDefinitions)
598 if (COTIRE_DEBUG AND _configDefinitions)
599 message (STATUS "Target ${_target} compile definitions ${_configDefinitions}")
601 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
604 function (cotire_get_target_compiler_flags _config _language _directory _target _compilerFlagsVar)
605 # parse target compile flags omitting compile definitions and include directives
606 set (_targetFlags "")
607 cotire_get_target_compile_flags("${_config}" "${_language}" "${_directory}" "${_target}" _targetFlags)
608 set (_compilerFlags "")
609 cotire_filter_compile_flags("${_language}" "[ID]" _ignore _compilerFlags ${_targetFlags})
610 if (COTIRE_DEBUG AND _compilerFlags)
611 message (STATUS "Target ${_target} compiler flags ${_compilerFlags}")
613 set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE)
616 function (cotire_add_sys_root_paths _pathsVar)
618 if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT)
619 foreach (_path IN LISTS ${_pathsVar})
620 if (IS_ABSOLUTE "${_path}")
621 get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE)
622 if (EXISTS "${_path}")
623 list (APPEND ${_pathsVar} "${_path}")
629 set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE)
631 message (STATUS "${_pathsVar}=${${_pathsVar}}")
635 function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar)
636 set (_extraProperties ${ARGN})
638 if (_extraProperties)
639 list (FIND _extraProperties "${_sourceFile}" _index)
640 if (_index GREATER -1)
641 math (EXPR _index "${_index} + 1")
642 list (LENGTH _extraProperties _len)
643 math (EXPR _len "${_len} - 1")
644 foreach (_index RANGE ${_index} ${_len})
645 list (GET _extraProperties ${_index} _value)
646 if (_value MATCHES "${_pattern}")
647 list (APPEND _result "${_value}")
654 set (${_resultVar} ${_result} PARENT_SCOPE)
657 function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
658 set (_compileDefinitions "")
659 if (NOT CMAKE_SCRIPT_MODE_FILE)
660 string (TOUPPER "${_config}" _upperConfig)
661 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
663 list (APPEND _compileDefinitions ${_definitions})
665 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig})
667 list (APPEND _compileDefinitions ${_definitions})
670 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN})
672 list (APPEND _compileDefinitions ${_definitions})
674 if (COTIRE_DEBUG AND _compileDefinitions)
675 message (STATUS "Source ${_sourceFile} compile definitions ${_compileDefinitions}")
677 set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE)
680 function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
681 set (_configDefinitions "")
682 foreach (_sourceFile ${ARGN})
683 cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
684 if (_sourceDefinitions)
685 list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
688 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
691 function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
692 set (_sourceUndefs "")
693 if (NOT CMAKE_SCRIPT_MODE_FILE)
694 get_source_file_property(_undefs "${_sourceFile}" ${_property})
696 list (APPEND _sourceUndefs ${_undefs})
699 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN})
701 list (APPEND _sourceUndefs ${_undefs})
703 if (COTIRE_DEBUG AND _sourceUndefs)
704 message (STATUS "Source ${_sourceFile} ${_property} undefs ${_sourceUndefs}")
706 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
709 function (cotire_get_source_files_undefs _property _sourceUndefsVar)
710 set (_sourceUndefs "")
711 foreach (_sourceFile ${ARGN})
712 cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs)
714 list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-")
717 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
720 macro (cotire_set_cmd_to_prologue _cmdVar)
721 set (${_cmdVar} "${CMAKE_COMMAND}")
723 list (APPEND ${_cmdVar} "--warn-uninitialized")
725 list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>")
727 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON")
728 elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles")
729 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)")
733 function (cotire_init_compile_cmd _cmdVar _language _compilerExe _compilerArg1)
734 if (NOT _compilerExe)
735 set (_compilerExe "${CMAKE_${_language}_COMPILER}")
737 if (NOT _compilerArg1)
738 set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1})
740 string (STRIP "${_compilerArg1}" _compilerArg1)
741 set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
744 macro (cotire_add_definitions_to_cmd _cmdVar _language)
745 foreach (_definition ${ARGN})
746 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
747 list (APPEND ${_cmdVar} "/D${_definition}")
749 list (APPEND ${_cmdVar} "-D${_definition}")
754 macro (cotire_add_includes_to_cmd _cmdVar _language _includeSystemFlag _includesVar _systemIncludesVar)
755 foreach (_include ${${_includesVar}})
756 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
757 file (TO_NATIVE_PATH "${_include}" _include)
758 list (APPEND ${_cmdVar} "/I${_include}")
760 list (FIND ${_systemIncludesVar} ${_include} _index)
761 if(_index GREATER -1 AND NOT "${_includeSystemFlag}" STREQUAL "")
762 list (APPEND ${_cmdVar} "${_includeSystemFlag}${_include}")
764 list (APPEND ${_cmdVar} "-I${_include}")
770 macro (cotire_add_frameworks_to_cmd _cmdVar _language)
772 set (_frameWorkDirs "")
773 foreach (_include ${ARGN})
774 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
775 get_filename_component(_frameWorkDir "${_include}" PATH)
776 list (APPEND _frameWorkDirs "${_frameWorkDir}")
780 list (REMOVE_DUPLICATES _frameWorkDirs)
781 foreach (_frameWorkDir ${_frameWorkDirs})
782 list (APPEND ${_cmdVar} "-F${_frameWorkDir}")
788 macro (cotire_add_compile_flags_to_cmd _cmdVar)
789 foreach (_flag ${ARGN})
790 list (APPEND ${_cmdVar} "${_flag}")
794 function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
795 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
796 set (_triggerFile "")
797 foreach (_dependencyFile ${ARGN})
798 if (EXISTS "${_dependencyFile}" AND "${_dependencyFile}" IS_NEWER_THAN "${_file}")
799 set (_triggerFile "${_dependencyFile}")
803 get_filename_component(_fileName "${_file}" NAME)
804 if (EXISTS "${_file}")
807 message (STATUS "${_fileName} update triggered by ${_triggerFile} change.")
811 message (STATUS "${_fileName} is up-to-date.")
813 set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE)
817 message (STATUS "${_fileName} does not exist yet.")
822 macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
823 set (${_relPathVar} "")
824 foreach (_includeDir ${_includeDirs})
825 if (IS_DIRECTORY "${_includeDir}")
826 file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
827 if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
828 string (LENGTH "${${_relPathVar}}" _closestLen)
829 string (LENGTH "${_relPath}" _relLen)
830 if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
831 set (${_relPathVar} "${_relPath}")
834 elseif ("${_includeDir}" STREQUAL "${_headerFile}")
835 # if path matches exactly, return short non-empty string
836 set (${_relPathVar} "1")
842 macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside)
843 # check header path against ignored and honored include directories
844 cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath)
846 # header is inside, but could be become outside if there is a shorter outside match
847 cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath)
849 string (LENGTH "${_insideRelPath}" _insideRelPathLen)
850 string (LENGTH "${_outsideRelPath}" _outsideRelPathLen)
851 if (_outsideRelPathLen LESS _insideRelPathLen)
852 set (${_headerIsInside} FALSE)
854 set (${_headerIsInside} TRUE)
857 set (${_headerIsInside} TRUE)
861 set (${_headerIsInside} FALSE)
865 macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
866 if (NOT EXISTS "${_headerFile}")
867 set (${_headerIsIgnoredVar} TRUE)
868 elseif (IS_DIRECTORY "${_headerFile}")
869 set (${_headerIsIgnoredVar} TRUE)
870 elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$")
871 # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path
872 # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
873 # with the error message "error: no include path in which to search for header.h"
874 set (${_headerIsIgnoredVar} TRUE)
876 set (${_headerIsIgnoredVar} FALSE)
880 macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
881 # check header file extension
882 cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
883 set (${_headerIsIgnoredVar} FALSE)
885 list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
886 if (_index GREATER -1)
887 set (${_headerIsIgnoredVar} TRUE)
892 macro (cotire_parse_line _line _headerFileVar _headerDepthVar)
894 # cl.exe /showIncludes output looks different depending on the language pack used, e.g.:
895 # English: "Note: including file: C:\directory\file"
896 # German: "Hinweis: Einlesen der Datei: C:\directory\file"
897 # We use a very general regular expression, relying on the presence of the : characters
898 if (_line MATCHES ":( +)([^:]+:[^:]+)$")
899 # Visual Studio compiler output
900 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
901 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE)
903 set (${_headerFileVar} "")
904 set (${_headerDepthVar} 0)
907 if (_line MATCHES "^(\\.+) (.*)$")
909 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
910 if (IS_ABSOLUTE "${CMAKE_MATCH_2}")
911 set (${_headerFileVar} "${CMAKE_MATCH_2}")
913 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH)
916 set (${_headerFileVar} "")
917 set (${_headerDepthVar} 0)
922 function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar)
924 # prevent CMake macro invocation errors due to backslash characters in Windows paths
925 string (REPLACE "\\" "/" _scanOutput "${_scanOutput}")
928 string (REPLACE "//" "/" _scanOutput "${_scanOutput}")
929 # prevent semicolon from being interpreted as a line separator
930 string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}")
931 # then separate lines
932 string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}")
933 list (LENGTH _scanOutput _len)
934 # remove duplicate lines to speed up parsing
935 list (REMOVE_DUPLICATES _scanOutput)
936 list (LENGTH _scanOutput _uniqueLen)
937 if (COTIRE_VERBOSE OR COTIRE_DEBUG)
938 message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes")
939 if (_ignoredExtensions)
940 message (STATUS "Ignored extensions: ${_ignoredExtensions}")
942 if (_ignoredIncludeDirs)
943 message (STATUS "Ignored paths: ${_ignoredIncludeDirs}")
945 if (_honoredIncludeDirs)
946 message (STATUS "Included paths: ${_honoredIncludeDirs}")
949 set (_sourceFiles ${ARGN})
950 set (_selectedIncludes "")
951 set (_unparsedLines "")
952 # stack keeps track of inside/outside project status of processed header files
953 set (_headerIsInsideStack "")
954 foreach (_line IN LISTS _scanOutput)
956 cotire_parse_line("${_line}" _headerFile _headerDepth)
958 cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside)
960 message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}")
963 list (LENGTH _headerIsInsideStack _stackLen)
964 if (_headerDepth GREATER _stackLen)
965 math (EXPR _stackLen "${_stackLen} + 1")
966 foreach (_index RANGE ${_stackLen} ${_headerDepth})
967 list (APPEND _headerIsInsideStack ${_headerIsInside})
970 foreach (_index RANGE ${_headerDepth} ${_stackLen})
971 list (REMOVE_AT _headerIsInsideStack -1)
973 list (APPEND _headerIsInsideStack ${_headerIsInside})
976 message (STATUS "${_headerIsInsideStack}")
978 # header is a candidate if it is outside project
979 if (NOT _headerIsInside)
980 # get parent header file's inside/outside status
981 if (_headerDepth GREATER 1)
982 math (EXPR _index "${_headerDepth} - 2")
983 list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside)
985 set (_parentHeaderIsInside TRUE)
987 # select header file if parent header file is inside project
988 # (e.g., a project header file that includes a standard header file)
989 if (_parentHeaderIsInside)
990 cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored)
991 if (NOT _headerIsIgnored)
992 cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored)
993 if (NOT _headerIsIgnored)
994 list (APPEND _selectedIncludes "${_headerFile}")
996 # fix header's inside status on stack, it is ignored by extension now
997 list (REMOVE_AT _headerIsInsideStack -1)
998 list (APPEND _headerIsInsideStack TRUE)
1002 message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}")
1008 # for cl.exe do not keep unparsed lines which solely consist of a source file name
1009 string (FIND "${_sourceFiles}" "${_line}" _index)
1011 list (APPEND _unparsedLines "${_line}")
1014 list (APPEND _unparsedLines "${_line}")
1019 list (REMOVE_DUPLICATES _selectedIncludes)
1020 set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE)
1021 set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE)
1024 function (cotire_scan_includes _includesVar)
1026 set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE UNPARSED_LINES)
1027 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS)
1028 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1029 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1030 if (NOT _option_LANGUAGE)
1031 set (_option_LANGUAGE "CXX")
1033 if (NOT _option_COMPILER_ID)
1034 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1036 set (_cmd "${_option_COMPILER_EXECUTABLE}" ${_option_COMPILER_ARG1})
1037 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1038 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1039 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1040 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1041 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES})
1042 cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd)
1043 # only consider existing source files for scanning
1044 set (_existingSourceFiles "")
1045 foreach (_sourceFile ${_sourceFiles})
1046 if (EXISTS "${_sourceFile}")
1047 list (APPEND _existingSourceFiles "${_sourceFile}")
1050 if (NOT _existingSourceFiles)
1051 set (${_includesVar} "" PARENT_SCOPE)
1054 list (APPEND _cmd ${_existingSourceFiles})
1056 message (STATUS "execute_process: ${_cmd}")
1058 if (_option_COMPILER_ID MATCHES "MSVC")
1060 message (STATUS "clearing VS_UNICODE_OUTPUT")
1062 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1063 unset (ENV{VS_UNICODE_OUTPUT})
1066 COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1067 RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output)
1069 message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.")
1071 cotire_parse_includes(
1072 "${_option_LANGUAGE}" "${_output}"
1073 "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}"
1074 "${_option_IGNORE_EXTENSIONS}"
1075 _includes _unparsedLines
1077 set (${_includesVar} ${_includes} PARENT_SCOPE)
1078 if (_option_UNPARSED_LINES)
1079 set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE)
1083 macro (cotire_append_undefs _contentsVar)
1084 set (_undefs ${ARGN})
1086 list (REMOVE_DUPLICATES _undefs)
1087 foreach (_definition ${_undefs})
1088 list (APPEND ${_contentsVar} "#undef ${_definition}")
1093 macro (cotire_comment_str _language _commentText _commentVar)
1094 if ("${_language}" STREQUAL "CMAKE")
1095 set (${_commentVar} "# ${_commentText}")
1097 set (${_commentVar} "/* ${_commentText} */")
1101 function (cotire_write_file _language _file _contents _force)
1102 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1103 cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
1104 cotire_comment_str("${_language}" "${_file}" _header2)
1105 set (_contents "${_header1}\n${_header2}\n${_contents}")
1107 message (STATUS "${_contents}")
1109 if (_force OR NOT EXISTS "${_file}")
1110 file (WRITE "${_file}" "${_contents}")
1112 file (READ "${_file}" _oldContents)
1113 if (NOT "${_oldContents}" STREQUAL "${_contents}")
1114 file (WRITE "${_file}" "${_contents}")
1117 message (STATUS "${_file} unchanged")
1123 function (cotire_generate_unity_source _unityFile)
1125 set(_oneValueArgs LANGUAGE)
1127 DEPENDS SOURCES_COMPILE_DEFINITIONS
1128 PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE)
1129 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1130 if (_option_DEPENDS)
1131 cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS})
1132 if (_unityFileIsUpToDate)
1136 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1137 if (NOT _option_PRE_UNDEFS)
1138 set (_option_PRE_UNDEFS "")
1140 if (NOT _option_SOURCES_PRE_UNDEFS)
1141 set (_option_SOURCES_PRE_UNDEFS "")
1143 if (NOT _option_POST_UNDEFS)
1144 set (_option_POST_UNDEFS "")
1146 if (NOT _option_SOURCES_POST_UNDEFS)
1147 set (_option_SOURCES_POST_UNDEFS "")
1150 if (_option_PROLOGUE)
1151 list (APPEND _contents ${_option_PROLOGUE})
1153 if (_option_LANGUAGE AND _sourceFiles)
1154 if ("${_option_LANGUAGE}" STREQUAL "CXX")
1155 list (APPEND _contents "#ifdef __cplusplus")
1156 elseif ("${_option_LANGUAGE}" STREQUAL "C")
1157 list (APPEND _contents "#ifndef __cplusplus")
1160 set (_compileUndefinitions "")
1161 foreach (_sourceFile ${_sourceFiles})
1162 cotire_get_source_compile_definitions(
1163 "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions
1164 ${_option_SOURCES_COMPILE_DEFINITIONS})
1165 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS})
1166 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS})
1167 if (_option_PRE_UNDEFS)
1168 list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS})
1170 if (_sourcePreUndefs)
1171 list (APPEND _compileUndefinitions ${_sourcePreUndefs})
1173 if (_compileUndefinitions)
1174 cotire_append_undefs(_contents ${_compileUndefinitions})
1175 set (_compileUndefinitions "")
1177 if (_sourcePostUndefs)
1178 list (APPEND _compileUndefinitions ${_sourcePostUndefs})
1180 if (_option_POST_UNDEFS)
1181 list (APPEND _compileUndefinitions ${_option_POST_UNDEFS})
1183 foreach (_definition ${_compileDefinitions})
1184 if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$")
1185 list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}")
1186 list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}")
1188 list (APPEND _contents "#define ${_definition}")
1189 list (INSERT _compileUndefinitions 0 "${_definition}")
1192 get_filename_component(_sourceFile "${_sourceFile}" ABSOLUTE)
1194 file (TO_NATIVE_PATH "${_sourceFile}" _sourceFile)
1196 list (APPEND _contents "#include \"${_sourceFile}\"")
1198 if (_compileUndefinitions)
1199 cotire_append_undefs(_contents ${_compileUndefinitions})
1200 set (_compileUndefinitions "")
1202 if (_option_LANGUAGE AND _sourceFiles)
1203 list (APPEND _contents "#endif")
1205 if (_option_EPILOGUE)
1206 list (APPEND _contents ${_option_EPILOGUE})
1208 list (APPEND _contents "")
1209 string (REPLACE ";" "\n" _contents "${_contents}")
1211 message ("${_contents}")
1213 cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE)
1216 function (cotire_generate_prefix_header _prefixFile)
1218 set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG)
1219 set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS
1220 INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS)
1221 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1222 if (_option_DEPENDS)
1223 cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS})
1224 if (_prefixFileIsUpToDate)
1225 set (_unparsedLinesFile "${_prefixFile}.log")
1226 file (WRITE "${_unparsedLinesFile}" "")
1232 if (_option_COMPILER_ID MATCHES "Clang")
1233 set (_prologue "#pragma clang system_header")
1234 elseif (_option_COMPILER_ID MATCHES "GNU")
1235 set (_prologue "#pragma GCC system_header")
1236 elseif (_option_COMPILER_ID MATCHES "MSVC")
1237 set (_prologue "#pragma warning(push, 0)")
1238 set (_epilogue "#pragma warning(pop)")
1239 elseif (_option_COMPILER_ID MATCHES "Intel")
1240 # Intel compiler requires hdrstop pragma to stop generating PCH file
1241 set (_epilogue "#pragma hdrstop")
1243 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1244 cotire_scan_includes(_selectedHeaders ${_sourceFiles}
1245 LANGUAGE "${_option_LANGUAGE}"
1246 COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}"
1247 COMPILER_ID "${_option_COMPILER_ID}"
1248 COMPILER_VERSION "${_option_COMPILER_VERSION}"
1249 COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS}
1250 COMPILE_FLAGS ${_option_COMPILE_FLAGS}
1251 INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES}
1252 INCLUDE_SYSTEM_FLAG ${_option_INCLUDE_SYSTEM_FLAG}
1253 SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES}
1254 IGNORE_PATH ${_option_IGNORE_PATH}
1255 INCLUDE_PATH ${_option_INCLUDE_PATH}
1256 IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS}
1257 UNPARSED_LINES _unparsedLines)
1258 cotire_generate_unity_source("${_prefixFile}"
1259 PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders})
1260 set (_unparsedLinesFile "${_prefixFile}.log")
1262 if (COTIRE_VERBOSE OR NOT _selectedHeaders)
1263 list (LENGTH _unparsedLines _skippedLineCount)
1264 file (RELATIVE_PATH _unparsedLinesFileRelPath "${CMAKE_BINARY_DIR}" "${_unparsedLinesFile}")
1265 message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFileRelPath}")
1267 string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}")
1269 file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}")
1272 function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
1273 set (_flags ${${_flagsVar}})
1274 if (_compilerID MATCHES "MSVC")
1275 # cl.exe options used
1276 # /nologo suppresses display of sign-on banner
1277 # /TC treat all files named on the command line as C source files
1278 # /TP treat all files named on the command line as C++ source files
1279 # /EP preprocess to stdout without #line directives
1280 # /showIncludes list include files
1281 set (_sourceFileTypeC "/TC")
1282 set (_sourceFileTypeCXX "/TP")
1285 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes)
1287 # return as a flag string
1288 set (_flags "${_sourceFileType${_language}} /EP /showIncludes")
1290 elseif (_compilerID MATCHES "GNU")
1292 # -H print the name of each header file used
1293 # -E invoke preprocessor
1294 # -fdirectives-only do not expand macros, requires GCC >= 4.3
1297 list (APPEND _flags -H -E)
1298 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1299 list (APPEND _flags "-fdirectives-only")
1302 # return as a flag string
1303 set (_flags "-H -E")
1304 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1305 set (_flags "${_flags} -fdirectives-only")
1308 elseif (_compilerID MATCHES "Clang")
1309 # Clang options used
1310 # -H print the name of each header file used
1311 # -E invoke preprocessor
1314 list (APPEND _flags -H -E)
1316 # return as a flag string
1317 set (_flags "-H -E")
1319 elseif (_compilerID MATCHES "Intel")
1321 # Windows Intel options used
1322 # /nologo do not display compiler version information
1323 # /QH display the include file order
1324 # /EP preprocess to stdout, omitting #line directives
1325 # /TC process all source or unrecognized file types as C source files
1326 # /TP process all source or unrecognized file types as C++ source files
1327 set (_sourceFileTypeC "/TC")
1328 set (_sourceFileTypeCXX "/TP")
1331 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH)
1333 # return as a flag string
1334 set (_flags "${_sourceFileType${_language}} /EP /QH")
1337 # Linux / Mac OS X Intel options used
1338 # -H print the name of each header file used
1339 # -EP preprocess to stdout, omitting #line directives
1340 # -Kc++ process all source or unrecognized file types as C++ source files
1343 if ("${_language}" STREQUAL "CXX")
1344 list (APPEND _flags -Kc++)
1346 list (APPEND _flags -H -EP)
1348 # return as a flag string
1349 if ("${_language}" STREQUAL "CXX")
1350 set (_flags "-Kc++ ")
1352 set (_flags "${_flags}-H -EP")
1356 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1358 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1361 function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
1362 set (_flags ${${_flagsVar}})
1363 if (_compilerID MATCHES "MSVC")
1364 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1365 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1366 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1367 # cl.exe options used
1368 # /Yc creates a precompiled header file
1369 # /Fp specifies precompiled header binary file name
1370 # /FI forces inclusion of file
1371 # /TC treat all files named on the command line as C source files
1372 # /TP treat all files named on the command line as C++ source files
1373 # /Zs syntax check only
1374 set (_sourceFileTypeC "/TC")
1375 set (_sourceFileTypeCXX "/TP")
1378 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1379 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1381 # return as a flag string
1382 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1384 elseif (_compilerID MATCHES "GNU|Clang")
1385 # GCC / Clang options used
1386 # -x specify the source language
1387 # -c compile but do not link
1388 # -o place output in file
1389 # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may
1390 # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings)
1391 set (_xLanguage_C "c-header")
1392 set (_xLanguage_CXX "c++-header")
1395 list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}")
1397 # return as a flag string
1398 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1400 elseif (_compilerID MATCHES "Intel")
1402 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1403 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1404 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1405 # Windows Intel options used
1406 # /nologo do not display compiler version information
1407 # /Yc create a precompiled header (PCH) file
1408 # /Fp specify a path or file name for precompiled header files
1409 # /FI tells the preprocessor to include a specified file name as the header file
1410 # /TC process all source or unrecognized file types as C source files
1411 # /TP process all source or unrecognized file types as C++ source files
1412 # /Zs syntax check only
1413 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1414 set (_sourceFileTypeC "/TC")
1415 set (_sourceFileTypeCXX "/TP")
1418 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1419 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1420 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1421 list (APPEND _flags "/Wpch-messages")
1424 # return as a flag string
1425 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1426 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1427 set (_flags "${_flags} /Wpch-messages")
1431 # Linux / Mac OS X Intel options used
1432 # -pch-dir location for precompiled header files
1433 # -pch-create name of the precompiled header (PCH) to create
1434 # -Kc++ process all source or unrecognized file types as C++ source files
1435 # -fsyntax-only check only for correct syntax
1436 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1437 get_filename_component(_pchDir "${_pchFile}" PATH)
1438 get_filename_component(_pchName "${_pchFile}" NAME)
1439 set (_xLanguage_C "c-header")
1440 set (_xLanguage_CXX "c++-header")
1443 if ("${_language}" STREQUAL "CXX")
1444 list (APPEND _flags -Kc++)
1446 list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}")
1447 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1448 list (APPEND _flags "-Wpch-messages")
1451 # return as a flag string
1452 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1453 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1454 set (_flags "${_flags} -Wpch-messages")
1459 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1461 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1464 function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1465 set (_flags ${${_flagsVar}})
1466 if (_compilerID MATCHES "MSVC")
1467 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1468 # cl.exe options used
1469 # /Yu uses a precompiled header file during build
1470 # /Fp specifies precompiled header binary file name
1471 # /FI forces inclusion of file
1473 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1476 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1478 # return as a flag string
1479 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1482 # no precompiled header, force inclusion of prefix header
1485 list (APPEND _flags "/FI${_prefixFileNative}")
1487 # return as a flag string
1488 set (_flags "/FI\"${_prefixFileNative}\"")
1491 elseif (_compilerID MATCHES "GNU")
1493 # -include process include file as the first line of the primary source file
1494 # -Winvalid-pch warns if precompiled header is found but cannot be used
1495 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1498 list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}")
1500 # return as a flag string
1501 set (_flags "-Winvalid-pch -include \"${_prefixFile}\"")
1503 elseif (_compilerID MATCHES "Clang")
1504 # Clang options used
1505 # -include process include file as the first line of the primary source file
1506 # -include-pch include precompiled header file
1507 # -Qunused-arguments don't emit warning for unused driver arguments
1508 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1511 list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}")
1513 # return as a flag string
1514 set (_flags "-Qunused-arguments -include \"${_prefixFile}\"")
1516 elseif (_compilerID MATCHES "Intel")
1518 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1519 # Windows Intel options used
1520 # /Yu use a precompiled header (PCH) file
1521 # /Fp specify a path or file name for precompiled header files
1522 # /FI tells the preprocessor to include a specified file name as the header file
1523 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1525 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1528 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1529 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1530 list (APPEND _flags "/Wpch-messages")
1533 # return as a flag string
1534 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1535 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1536 set (_flags "${_flags} /Wpch-messages")
1540 # no precompiled header, force inclusion of prefix header
1543 list (APPEND _flags "/FI${_prefixFileNative}")
1545 # return as a flag string
1546 set (_flags "/FI\"${_prefixFileNative}\"")
1550 # Linux / Mac OS X Intel options used
1551 # -pch-dir location for precompiled header files
1552 # -pch-use name of the precompiled header (PCH) to use
1553 # -include process include file as the first line of the primary source file
1554 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1556 get_filename_component(_pchDir "${_pchFile}" PATH)
1557 get_filename_component(_pchName "${_pchFile}" NAME)
1560 list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}")
1561 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1562 list (APPEND _flags "-Wpch-messages")
1565 # return as a flag string
1566 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1567 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1568 set (_flags "${_flags} -Wpch-messages")
1572 # no precompiled header, force inclusion of prefix header
1575 list (APPEND _flags "-include" "${_prefixFile}")
1577 # return as a flag string
1578 set (_flags "-include \"${_prefixFile}\"")
1583 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1585 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1588 function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1590 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE)
1591 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS)
1592 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1593 if (NOT _option_LANGUAGE)
1594 set (_option_LANGUAGE "CXX")
1596 if (NOT _option_COMPILER_ID)
1597 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1599 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1600 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1601 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1602 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1603 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES})
1604 cotire_add_pch_compilation_flags(
1605 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1606 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1608 message (STATUS "execute_process: ${_cmd}")
1610 if (_option_COMPILER_ID MATCHES "MSVC")
1612 message (STATUS "clearing VS_UNICODE_OUTPUT")
1614 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1615 unset (ENV{VS_UNICODE_OUTPUT})
1619 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1620 RESULT_VARIABLE _result)
1622 message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.")
1626 function (cotire_check_precompiled_header_support _language _targetSourceDir _target _msgVar)
1627 set (_unsupportedCompiler
1628 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
1629 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1630 # supported since Visual Studio C++ 6.0
1631 # and CMake does not support an earlier version
1632 set (${_msgVar} "" PARENT_SCOPE)
1633 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
1634 # GCC PCH support requires version >= 3.4
1635 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1636 if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND
1637 "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
1638 set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
1640 set (${_msgVar} "" PARENT_SCOPE)
1642 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
1643 # all Clang versions have PCH support
1644 set (${_msgVar} "" PARENT_SCOPE)
1645 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
1646 # Intel PCH support requires version >= 8.0.0
1647 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1648 if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND
1649 "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
1650 set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
1652 set (${_msgVar} "" PARENT_SCOPE)
1655 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
1657 if (CMAKE_${_language}_COMPILER MATCHES "ccache")
1658 if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros")
1660 "ccache requires the environment variable CCACHE_SLOPPINESS to be set to time_macros."
1665 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
1666 if (CMAKE_CONFIGURATION_TYPES)
1667 set (_configs ${CMAKE_CONFIGURATION_TYPES})
1668 elseif (CMAKE_BUILD_TYPE)
1669 set (_configs ${CMAKE_BUILD_TYPE})
1671 set (_configs "None")
1673 foreach (_config ${_configs})
1674 set (_targetFlags "")
1675 cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags)
1676 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
1677 list (LENGTH _architectures _numberOfArchitectures)
1678 if (_numberOfArchitectures GREATER 1)
1679 string (REPLACE ";" ", " _architectureStr "${_architectures}")
1681 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
1689 macro (cotire_get_intermediate_dir _cotireDir)
1690 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
1693 macro (cotire_setup_file_extension_variables)
1694 set (_unityFileExt_C ".c")
1695 set (_unityFileExt_CXX ".cxx")
1696 set (_prefixFileExt_C ".h")
1697 set (_prefixFileExt_CXX ".hxx")
1698 set (_prefixSourceFileExt_C ".c")
1699 set (_prefixSourceFileExt_CXX ".cxx")
1702 function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
1703 cotire_setup_file_extension_variables()
1704 if (NOT DEFINED _unityFileExt_${_language})
1705 set (${_unityFileVar} "" PARENT_SCOPE)
1708 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1709 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
1710 cotire_get_intermediate_dir(_baseDir)
1711 set (_unityFile "${_baseDir}/${_unityFileName}")
1712 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
1714 message(STATUS "${_unityFile}")
1718 function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
1719 cotire_setup_file_extension_variables()
1720 if (NOT DEFINED _unityFileExt_${_language})
1721 set (${_unityFileVar} "" PARENT_SCOPE)
1724 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1725 cotire_get_intermediate_dir(_baseDir)
1728 set (_unityFiles "")
1729 set (_sourceFiles ${ARGN})
1730 foreach (_sourceFile ${_sourceFiles})
1731 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
1732 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
1733 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
1734 if (_index GREATER 0)
1735 # start new unity file segment
1736 math (EXPR _endIndex "${_index} - 1")
1737 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
1738 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
1740 set (_startIndex ${_index})
1742 math (EXPR _index "${_index} + 1")
1744 list (LENGTH _sourceFiles _numberOfSources)
1745 if (_startIndex EQUAL 0)
1746 # there is only a single unity file
1747 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
1748 elseif (_startIndex LESS _numberOfSources)
1749 # end with final unity file segment
1750 math (EXPR _endIndex "${_index} - 1")
1751 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
1752 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
1754 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
1756 message(STATUS "${_unityFiles}")
1760 function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
1761 cotire_setup_file_extension_variables()
1762 if (NOT DEFINED _unityFileExt_${_language})
1763 set (${_prefixFileVar} "" PARENT_SCOPE)
1766 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1767 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
1768 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
1769 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
1770 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
1773 function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar)
1774 cotire_setup_file_extension_variables()
1775 if (NOT DEFINED _prefixSourceFileExt_${_language})
1776 set (${_prefixSourceFileVar} "" PARENT_SCOPE)
1779 string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}")
1780 set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE)
1783 function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
1784 cotire_setup_file_extension_variables()
1786 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
1787 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
1788 elseif (DEFINED _prefixFileExt_${_language})
1789 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
1790 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
1792 set (_prefixFileBaseName "")
1793 set (_prefixFileName "")
1795 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
1796 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
1799 function (cotire_make_prefix_file_path _language _target _prefixFileVar)
1800 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
1801 set (${_prefixFileVar} "" PARENT_SCOPE)
1802 if (_prefixFileName)
1806 if (MSVC OR CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel")
1807 cotire_get_intermediate_dir(_baseDir)
1808 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
1813 function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileVar)
1814 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
1815 set (${_pchFileVar} "" PARENT_SCOPE)
1816 if (_prefixFileBaseName AND _prefixFileName)
1817 cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _msg)
1820 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
1823 cotire_get_intermediate_dir(_baseDir)
1824 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1825 # MSVC uses the extension .pch added to the prefix header base name
1826 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
1827 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
1828 # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended
1829 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE)
1830 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
1831 # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended
1832 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
1833 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
1834 # Intel uses the extension .pchi added to the prefix header base name
1835 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
1841 function (cotire_select_unity_source_files _unityFile _sourcesVar)
1842 set (_sourceFiles ${ARGN})
1843 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
1844 set (_startIndex ${CMAKE_MATCH_1})
1845 set (_endIndex ${CMAKE_MATCH_2})
1846 list (LENGTH _sourceFiles _numberOfSources)
1847 if (NOT _startIndex LESS _numberOfSources)
1848 math (EXPR _startIndex "${_numberOfSources} - 1")
1850 if (NOT _endIndex LESS _numberOfSources)
1851 math (EXPR _endIndex "${_numberOfSources} - 1")
1854 foreach (_index RANGE ${_startIndex} ${_endIndex})
1855 list (GET _sourceFiles ${_index} _file)
1856 list (APPEND _files "${_file}")
1859 set (_files ${_sourceFiles})
1861 set (${_sourcesVar} ${_files} PARENT_SCOPE)
1864 function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
1865 set (_dependencySources "")
1866 # depend on target's generated source files
1867 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN})
1868 if (_generatedSources)
1869 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
1870 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
1871 if (_excludedGeneratedSources)
1872 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
1874 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
1875 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
1876 if (_excludedNonDependencySources)
1877 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
1879 if (_generatedSources)
1880 list (APPEND _dependencySources ${_generatedSources})
1883 if (COTIRE_DEBUG AND _dependencySources)
1884 message (STATUS "${_language} ${_target} unity source depends on ${_dependencySources}")
1886 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
1889 function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
1890 # depend on target source files marked with custom COTIRE_DEPENDENCY property
1891 set (_dependencySources "")
1892 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN})
1893 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
1894 # GCC and clang raise a fatal error if a file is not found during preprocessing
1895 # thus we depend on target's generated source files for prefix header generation
1896 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN})
1897 if (_generatedSources)
1898 list (APPEND _dependencySources ${_generatedSources})
1901 if (COTIRE_DEBUG AND _dependencySources)
1902 message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}")
1904 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
1907 function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar _targetConfigScriptVar)
1908 set (COTIRE_TARGET_SOURCES ${ARGN})
1909 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES})
1910 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES})
1911 # set up variables to be configured
1912 set (COTIRE_TARGET_LANGUAGE "${_language}")
1913 cotire_determine_compiler_version("${COTIRE_TARGET_LANGUAGE}" COTIRE_${_language}_COMPILER)
1914 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
1915 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
1916 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
1917 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
1918 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
1919 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
1920 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
1921 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES})
1922 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES})
1923 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" COTIRE_INCLUDE_SYSTEM_FLAG)
1924 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
1925 foreach (_config ${_configurations})
1926 string (TOUPPER "${_config}" _upperConfig)
1927 cotire_get_target_include_directories(
1928 "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig})
1929 cotire_get_target_compile_definitions(
1930 "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
1931 cotire_get_target_compiler_flags(
1932 "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
1933 cotire_get_source_files_compile_definitions(
1934 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${COTIRE_TARGET_SOURCES})
1936 get_cmake_property(_vars VARIABLES)
1937 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
1938 # remove COTIRE_VERBOSE which is passed as a CMake define on command line
1939 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
1941 set (_contentsHasGeneratorExpressions FALSE)
1942 foreach (_var IN LISTS _matchVars ITEMS
1943 MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
1944 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
1945 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
1946 if (DEFINED ${_var})
1947 string (REPLACE "\"" "\\\"" _value "${${_var}}")
1948 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
1949 if (NOT _contentsHasGeneratorExpressions)
1950 if ("${_value}" MATCHES "\\$<.*>")
1951 set (_contentsHasGeneratorExpressions TRUE)
1956 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1957 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
1958 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
1959 if (_contentsHasGeneratorExpressions)
1960 # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time
1961 if (NOT CMAKE_VERSION VERSION_LESS "2.8.12")
1962 # the file(GENERATE ...) command requires cmake 2.8.12 or later
1963 set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>")
1964 set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}")
1965 file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}")
1967 message (WARNING "cotire: generator expression used in target ${_target}. This requires CMake 2.8.12 or later.")
1968 set (_targetCotireConfigScript "${_targetCotireScript}")
1971 set (_targetCotireConfigScript "${_targetCotireScript}")
1973 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
1974 set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE)
1977 function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _targetScript _prefixFile _pchFile)
1978 set (_sourceFiles ${ARGN})
1979 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
1980 # for Visual Studio and Intel, we attach the precompiled header compilation to the first source file
1981 # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion
1983 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1984 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1985 list (GET _sourceFiles 0 _hostFile)
1987 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1988 cotire_add_pch_compilation_flags(
1989 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
1990 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
1991 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
1992 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
1993 # make first source file depend on prefix header
1994 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
1995 # mark first source file as cotired to prevent it from being used in another cotired target
1996 set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}")
1998 elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
1999 # for makefile based generator, we add a custom command to precompile the prefix header
2001 cotire_set_cmd_to_prologue(_cmds)
2002 list (GET _sourceFiles 0 _hostFile)
2003 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
2004 file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
2006 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
2008 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
2010 OUTPUT "${_pchFile}"
2012 DEPENDS "${_prefixFile}"
2013 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
2014 WORKING_DIRECTORY "${_targetSourceDir}"
2015 COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM)
2020 function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile)
2021 set (_sourceFiles ${ARGN})
2022 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2023 # for Visual Studio and Intel, we include the precompiled header in all but the first source file
2024 # the first source file does the precompiled header compilation, see cotire_setup_pch_file_compilation
2025 list (LENGTH _sourceFiles _numberOfSourceFiles)
2026 if (_numberOfSourceFiles GREATER 1)
2027 # mark sources as cotired to prevent them from being used in another cotired target
2028 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2029 list (REMOVE_AT _sourceFiles 0)
2031 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
2032 cotire_add_prefix_pch_inclusion_flags(
2033 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
2034 "${_prefixFile}" "${_pchFile}" _flags)
2035 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2036 # make source files depend on precompiled header
2037 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2039 elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
2040 if (NOT _wholeTarget)
2041 # for makefile based generator, we force the inclusion of the prefix header for a subset
2042 # of the source files, if this is a multi-language target or has excluded files
2044 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
2045 cotire_add_prefix_pch_inclusion_flags(
2046 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
2047 "${_prefixFile}" "${_pchFile}" _flags)
2048 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2049 # mark sources as cotired to prevent them from being used in another cotired target
2050 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2052 # make source files depend on precompiled header
2053 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2057 function (cotire_setup_prefix_file_inclusion _language _target _prefixFile)
2058 set (_sourceFiles ${ARGN})
2059 # force the inclusion of the prefix header for the given source files
2061 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
2062 cotire_add_prefix_pch_inclusion_flags(
2063 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
2064 "${_prefixFile}" "" _flags)
2065 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2066 # mark sources as cotired to prevent them from being used in another cotired target
2067 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2068 # make source files depend on prefix header
2069 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2072 function (cotire_get_first_set_property_value _propertyValueVar _type _object)
2073 set (_properties ${ARGN})
2074 foreach (_property ${_properties})
2075 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
2077 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
2081 set (${_propertyValueVar} "" PARENT_SCOPE)
2084 function (cotire_setup_combine_command _language _sourceDir _targetScript _joinedFile _cmdsVar)
2085 set (_files ${ARGN})
2086 set (_filesPaths "")
2087 foreach (_file ${_files})
2088 if (IS_ABSOLUTE "${_file}")
2089 set (_filePath "${_file}")
2091 get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE)
2093 file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}")
2094 if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.")
2095 list (APPEND _filesPaths "${_fileRelPath}")
2097 list (APPEND _filesPaths "${_filePath}")
2100 cotire_set_cmd_to_prologue(_prefixCmd)
2101 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
2103 list (APPEND _prefixCmd "${_targetScript}")
2105 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
2107 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
2109 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
2110 file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
2111 get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE)
2112 get_filename_component(_joinedFileExt "${_joinedFile}" EXT)
2113 if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
2114 set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}")
2115 elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$")
2116 if (_joinedFileExt MATCHES "^\\.c")
2117 set (_comment "Generating ${_language} prefix source ${_joinedFileRelPath}")
2119 set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}")
2122 set (_comment "Generating ${_joinedFileRelPath}")
2125 OUTPUT "${_joinedFile}"
2126 COMMAND ${_prefixCmd}
2128 COMMENT "${_comment}"
2129 WORKING_DIRECTORY "${_sourceDir}" VERBATIM)
2130 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2131 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2134 function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget)
2136 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
2137 # if necessary, we also generate a single prefix header which includes all language specific prefix headers
2138 set (_prefixFiles "")
2139 foreach (_language ${_languages})
2140 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2142 list (APPEND _prefixFiles "${_prefixFile}")
2146 list (LENGTH _prefixFiles _numberOfPrefixFiles)
2147 if (_numberOfPrefixFiles GREATER 1)
2148 cotire_make_prefix_file_path("" ${_target} _prefixHeader)
2149 cotire_setup_combine_command("" "${_targetSourceDir}" "" "${_prefixHeader}" _cmds ${_prefixFiles})
2151 set (_prefixHeader "${_prefixFiles}")
2154 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
2156 add_custom_command(TARGET "${_target}"
2158 WORKING_DIRECTORY "${_targetSourceDir}"
2159 COMMENT "Updating target ${_target} prefix headers" VERBATIM)
2160 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
2161 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
2162 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
2163 elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
2164 # for makefile based generator, we force inclusion of the prefix header for all target source files
2165 # if this is a single-language target without any excluded files
2167 set (_language "${_languages}")
2168 # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level
2169 # see cotire_setup_pch_file_inclusion
2170 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2171 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2172 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
2174 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
2175 cotire_add_prefix_pch_inclusion_flags(
2176 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
2177 "${_prefixFile}" "${_pchFile}" _flags)
2178 set_property(TARGET ${_target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2184 function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _targetConfigScript _unityFiles _cmdsVar)
2185 set (_dependencySources "")
2186 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
2187 foreach (_unityFile ${_unityFiles})
2188 file (RELATIVE_PATH _unityFileRelPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
2189 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
2190 # set up compiled unity source dependencies
2191 # this ensures that missing source files are generated before the unity file is compiled
2192 if (COTIRE_DEBUG AND _dependencySources)
2193 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
2195 if (_dependencySources)
2196 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_dependencySources})
2198 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2199 # unity file compilation results in potentially huge object file, thus use /bigobj by default under MSVC and Windows Intel
2200 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
2202 cotire_set_cmd_to_prologue(_unityCmd)
2203 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}")
2205 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_targetScript}")
2208 OUTPUT "${_unityFile}"
2209 COMMAND ${_unityCmd}
2210 DEPENDS "${_targetScript}"
2211 COMMENT "Generating ${_language} unity source ${_unityFileRelPath}"
2212 WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM)
2213 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
2215 list (LENGTH _unityFiles _numberOfUnityFiles)
2216 if (_numberOfUnityFiles GREATER 1)
2217 # create a joint unity file from all unity file segments
2218 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
2219 cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetConfigScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles})
2221 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2224 function (cotire_setup_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar)
2225 set (_sourceFiles ${ARGN})
2226 set (_dependencySources "")
2227 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
2228 cotire_set_cmd_to_prologue(_prefixCmd)
2229 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}")
2230 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
2232 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources}")
2234 file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
2235 get_filename_component(_prefixFileExt "${_prefixFile}" EXT)
2236 if (_prefixFileExt MATCHES "^\\.c")
2237 set (_comment "Generating ${_language} prefix source ${_prefixFileRelPath}")
2239 set (_comment "Generating ${_language} prefix header ${_prefixFileRelPath}")
2242 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
2243 COMMAND ${_prefixCmd}
2244 DEPENDS "${_unityFile}" ${_dependencySources}
2245 COMMENT "${_comment}"
2246 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
2247 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2248 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2251 function (cotire_setup_prefix_generation_from_unity_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar)
2252 set (_sourceFiles ${ARGN})
2253 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2254 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2255 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2257 set (_prefixSourceFile "${_prefixFile}")
2259 list (LENGTH _unityFiles _numberOfUnityFiles)
2260 if (_numberOfUnityFiles GREATER 1)
2261 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
2262 cotire_setup_prefix_generation_command(
2263 ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
2264 "${_prefixSourceFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles})
2266 cotire_setup_prefix_generation_command(
2267 ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
2268 "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2270 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2271 cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" ${_cmdsVar} ${_prefixSourceFile})
2273 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2276 function (cotire_setup_prefix_generation_from_provided_command _language _target _targetSourceDir _targetScript _prefixFile _cmdsVar)
2277 set (_prefixHeaderFiles ${ARGN})
2278 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2279 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2280 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2282 set (_prefixSourceFile "${_prefixFile}")
2284 cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles})
2285 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2286 cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2288 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2291 function (cotire_init_cotire_target_properties _target)
2292 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2294 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2296 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2298 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2300 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2302 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2304 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2306 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2307 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2308 if (NOT _isRelative)
2309 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2312 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2314 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2316 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2318 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2320 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2322 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2324 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET)
2326 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "")
2328 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2330 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2331 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2333 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2338 function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2339 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2340 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2341 string (REPLACE ";" " " _languagesStr "${_languages}")
2342 math (EXPR _numberOfExcludedFiles "${ARGC} - 4")
2343 if (_numberOfExcludedFiles EQUAL 0)
2344 set (_excludedStr "")
2345 elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4)
2346 string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}")
2348 set (_excludedStr "excluding ${_numberOfExcludedFiles} files")
2352 set (_targetMsg "Target ${_target} cannot be cotired.")
2354 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2356 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2357 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2359 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2361 elseif (NOT _targetUsePCH)
2363 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.")
2365 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2368 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2370 elseif (NOT _targetAddSCU)
2372 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.")
2374 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2378 set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.")
2380 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2383 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2386 function (cotire_choose_target_languages _targetSourceDir _target _targetLanguagesVar)
2387 set (_languages ${ARGN})
2388 set (_allSourceFiles "")
2389 set (_allExcludedSourceFiles "")
2390 set (_allCotiredSourceFiles "")
2391 set (_targetLanguages "")
2392 get_target_property(_targetType ${_target} TYPE)
2393 get_target_property(_targetSourceFiles ${_target} SOURCES)
2394 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2395 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2396 set (_disableMsg "")
2397 foreach (_language ${_languages})
2398 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2399 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2400 if (_prefixHeader OR _unityBuildFile)
2401 message (STATUS "cotire: target ${_target} has already been cotired.")
2402 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2405 if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$")
2406 cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg)
2408 set (_targetUsePCH FALSE)
2411 set (_sourceFiles "")
2412 set (_excludedSources "")
2413 set (_cotiredSources "")
2414 cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2415 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2416 list (APPEND _targetLanguages ${_language})
2419 list (APPEND _allSourceFiles ${_sourceFiles})
2421 if (_excludedSources)
2422 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2424 if (_cotiredSources)
2425 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2428 set (_targetMsgLevel STATUS)
2429 if (NOT _targetLanguages)
2430 string (REPLACE ";" " or " _languagesStr "${_languages}")
2431 set (_disableMsg "No ${_languagesStr} source files.")
2432 set (_targetUsePCH FALSE)
2433 set (_targetAddSCU FALSE)
2436 list (LENGTH _allSourceFiles _numberOfSources)
2437 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2438 set (_disableMsg "Too few applicable sources.")
2439 set (_targetUsePCH FALSE)
2440 elseif (_allCotiredSourceFiles)
2441 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2442 list (REMOVE_DUPLICATES _cotireTargets)
2443 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2444 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2445 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2446 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2447 set (_targetMsgLevel SEND_ERROR)
2448 set (_targetUsePCH FALSE)
2449 elseif (XCODE AND _allExcludedSourceFiles)
2450 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2451 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2452 set (_targetUsePCH FALSE)
2453 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2454 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2455 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2456 set (_targetUsePCH FALSE)
2459 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2460 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2461 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2463 if (NOT DEFINED COTIREMSG_${_target})
2464 set (COTIREMSG_${_target} "")
2466 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2467 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2468 # cache message to avoid redundant messages on re-configure
2469 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2470 message (${_targetMsgLevel} "${_targetMsg}")
2473 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2476 function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2477 set (_sourceFiles ${ARGN})
2478 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2479 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2480 set (_numberOfThreads "${CMAKE_MATCH_2}")
2481 if (NOT _numberOfThreads)
2482 # use all available cores
2483 ProcessorCount(_numberOfThreads)
2485 list (LENGTH _sourceFiles _numberOfSources)
2486 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2487 # a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files
2488 if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2489 set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2491 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2492 set (_maxIncludes 0)
2495 message (STATUS "${_target} unity source max includes = ${_maxIncludes}")
2497 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2500 function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTargetVar _cmdsVar)
2501 set (${_cmdsVar} "" PARENT_SCOPE)
2502 get_target_property(_targetSourceFiles ${_target} SOURCES)
2503 set (_sourceFiles "")
2504 set (_excludedSources "")
2505 set (_cotiredSources "")
2506 cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2507 if (NOT _sourceFiles AND NOT _cotiredSources)
2510 set (_wholeTarget ${${_wholeTargetVar}})
2512 # check for user provided unity source file list
2513 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
2514 if (NOT _unitySourceFiles)
2515 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
2517 cotire_generate_target_script(
2518 ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles})
2519 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
2520 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
2521 if (NOT _unityFiles)
2524 cotire_setup_unity_generation_commands(
2525 ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
2526 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
2528 # check for user provided prefix header files
2529 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
2530 if (_prefixHeaderFiles)
2531 cotire_setup_prefix_generation_from_provided_command(
2532 ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
2534 cotire_setup_prefix_generation_from_unity_command(
2535 ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles})
2537 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2539 cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile)
2541 cotire_setup_pch_file_compilation(
2542 ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
2543 if (_excludedSources)
2544 set (_wholeTarget FALSE)
2546 cotire_setup_pch_file_inclusion(
2547 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
2549 elseif (_prefixHeaderFiles)
2550 # user provided prefix header must be included
2551 cotire_setup_prefix_file_inclusion(
2552 ${_language} ${_target} "${_prefixFile}" ${_sourceFiles})
2555 # mark target as cotired for language
2556 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
2558 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
2559 if (_targetUsePCH AND _pchFile)
2560 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
2563 set (${_wholeTargetVar} ${_wholeTarget} PARENT_SCOPE)
2564 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
2567 function (cotire_setup_clean_target _target)
2568 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
2569 if (NOT TARGET "${_cleanTargetName}")
2570 cotire_set_cmd_to_prologue(_cmds)
2571 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
2572 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
2573 add_custom_target(${_cleanTargetName} COMMAND ${_cmds} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2574 COMMENT "Cleaning up target ${_target} cotire generated files" VERBATIM)
2575 cotire_init_target("${_cleanTargetName}")
2579 function (cotire_setup_pch_target _languages _configurations _target)
2580 if ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
2581 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
2582 set (_dependsFiles "")
2583 foreach (_language ${_languages})
2584 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
2585 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2586 # Visual Studio and Intel only create precompiled header as a side effect
2587 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
2589 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
2591 list (APPEND _dependsFiles "${_dependsFile}")
2595 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
2596 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
2597 cotire_init_target("${_pchTargetName}")
2598 cotire_add_to_pch_all_target(${_pchTargetName})
2601 # for other generators, we add the "clean all" target to clean up the precompiled header
2602 cotire_setup_clean_all_target()
2606 function (cotire_setup_unity_build_target _languages _configurations _targetSourceDir _target)
2607 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
2608 if (NOT _unityTargetName)
2609 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
2611 # determine unity target sub type
2612 get_target_property(_targetType ${_target} TYPE)
2613 if ("${_targetType}" STREQUAL "EXECUTABLE")
2614 set (_unityTargetSubType "")
2615 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
2616 set (_unityTargetSubType "${CMAKE_MATCH_1}")
2618 message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.")
2621 # determine unity target sources
2622 get_target_property(_targetSourceFiles ${_target} SOURCES)
2623 set (_unityTargetSources ${_targetSourceFiles})
2624 foreach (_language ${_languages})
2625 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
2627 # remove source files that are included in the unity source
2628 set (_sourceFiles "")
2629 set (_excludedSources "")
2630 set (_cotiredSources "")
2631 cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2632 if (_sourceFiles OR _cotiredSources)
2633 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
2635 # if cotire is applied to a target which has not been added in the current source dir,
2636 # non-existing files cannot be referenced from the unity build target (this is a CMake restriction)
2637 if (NOT "${_targetSourceDir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
2638 set (_nonExistingFiles "")
2639 foreach (_file ${_unityTargetSources})
2640 if (NOT EXISTS "${_file}")
2641 list (APPEND _nonExistingFiles "${_file}")
2644 if (_nonExistingFiles)
2646 message (STATUS "removing non-existing ${_nonExistingFiles} from ${_unityTargetName}")
2648 list (REMOVE_ITEM _unityTargetSources ${_nonExistingFiles})
2651 # add unity source files instead
2652 list (APPEND _unityTargetSources ${_unityFiles})
2656 message (STATUS "add ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
2658 # generate unity target
2659 if ("${_targetType}" STREQUAL "EXECUTABLE")
2660 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
2662 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
2664 set (_outputDirProperties
2665 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
2666 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
2667 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
2668 # copy output location properties
2669 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
2670 set (_setDefaultOutputDir TRUE)
2671 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
2672 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
2674 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
2675 cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties})
2676 foreach (_property ${_properties})
2677 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
2679 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
2680 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
2681 set (_setDefaultOutputDir FALSE)
2684 if (_setDefaultOutputDir)
2685 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
2688 if (_setDefaultOutputDir)
2689 set_target_properties(${_unityTargetName} PROPERTIES
2690 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
2691 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
2692 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
2695 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
2698 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2699 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
2700 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
2701 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
2702 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
2703 PREFIX <CONFIG>_POSTFIX SUFFIX)
2704 # copy compile stuff
2705 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2706 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
2707 COMPILE_FLAGS COMPILE_OPTIONS
2708 Fortran_FORMAT Fortran_MODULE_DIRECTORY
2710 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
2711 POSITION_INDEPENDENT_CODE
2712 C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN)
2713 # copy interface stuff
2714 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2715 COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN COMPATIBLE_INTERFACE_STRING
2716 INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_INCLUDE_DIRECTORIES
2717 INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
2718 INTERFACE_AUTOUIC_OPTIONS)
2720 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2721 BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
2722 LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED
2723 LINK_FLAGS LINK_FLAGS_<CONFIG>
2724 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
2725 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
2726 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
2727 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
2728 NO_SONAME SOVERSION VERSION)
2730 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2731 AUTOMOC AUTOMOC_MOC_OPTIONS AUTOUIC AUTOUIC_OPTIONS AUTORCC AUTORCC_OPTIONS
2732 AUTOGEN_TARGET_DEPENDS)
2734 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2735 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
2736 # copy Apple platform specific stuff
2737 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2738 BUNDLE BUNDLE_EXTENSION FRAMEWORK INSTALL_NAME_DIR MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST
2739 MACOSX_RPATH OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE)
2740 # copy Windows platform specific stuff
2741 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
2743 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
2744 VS_DOTNET_REFERENCES VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE VS_KEYWORD
2745 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
2746 VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES WIN32_EXECUTABLE)
2747 # use output name from original target
2748 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
2749 if (NOT _targetOutputName)
2750 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
2752 # use export symbol from original target
2753 cotire_get_target_export_symbol("${_target}" _defineSymbol)
2755 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
2756 if ("${_targetType}" STREQUAL "EXECUTABLE")
2757 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
2760 cotire_init_target(${_unityTargetName})
2761 cotire_add_to_unity_all_target(${_unityTargetName})
2762 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
2763 endfunction(cotire_setup_unity_build_target)
2765 function (cotire_target _target)
2767 set(_oneValueArgs SOURCE_DIR BINARY_DIR)
2768 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
2769 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
2770 if (NOT _option_SOURCE_DIR)
2771 set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
2773 if (NOT _option_BINARY_DIR)
2774 set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
2776 if (NOT _option_LANGUAGES)
2777 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
2779 if (NOT _option_CONFIGURATIONS)
2780 if (CMAKE_CONFIGURATION_TYPES)
2781 set (_option_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
2782 elseif (CMAKE_BUILD_TYPE)
2783 set (_option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}")
2785 set (_option_CONFIGURATIONS "None")
2789 get_target_property(_imported ${_target} IMPORTED)
2791 message (WARNING "cotire: imported target ${_target} cannot be cotired.")
2795 get_target_property(_aliasName ${_target} ALIASED_TARGET)
2798 message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.")
2800 set (_target ${_aliasName})
2802 # check if target needs to be cotired for build type
2803 # when using configuration types, the test is performed at build time
2804 cotire_init_cotire_target_properties(${_target})
2805 if (NOT CMAKE_CONFIGURATION_TYPES)
2806 if (CMAKE_BUILD_TYPE)
2807 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
2809 list (FIND _option_CONFIGURATIONS "None" _index)
2811 if (_index EQUAL -1)
2813 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
2818 # choose languages that apply to the target
2819 cotire_choose_target_languages("${_option_SOURCE_DIR}" "${_target}" _targetLanguages ${_option_LANGUAGES})
2820 if (NOT _targetLanguages)
2823 list (LENGTH _targetLanguages _numberOfLanguages)
2824 if (_numberOfLanguages GREATER 1)
2825 set (_wholeTarget FALSE)
2827 set (_wholeTarget TRUE)
2830 foreach (_language ${_targetLanguages})
2831 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}"
2832 "${_option_SOURCE_DIR}" "${_option_BINARY_DIR}" ${_target} _wholeTarget _cmd)
2834 list (APPEND _cmds ${_cmd})
2837 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2839 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" "${_option_SOURCE_DIR}" ${_target})
2841 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2843 cotire_setup_target_pch_usage("${_targetLanguages}" "${_option_SOURCE_DIR}" ${_target} ${_wholeTarget} ${_cmds})
2844 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
2846 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
2847 if (_targetAddCleanTarget)
2848 cotire_setup_clean_target(${_target})
2850 endfunction(cotire_target)
2852 function (cotire_map_libraries _strategy _mappedLibrariesVar)
2853 set (_mappedLibraries "")
2854 foreach (_library ${ARGN})
2855 if (TARGET "${_library}" AND "${_strategy}" MATCHES "COPY_UNITY")
2856 get_target_property(_libraryUnityTargetName ${_library} COTIRE_UNITY_TARGET_NAME)
2857 if (TARGET "${_libraryUnityTargetName}")
2858 list (APPEND _mappedLibraries "${_libraryUnityTargetName}")
2860 list (APPEND _mappedLibraries "${_library}")
2863 list (APPEND _mappedLibraries "${_library}")
2866 list (REMOVE_DUPLICATES _mappedLibraries)
2867 set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE)
2870 function (cotire_target_link_libraries _target)
2871 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
2872 if (TARGET "${_unityTargetName}")
2873 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
2875 message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}")
2877 if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$")
2878 if (CMAKE_VERSION VERSION_LESS "2.8.11")
2879 message (WARNING "cotire: unity target link strategy ${_linkLibrariesStrategy} requires CMake 2.8.11 or later. Defaulting to NONE for ${_target}.")
2881 get_target_property(_linkLibraries ${_target} LINK_LIBRARIES)
2882 get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES)
2883 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries} ${_interfaceLinkLibraries})
2885 message (STATUS "unity target ${_unityTargetName} libraries: ${_unityLinkLibraries}")
2887 if (_unityLinkLibraries)
2888 target_link_libraries(${_unityTargetName} ${_unityLinkLibraries})
2893 endfunction(cotire_target_link_libraries)
2895 function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
2897 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
2899 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
2901 # filter files in intermediate directory
2902 set (_filesToRemove "")
2903 foreach (_file ${_cotireFiles})
2904 get_filename_component(_dir "${_file}" PATH)
2905 get_filename_component(_dirName "${_dir}" NAME)
2906 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
2907 list (APPEND _filesToRemove "${_file}")
2912 message (STATUS "removing ${_filesToRemove}")
2914 file (REMOVE ${_filesToRemove})
2918 function (cotire_init_target _targetName)
2919 if (COTIRE_TARGETS_FOLDER)
2920 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
2923 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
2927 function (cotire_add_to_pch_all_target _pchTargetName)
2928 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
2929 if (NOT TARGET "${_targetName}")
2930 add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
2931 cotire_init_target("${_targetName}")
2933 cotire_setup_clean_all_target()
2934 add_dependencies(${_targetName} ${_pchTargetName})
2937 function (cotire_add_to_unity_all_target _unityTargetName)
2938 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
2939 if (NOT TARGET "${_targetName}")
2940 add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
2941 cotire_init_target("${_targetName}")
2943 cotire_setup_clean_all_target()
2944 add_dependencies(${_targetName} ${_unityTargetName})
2947 function (cotire_setup_clean_all_target)
2948 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
2949 if (NOT TARGET "${_targetName}")
2950 cotire_set_cmd_to_prologue(_cmds)
2951 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
2952 add_custom_target(${_targetName} COMMAND ${_cmds}
2953 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Cleaning up all cotire generated files" VERBATIM)
2954 cotire_init_target("${_targetName}")
2960 set(_oneValueArgs SOURCE_DIR BINARY_DIR)
2961 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
2962 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
2963 set (_targets ${_option_UNPARSED_ARGUMENTS})
2964 if (NOT _option_SOURCE_DIR)
2965 set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
2967 if (NOT _option_BINARY_DIR)
2968 set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
2970 foreach (_target ${_targets})
2971 if (TARGET ${_target})
2972 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}
2973 SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}")
2975 message (WARNING "cotire: ${_target} is not a target.")
2978 foreach (_target ${_targets})
2979 if (TARGET ${_target})
2980 cotire_target_link_libraries(${_target})
2985 if (CMAKE_SCRIPT_MODE_FILE)
2987 # cotire is being run in script mode
2988 # locate -P on command args
2989 set (COTIRE_ARGC -1)
2990 foreach (_index RANGE ${CMAKE_ARGC})
2991 if (COTIRE_ARGC GREATER -1)
2992 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
2993 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
2994 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
2999 # include target script if available
3000 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
3001 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
3002 include("${COTIRE_ARGV2}")
3006 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
3010 # for MSVC, compiler IDs may not always be set correctly
3012 set (CMAKE_C_COMPILER_ID "MSVC")
3013 set (CMAKE_CXX_COMPILER_ID "MSVC")
3017 if (NOT COTIRE_BUILD_TYPE)
3018 set (COTIRE_BUILD_TYPE "None")
3020 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
3021 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
3022 set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}})
3023 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
3024 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
3025 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
3026 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
3027 if (_index GREATER -1)
3028 set (_sources ${COTIRE_TARGET_SOURCES})
3029 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
3032 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
3035 set (_sourcesDefinitions "")
3037 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
3038 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
3039 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
3040 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
3042 if ("${COTIRE_ARGV1}" STREQUAL "unity")
3044 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
3045 cotire_generate_unity_source(
3046 "${COTIRE_ARGV3}" ${_sources}
3047 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3048 DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV2}"
3049 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
3050 PRE_UNDEFS ${_targetPreUndefs}
3051 POST_UNDEFS ${_targetPostUndefs}
3052 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
3053 SOURCES_POST_UNDEFS ${_sourcesPostUndefs})
3055 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
3058 foreach (_index RANGE 4 ${COTIRE_ARGC})
3059 if (COTIRE_ARGV${_index})
3060 list (APPEND _files "${COTIRE_ARGV${_index}}")
3064 cotire_generate_prefix_header(
3065 "${COTIRE_ARGV3}" ${_files}
3066 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3067 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3068 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3069 COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3070 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3071 DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}
3072 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
3073 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
3074 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
3075 INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}"
3076 INCLUDE_DIRECTORIES ${_includeDirs}
3077 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3078 COMPILE_DEFINITIONS ${_compileDefinitions}
3079 COMPILE_FLAGS ${_compileFlags})
3081 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
3084 foreach (_index RANGE 5 ${COTIRE_ARGC})
3085 if (COTIRE_ARGV${_index})
3086 list (APPEND _files "${COTIRE_ARGV${_index}}")
3090 cotire_precompile_prefix_header(
3091 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
3092 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3093 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3094 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3095 COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3096 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3097 INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}"
3098 INCLUDE_DIRECTORIES ${_includeDirs}
3099 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3100 COMPILE_DEFINITIONS ${_compileDefinitions}
3101 COMPILE_FLAGS ${_compileFlags})
3103 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
3105 if (COTIRE_TARGET_LANGUAGE)
3111 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
3112 if (COTIRE_ARGV${_index})
3113 list (APPEND _files "${COTIRE_ARGV${_index}}")
3116 if (COTIRE_TARGET_LANGUAGE)
3117 cotire_generate_unity_source(${_files} LANGUAGE "${COTIRE_TARGET_LANGUAGE}")
3119 cotire_generate_unity_source(${_files})
3122 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
3124 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
3127 message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".")
3132 # cotire is being run in include mode
3133 # set up all variable and property definitions
3135 unset (COTIRE_C_COMPILER_VERSION CACHE)
3136 unset (COTIRE_CXX_COMPILER_VERSION CACHE)
3138 if (NOT DEFINED COTIRE_DEBUG_INIT)
3139 if (DEFINED COTIRE_DEBUG)
3140 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
3142 set (COTIRE_DEBUG_INIT FALSE)
3145 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
3147 if (NOT DEFINED COTIRE_VERBOSE_INIT)
3148 if (DEFINED COTIRE_VERBOSE)
3149 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
3151 set (COTIRE_VERBOSE_INIT FALSE)
3154 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
3156 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
3157 "Ignore headers with the listed file extensions from the generated prefix header.")
3159 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
3160 "Ignore headers from these directories when generating the prefix header.")
3162 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
3163 "Ignore sources with the listed file extensions from the generated unity source.")
3165 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING
3166 "Minimum number of sources in target required to enable use of precompiled header.")
3168 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
3169 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
3170 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
3171 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
3172 # enable parallelization for generators that run multiple jobs by default
3173 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
3175 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
3178 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
3179 "Maximum number of source files to include in a single unity source file.")
3181 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
3182 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
3184 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
3185 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
3187 if (NOT COTIRE_INTDIR)
3188 set (COTIRE_INTDIR "cotire")
3190 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
3191 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
3193 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
3194 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
3196 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
3197 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
3199 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
3200 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
3202 if (NOT COTIRE_PCH_TARGET_SUFFIX)
3203 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
3205 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
3206 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
3208 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
3209 set (COTIRE_TARGETS_FOLDER "cotire")
3211 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
3212 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
3213 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
3214 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
3216 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
3220 # define cotire cache variables
3223 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
3224 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3226 "The variable can be set to a semicolon separated list of include directories."
3227 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3228 "If not defined, defaults to empty list."
3232 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
3233 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
3235 "The variable can be set to a semicolon separated list of file extensions."
3236 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
3237 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
3238 "If not defined, defaults to inc;inl;ipp."
3242 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
3243 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
3245 "The variable can be set to a semicolon separated list of file extensions."
3246 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
3247 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
3248 "If not defined, defaults to m;mm."
3252 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
3253 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
3255 "The variable can be set to an integer > 0."
3256 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
3257 "If not defined, defaults to 3."
3261 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
3262 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3264 "This may be set to an integer >= 0."
3265 "If 0, cotire will only create a single unity source file."
3266 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
3267 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
3268 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
3269 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3270 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
3273 # define cotire directory properties
3276 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
3277 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
3279 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
3283 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
3284 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
3286 "See target property COTIRE_ADD_UNITY_BUILD."
3290 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
3291 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
3293 "See target property COTIRE_ADD_CLEAN."
3297 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
3298 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3300 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
3304 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
3305 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3307 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
3311 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3312 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
3314 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
3318 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3319 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
3321 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
3325 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
3326 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3328 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3332 DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT"
3333 BRIEF_DOCS "Define strategy for setting up the unity target's link libraries."
3335 "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT."
3338 # define cotire target properties
3341 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
3342 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
3344 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
3345 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
3346 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
3347 "The target name will be set to this target's name with the suffix _pch appended."
3348 "Inherited from directory."
3353 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
3354 BRIEF_DOCS "Add a new target that performs a unity build for this target."
3356 "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources."
3357 "Most of the relevant target properties will be copied from this target to the new unity build target."
3358 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
3359 "The unity target name will be set to this target's name with the suffix _unity appended."
3360 "Inherited from directory."
3365 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
3366 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
3368 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
3369 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
3370 "Inherited from directory."
3371 "Defaults to FALSE."
3375 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
3376 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3378 "The property can be set to a list of directories."
3379 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3380 "Inherited from directory."
3381 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
3385 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
3386 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3388 "The property can be set to a list of directories."
3389 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
3390 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
3391 "the option which yields the closer relative path match wins."
3392 "Inherited from directory."
3393 "If not set, this property is initialized to the empty list."
3397 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
3398 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
3400 "This may be set to a semicolon-separated list of preprocessor symbols."
3401 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
3402 "Inherited from directory."
3403 "Defaults to empty string."
3407 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
3408 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
3410 "This may be set to a semicolon-separated list of preprocessor symbols."
3411 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
3412 "Inherited from directory."
3413 "Defaults to empty string."
3417 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
3418 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3420 "This may be set to an integer > 0."
3421 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
3422 "If not set, cotire will only create a single unity source file."
3423 "Inherited from directory."
3424 "Defaults to empty."
3428 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
3429 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
3431 "If set, cotire will only add the given file(s) to the generated unity source file."
3432 "If not set, cotire will add all the target source files to the generated unity source file."
3433 "The property can be set to a user provided unity source file."
3434 "Defaults to empty."
3438 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
3439 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
3441 "If set, cotire will add the given header file(s) to the generated prefix header file."
3442 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
3443 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
3444 "Defaults to empty."
3448 TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED
3449 BRIEF_DOCS "Define strategy for setting up unity target's link libraries."
3451 "If this property is empty, the generated unity target's link libraries have to be set up manually."
3452 "If this property is set to COPY, the unity target's link libraries will be copied from this target."
3453 "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets."
3454 "Inherited from directory."
3455 "Defaults to empty."
3459 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
3460 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
3462 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
3463 "Defaults to empty string."
3467 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
3468 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
3470 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
3471 "Defaults to empty string."
3475 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
3476 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
3478 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
3479 "Defaults to empty string."
3483 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
3484 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
3486 "This property can be set to the desired name of the unity target that will be created by cotire."
3487 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
3488 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
3489 "Defaults to empty string."
3492 # define cotire source properties
3495 SOURCE PROPERTY "COTIRE_EXCLUDED"
3496 BRIEF_DOCS "Do not modify source file's build command."
3498 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
3499 "The source file will also be excluded from the generated unity source file."
3500 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
3501 "Defaults to FALSE."
3505 SOURCE PROPERTY "COTIRE_DEPENDENCY"
3506 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
3508 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
3509 "If the file is modified, cotire will re-generate the prefix header source upon build."
3510 "Defaults to FALSE."
3514 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3515 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
3517 "This may be set to a semicolon-separated list of preprocessor symbols."
3518 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
3519 "Defaults to empty string."
3523 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3524 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
3526 "This may be set to a semicolon-separated list of preprocessor symbols."
3527 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
3528 "Defaults to empty string."
3532 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
3533 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
3535 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
3536 "The new unity source file will include this source file as the first one."
3537 "This property essentially works as a separator for unity source files."
3538 "Defaults to FALSE."
3542 SOURCE PROPERTY "COTIRE_TARGET"
3543 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
3545 "cotire sets this property to the name of target, that the source file's build command has been altered for."
3546 "Defaults to empty string."
3549 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")