1 # - cotire (compile time reducer)
3 # See the cotire manual for usage hints.
5 #=============================================================================
6 # Copyright 2012-2016 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 cmake_minimum_required(VERSION 2.8.12)
41 if (NOT CMAKE_SCRIPT_MODE_FILE)
45 set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
46 set (COTIRE_CMAKE_MODULE_VERSION "1.7.9")
48 # activate select policies
50 # Compiler id for Apple Clang is now AppleClang
51 cmake_policy(SET CMP0025 NEW)
55 # disallow use of the LOCATION target property
56 cmake_policy(SET CMP0026 NEW)
60 # targets may not link directly to themselves
61 cmake_policy(SET CMP0038 NEW)
65 # utility targets may not have link dependencies
66 cmake_policy(SET CMP0039 NEW)
70 # target in the TARGET signature of add_custom_command() must exist
71 cmake_policy(SET CMP0040 NEW)
75 # error on non-existent target in get_target_property
76 cmake_policy(SET CMP0045 NEW)
80 # error on non-existent dependency in add_dependencies
81 cmake_policy(SET CMP0046 NEW)
85 # do not expand variables in target source entries
86 cmake_policy(SET CMP0049 NEW)
90 # disallow add_custom_command SOURCE signatures
91 cmake_policy(SET CMP0050 NEW)
95 # include TARGET_OBJECTS expressions in a target's SOURCES property
96 cmake_policy(SET CMP0051 NEW)
100 # simplify variable reference and escape sequence evaluation
101 cmake_policy(SET CMP0053 NEW)
105 # only interpret if() arguments as variables or keywords when unquoted
106 cmake_policy(SET CMP0054 NEW)
109 include(CMakeParseArguments)
110 include(ProcessorCount)
112 function (cotire_get_configuration_types _configsVar)
114 if (CMAKE_CONFIGURATION_TYPES)
115 list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES})
117 if (CMAKE_BUILD_TYPE)
118 list (APPEND _configs "${CMAKE_BUILD_TYPE}")
121 list (REMOVE_DUPLICATES _configs)
122 set (${_configsVar} ${_configs} PARENT_SCOPE)
124 set (${_configsVar} "None" PARENT_SCOPE)
128 function (cotire_get_source_file_extension _sourceFile _extVar)
129 # get_filename_component returns extension from first occurrence of . in file name
130 # this function computes the extension from last occurrence of . in file name
131 string (FIND "${_sourceFile}" "." _index REVERSE)
132 if (_index GREATER -1)
133 math (EXPR _index "${_index} + 1")
134 string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
138 set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
141 macro (cotire_check_is_path_relative_to _path _isRelativeVar)
142 set (${_isRelativeVar} FALSE)
143 if (IS_ABSOLUTE "${_path}")
144 foreach (_dir ${ARGN})
145 file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
146 if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
147 set (${_isRelativeVar} TRUE)
154 function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
155 if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
156 set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
158 set (_languageExtensions "")
160 if (CMAKE_${_language}_IGNORE_EXTENSIONS)
161 set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}")
163 set (_ignoreExtensions "")
165 if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS)
166 set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}")
168 set (_excludeExtensions "")
170 if (COTIRE_DEBUG AND _languageExtensions)
171 message (STATUS "${_language} source file extensions: ${_languageExtensions}")
173 if (COTIRE_DEBUG AND _ignoreExtensions)
174 message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}")
176 if (COTIRE_DEBUG AND _excludeExtensions)
177 message (STATUS "${_language} exclude extensions: ${_excludeExtensions}")
179 if (CMAKE_VERSION VERSION_LESS "3.1.0")
180 set (_allSourceFiles ${ARGN})
182 # as of CMake 3.1 target sources may contain generator expressions
183 # since we cannot obtain required property information about source files added
184 # through generator expressions at configure time, we filter them out
185 string (GENEX_STRIP "${ARGN}" _allSourceFiles)
187 set (_filteredSourceFiles "")
188 set (_excludedSourceFiles "")
189 foreach (_sourceFile ${_allSourceFiles})
190 get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY)
191 get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT)
192 get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC)
193 if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic)
194 cotire_get_source_file_extension("${_sourceFile}" _sourceExt)
196 list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex)
197 if (_ignoreIndex LESS 0)
198 list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex)
199 if (_excludeIndex GREATER -1)
200 list (APPEND _excludedSourceFiles "${_sourceFile}")
202 list (FIND _languageExtensions "${_sourceExt}" _sourceIndex)
203 if (_sourceIndex GREATER -1)
204 # consider source file unless it is excluded explicitly
205 get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED)
206 if (_sourceIsExcluded)
207 list (APPEND _excludedSourceFiles "${_sourceFile}")
209 list (APPEND _filteredSourceFiles "${_sourceFile}")
212 get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE)
213 if ("${_sourceLanguage}" STREQUAL "${_language}")
214 # add to excluded sources, if file is not ignored and has correct language without having the correct extension
215 list (APPEND _excludedSourceFiles "${_sourceFile}")
223 # separate filtered source files from already cotired ones
224 # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire
225 set (_sourceFiles "")
226 set (_cotiredSourceFiles "")
227 foreach (_sourceFile ${_filteredSourceFiles})
228 get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET)
229 if (_sourceIsCotired)
230 list (APPEND _cotiredSourceFiles "${_sourceFile}")
232 get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS)
233 if (_sourceCompileFlags)
234 # add to excluded sources, if file has custom compile flags
235 list (APPEND _excludedSourceFiles "${_sourceFile}")
237 list (APPEND _sourceFiles "${_sourceFile}")
243 message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}")
245 if (_excludedSourceFiles)
246 message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}")
248 if (_cotiredSourceFiles)
249 message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}")
252 set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE)
253 set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE)
254 set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE)
257 function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
258 set (_filteredObjects "")
259 foreach (_object ${ARGN})
260 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
262 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
264 list (APPEND _filteredObjects "${_object}")
268 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
271 function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
272 set (_filteredObjects "")
273 foreach (_object ${ARGN})
274 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
276 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
277 if (NOT _propertyValue)
278 list (APPEND _filteredObjects "${_object}")
282 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
285 function (cotire_get_source_file_property_values _valuesVar _property)
287 foreach (_sourceFile ${ARGN})
288 get_source_file_property(_propertyValue "${_sourceFile}" ${_property})
290 list (APPEND _values "${_propertyValue}")
293 set (${_valuesVar} ${_values} PARENT_SCOPE)
296 function (cotire_resolve_config_properites _configurations _propertiesVar)
298 foreach (_property ${ARGN})
299 if ("${_property}" MATCHES "<CONFIG>")
300 foreach (_config ${_configurations})
301 string (TOUPPER "${_config}" _upperConfig)
302 string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}")
303 list (APPEND _properties ${_configProperty})
306 list (APPEND _properties ${_property})
309 set (${_propertiesVar} ${_properties} PARENT_SCOPE)
312 function (cotire_copy_set_properites _configurations _type _source _target)
313 cotire_resolve_config_properites("${_configurations}" _properties ${ARGN})
314 foreach (_property ${_properties})
315 get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
317 get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
318 set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
323 function (cotire_get_target_usage_requirements _target _targetRequirementsVar)
324 set (_targetRequirements "")
325 get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES)
326 while (_librariesToProcess)
328 list (GET _librariesToProcess 0 _library)
329 list (REMOVE_AT _librariesToProcess 0)
330 if (TARGET ${_library})
331 list (FIND _targetRequirements ${_library} _index)
333 list (APPEND _targetRequirements ${_library})
334 # BFS traversal of transitive libraries
335 get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES)
337 list (APPEND _librariesToProcess ${_libraries})
338 list (REMOVE_DUPLICATES _librariesToProcess)
343 set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE)
346 function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar)
347 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
348 set (_flagPrefix "[/-]")
350 set (_flagPrefix "--?")
353 set (_matchedOptions "")
354 set (_unmatchedOptions "")
355 foreach (_compileFlag ${ARGN})
357 if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}")
358 # option with separate argument
359 list (APPEND _matchedOptions "${_compileFlag}")
361 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$")
363 set (_optionFlag "${CMAKE_MATCH_2}")
364 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$")
365 # option with joined argument
366 list (APPEND _matchedOptions "${CMAKE_MATCH_3}")
369 # flush remembered option
371 list (APPEND _matchedOptions "${_optionFlag}")
374 # add to unfiltered options
375 list (APPEND _unmatchedOptions "${_compileFlag}")
380 list (APPEND _matchedOptions "${_optionFlag}")
382 if (COTIRE_DEBUG AND _matchedOptions)
383 message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}")
385 if (COTIRE_DEBUG AND _unmatchedOptions)
386 message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}")
388 set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE)
389 set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE)
392 function (cotire_is_target_supported _target _isSupportedVar)
393 if (NOT TARGET "${_target}")
394 set (${_isSupportedVar} FALSE PARENT_SCOPE)
397 get_target_property(_imported ${_target} IMPORTED)
399 set (${_isSupportedVar} FALSE PARENT_SCOPE)
402 get_target_property(_targetType ${_target} TYPE)
403 if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
404 set (${_isSupportedVar} FALSE PARENT_SCOPE)
407 set (${_isSupportedVar} TRUE PARENT_SCOPE)
410 function (cotire_get_target_compile_flags _config _language _target _flagsVar)
411 string (TOUPPER "${_config}" _upperConfig)
412 # collect options from CMake language variables
413 set (_compileFlags "")
414 if (CMAKE_${_language}_FLAGS)
415 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
417 if (CMAKE_${_language}_FLAGS_${_upperConfig})
418 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}")
421 # add target compile flags
422 get_target_property(_targetflags ${_target} COMPILE_FLAGS)
424 set (_compileFlags "${_compileFlags} ${_targetflags}")
428 separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}")
430 separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}")
432 separate_arguments(_compileFlags)
434 # target compile options
436 get_target_property(_targetOptions ${_target} COMPILE_OPTIONS)
438 list (APPEND _compileFlags ${_targetOptions})
441 # interface compile options from linked library targets
443 set (_linkedTargets "")
444 cotire_get_target_usage_requirements(${_target} _linkedTargets)
445 foreach (_linkedTarget ${_linkedTargets})
446 get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS)
448 list (APPEND _compileFlags ${_targetOptions})
452 # handle language standard properties
453 if (CMAKE_${_language}_STANDARD_DEFAULT)
454 # used compiler supports language standard levels
456 get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD)
457 if (_targetLanguageStandard)
458 set (_type "EXTENSION")
459 get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET)
461 get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS)
462 if (NOT _targetUseLanguageExtensions)
463 set (_type "STANDARD")
466 if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION)
467 list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}")
472 # handle the POSITION_INDEPENDENT_CODE target property
474 get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE)
476 get_target_property(_targetType ${_target} TYPE)
477 if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE)
478 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}")
479 elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC)
480 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}")
484 # handle visibility target properties
486 get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET)
487 if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY)
488 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}")
490 get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN)
491 if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN)
492 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}")
495 # platform specific flags
497 get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig})
498 if (NOT _architectures)
499 get_target_property(_architectures ${_target} OSX_ARCHITECTURES)
502 foreach (_arch ${_architectures})
503 list (APPEND _compileFlags "-arch" "${_arch}")
506 if (CMAKE_OSX_SYSROOT)
507 if (CMAKE_${_language}_SYSROOT_FLAG)
508 list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}")
510 list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}")
513 if (CMAKE_OSX_DEPLOYMENT_TARGET)
514 if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG)
515 list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
517 list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
521 if (COTIRE_DEBUG AND _compileFlags)
522 message (STATUS "Target ${_target} compile flags: ${_compileFlags}")
524 set (${_flagsVar} ${_compileFlags} PARENT_SCOPE)
527 function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar)
528 set (_includeDirs "")
529 set (_systemIncludeDirs "")
530 # default include dirs
531 if (CMAKE_INCLUDE_CURRENT_DIR)
532 list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}")
533 list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}")
535 set (_targetFlags "")
536 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
537 # parse additional include directories from target compile flags
538 if (CMAKE_INCLUDE_FLAG_${_language})
539 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
540 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
543 cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags})
545 list (APPEND _includeDirs ${_dirs})
549 # parse additional system include directories from target compile flags
550 if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language})
551 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag)
552 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
555 cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags})
557 list (APPEND _systemIncludeDirs ${_dirs})
561 # target include directories
562 get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES)
564 get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES)
566 list (APPEND _dirs ${_targetDirs})
568 get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
570 list (APPEND _systemIncludeDirs ${_targetDirs})
573 # interface include directories from linked library targets
575 set (_linkedTargets "")
576 cotire_get_target_usage_requirements(${_target} _linkedTargets)
577 foreach (_linkedTarget ${_linkedTargets})
578 get_target_property(_linkedTargetType ${_linkedTarget} TYPE)
579 if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND
580 _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
581 # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR
582 # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR
583 # which are only available with CMake 3.4 or later.
584 get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR)
586 list (APPEND _dirs ${_targetDirs})
588 get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR)
590 list (APPEND _dirs ${_targetDirs})
593 get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES)
595 list (APPEND _dirs ${_targetDirs})
597 get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
599 list (APPEND _systemIncludeDirs ${_targetDirs})
604 list (REMOVE_DUPLICATES _dirs)
606 list (LENGTH _includeDirs _projectInsertIndex)
607 foreach (_dir ${_dirs})
608 if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE)
609 cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
611 list (LENGTH _includeDirs _len)
612 if (_len EQUAL _projectInsertIndex)
613 list (APPEND _includeDirs "${_dir}")
615 list (INSERT _includeDirs _projectInsertIndex "${_dir}")
617 math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1")
619 list (APPEND _includeDirs "${_dir}")
622 list (APPEND _includeDirs "${_dir}")
625 list (REMOVE_DUPLICATES _includeDirs)
626 list (REMOVE_DUPLICATES _systemIncludeDirs)
627 if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES)
628 list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES})
631 # convert Windows paths in include directories to CMake paths
634 foreach (_dir ${_includeDirs})
635 file (TO_CMAKE_PATH "${_dir}" _path)
636 list (APPEND _paths "${_path}")
638 set (_includeDirs ${_paths})
640 if (_systemIncludeDirs)
642 foreach (_dir ${_systemIncludeDirs})
643 file (TO_CMAKE_PATH "${_dir}" _path)
644 list (APPEND _paths "${_path}")
646 set (_systemIncludeDirs ${_paths})
649 if (COTIRE_DEBUG AND _includeDirs)
650 message (STATUS "Target ${_target} include dirs: ${_includeDirs}")
652 set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE)
653 if (COTIRE_DEBUG AND _systemIncludeDirs)
654 message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}")
656 set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE)
659 function (cotire_get_target_export_symbol _target _exportSymbolVar)
660 set (_exportSymbol "")
661 get_target_property(_targetType ${_target} TYPE)
662 get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
663 if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
664 (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
665 get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
666 if (NOT _exportSymbol)
667 set (_exportSymbol "${_target}_EXPORTS")
669 string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol)
671 set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
674 function (cotire_get_target_compile_definitions _config _language _target _definitionsVar)
675 string (TOUPPER "${_config}" _upperConfig)
676 set (_configDefinitions "")
677 # CMAKE_INTDIR for multi-configuration build systems
678 if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
679 list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
681 # target export define symbol
682 cotire_get_target_export_symbol("${_target}" _defineSymbol)
684 list (APPEND _configDefinitions "${_defineSymbol}")
686 # directory compile definitions
687 get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS)
689 list (APPEND _configDefinitions ${_definitions})
691 get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig})
693 list (APPEND _configDefinitions ${_definitions})
695 # target compile definitions
696 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS)
698 list (APPEND _configDefinitions ${_definitions})
700 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig})
702 list (APPEND _configDefinitions ${_definitions})
704 # interface compile definitions from linked library targets
705 set (_linkedTargets "")
706 cotire_get_target_usage_requirements(${_target} _linkedTargets)
707 foreach (_linkedTarget ${_linkedTargets})
708 get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS)
710 list (APPEND _configDefinitions ${_definitions})
713 # parse additional compile definitions from target compile flags
714 # and don't look at directory compile definitions, which we already handled
715 set (_targetFlags "")
716 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
717 cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags})
719 list (APPEND _configDefinitions ${_definitions})
721 list (REMOVE_DUPLICATES _configDefinitions)
722 if (COTIRE_DEBUG AND _configDefinitions)
723 message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}")
725 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
728 function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar)
729 # parse target compile flags omitting compile definitions and include directives
730 set (_targetFlags "")
731 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
732 set (_flagFilter "D")
733 if (CMAKE_INCLUDE_FLAG_${_language})
734 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
735 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
737 set (_flagFilter "${_flagFilter}|${_includeFlag}")
740 if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language})
741 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag)
742 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
744 set (_flagFilter "${_flagFilter}|${_includeFlag}")
747 set (_compilerFlags "")
748 cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags})
749 if (COTIRE_DEBUG AND _compilerFlags)
750 message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}")
752 set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE)
755 function (cotire_add_sys_root_paths _pathsVar)
757 if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT)
758 foreach (_path IN LISTS ${_pathsVar})
759 if (IS_ABSOLUTE "${_path}")
760 get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE)
761 if (EXISTS "${_path}")
762 list (APPEND ${_pathsVar} "${_path}")
768 set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE)
771 function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar)
772 set (_extraProperties ${ARGN})
774 if (_extraProperties)
775 list (FIND _extraProperties "${_sourceFile}" _index)
776 if (_index GREATER -1)
777 math (EXPR _index "${_index} + 1")
778 list (LENGTH _extraProperties _len)
779 math (EXPR _len "${_len} - 1")
780 foreach (_index RANGE ${_index} ${_len})
781 list (GET _extraProperties ${_index} _value)
782 if (_value MATCHES "${_pattern}")
783 list (APPEND _result "${_value}")
790 set (${_resultVar} ${_result} PARENT_SCOPE)
793 function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
794 set (_compileDefinitions "")
795 if (NOT CMAKE_SCRIPT_MODE_FILE)
796 string (TOUPPER "${_config}" _upperConfig)
797 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
799 list (APPEND _compileDefinitions ${_definitions})
801 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig})
803 list (APPEND _compileDefinitions ${_definitions})
806 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN})
808 list (APPEND _compileDefinitions ${_definitions})
810 if (COTIRE_DEBUG AND _compileDefinitions)
811 message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}")
813 set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE)
816 function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
817 set (_configDefinitions "")
818 foreach (_sourceFile ${ARGN})
819 cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
820 if (_sourceDefinitions)
821 list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
824 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
827 function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
828 set (_sourceUndefs "")
829 if (NOT CMAKE_SCRIPT_MODE_FILE)
830 get_source_file_property(_undefs "${_sourceFile}" ${_property})
832 list (APPEND _sourceUndefs ${_undefs})
835 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN})
837 list (APPEND _sourceUndefs ${_undefs})
839 if (COTIRE_DEBUG AND _sourceUndefs)
840 message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}")
842 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
845 function (cotire_get_source_files_undefs _property _sourceUndefsVar)
846 set (_sourceUndefs "")
847 foreach (_sourceFile ${ARGN})
848 cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs)
850 list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-")
853 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
856 macro (cotire_set_cmd_to_prologue _cmdVar)
857 set (${_cmdVar} "${CMAKE_COMMAND}")
859 list (APPEND ${_cmdVar} "--warn-uninitialized")
861 list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>")
863 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON")
864 elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles")
865 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)")
869 function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1)
870 if (NOT _compilerLauncher)
871 set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER})
873 if (NOT _compilerExe)
874 set (_compilerExe "${CMAKE_${_language}_COMPILER}")
876 if (NOT _compilerArg1)
877 set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1})
879 string (STRIP "${_compilerArg1}" _compilerArg1)
880 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
881 # compiler launcher is only supported for Makefile and Ninja
882 set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
884 set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
888 macro (cotire_add_definitions_to_cmd _cmdVar _language)
889 foreach (_definition ${ARGN})
890 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
891 list (APPEND ${_cmdVar} "/D${_definition}")
893 list (APPEND ${_cmdVar} "-D${_definition}")
898 function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar)
899 set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}})
901 list (REMOVE_DUPLICATES _includeDirs)
902 foreach (_include ${_includeDirs})
903 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
904 file (TO_NATIVE_PATH "${_include}" _include)
905 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_${_language}_SEP}${_include}")
908 if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+")
909 list (FIND ${_systemIncludesVar} "${_include}" _index)
911 if (_index GREATER -1)
912 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${_include}")
914 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_${_language}_SEP}${_include}")
919 set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE)
922 function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar)
924 set (_frameworkDirs "")
925 foreach (_include ${${_includesVar}})
926 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
927 get_filename_component(_frameworkDir "${_include}" DIRECTORY)
928 list (APPEND _frameworkDirs "${_frameworkDir}")
931 set (_systemFrameworkDirs "")
932 foreach (_include ${${_systemIncludesVar}})
933 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
934 get_filename_component(_frameworkDir "${_include}" DIRECTORY)
935 list (APPEND _systemFrameworkDirs "${_frameworkDir}")
938 if (_systemFrameworkDirs)
939 list (APPEND _frameworkDirs ${_systemFrameworkDirs})
942 list (REMOVE_DUPLICATES _frameworkDirs)
943 foreach (_frameworkDir ${_frameworkDirs})
945 if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+")
946 list (FIND _systemFrameworkDirs "${_frameworkDir}" _index)
948 if (_index GREATER -1)
949 list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}")
951 list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}")
956 set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE)
959 macro (cotire_add_compile_flags_to_cmd _cmdVar)
960 foreach (_flag ${ARGN})
961 list (APPEND ${_cmdVar} "${_flag}")
965 function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
966 if (EXISTS "${_file}")
967 set (_triggerFile "")
968 foreach (_dependencyFile ${ARGN})
969 if (EXISTS "${_dependencyFile}")
970 # IS_NEWER_THAN returns TRUE if both files have the same timestamp
971 # thus we do the comparison in both directions to exclude ties
972 if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND
973 NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}")
974 set (_triggerFile "${_dependencyFile}")
981 get_filename_component(_fileName "${_file}" NAME)
982 message (STATUS "${_fileName} update triggered by ${_triggerFile} change.")
984 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
987 get_filename_component(_fileName "${_file}" NAME)
988 message (STATUS "${_fileName} is up-to-date.")
990 set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE)
994 get_filename_component(_fileName "${_file}" NAME)
995 message (STATUS "${_fileName} does not exist yet.")
997 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
1001 macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
1002 set (${_relPathVar} "")
1003 foreach (_includeDir ${_includeDirs})
1004 if (IS_DIRECTORY "${_includeDir}")
1005 file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
1006 if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
1007 string (LENGTH "${${_relPathVar}}" _closestLen)
1008 string (LENGTH "${_relPath}" _relLen)
1009 if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
1010 set (${_relPathVar} "${_relPath}")
1013 elseif ("${_includeDir}" STREQUAL "${_headerFile}")
1014 # if path matches exactly, return short non-empty string
1015 set (${_relPathVar} "1")
1021 macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside)
1022 # check header path against ignored and honored include directories
1023 cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath)
1025 # header is inside, but could be become outside if there is a shorter outside match
1026 cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath)
1027 if (_outsideRelPath)
1028 string (LENGTH "${_insideRelPath}" _insideRelPathLen)
1029 string (LENGTH "${_outsideRelPath}" _outsideRelPathLen)
1030 if (_outsideRelPathLen LESS _insideRelPathLen)
1031 set (${_headerIsInside} FALSE)
1033 set (${_headerIsInside} TRUE)
1036 set (${_headerIsInside} TRUE)
1040 set (${_headerIsInside} FALSE)
1044 macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
1045 if (NOT EXISTS "${_headerFile}")
1046 set (${_headerIsIgnoredVar} TRUE)
1047 elseif (IS_DIRECTORY "${_headerFile}")
1048 set (${_headerIsIgnoredVar} TRUE)
1049 elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$")
1050 # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path
1051 # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
1052 # with the error message "error: no include path in which to search for header.h"
1053 set (${_headerIsIgnoredVar} TRUE)
1055 set (${_headerIsIgnoredVar} FALSE)
1059 macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
1060 # check header file extension
1061 cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
1062 set (${_headerIsIgnoredVar} FALSE)
1064 list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
1065 if (_index GREATER -1)
1066 set (${_headerIsIgnoredVar} TRUE)
1071 macro (cotire_parse_line _line _headerFileVar _headerDepthVar)
1073 # cl.exe /showIncludes output looks different depending on the language pack used, e.g.:
1074 # English: "Note: including file: C:\directory\file"
1075 # German: "Hinweis: Einlesen der Datei: C:\directory\file"
1076 # We use a very general regular expression, relying on the presence of the : characters
1077 if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$")
1078 # Visual Studio compiler output
1079 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
1080 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE)
1082 set (${_headerFileVar} "")
1083 set (${_headerDepthVar} 0)
1086 if (_line MATCHES "^(\\.+) (.*)$")
1088 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
1089 if (IS_ABSOLUTE "${CMAKE_MATCH_2}")
1090 set (${_headerFileVar} "${CMAKE_MATCH_2}")
1092 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH)
1095 set (${_headerFileVar} "")
1096 set (${_headerDepthVar} 0)
1101 function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar)
1103 # prevent CMake macro invocation errors due to backslash characters in Windows paths
1104 string (REPLACE "\\" "/" _scanOutput "${_scanOutput}")
1107 string (REPLACE "//" "/" _scanOutput "${_scanOutput}")
1108 # prevent semicolon from being interpreted as a line separator
1109 string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}")
1110 # then separate lines
1111 string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}")
1112 list (LENGTH _scanOutput _len)
1113 # remove duplicate lines to speed up parsing
1114 list (REMOVE_DUPLICATES _scanOutput)
1115 list (LENGTH _scanOutput _uniqueLen)
1116 if (COTIRE_VERBOSE OR COTIRE_DEBUG)
1117 message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes")
1118 if (_ignoredExtensions)
1119 message (STATUS "Ignored extensions: ${_ignoredExtensions}")
1121 if (_ignoredIncludeDirs)
1122 message (STATUS "Ignored paths: ${_ignoredIncludeDirs}")
1124 if (_honoredIncludeDirs)
1125 message (STATUS "Included paths: ${_honoredIncludeDirs}")
1128 set (_sourceFiles ${ARGN})
1129 set (_selectedIncludes "")
1130 set (_unparsedLines "")
1131 # stack keeps track of inside/outside project status of processed header files
1132 set (_headerIsInsideStack "")
1133 foreach (_line IN LISTS _scanOutput)
1135 cotire_parse_line("${_line}" _headerFile _headerDepth)
1137 cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside)
1139 message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}")
1142 list (LENGTH _headerIsInsideStack _stackLen)
1143 if (_headerDepth GREATER _stackLen)
1144 math (EXPR _stackLen "${_stackLen} + 1")
1145 foreach (_index RANGE ${_stackLen} ${_headerDepth})
1146 list (APPEND _headerIsInsideStack ${_headerIsInside})
1149 foreach (_index RANGE ${_headerDepth} ${_stackLen})
1150 list (REMOVE_AT _headerIsInsideStack -1)
1152 list (APPEND _headerIsInsideStack ${_headerIsInside})
1155 message (STATUS "${_headerIsInsideStack}")
1157 # header is a candidate if it is outside project
1158 if (NOT _headerIsInside)
1159 # get parent header file's inside/outside status
1160 if (_headerDepth GREATER 1)
1161 math (EXPR _index "${_headerDepth} - 2")
1162 list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside)
1164 set (_parentHeaderIsInside TRUE)
1166 # select header file if parent header file is inside project
1167 # (e.g., a project header file that includes a standard header file)
1168 if (_parentHeaderIsInside)
1169 cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored)
1170 if (NOT _headerIsIgnored)
1171 cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored)
1172 if (NOT _headerIsIgnored)
1173 list (APPEND _selectedIncludes "${_headerFile}")
1175 # fix header's inside status on stack, it is ignored by extension now
1176 list (REMOVE_AT _headerIsInsideStack -1)
1177 list (APPEND _headerIsInsideStack TRUE)
1181 message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}")
1187 # for cl.exe do not keep unparsed lines which solely consist of a source file name
1188 string (FIND "${_sourceFiles}" "${_line}" _index)
1190 list (APPEND _unparsedLines "${_line}")
1193 list (APPEND _unparsedLines "${_line}")
1198 list (REMOVE_DUPLICATES _selectedIncludes)
1199 set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE)
1200 set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE)
1203 function (cotire_scan_includes _includesVar)
1205 set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT)
1206 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES
1207 IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER)
1208 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1209 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1210 if (NOT _option_LANGUAGE)
1211 set (_option_LANGUAGE "CXX")
1213 if (NOT _option_COMPILER_ID)
1214 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1216 if (NOT _option_COMPILER_VERSION)
1217 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1219 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1220 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1221 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1222 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1223 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1224 cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd)
1225 # only consider existing source files for scanning
1226 set (_existingSourceFiles "")
1227 foreach (_sourceFile ${_sourceFiles})
1228 if (EXISTS "${_sourceFile}")
1229 list (APPEND _existingSourceFiles "${_sourceFile}")
1232 if (NOT _existingSourceFiles)
1233 set (${_includesVar} "" PARENT_SCOPE)
1236 list (APPEND _cmd ${_existingSourceFiles})
1238 message (STATUS "execute_process: ${_cmd}")
1240 if (_option_COMPILER_ID MATCHES "MSVC")
1241 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1242 unset (ENV{VS_UNICODE_OUTPUT})
1246 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1247 RESULT_VARIABLE _result
1249 ERROR_VARIABLE _output)
1251 message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.")
1253 cotire_parse_includes(
1254 "${_option_LANGUAGE}" "${_output}"
1255 "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}"
1256 "${_option_IGNORE_EXTENSIONS}"
1257 _includes _unparsedLines
1259 if (_option_INCLUDE_PRIORITY_PATH)
1260 set (_sortedIncludes "")
1261 foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH})
1262 foreach (_include ${_includes})
1263 string (FIND ${_include} ${_priorityPath} _position)
1264 if (_position GREATER -1)
1265 list (APPEND _sortedIncludes ${_include})
1269 if (_sortedIncludes)
1270 list (INSERT _includes 0 ${_sortedIncludes})
1271 list (REMOVE_DUPLICATES _includes)
1274 set (${_includesVar} ${_includes} PARENT_SCOPE)
1275 if (_option_UNPARSED_LINES)
1276 set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE)
1278 if (_option_SCAN_RESULT)
1279 set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE)
1283 macro (cotire_append_undefs _contentsVar)
1284 set (_undefs ${ARGN})
1286 list (REMOVE_DUPLICATES _undefs)
1287 foreach (_definition ${_undefs})
1288 list (APPEND ${_contentsVar} "#undef ${_definition}")
1293 macro (cotire_comment_str _language _commentText _commentVar)
1294 if ("${_language}" STREQUAL "CMAKE")
1295 set (${_commentVar} "# ${_commentText}")
1297 set (${_commentVar} "/* ${_commentText} */")
1301 function (cotire_write_file _language _file _contents _force)
1302 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1303 cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
1304 cotire_comment_str("${_language}" "${_file}" _header2)
1305 set (_contents "${_header1}\n${_header2}\n${_contents}")
1307 message (STATUS "${_contents}")
1309 if (_force OR NOT EXISTS "${_file}")
1310 file (WRITE "${_file}" "${_contents}")
1312 file (READ "${_file}" _oldContents)
1313 if (NOT "${_oldContents}" STREQUAL "${_contents}")
1314 file (WRITE "${_file}" "${_contents}")
1317 message (STATUS "${_file} unchanged")
1323 function (cotire_generate_unity_source _unityFile)
1325 set(_oneValueArgs LANGUAGE)
1327 DEPENDS SOURCES_COMPILE_DEFINITIONS
1328 PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE)
1329 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1330 if (_option_DEPENDS)
1331 cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS})
1332 if (_unityFileIsUpToDate)
1336 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1337 if (NOT _option_PRE_UNDEFS)
1338 set (_option_PRE_UNDEFS "")
1340 if (NOT _option_SOURCES_PRE_UNDEFS)
1341 set (_option_SOURCES_PRE_UNDEFS "")
1343 if (NOT _option_POST_UNDEFS)
1344 set (_option_POST_UNDEFS "")
1346 if (NOT _option_SOURCES_POST_UNDEFS)
1347 set (_option_SOURCES_POST_UNDEFS "")
1350 if (_option_PROLOGUE)
1351 list (APPEND _contents ${_option_PROLOGUE})
1353 if (_option_LANGUAGE AND _sourceFiles)
1354 if ("${_option_LANGUAGE}" STREQUAL "CXX")
1355 list (APPEND _contents "#ifdef __cplusplus")
1356 elseif ("${_option_LANGUAGE}" STREQUAL "C")
1357 list (APPEND _contents "#ifndef __cplusplus")
1360 set (_compileUndefinitions "")
1361 foreach (_sourceFile ${_sourceFiles})
1362 cotire_get_source_compile_definitions(
1363 "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions
1364 ${_option_SOURCES_COMPILE_DEFINITIONS})
1365 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS})
1366 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS})
1367 if (_option_PRE_UNDEFS)
1368 list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS})
1370 if (_sourcePreUndefs)
1371 list (APPEND _compileUndefinitions ${_sourcePreUndefs})
1373 if (_compileUndefinitions)
1374 cotire_append_undefs(_contents ${_compileUndefinitions})
1375 set (_compileUndefinitions "")
1377 if (_sourcePostUndefs)
1378 list (APPEND _compileUndefinitions ${_sourcePostUndefs})
1380 if (_option_POST_UNDEFS)
1381 list (APPEND _compileUndefinitions ${_option_POST_UNDEFS})
1383 foreach (_definition ${_compileDefinitions})
1384 if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$")
1385 list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}")
1386 list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}")
1388 list (APPEND _contents "#define ${_definition}")
1389 list (INSERT _compileUndefinitions 0 "${_definition}")
1392 # use absolute path as source file location
1393 get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE)
1395 file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation)
1397 list (APPEND _contents "#include \"${_sourceFileLocation}\"")
1399 if (_compileUndefinitions)
1400 cotire_append_undefs(_contents ${_compileUndefinitions})
1401 set (_compileUndefinitions "")
1403 if (_option_LANGUAGE AND _sourceFiles)
1404 list (APPEND _contents "#endif")
1406 if (_option_EPILOGUE)
1407 list (APPEND _contents ${_option_EPILOGUE})
1409 list (APPEND _contents "")
1410 string (REPLACE ";" "\n" _contents "${_contents}")
1412 message ("${_contents}")
1414 cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE)
1417 function (cotire_generate_prefix_header _prefixFile)
1419 set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION)
1420 set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS
1421 INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH
1422 IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER)
1423 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1424 if (NOT _option_COMPILER_ID)
1425 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1427 if (NOT _option_COMPILER_VERSION)
1428 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1430 if (_option_DEPENDS)
1431 cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS})
1432 if (_prefixFileIsUpToDate)
1433 # create empty log file
1434 set (_unparsedLinesFile "${_prefixFile}.log")
1435 file (WRITE "${_unparsedLinesFile}" "")
1441 if (_option_COMPILER_ID MATCHES "Clang")
1442 set (_prologue "#pragma clang system_header")
1443 elseif (_option_COMPILER_ID MATCHES "GNU")
1444 set (_prologue "#pragma GCC system_header")
1445 elseif (_option_COMPILER_ID MATCHES "MSVC")
1446 set (_prologue "#pragma warning(push, 0)")
1447 set (_epilogue "#pragma warning(pop)")
1448 elseif (_option_COMPILER_ID MATCHES "Intel")
1449 # Intel compiler requires hdrstop pragma to stop generating PCH file
1450 set (_epilogue "#pragma hdrstop")
1452 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1453 cotire_scan_includes(_selectedHeaders ${_sourceFiles}
1454 LANGUAGE "${_option_LANGUAGE}"
1455 COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}"
1456 COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}"
1457 COMPILER_ARG1 "${_option_COMPILER_ARG1}"
1458 COMPILER_ID "${_option_COMPILER_ID}"
1459 COMPILER_VERSION "${_option_COMPILER_VERSION}"
1460 COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS}
1461 COMPILE_FLAGS ${_option_COMPILE_FLAGS}
1462 INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES}
1463 SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES}
1464 IGNORE_PATH ${_option_IGNORE_PATH}
1465 INCLUDE_PATH ${_option_INCLUDE_PATH}
1466 IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS}
1467 INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH}
1468 UNPARSED_LINES _unparsedLines
1469 SCAN_RESULT _scanResult)
1470 cotire_generate_unity_source("${_prefixFile}"
1471 PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders})
1472 set (_unparsedLinesFile "${_prefixFile}.log")
1474 if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders)
1475 list (LENGTH _unparsedLines _skippedLineCount)
1476 message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFile}")
1478 string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}")
1480 file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}")
1483 function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
1484 set (_flags ${${_flagsVar}})
1485 if (_compilerID MATCHES "MSVC")
1486 # cl.exe options used
1487 # /nologo suppresses display of sign-on banner
1488 # /TC treat all files named on the command line as C source files
1489 # /TP treat all files named on the command line as C++ source files
1490 # /EP preprocess to stdout without #line directives
1491 # /showIncludes list include files
1492 set (_sourceFileTypeC "/TC")
1493 set (_sourceFileTypeCXX "/TP")
1496 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes)
1498 # return as a flag string
1499 set (_flags "${_sourceFileType${_language}} /EP /showIncludes")
1501 elseif (_compilerID MATCHES "GNU")
1503 # -H print the name of each header file used
1504 # -E invoke preprocessor
1505 # -fdirectives-only do not expand macros, requires GCC >= 4.3
1508 list (APPEND _flags -H -E)
1509 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1510 list (APPEND _flags "-fdirectives-only")
1513 # return as a flag string
1514 set (_flags "-H -E")
1515 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1516 set (_flags "${_flags} -fdirectives-only")
1519 elseif (_compilerID MATCHES "Clang")
1520 # Clang options used
1521 # -H print the name of each header file used
1522 # -E invoke preprocessor
1523 # -fno-color-diagnostics don't prints diagnostics in color
1526 list (APPEND _flags -H -E -fno-color-diagnostics)
1528 # return as a flag string
1529 set (_flags "-H -E -fno-color-diagnostics")
1531 elseif (_compilerID MATCHES "Intel")
1533 # Windows Intel options used
1534 # /nologo do not display compiler version information
1535 # /QH display the include file order
1536 # /EP preprocess to stdout, omitting #line directives
1537 # /TC process all source or unrecognized file types as C source files
1538 # /TP process all source or unrecognized file types as C++ source files
1539 set (_sourceFileTypeC "/TC")
1540 set (_sourceFileTypeCXX "/TP")
1543 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH)
1545 # return as a flag string
1546 set (_flags "${_sourceFileType${_language}} /EP /QH")
1549 # Linux / Mac OS X Intel options used
1550 # -H print the name of each header file used
1551 # -EP preprocess to stdout, omitting #line directives
1552 # -Kc++ process all source or unrecognized file types as C++ source files
1555 if ("${_language}" STREQUAL "CXX")
1556 list (APPEND _flags -Kc++)
1558 list (APPEND _flags -H -EP)
1560 # return as a flag string
1561 if ("${_language}" STREQUAL "CXX")
1562 set (_flags "-Kc++ ")
1564 set (_flags "${_flags}-H -EP")
1568 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1570 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1573 function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
1574 set (_flags ${${_flagsVar}})
1575 if (_compilerID MATCHES "MSVC")
1576 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1577 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1578 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1579 # cl.exe options used
1580 # /Yc creates a precompiled header file
1581 # /Fp specifies precompiled header binary file name
1582 # /FI forces inclusion of file
1583 # /TC treat all files named on the command line as C source files
1584 # /TP treat all files named on the command line as C++ source files
1585 # /Zs syntax check only
1586 # /Zm precompiled header memory allocation scaling factor
1587 set (_sourceFileTypeC "/TC")
1588 set (_sourceFileTypeCXX "/TP")
1591 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1592 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1593 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1594 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1597 # return as a flag string
1598 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1599 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1600 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1603 elseif (_compilerID MATCHES "GNU|Clang")
1604 # GCC / Clang options used
1605 # -x specify the source language
1606 # -c compile but do not link
1607 # -o place output in file
1608 # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may
1609 # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings)
1610 set (_xLanguage_C "c-header")
1611 set (_xLanguage_CXX "c++-header")
1614 list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}")
1616 # return as a flag string
1617 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1619 elseif (_compilerID MATCHES "Intel")
1621 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1622 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1623 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1624 # Windows Intel options used
1625 # /nologo do not display compiler version information
1626 # /Yc create a precompiled header (PCH) file
1627 # /Fp specify a path or file name for precompiled header files
1628 # /FI tells the preprocessor to include a specified file name as the header file
1629 # /TC process all source or unrecognized file types as C source files
1630 # /TP process all source or unrecognized file types as C++ source files
1631 # /Zs syntax check only
1632 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1633 set (_sourceFileTypeC "/TC")
1634 set (_sourceFileTypeCXX "/TP")
1637 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1638 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1639 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1640 list (APPEND _flags "/Wpch-messages")
1643 # return as a flag string
1644 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1645 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1646 set (_flags "${_flags} /Wpch-messages")
1650 # Linux / Mac OS X Intel options used
1651 # -pch-dir location for precompiled header files
1652 # -pch-create name of the precompiled header (PCH) to create
1653 # -Kc++ process all source or unrecognized file types as C++ source files
1654 # -fsyntax-only check only for correct syntax
1655 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1656 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1657 get_filename_component(_pchName "${_pchFile}" NAME)
1658 set (_xLanguage_C "c-header")
1659 set (_xLanguage_CXX "c++-header")
1662 if ("${_language}" STREQUAL "CXX")
1663 list (APPEND _flags -Kc++)
1665 list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}")
1666 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1667 list (APPEND _flags "-Wpch-messages")
1670 # return as a flag string
1671 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1672 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1673 set (_flags "${_flags} -Wpch-messages")
1678 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1680 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1683 function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1684 set (_flags ${${_flagsVar}})
1685 if (_compilerID MATCHES "MSVC")
1686 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1687 # cl.exe options used
1688 # /Yu uses a precompiled header file during build
1689 # /Fp specifies precompiled header binary file name
1690 # /FI forces inclusion of file
1691 # /Zm precompiled header memory allocation scaling factor
1693 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1696 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1697 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1698 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1701 # return as a flag string
1702 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1703 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1704 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1708 # no precompiled header, force inclusion of prefix header
1711 list (APPEND _flags "/FI${_prefixFileNative}")
1713 # return as a flag string
1714 set (_flags "/FI\"${_prefixFileNative}\"")
1717 elseif (_compilerID MATCHES "GNU")
1719 # -include process include file as the first line of the primary source file
1720 # -Winvalid-pch warns if precompiled header is found but cannot be used
1721 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1724 list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}")
1726 # return as a flag string
1727 set (_flags "-Winvalid-pch -include \"${_prefixFile}\"")
1729 elseif (_compilerID MATCHES "Clang")
1730 # Clang options used
1731 # -include process include file as the first line of the primary source file
1732 # -include-pch include precompiled header file
1733 # -Qunused-arguments don't emit warning for unused driver arguments
1734 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1737 list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}")
1739 # return as a flag string
1740 set (_flags "-Qunused-arguments -include \"${_prefixFile}\"")
1742 elseif (_compilerID MATCHES "Intel")
1744 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1745 # Windows Intel options used
1746 # /Yu use a precompiled header (PCH) file
1747 # /Fp specify a path or file name for precompiled header files
1748 # /FI tells the preprocessor to include a specified file name as the header file
1749 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1751 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1754 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1755 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1756 list (APPEND _flags "/Wpch-messages")
1759 # return as a flag string
1760 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1761 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1762 set (_flags "${_flags} /Wpch-messages")
1766 # no precompiled header, force inclusion of prefix header
1769 list (APPEND _flags "/FI${_prefixFileNative}")
1771 # return as a flag string
1772 set (_flags "/FI\"${_prefixFileNative}\"")
1776 # Linux / Mac OS X Intel options used
1777 # -pch-dir location for precompiled header files
1778 # -pch-use name of the precompiled header (PCH) to use
1779 # -include process include file as the first line of the primary source file
1780 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1782 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1783 get_filename_component(_pchName "${_pchFile}" NAME)
1786 list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}")
1787 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1788 list (APPEND _flags "-Wpch-messages")
1791 # return as a flag string
1792 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1793 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1794 set (_flags "${_flags} -Wpch-messages")
1798 # no precompiled header, force inclusion of prefix header
1801 list (APPEND _flags "-include" "${_prefixFile}")
1803 # return as a flag string
1804 set (_flags "-include \"${_prefixFile}\"")
1809 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1811 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1814 function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1816 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE)
1817 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER)
1818 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1819 if (NOT _option_LANGUAGE)
1820 set (_option_LANGUAGE "CXX")
1822 if (NOT _option_COMPILER_ID)
1823 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1825 if (NOT _option_COMPILER_VERSION)
1826 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1828 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1829 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1830 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1831 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1832 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1833 cotire_add_pch_compilation_flags(
1834 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1835 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1837 message (STATUS "execute_process: ${_cmd}")
1839 if (_option_COMPILER_ID MATCHES "MSVC")
1840 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1841 unset (ENV{VS_UNICODE_OUTPUT})
1845 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1846 RESULT_VARIABLE _result)
1848 message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.")
1852 function (cotire_check_precompiled_header_support _language _target _msgVar)
1853 set (_unsupportedCompiler
1854 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
1855 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1856 # supported since Visual Studio C++ 6.0
1857 # and CMake does not support an earlier version
1858 set (${_msgVar} "" PARENT_SCOPE)
1859 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
1860 # GCC PCH support requires version >= 3.4
1861 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
1862 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
1864 set (${_msgVar} "" PARENT_SCOPE)
1866 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
1867 # all Clang versions have PCH support
1868 set (${_msgVar} "" PARENT_SCOPE)
1869 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
1870 # Intel PCH support requires version >= 8.0.0
1871 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
1872 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
1874 set (${_msgVar} "" PARENT_SCOPE)
1877 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
1879 get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER)
1880 if (CMAKE_${_language}_COMPILER MATCHES "ccache" OR _launcher MATCHES "ccache")
1881 if (DEFINED ENV{CCACHE_SLOPPINESS})
1882 if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros")
1884 "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"."
1888 if (_launcher MATCHES "ccache")
1889 get_filename_component(_ccacheExe "${_launcher}" REALPATH)
1891 get_filename_component(_ccacheExe "${CMAKE_${_language}_COMPILER}" REALPATH)
1894 COMMAND "${_ccacheExe}" "--print-config"
1895 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
1896 RESULT_VARIABLE _result
1897 OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE
1900 _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR NOT
1901 _ccacheConfig MATCHES "sloppiness.*=.*pch_defines")
1903 "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"."
1909 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
1910 cotire_get_configuration_types(_configs)
1911 foreach (_config ${_configs})
1912 set (_targetFlags "")
1913 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
1914 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
1915 list (LENGTH _architectures _numberOfArchitectures)
1916 if (_numberOfArchitectures GREATER 1)
1917 string (REPLACE ";" ", " _architectureStr "${_architectures}")
1919 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
1927 macro (cotire_get_intermediate_dir _cotireDir)
1928 # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types
1929 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
1932 macro (cotire_setup_file_extension_variables)
1933 set (_unityFileExt_C ".c")
1934 set (_unityFileExt_CXX ".cxx")
1935 set (_prefixFileExt_C ".h")
1936 set (_prefixFileExt_CXX ".hxx")
1937 set (_prefixSourceFileExt_C ".c")
1938 set (_prefixSourceFileExt_CXX ".cxx")
1941 function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
1942 cotire_setup_file_extension_variables()
1943 if (NOT DEFINED _unityFileExt_${_language})
1944 set (${_unityFileVar} "" PARENT_SCOPE)
1947 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1948 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
1949 cotire_get_intermediate_dir(_baseDir)
1950 set (_unityFile "${_baseDir}/${_unityFileName}")
1951 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
1954 function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
1955 cotire_setup_file_extension_variables()
1956 if (NOT DEFINED _unityFileExt_${_language})
1957 set (${_unityFileVar} "" PARENT_SCOPE)
1960 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1961 cotire_get_intermediate_dir(_baseDir)
1964 set (_unityFiles "")
1965 set (_sourceFiles ${ARGN})
1966 foreach (_sourceFile ${_sourceFiles})
1967 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
1968 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
1969 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
1970 if (_index GREATER 0)
1971 # start new unity file segment
1972 math (EXPR _endIndex "${_index} - 1")
1973 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
1974 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
1976 set (_startIndex ${_index})
1978 math (EXPR _index "${_index} + 1")
1980 list (LENGTH _sourceFiles _numberOfSources)
1981 if (_startIndex EQUAL 0)
1982 # there is only a single unity file
1983 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
1984 elseif (_startIndex LESS _numberOfSources)
1985 # end with final unity file segment
1986 math (EXPR _endIndex "${_index} - 1")
1987 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
1988 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
1990 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
1991 if (COTIRE_DEBUG AND _unityFiles)
1992 message (STATUS "unity files: ${_unityFiles}")
1996 function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
1997 cotire_setup_file_extension_variables()
1998 if (NOT DEFINED _unityFileExt_${_language})
1999 set (${_prefixFileVar} "" PARENT_SCOPE)
2002 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2003 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2004 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
2005 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
2006 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
2009 function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar)
2010 cotire_setup_file_extension_variables()
2011 if (NOT DEFINED _prefixSourceFileExt_${_language})
2012 set (${_prefixSourceFileVar} "" PARENT_SCOPE)
2015 string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}")
2016 set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE)
2019 function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
2020 cotire_setup_file_extension_variables()
2022 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2023 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
2024 elseif (DEFINED _prefixFileExt_${_language})
2025 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2026 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
2028 set (_prefixFileBaseName "")
2029 set (_prefixFileName "")
2031 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
2032 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
2035 function (cotire_make_prefix_file_path _language _target _prefixFileVar)
2036 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2037 set (${_prefixFileVar} "" PARENT_SCOPE)
2038 if (_prefixFileName)
2042 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC")
2043 cotire_get_intermediate_dir(_baseDir)
2044 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
2049 function (cotire_make_pch_file_path _language _target _pchFileVar)
2050 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2051 set (${_pchFileVar} "" PARENT_SCOPE)
2052 if (_prefixFileBaseName AND _prefixFileName)
2053 cotire_check_precompiled_header_support("${_language}" "${_target}" _msg)
2056 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
2059 cotire_get_intermediate_dir(_baseDir)
2060 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2061 # MSVC uses the extension .pch added to the prefix header base name
2062 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
2063 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2064 # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended
2065 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE)
2066 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2067 # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended
2068 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
2069 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2070 # Intel uses the extension .pchi added to the prefix header base name
2071 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
2077 function (cotire_select_unity_source_files _unityFile _sourcesVar)
2078 set (_sourceFiles ${ARGN})
2079 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
2080 set (_startIndex ${CMAKE_MATCH_1})
2081 set (_endIndex ${CMAKE_MATCH_2})
2082 list (LENGTH _sourceFiles _numberOfSources)
2083 if (NOT _startIndex LESS _numberOfSources)
2084 math (EXPR _startIndex "${_numberOfSources} - 1")
2086 if (NOT _endIndex LESS _numberOfSources)
2087 math (EXPR _endIndex "${_numberOfSources} - 1")
2090 foreach (_index RANGE ${_startIndex} ${_endIndex})
2091 list (GET _sourceFiles ${_index} _file)
2092 list (APPEND _files "${_file}")
2095 set (_files ${_sourceFiles})
2097 set (${_sourcesVar} ${_files} PARENT_SCOPE)
2100 function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
2101 set (_dependencySources "")
2102 # depend on target's generated source files
2103 get_target_property(_targetSourceFiles ${_target} SOURCES)
2104 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2105 if (_generatedSources)
2106 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
2107 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
2108 if (_excludedGeneratedSources)
2109 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
2111 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
2112 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
2113 if (_excludedNonDependencySources)
2114 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
2116 if (_generatedSources)
2117 list (APPEND _dependencySources ${_generatedSources})
2120 if (COTIRE_DEBUG AND _dependencySources)
2121 message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}")
2123 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2126 function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
2127 set (_dependencySources "")
2128 # depend on target source files marked with custom COTIRE_DEPENDENCY property
2129 get_target_property(_targetSourceFiles ${_target} SOURCES)
2130 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles})
2131 if (COTIRE_DEBUG AND _dependencySources)
2132 message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}")
2134 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2137 function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar)
2138 set (_targetSources ${ARGN})
2139 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources})
2140 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources})
2141 # set up variables to be configured
2142 set (COTIRE_TARGET_LANGUAGE "${_language}")
2143 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
2144 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
2145 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
2146 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
2147 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
2148 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
2149 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2150 get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH)
2151 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources})
2152 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources})
2153 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
2154 foreach (_config ${_configurations})
2155 string (TOUPPER "${_config}" _upperConfig)
2156 cotire_get_target_include_directories(
2157 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig})
2158 cotire_get_target_compile_definitions(
2159 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
2160 cotire_get_target_compiler_flags(
2161 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
2162 cotire_get_source_files_compile_definitions(
2163 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources})
2165 get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER)
2166 # set up COTIRE_TARGET_SOURCES
2167 set (COTIRE_TARGET_SOURCES "")
2168 foreach (_sourceFile ${_targetSources})
2169 get_source_file_property(_generated "${_sourceFile}" GENERATED)
2171 # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation
2172 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2173 list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}")
2175 list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}")
2178 # copy variable definitions to cotire target script
2179 get_cmake_property(_vars VARIABLES)
2180 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
2181 # omit COTIRE_*_INIT variables
2182 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}")
2184 list (REMOVE_ITEM _matchVars ${_initVars})
2186 # omit COTIRE_VERBOSE which is passed as a CMake define on command line
2187 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
2189 set (_contentsHasGeneratorExpressions FALSE)
2190 foreach (_var IN LISTS _matchVars ITEMS
2191 XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
2192 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION
2193 CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
2194 CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_${_language}_SEP
2195 CMAKE_INCLUDE_SYSTEM_FLAG_${_language}
2196 CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG
2197 CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG
2198 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
2199 if (DEFINED ${_var})
2200 string (REPLACE "\"" "\\\"" _value "${${_var}}")
2201 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
2202 if (NOT _contentsHasGeneratorExpressions)
2203 if ("${_value}" MATCHES "\\$<.*>")
2204 set (_contentsHasGeneratorExpressions TRUE)
2209 # generate target script file
2210 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
2211 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
2212 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
2213 if (_contentsHasGeneratorExpressions)
2214 # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time
2215 set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>")
2216 set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}")
2217 file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}")
2219 set (_targetCotireConfigScript "${_targetCotireScript}")
2221 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
2222 set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE)
2225 function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile)
2226 set (_sourceFiles ${ARGN})
2227 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2228 # for Visual Studio and Intel, we attach the precompiled header compilation to the host file
2229 # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion
2232 cotire_add_pch_compilation_flags(
2233 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2234 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
2235 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2236 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
2237 # make object file generated from host file depend on prefix header
2238 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2239 # mark host file as cotired to prevent it from being used in another cotired target
2240 set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}")
2242 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2243 # for makefile based generator, we add a custom command to precompile the prefix header
2245 cotire_set_cmd_to_prologue(_cmds)
2246 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
2248 file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath)
2250 file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
2252 # make precompiled header compilation depend on the actual compiler executable used to force
2253 # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable"
2254 # warnings when the precompiled header is included.
2255 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2257 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
2259 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
2261 OUTPUT "${_pchFile}"
2263 DEPENDS "${_prefixFile}" "${_realCompilerExe}"
2264 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
2265 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2266 COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}"
2272 function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile)
2273 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2274 # for Visual Studio and Intel, we include the precompiled header in all but the host file
2275 # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation
2276 set (_sourceFiles ${ARGN})
2277 list (LENGTH _sourceFiles _numberOfSourceFiles)
2278 if (_numberOfSourceFiles GREATER 0)
2279 # mark sources as cotired to prevent them from being used in another cotired target
2280 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2282 cotire_add_prefix_pch_inclusion_flags(
2283 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2284 "${_prefixFile}" "${_pchFile}" _flags)
2285 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2286 # make object files generated from source files depend on precompiled header
2287 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2289 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2290 set (_sourceFiles ${_hostFile} ${ARGN})
2291 if (NOT _wholeTarget)
2292 # for makefile based generator, we force the inclusion of the prefix header for a subset
2293 # of the source files, if this is a multi-language target or has excluded files
2295 cotire_add_prefix_pch_inclusion_flags(
2296 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2297 "${_prefixFile}" "${_pchFile}" _flags)
2298 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2299 # mark sources as cotired to prevent them from being used in another cotired target
2300 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2302 # make object files generated from source files depend on precompiled header
2303 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2307 function (cotire_setup_prefix_file_inclusion _language _target _prefixFile)
2308 set (_sourceFiles ${ARGN})
2309 # force the inclusion of the prefix header for the given source files
2312 cotire_add_prefix_pch_inclusion_flags(
2313 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2314 "${_prefixFile}" "${_pchFile}" _flags)
2315 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2316 # mark sources as cotired to prevent them from being used in another cotired target
2317 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2318 # make object files generated from source files depend on prefix header
2319 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2322 function (cotire_get_first_set_property_value _propertyValueVar _type _object)
2323 set (_properties ${ARGN})
2324 foreach (_property ${_properties})
2325 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
2327 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
2331 set (${_propertyValueVar} "" PARENT_SCOPE)
2334 function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar)
2335 set (_files ${ARGN})
2336 set (_filesPaths "")
2337 foreach (_file ${_files})
2338 get_filename_component(_filePath "${_file}" ABSOLUTE)
2339 list (APPEND _filesPaths "${_filePath}")
2341 cotire_set_cmd_to_prologue(_prefixCmd)
2342 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
2344 list (APPEND _prefixCmd "${_targetScript}")
2346 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
2348 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
2350 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
2352 file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath)
2354 file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
2356 get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE)
2357 get_filename_component(_joinedFileExt "${_joinedFile}" EXT)
2358 if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
2359 set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}")
2360 elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$")
2361 if (_joinedFileExt MATCHES "^\\.c")
2362 set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}")
2364 set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}")
2367 set (_comment "Generating ${_joinedFileLogPath}")
2370 OUTPUT "${_joinedFile}"
2371 COMMAND ${_prefixCmd}
2373 COMMENT "${_comment}"
2374 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2376 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2377 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2380 function (cotire_setup_target_pch_usage _languages _target _wholeTarget)
2382 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
2383 set (_prefixFiles "")
2384 foreach (_language ${_languages})
2385 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2387 list (APPEND _prefixFiles "${_prefixFile}")
2391 list (LENGTH _prefixFiles _numberOfPrefixFiles)
2392 if (_numberOfPrefixFiles GREATER 1)
2393 # we also generate a generic, single prefix header which includes all language specific prefix headers
2395 set (_targetScript "")
2396 cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader)
2397 cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles})
2399 set (_prefixHeader "${_prefixFiles}")
2402 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
2404 # because CMake PRE_BUILD command does not support dependencies,
2405 # we check dependencies explicitly in cotire script mode when the pre-build action is run
2409 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2410 COMMENT "Updating target ${_target} prefix headers"
2412 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
2413 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
2414 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
2415 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2416 # for makefile based generator, we force inclusion of the prefix header for all target source files
2417 # if this is a single-language target without any excluded files
2419 set (_language "${_languages}")
2420 # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level
2421 # see cotire_setup_pch_file_inclusion
2422 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2423 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2425 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
2426 set (_options COMPILE_OPTIONS)
2427 cotire_add_prefix_pch_inclusion_flags(
2428 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2429 "${_prefixFile}" "${_pchFile}" _options)
2430 set_property(TARGET ${_target} APPEND PROPERTY ${_options})
2437 function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar)
2438 set (_dependencySources "")
2439 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
2440 foreach (_unityFile ${_unityFiles})
2441 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
2442 # set up compiled unity source dependencies via OBJECT_DEPENDS
2443 # this ensures that missing source files are generated before the unity file is compiled
2444 if (COTIRE_DEBUG AND _dependencySources)
2445 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
2447 if (_dependencySources)
2448 # the OBJECT_DEPENDS property requires a list of full paths
2449 set (_objectDependsPaths "")
2450 foreach (_sourceFile ${_dependencySources})
2451 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2452 list (APPEND _objectDependsPaths "${_sourceLocation}")
2454 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths})
2456 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2457 # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel
2458 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
2460 cotire_set_cmd_to_prologue(_unityCmd)
2461 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}")
2462 if (CMAKE_VERSION VERSION_LESS "3.1.0")
2463 set (_unityCmdDepends "${_targetScript}")
2465 # CMake 3.1.0 supports generator expressions in arguments to DEPENDS
2466 set (_unityCmdDepends "${_targetConfigScript}")
2469 file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath)
2471 file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
2474 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}")
2477 OUTPUT "${_unityFile}"
2478 COMMAND ${_unityCmd}
2479 DEPENDS ${_unityCmdDepends}
2480 COMMENT "Generating ${_language} unity source ${_unityFileLogPath}"
2481 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2483 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
2485 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2488 function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2489 set (_sourceFiles ${ARGN})
2490 set (_dependencySources "")
2491 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
2492 cotire_set_cmd_to_prologue(_prefixCmd)
2493 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles})
2494 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
2495 # make prefix header generation depend on the actual compiler executable used to force
2496 # re-generation when the compiler executable is updated. This prevents "file not found"
2497 # errors for compiler version specific system header files.
2498 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2500 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}")
2503 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath)
2505 file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
2507 get_filename_component(_prefixFileExt "${_prefixFile}" EXT)
2508 if (_prefixFileExt MATCHES "^\\.c")
2509 set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}")
2511 set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}")
2513 # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist
2514 # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence
2515 # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files
2516 set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre")
2517 if (TARGET ${_preTargetName})
2518 # custom helper target has already been generated while processing a different language
2519 list (APPEND _dependencySources ${_preTargetName})
2521 get_target_property(_targetSourceFiles ${_target} SOURCES)
2522 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2523 if (_generatedSources)
2524 add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources})
2525 cotire_init_target("${_preTargetName}")
2526 list (APPEND _dependencySources ${_preTargetName})
2530 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
2531 COMMAND ${_prefixCmd}
2532 DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}"
2533 COMMENT "${_comment}"
2534 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2536 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2537 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2540 function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2541 set (_sourceFiles ${ARGN})
2542 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2543 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2544 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2546 set (_prefixSourceFile "${_prefixFile}")
2548 cotire_setup_prefix_generation_command(
2549 ${_language} ${_target} "${_targetScript}"
2550 "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2551 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2552 # set up generation of a prefix source file which includes the prefix header
2553 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2555 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2558 function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar)
2559 set (_prefixHeaderFiles ${ARGN})
2560 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2561 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2562 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2564 set (_prefixSourceFile "${_prefixFile}")
2566 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles})
2567 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2568 # set up generation of a prefix source file which includes the prefix header
2569 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2571 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2574 function (cotire_init_cotire_target_properties _target)
2575 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2577 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2579 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2581 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2583 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2585 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2587 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2589 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2590 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2591 if (NOT _isRelative)
2592 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2595 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2597 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2599 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET)
2601 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "")
2603 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2605 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2607 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2609 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2611 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET)
2613 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY")
2615 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2617 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2618 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2620 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2625 function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2626 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2627 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2628 string (REPLACE ";" " " _languagesStr "${_languages}")
2629 math (EXPR _numberOfExcludedFiles "${ARGC} - 4")
2630 if (_numberOfExcludedFiles EQUAL 0)
2631 set (_excludedStr "")
2632 elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4)
2633 string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}")
2635 set (_excludedStr "excluding ${_numberOfExcludedFiles} files")
2639 set (_targetMsg "Target ${_target} cannot be cotired.")
2641 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2643 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2644 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2646 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2648 elseif (NOT _targetUsePCH)
2650 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.")
2652 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2655 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2657 elseif (NOT _targetAddSCU)
2659 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.")
2661 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2665 set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.")
2667 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2670 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2673 function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar)
2674 set (_languages ${ARGN})
2675 set (_allSourceFiles "")
2676 set (_allExcludedSourceFiles "")
2677 set (_allCotiredSourceFiles "")
2678 set (_targetLanguages "")
2679 set (_pchEligibleTargetLanguages "")
2680 get_target_property(_targetType ${_target} TYPE)
2681 get_target_property(_targetSourceFiles ${_target} SOURCES)
2682 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2683 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2684 set (_disableMsg "")
2685 foreach (_language ${_languages})
2686 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2687 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2688 if (_prefixHeader OR _unityBuildFile)
2689 message (STATUS "cotire: target ${_target} has already been cotired.")
2690 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2693 if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID)
2694 if (CMAKE_${_language}_COMPILER_ID)
2695 cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg)
2697 set (_targetUsePCH FALSE)
2701 set (_sourceFiles "")
2702 set (_excludedSources "")
2703 set (_cotiredSources "")
2704 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2705 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2706 list (APPEND _targetLanguages ${_language})
2709 list (APPEND _allSourceFiles ${_sourceFiles})
2711 list (LENGTH _sourceFiles _numberOfSources)
2712 if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2713 list (APPEND _pchEligibleTargetLanguages ${_language})
2715 if (_excludedSources)
2716 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2718 if (_cotiredSources)
2719 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2722 set (_targetMsgLevel STATUS)
2723 if (NOT _targetLanguages)
2724 string (REPLACE ";" " or " _languagesStr "${_languages}")
2725 set (_disableMsg "No ${_languagesStr} source files.")
2726 set (_targetUsePCH FALSE)
2727 set (_targetAddSCU FALSE)
2730 if (_allCotiredSourceFiles)
2731 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2732 list (REMOVE_DUPLICATES _cotireTargets)
2733 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2734 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2735 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2736 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2737 set (_targetMsgLevel SEND_ERROR)
2738 set (_targetUsePCH FALSE)
2739 elseif (NOT _pchEligibleTargetLanguages)
2740 set (_disableMsg "Too few applicable sources.")
2741 set (_targetUsePCH FALSE)
2742 elseif (XCODE AND _allExcludedSourceFiles)
2743 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2744 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2745 set (_targetUsePCH FALSE)
2746 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2747 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2748 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2749 set (_targetUsePCH FALSE)
2752 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2753 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2754 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2756 if (NOT DEFINED COTIREMSG_${_target})
2757 set (COTIREMSG_${_target} "")
2759 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2760 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2761 # cache message to avoid redundant messages on re-configure
2762 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2763 message (${_targetMsgLevel} "${_targetMsg}")
2766 list (LENGTH _targetLanguages _numberOfLanguages)
2767 if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles)
2768 set (${_wholeTargetVar} FALSE PARENT_SCOPE)
2770 set (${_wholeTargetVar} TRUE PARENT_SCOPE)
2772 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2775 function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2776 set (_sourceFiles ${ARGN})
2777 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2778 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2779 set (_numberOfThreads "${CMAKE_MATCH_2}")
2780 if (NOT _numberOfThreads)
2781 # use all available cores
2782 ProcessorCount(_numberOfThreads)
2784 list (LENGTH _sourceFiles _numberOfSources)
2785 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2786 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2787 set (_maxIncludes 0)
2790 message (STATUS "${_target} unity source max includes: ${_maxIncludes}")
2792 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2795 function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar)
2796 set (${_cmdsVar} "" PARENT_SCOPE)
2797 get_target_property(_targetSourceFiles ${_target} SOURCES)
2798 set (_sourceFiles "")
2799 set (_excludedSources "")
2800 set (_cotiredSources "")
2801 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2802 if (NOT _sourceFiles AND NOT _cotiredSources)
2806 # check for user provided unity source file list
2807 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
2808 if (NOT _unitySourceFiles)
2809 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
2811 cotire_generate_target_script(
2812 ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles})
2813 # set up unity files for parallel compilation
2814 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
2815 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
2816 list (LENGTH _unityFiles _numberOfUnityFiles)
2817 if (_numberOfUnityFiles EQUAL 0)
2819 elseif (_numberOfUnityFiles GREATER 1)
2820 cotire_setup_unity_generation_commands(
2821 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
2823 # set up single unity file for prefix header generation
2824 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
2825 cotire_setup_unity_generation_commands(
2826 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles})
2827 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
2828 # set up prefix header
2830 # check for user provided prefix header files
2831 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
2832 if (_prefixHeaderFiles)
2833 cotire_setup_prefix_generation_from_provided_command(
2834 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
2836 cotire_setup_prefix_generation_from_unity_command(
2837 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles})
2839 # check if selected language has enough sources at all
2840 list (LENGTH _sourceFiles _numberOfSources)
2841 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2842 set (_targetUsePCH FALSE)
2844 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2847 cotire_make_pch_file_path(${_language} ${_target} _pchFile)
2849 # first file in _sourceFiles is passed as the host file
2850 cotire_setup_pch_file_compilation(
2851 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
2852 cotire_setup_pch_file_inclusion(
2853 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
2855 elseif (_prefixHeaderFiles)
2856 # user provided prefix header must be included unconditionally
2857 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles})
2860 # mark target as cotired for language
2861 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
2863 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
2864 if (_targetUsePCH AND _pchFile)
2865 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
2868 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
2871 function (cotire_setup_clean_target _target)
2872 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
2873 if (NOT TARGET "${_cleanTargetName}")
2874 cotire_set_cmd_to_prologue(_cmds)
2875 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
2876 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
2877 add_custom_target(${_cleanTargetName}
2879 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2880 COMMENT "Cleaning up target ${_target} cotire generated files"
2882 cotire_init_target("${_cleanTargetName}")
2886 function (cotire_setup_pch_target _languages _configurations _target)
2887 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2888 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
2889 set (_dependsFiles "")
2890 foreach (_language ${_languages})
2891 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
2892 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2893 # Visual Studio and Intel only create precompiled header as a side effect
2894 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
2896 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
2898 list (APPEND _dependsFiles "${_dependsFile}")
2902 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
2903 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
2904 cotire_init_target("${_pchTargetName}")
2905 cotire_add_to_pch_all_target(${_pchTargetName})
2908 # for other generators, we add the "clean all" target to clean up the precompiled header
2909 cotire_setup_clean_all_target()
2913 function (cotire_filter_object_libraries _target _objectLibrariesVar)
2914 set (_objectLibraries "")
2915 foreach (_source ${ARGN})
2916 if (_source MATCHES "^\\$<TARGET_OBJECTS:.+>$")
2917 list (APPEND _objectLibraries "${_source}")
2920 set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE)
2923 function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar)
2924 get_target_property(_targetSourceFiles ${_target} SOURCES)
2925 set (_unityTargetSources ${_targetSourceFiles})
2926 foreach (_language ${_languages})
2927 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
2929 # remove source files that are included in the unity source
2930 set (_sourceFiles "")
2931 set (_excludedSources "")
2932 set (_cotiredSources "")
2933 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2934 if (_sourceFiles OR _cotiredSources)
2935 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
2937 # add unity source files instead
2938 list (APPEND _unityTargetSources ${_unityFiles})
2941 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
2942 if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$")
2943 cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles})
2944 if (_objectLibraries)
2945 cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries})
2946 list (REMOVE_ITEM _unityTargetSources ${_objectLibraries})
2947 list (APPEND _unityTargetSources ${_unityObjectLibraries})
2950 set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE)
2953 function (cotire_setup_unity_target_pch_usage _languages _target)
2954 foreach (_language ${_languages})
2955 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
2957 get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
2958 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2959 if (_userPrefixFile AND _prefixFile)
2960 # user provided prefix header must be included unconditionally by unity sources
2961 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles})
2967 function (cotire_setup_unity_build_target _languages _configurations _target)
2968 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
2969 if (NOT _unityTargetName)
2970 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
2972 # determine unity target sub type
2973 get_target_property(_targetType ${_target} TYPE)
2974 if ("${_targetType}" STREQUAL "EXECUTABLE")
2975 set (_unityTargetSubType "")
2976 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
2977 set (_unityTargetSubType "${CMAKE_MATCH_1}")
2979 message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.")
2982 # determine unity target sources
2983 set (_unityTargetSources "")
2984 cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources)
2985 # handle automatic Qt processing
2986 get_target_property(_targetAutoMoc ${_target} AUTOMOC)
2987 get_target_property(_targetAutoUic ${_target} AUTOUIC)
2988 get_target_property(_targetAutoRcc ${_target} AUTORCC)
2989 if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc)
2990 # if the original target sources are subject to CMake's automatic Qt processing,
2991 # also include implicitly generated <targetname>_automoc.cpp file
2992 if (CMAKE_VERSION VERSION_LESS "3.8.0")
2993 list (APPEND _unityTargetSources "${_target}_automoc.cpp")
2994 set_property (SOURCE "${_target}_automoc.cpp" PROPERTY GENERATED TRUE)
2996 list (APPEND _unityTargetSources "${_target}_autogen/moc_compilation.cpp")
2997 set_property (SOURCE "${_target}_autogen/moc_compilation.cpp" PROPERTY GENERATED TRUE)
3000 # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created
3001 set (CMAKE_AUTOMOC OFF)
3002 set (CMAKE_AUTOUIC OFF)
3003 set (CMAKE_AUTORCC OFF)
3005 message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
3007 # generate unity target
3008 if ("${_targetType}" STREQUAL "EXECUTABLE")
3009 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3011 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3013 if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
3014 # depend on original target's automoc target, if it exists
3015 if (TARGET ${_target}_automoc)
3016 add_dependencies(${_unityTargetName} ${_target}_automoc)
3019 if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc)
3020 # depend on the original target's implicity generated <targetname>_automoc target
3021 if (CMAKE_VERSION VERSION_LESS "3.8.0")
3022 add_dependencies(${_unityTargetName} ${_target}_automoc)
3024 add_dependencies(${_unityTargetName} ${_target}_autogen)
3028 # copy output location properties
3029 set (_outputDirProperties
3030 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
3031 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
3032 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
3033 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
3034 set (_setDefaultOutputDir TRUE)
3035 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3036 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3038 # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory
3039 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
3040 cotire_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties})
3041 foreach (_property ${_properties})
3042 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
3044 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3045 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
3046 set (_setDefaultOutputDir FALSE)
3049 if (_setDefaultOutputDir)
3050 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3053 if (_setDefaultOutputDir)
3054 set_target_properties(${_unityTargetName} PROPERTIES
3055 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
3056 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
3057 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
3060 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3061 ${_outputDirProperties})
3064 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3065 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
3066 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
3067 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
3068 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
3069 PREFIX <CONFIG>_POSTFIX SUFFIX
3070 IMPORT_PREFIX IMPORT_SUFFIX)
3071 # copy compile stuff
3072 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3073 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
3074 COMPILE_FLAGS COMPILE_OPTIONS
3075 Fortran_FORMAT Fortran_MODULE_DIRECTORY
3077 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
3078 POSITION_INDEPENDENT_CODE
3079 C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER
3080 C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE
3081 C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN
3082 C_CLANG_TIDY CXX_CLANG_TIDY)
3083 # copy compile features
3084 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3085 C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED
3086 CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED
3088 # copy interface stuff
3089 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3090 COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN
3091 COMPATIBLE_INTERFACE_STRING
3092 INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS
3093 INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES
3094 INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
3095 INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED)
3097 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3098 BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
3099 LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED
3100 LINK_FLAGS LINK_FLAGS_<CONFIG>
3101 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
3102 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
3103 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
3104 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
3105 NO_SONAME SOVERSION VERSION
3108 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3109 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
3110 # copy Apple platform specific stuff
3111 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3112 BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR
3113 MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH
3114 OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST
3115 IOS_INSTALL_COMBINED)
3116 # copy Windows platform specific stuff
3117 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3119 COMPILE_PDB_NAME COMPILE_PDB_NAME_<CONFIG>
3120 COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
3121 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
3122 VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION
3123 VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE
3124 VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK
3125 VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION
3126 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
3127 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
3128 VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES
3129 WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS
3130 DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE
3132 # copy Android platform specific stuff
3133 cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
3134 ANDROID_API ANDROID_API_MIN ANDROID_GUI
3135 ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES
3136 ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR
3137 ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES
3138 ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH
3139 ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE)
3140 # use output name from original target
3141 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
3142 if (NOT _targetOutputName)
3143 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
3145 # use export symbol from original target
3146 cotire_get_target_export_symbol("${_target}" _defineSymbol)
3148 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
3149 if ("${_targetType}" STREQUAL "EXECUTABLE")
3150 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
3153 cotire_init_target(${_unityTargetName})
3154 cotire_add_to_unity_all_target(${_unityTargetName})
3155 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
3156 endfunction(cotire_setup_unity_build_target)
3158 function (cotire_target _target)
3160 set(_oneValueArgs "")
3161 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3162 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3163 if (NOT _option_LANGUAGES)
3164 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
3166 if (NOT _option_CONFIGURATIONS)
3167 cotire_get_configuration_types(_option_CONFIGURATIONS)
3169 # check if cotire can be applied to target at all
3170 cotire_is_target_supported(${_target} _isSupported)
3171 if (NOT _isSupported)
3172 get_target_property(_imported ${_target} IMPORTED)
3173 get_target_property(_targetType ${_target} TYPE)
3175 message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.")
3177 message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.")
3182 get_target_property(_aliasName ${_target} ALIASED_TARGET)
3185 message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.")
3187 set (_target ${_aliasName})
3189 # check if target needs to be cotired for build type
3190 # when using configuration types, the test is performed at build time
3191 cotire_init_cotire_target_properties(${_target})
3192 if (NOT CMAKE_CONFIGURATION_TYPES)
3193 if (CMAKE_BUILD_TYPE)
3194 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
3196 list (FIND _option_CONFIGURATIONS "None" _index)
3198 if (_index EQUAL -1)
3200 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
3205 # when not using configuration types, immediately create cotire intermediate dir
3206 if (NOT CMAKE_CONFIGURATION_TYPES)
3207 cotire_get_intermediate_dir(_baseDir)
3208 file (MAKE_DIRECTORY "${_baseDir}")
3210 # choose languages that apply to the target
3211 cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES})
3212 if (NOT _targetLanguages)
3216 foreach (_language ${_targetLanguages})
3217 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd)
3219 list (APPEND _cmds ${_cmd})
3222 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
3224 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3226 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3228 cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds})
3229 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3231 cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target})
3234 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
3235 if (_targetAddCleanTarget)
3236 cotire_setup_clean_target(${_target})
3238 endfunction(cotire_target)
3240 function (cotire_map_libraries _strategy _mappedLibrariesVar)
3241 set (_mappedLibraries "")
3242 foreach (_library ${ARGN})
3243 if (_library MATCHES "^\\$<LINK_ONLY:(.+)>$")
3244 set (_libraryName "${CMAKE_MATCH_1}")
3245 set (_linkOnly TRUE)
3246 set (_objectLibrary FALSE)
3247 elseif (_library MATCHES "^\\$<TARGET_OBJECTS:(.+)>$")
3248 set (_libraryName "${CMAKE_MATCH_1}")
3249 set (_linkOnly FALSE)
3250 set (_objectLibrary TRUE)
3252 set (_libraryName "${_library}")
3253 set (_linkOnly FALSE)
3254 set (_objectLibrary FALSE)
3256 if ("${_strategy}" MATCHES "COPY_UNITY")
3257 cotire_is_target_supported(${_libraryName} _isSupported)
3259 # use target's corresponding unity target, if available
3260 get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME)
3261 if (TARGET "${_libraryUnityTargetName}")
3263 list (APPEND _mappedLibraries "$<LINK_ONLY:${_libraryUnityTargetName}>")
3264 elseif (_objectLibrary)
3265 list (APPEND _mappedLibraries "$<TARGET_OBJECTS:${_libraryUnityTargetName}>")
3267 list (APPEND _mappedLibraries "${_libraryUnityTargetName}")
3270 list (APPEND _mappedLibraries "${_library}")
3273 list (APPEND _mappedLibraries "${_library}")
3276 list (APPEND _mappedLibraries "${_library}")
3279 list (REMOVE_DUPLICATES _mappedLibraries)
3280 set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE)
3283 function (cotire_target_link_libraries _target)
3284 cotire_is_target_supported(${_target} _isSupported)
3285 if (NOT _isSupported)
3288 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3289 if (TARGET "${_unityTargetName}")
3290 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3292 message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}")
3294 if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$")
3295 get_target_property(_linkLibraries ${_target} LINK_LIBRARIES)
3297 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries})
3298 set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}")
3300 message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}")
3303 get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES)
3304 if (_interfaceLinkLibraries)
3305 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries})
3306 set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}")
3308 message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}")
3313 endfunction(cotire_target_link_libraries)
3315 function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
3317 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
3319 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
3321 # filter files in intermediate directory
3322 set (_filesToRemove "")
3323 foreach (_file ${_cotireFiles})
3324 get_filename_component(_dir "${_file}" DIRECTORY)
3325 get_filename_component(_dirName "${_dir}" NAME)
3326 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
3327 list (APPEND _filesToRemove "${_file}")
3332 message (STATUS "cleaning up ${_filesToRemove}")
3334 file (REMOVE ${_filesToRemove})
3338 function (cotire_init_target _targetName)
3339 if (COTIRE_TARGETS_FOLDER)
3340 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
3342 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE)
3344 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
3348 function (cotire_add_to_pch_all_target _pchTargetName)
3349 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
3350 if (NOT TARGET "${_targetName}")
3351 add_custom_target("${_targetName}"
3352 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3354 cotire_init_target("${_targetName}")
3356 cotire_setup_clean_all_target()
3357 add_dependencies(${_targetName} ${_pchTargetName})
3360 function (cotire_add_to_unity_all_target _unityTargetName)
3361 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
3362 if (NOT TARGET "${_targetName}")
3363 add_custom_target("${_targetName}"
3364 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3366 cotire_init_target("${_targetName}")
3368 cotire_setup_clean_all_target()
3369 add_dependencies(${_targetName} ${_unityTargetName})
3372 function (cotire_setup_clean_all_target)
3373 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
3374 if (NOT TARGET "${_targetName}")
3375 cotire_set_cmd_to_prologue(_cmds)
3376 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
3377 add_custom_target(${_targetName}
3379 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3380 COMMENT "Cleaning up all cotire generated files"
3382 cotire_init_target("${_targetName}")
3388 set(_oneValueArgs "")
3389 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3390 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3391 set (_targets ${_option_UNPARSED_ARGUMENTS})
3392 foreach (_target ${_targets})
3393 if (TARGET ${_target})
3394 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS})
3396 message (WARNING "cotire: ${_target} is not a target.")
3399 foreach (_target ${_targets})
3400 if (TARGET ${_target})
3401 cotire_target_link_libraries(${_target})
3406 if (CMAKE_SCRIPT_MODE_FILE)
3408 # cotire is being run in script mode
3409 # locate -P on command args
3410 set (COTIRE_ARGC -1)
3411 foreach (_index RANGE ${CMAKE_ARGC})
3412 if (COTIRE_ARGC GREATER -1)
3413 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
3414 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
3415 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
3420 # include target script if available
3421 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
3422 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
3423 include("${COTIRE_ARGV2}")
3427 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
3430 if (NOT COTIRE_BUILD_TYPE)
3431 set (COTIRE_BUILD_TYPE "None")
3433 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
3434 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
3435 set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}})
3436 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
3437 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
3438 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
3439 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
3440 if (_index GREATER -1)
3441 set (_sources ${COTIRE_TARGET_SOURCES})
3442 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
3445 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
3448 set (_sourcesDefinitions "")
3450 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
3451 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
3452 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
3453 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
3455 if ("${COTIRE_ARGV1}" STREQUAL "unity")
3458 # executing pre-build action under Xcode, check dependency on target script
3459 set (_dependsOption DEPENDS "${COTIRE_ARGV2}")
3461 # executing custom command, no need to re-check for dependencies
3462 set (_dependsOption "")
3465 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
3467 cotire_generate_unity_source(
3468 "${COTIRE_ARGV3}" ${_sources}
3469 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3470 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
3471 PRE_UNDEFS ${_targetPreUndefs}
3472 POST_UNDEFS ${_targetPostUndefs}
3473 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
3474 SOURCES_POST_UNDEFS ${_sourcesPostUndefs}
3477 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
3480 # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies
3481 set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS})
3483 # executing custom command, no need to re-check for dependencies
3484 set (_dependsOption "")
3488 foreach (_index RANGE 4 ${COTIRE_ARGC})
3489 if (COTIRE_ARGV${_index})
3490 list (APPEND _files "${COTIRE_ARGV${_index}}")
3494 cotire_generate_prefix_header(
3495 "${COTIRE_ARGV3}" ${_files}
3496 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3497 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3498 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3499 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3500 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3501 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3502 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
3503 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
3504 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
3505 INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH}
3506 INCLUDE_DIRECTORIES ${_includeDirs}
3507 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3508 COMPILE_DEFINITIONS ${_compileDefinitions}
3509 COMPILE_FLAGS ${_compileFlags}
3512 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
3515 foreach (_index RANGE 5 ${COTIRE_ARGC})
3516 if (COTIRE_ARGV${_index})
3517 list (APPEND _files "${COTIRE_ARGV${_index}}")
3521 cotire_precompile_prefix_header(
3522 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
3523 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3524 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3525 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3526 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3527 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3528 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3529 INCLUDE_DIRECTORIES ${_includeDirs}
3530 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3531 COMPILE_DEFINITIONS ${_compileDefinitions}
3532 COMPILE_FLAGS ${_compileFlags})
3534 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
3536 if (COTIRE_TARGET_LANGUAGE)
3537 set (_combinedFile "${COTIRE_ARGV3}")
3540 set (_combinedFile "${COTIRE_ARGV2}")
3544 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
3545 if (COTIRE_ARGV${_index})
3546 list (APPEND _files "${COTIRE_ARGV${_index}}")
3551 # executing pre-build action under Xcode, check dependency on files to be combined
3552 set (_dependsOption DEPENDS ${_files})
3554 # executing custom command, no need to re-check for dependencies
3555 set (_dependsOption "")
3558 if (COTIRE_TARGET_LANGUAGE)
3559 cotire_generate_unity_source(
3560 "${_combinedFile}" ${_files}
3561 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3564 cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption})
3567 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
3569 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
3572 message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".")
3577 # cotire is being run in include mode
3578 # set up all variable and property definitions
3580 if (NOT DEFINED COTIRE_DEBUG_INIT)
3581 if (DEFINED COTIRE_DEBUG)
3582 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
3584 set (COTIRE_DEBUG_INIT FALSE)
3587 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
3589 if (NOT DEFINED COTIRE_VERBOSE_INIT)
3590 if (DEFINED COTIRE_VERBOSE)
3591 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
3593 set (COTIRE_VERBOSE_INIT FALSE)
3596 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
3598 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
3599 "Ignore headers with the listed file extensions from the generated prefix header.")
3601 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
3602 "Ignore headers from these directories when generating the prefix header.")
3604 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
3605 "Ignore sources with the listed file extensions from the generated unity source.")
3607 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING
3608 "Minimum number of sources in target required to enable use of precompiled header.")
3610 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
3611 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
3612 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
3613 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
3614 # enable parallelization for generators that run multiple jobs by default
3615 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
3617 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
3620 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
3621 "Maximum number of source files to include in a single unity source file.")
3623 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
3624 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
3626 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
3627 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
3629 if (NOT COTIRE_INTDIR)
3630 set (COTIRE_INTDIR "cotire")
3632 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
3633 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
3635 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
3636 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
3638 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
3639 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
3641 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
3642 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
3644 if (NOT COTIRE_PCH_TARGET_SUFFIX)
3645 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
3648 # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code
3649 # use a bigger default factor of 170 percent (128 MB)
3650 if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR)
3651 set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170")
3654 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
3655 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
3657 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
3658 set (COTIRE_TARGETS_FOLDER "cotire")
3660 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
3661 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
3662 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
3663 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
3665 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
3669 # define cotire cache variables
3672 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
3673 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3675 "The variable can be set to a semicolon separated list of include directories."
3676 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3677 "If not defined, defaults to empty list."
3681 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
3682 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
3684 "The variable can be set to a semicolon separated list of file extensions."
3685 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
3686 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
3687 "If not defined, defaults to inc;inl;ipp."
3691 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
3692 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
3694 "The variable can be set to a semicolon separated list of file extensions."
3695 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
3696 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
3697 "If not defined, defaults to m;mm."
3701 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
3702 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
3704 "The variable can be set to an integer > 0."
3705 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
3706 "If not defined, defaults to 3."
3710 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
3711 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3713 "This may be set to an integer >= 0."
3714 "If 0, cotire will only create a single unity source file."
3715 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
3716 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
3717 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
3718 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3719 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
3722 # define cotire directory properties
3725 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
3726 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
3728 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
3732 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
3733 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
3735 "See target property COTIRE_ADD_UNITY_BUILD."
3739 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
3740 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
3742 "See target property COTIRE_ADD_CLEAN."
3746 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
3747 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3749 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
3753 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
3754 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3756 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
3760 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH"
3761 BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header."
3763 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH."
3767 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3768 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
3770 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
3774 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3775 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
3777 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
3781 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
3782 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3784 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3788 DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT"
3789 BRIEF_DOCS "Define strategy for setting up the unity target's link libraries."
3791 "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT."
3794 # define cotire target properties
3797 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
3798 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
3800 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
3801 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
3802 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
3803 "The target name will be set to this target's name with the suffix _pch appended."
3804 "Inherited from directory."
3809 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
3810 BRIEF_DOCS "Add a new target that performs a unity build for this target."
3812 "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."
3813 "Most of the relevant target properties will be copied from this target to the new unity build target."
3814 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
3815 "The unity target name will be set to this target's name with the suffix _unity appended."
3816 "Inherited from directory."
3821 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
3822 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
3824 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
3825 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
3826 "Inherited from directory."
3827 "Defaults to FALSE."
3831 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
3832 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3834 "The property can be set to a list of directories."
3835 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3836 "Inherited from directory."
3837 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
3841 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
3842 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3844 "The property can be set to a list of directories."
3845 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
3846 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
3847 "the option which yields the closer relative path match wins."
3848 "Inherited from directory."
3849 "If not set, this property is initialized to the empty list."
3853 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED
3854 BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header."
3856 "The property can be set to a list of directories."
3857 "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header."
3858 "Header files are sorted according to the order of the directories in the property."
3859 "If not set, this property is initialized to the empty list."
3863 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
3864 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
3866 "This may be set to a semicolon-separated list of preprocessor symbols."
3867 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
3868 "Inherited from directory."
3869 "Defaults to empty string."
3873 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
3874 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
3876 "This may be set to a semicolon-separated list of preprocessor symbols."
3877 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
3878 "Inherited from directory."
3879 "Defaults to empty string."
3883 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
3884 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3886 "This may be set to an integer > 0."
3887 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
3888 "If not set, cotire will only create a single unity source file."
3889 "Inherited from directory."
3890 "Defaults to empty."
3894 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
3895 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
3897 "If set, cotire will only add the given file(s) to the generated unity source file."
3898 "If not set, cotire will add all the target source files to the generated unity source file."
3899 "The property can be set to a user provided unity source file."
3900 "Defaults to empty."
3904 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
3905 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
3907 "If set, cotire will add the given header file(s) to the generated prefix header file."
3908 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
3909 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
3910 "Defaults to empty."
3914 TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED
3915 BRIEF_DOCS "Define strategy for setting up unity target's link libraries."
3917 "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually."
3918 "If this property is set to COPY, the unity target's link libraries will be copied from this target."
3919 "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."
3920 "Inherited from directory."
3921 "Defaults to empty."
3925 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
3926 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
3928 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
3929 "Defaults to empty string."
3933 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
3934 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
3936 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
3937 "Defaults to empty string."
3941 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
3942 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
3944 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
3945 "Defaults to empty string."
3949 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
3950 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
3952 "This property can be set to the desired name of the unity target that will be created by cotire."
3953 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
3954 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
3955 "Defaults to empty string."
3958 # define cotire source properties
3961 SOURCE PROPERTY "COTIRE_EXCLUDED"
3962 BRIEF_DOCS "Do not modify source file's build command."
3964 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
3965 "The source file will also be excluded from the generated unity source file."
3966 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
3967 "Defaults to FALSE."
3971 SOURCE PROPERTY "COTIRE_DEPENDENCY"
3972 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
3974 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
3975 "If the file is modified, cotire will re-generate the prefix header source upon build."
3976 "Defaults to FALSE."
3980 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3981 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
3983 "This may be set to a semicolon-separated list of preprocessor symbols."
3984 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
3985 "Defaults to empty string."
3989 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3990 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
3992 "This may be set to a semicolon-separated list of preprocessor symbols."
3993 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
3994 "Defaults to empty string."
3998 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
3999 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
4001 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
4002 "The new unity source file will include this source file as the first one."
4003 "This property essentially works as a separator for unity source files."
4004 "Defaults to FALSE."
4008 SOURCE PROPERTY "COTIRE_TARGET"
4009 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
4011 "cotire sets this property to the name of target, that the source file's build command has been altered for."
4012 "Defaults to empty string."
4015 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")