1 # - cotire (compile time reducer)
3 # See the cotire manual for usage hints.
5 #=============================================================================
6 # Copyright 2012-2018 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.8.0")
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)
110 # strict checking for break() command
111 cmake_policy(SET CMP0055 NEW)
114 include(CMakeParseArguments)
115 include(ProcessorCount)
117 function (cotire_get_configuration_types _configsVar)
119 if (CMAKE_CONFIGURATION_TYPES)
120 list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES})
122 if (CMAKE_BUILD_TYPE)
123 list (APPEND _configs "${CMAKE_BUILD_TYPE}")
126 list (REMOVE_DUPLICATES _configs)
127 set (${_configsVar} ${_configs} PARENT_SCOPE)
129 set (${_configsVar} "None" PARENT_SCOPE)
133 function (cotire_get_source_file_extension _sourceFile _extVar)
134 # get_filename_component returns extension from first occurrence of . in file name
135 # this function computes the extension from last occurrence of . in file name
136 string (FIND "${_sourceFile}" "." _index REVERSE)
137 if (_index GREATER -1)
138 math (EXPR _index "${_index} + 1")
139 string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
143 set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
146 macro (cotire_check_is_path_relative_to _path _isRelativeVar)
147 set (${_isRelativeVar} FALSE)
148 if (IS_ABSOLUTE "${_path}")
149 foreach (_dir ${ARGN})
150 file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
151 if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
152 set (${_isRelativeVar} TRUE)
159 function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
160 if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
161 set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
163 set (_languageExtensions "")
165 if (CMAKE_${_language}_IGNORE_EXTENSIONS)
166 set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}")
168 set (_ignoreExtensions "")
170 if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS)
171 set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}")
173 set (_excludeExtensions "")
175 if (COTIRE_DEBUG AND _languageExtensions)
176 message (STATUS "${_language} source file extensions: ${_languageExtensions}")
178 if (COTIRE_DEBUG AND _ignoreExtensions)
179 message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}")
181 if (COTIRE_DEBUG AND _excludeExtensions)
182 message (STATUS "${_language} exclude extensions: ${_excludeExtensions}")
184 if (CMAKE_VERSION VERSION_LESS "3.1.0")
185 set (_allSourceFiles ${ARGN})
187 # as of CMake 3.1 target sources may contain generator expressions
188 # since we cannot obtain required property information about source files added
189 # through generator expressions at configure time, we filter them out
190 string (GENEX_STRIP "${ARGN}" _allSourceFiles)
192 set (_filteredSourceFiles "")
193 set (_excludedSourceFiles "")
194 foreach (_sourceFile ${_allSourceFiles})
195 get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY)
196 get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT)
197 get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC)
198 if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic)
199 cotire_get_source_file_extension("${_sourceFile}" _sourceExt)
201 list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex)
202 if (_ignoreIndex LESS 0)
203 list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex)
204 if (_excludeIndex GREATER -1)
205 list (APPEND _excludedSourceFiles "${_sourceFile}")
207 list (FIND _languageExtensions "${_sourceExt}" _sourceIndex)
208 if (_sourceIndex GREATER -1)
209 # consider source file unless it is excluded explicitly
210 get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED)
211 if (_sourceIsExcluded)
212 list (APPEND _excludedSourceFiles "${_sourceFile}")
214 list (APPEND _filteredSourceFiles "${_sourceFile}")
217 get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE)
218 if ("${_sourceLanguage}" STREQUAL "${_language}")
219 # add to excluded sources, if file is not ignored and has correct language without having the correct extension
220 list (APPEND _excludedSourceFiles "${_sourceFile}")
228 # separate filtered source files from already cotired ones
229 # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire
230 set (_sourceFiles "")
231 set (_cotiredSourceFiles "")
232 foreach (_sourceFile ${_filteredSourceFiles})
233 get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET)
234 if (_sourceIsCotired)
235 list (APPEND _cotiredSourceFiles "${_sourceFile}")
237 get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS)
238 if (_sourceCompileFlags)
239 # add to excluded sources, if file has custom compile flags
240 list (APPEND _excludedSourceFiles "${_sourceFile}")
242 get_source_file_property(_sourceCompileOptions "${_sourceFile}" COMPILE_OPTIONS)
243 if (_sourceCompileOptions)
244 # add to excluded sources, if file has list of custom compile options
245 list (APPEND _excludedSourceFiles "${_sourceFile}")
247 list (APPEND _sourceFiles "${_sourceFile}")
254 message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}")
256 if (_excludedSourceFiles)
257 message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}")
259 if (_cotiredSourceFiles)
260 message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}")
263 set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE)
264 set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE)
265 set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE)
268 function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
269 set (_filteredObjects "")
270 foreach (_object ${ARGN})
271 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
273 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
275 list (APPEND _filteredObjects "${_object}")
279 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
282 function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
283 set (_filteredObjects "")
284 foreach (_object ${ARGN})
285 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
287 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
288 if (NOT _propertyValue)
289 list (APPEND _filteredObjects "${_object}")
293 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
296 function (cotire_get_source_file_property_values _valuesVar _property)
298 foreach (_sourceFile ${ARGN})
299 get_source_file_property(_propertyValue "${_sourceFile}" ${_property})
301 list (APPEND _values "${_propertyValue}")
304 set (${_valuesVar} ${_values} PARENT_SCOPE)
307 function (cotire_resolve_config_properties _configurations _propertiesVar)
309 foreach (_property ${ARGN})
310 if ("${_property}" MATCHES "<CONFIG>")
311 foreach (_config ${_configurations})
312 string (TOUPPER "${_config}" _upperConfig)
313 string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}")
314 list (APPEND _properties ${_configProperty})
317 list (APPEND _properties ${_property})
320 set (${_propertiesVar} ${_properties} PARENT_SCOPE)
323 function (cotire_copy_set_properties _configurations _type _source _target)
324 cotire_resolve_config_properties("${_configurations}" _properties ${ARGN})
325 foreach (_property ${_properties})
326 get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
328 get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
329 set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
334 function (cotire_get_target_usage_requirements _target _config _targetRequirementsVar)
335 set (_targetRequirements "")
336 get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES)
337 while (_librariesToProcess)
339 list (GET _librariesToProcess 0 _library)
340 list (REMOVE_AT _librariesToProcess 0)
341 if (_library MATCHES "^\\$<\\$<CONFIG:${_config}>:([A-Za-z0-9_:-]+)>$")
342 set (_library "${CMAKE_MATCH_1}")
343 elseif (_config STREQUAL "None" AND _library MATCHES "^\\$<\\$<CONFIG:>:([A-Za-z0-9_:-]+)>$")
344 set (_library "${CMAKE_MATCH_1}")
346 if (TARGET ${_library})
347 list (FIND _targetRequirements ${_library} _index)
349 list (APPEND _targetRequirements ${_library})
350 # BFS traversal of transitive libraries
351 get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES)
353 list (APPEND _librariesToProcess ${_libraries})
354 list (REMOVE_DUPLICATES _librariesToProcess)
359 set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE)
362 function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar)
363 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
364 set (_flagPrefix "[/-]")
366 set (_flagPrefix "--?")
369 set (_matchedOptions "")
370 set (_unmatchedOptions "")
371 foreach (_compileFlag ${ARGN})
373 if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}")
374 # option with separate argument
375 list (APPEND _matchedOptions "${_compileFlag}")
377 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$")
379 set (_optionFlag "${CMAKE_MATCH_2}")
380 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$")
381 # option with joined argument
382 list (APPEND _matchedOptions "${CMAKE_MATCH_3}")
385 # flush remembered option
387 list (APPEND _matchedOptions "${_optionFlag}")
390 # add to unfiltered options
391 list (APPEND _unmatchedOptions "${_compileFlag}")
396 list (APPEND _matchedOptions "${_optionFlag}")
398 if (COTIRE_DEBUG AND _matchedOptions)
399 message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}")
401 if (COTIRE_DEBUG AND _unmatchedOptions)
402 message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}")
404 set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE)
405 set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE)
408 function (cotire_is_target_supported _target _isSupportedVar)
409 if (NOT TARGET "${_target}")
410 set (${_isSupportedVar} FALSE PARENT_SCOPE)
413 get_target_property(_imported ${_target} IMPORTED)
415 set (${_isSupportedVar} FALSE PARENT_SCOPE)
418 get_target_property(_targetType ${_target} TYPE)
419 if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
420 set (${_isSupportedVar} FALSE PARENT_SCOPE)
423 set (${_isSupportedVar} TRUE PARENT_SCOPE)
426 function (cotire_get_target_compile_flags _config _language _target _flagsVar)
427 string (TOUPPER "${_config}" _upperConfig)
428 # collect options from CMake language variables
429 set (_compileFlags "")
430 if (CMAKE_${_language}_FLAGS)
431 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
433 if (CMAKE_${_language}_FLAGS_${_upperConfig})
434 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}")
437 # add target compile flags
438 get_target_property(_targetflags ${_target} COMPILE_FLAGS)
440 set (_compileFlags "${_compileFlags} ${_targetflags}")
444 separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}")
446 separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}")
448 separate_arguments(_compileFlags)
450 # target compile options
452 get_target_property(_targetOptions ${_target} COMPILE_OPTIONS)
454 list (APPEND _compileFlags ${_targetOptions})
457 # interface compile options from linked library targets
459 set (_linkedTargets "")
460 cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets)
461 foreach (_linkedTarget ${_linkedTargets})
462 get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS)
464 list (APPEND _compileFlags ${_targetOptions})
468 # handle language standard properties
469 if (CMAKE_${_language}_STANDARD_DEFAULT)
470 # used compiler supports language standard levels
472 get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD)
473 if (_targetLanguageStandard)
474 set (_type "EXTENSION")
475 get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET)
477 get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS)
478 if (NOT _targetUseLanguageExtensions)
479 set (_type "STANDARD")
482 if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION)
483 list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}")
488 # handle the POSITION_INDEPENDENT_CODE target property
490 get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE)
492 get_target_property(_targetType ${_target} TYPE)
493 if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE)
494 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}")
495 elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC)
496 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}")
500 # handle visibility target properties
502 get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET)
503 if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY)
504 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}")
506 get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN)
507 if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN)
508 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}")
511 # platform specific flags
513 get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig})
514 if (NOT _architectures)
515 get_target_property(_architectures ${_target} OSX_ARCHITECTURES)
518 foreach (_arch ${_architectures})
519 list (APPEND _compileFlags "-arch" "${_arch}")
522 if (CMAKE_OSX_SYSROOT)
523 if (CMAKE_${_language}_SYSROOT_FLAG)
524 list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}")
526 list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}")
529 if (CMAKE_OSX_DEPLOYMENT_TARGET)
530 if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG)
531 list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
533 list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
537 if (COTIRE_DEBUG AND _compileFlags)
538 message (STATUS "Target ${_target} compile flags: ${_compileFlags}")
540 set (${_flagsVar} ${_compileFlags} PARENT_SCOPE)
543 function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar)
544 set (_includeDirs "")
545 set (_systemIncludeDirs "")
546 # default include dirs
547 if (CMAKE_INCLUDE_CURRENT_DIR)
548 list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}")
549 list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}")
551 set (_targetFlags "")
552 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
553 # parse additional include directories from target compile flags
554 if (CMAKE_INCLUDE_FLAG_${_language})
555 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
556 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
559 cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags})
561 list (APPEND _includeDirs ${_dirs})
565 # parse additional system include directories from target compile flags
566 if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language})
567 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag)
568 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
571 cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags})
573 list (APPEND _systemIncludeDirs ${_dirs})
577 # target include directories
578 get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES)
580 get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES)
582 list (APPEND _dirs ${_targetDirs})
584 get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
586 list (APPEND _systemIncludeDirs ${_targetDirs})
589 # interface include directories from linked library targets
591 set (_linkedTargets "")
592 cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets)
593 foreach (_linkedTarget ${_linkedTargets})
594 get_target_property(_linkedTargetType ${_linkedTarget} TYPE)
595 if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND
596 _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
597 # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR
598 # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR
599 # which are only available with CMake 3.4 or later.
600 get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR)
602 list (APPEND _dirs ${_targetDirs})
604 get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR)
606 list (APPEND _dirs ${_targetDirs})
609 get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES)
611 list (APPEND _dirs ${_targetDirs})
613 get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
615 list (APPEND _systemIncludeDirs ${_targetDirs})
620 list (REMOVE_DUPLICATES _dirs)
622 list (LENGTH _includeDirs _projectInsertIndex)
623 foreach (_dir ${_dirs})
624 if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE)
625 cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
627 list (LENGTH _includeDirs _len)
628 if (_len EQUAL _projectInsertIndex)
629 list (APPEND _includeDirs "${_dir}")
631 list (INSERT _includeDirs _projectInsertIndex "${_dir}")
633 math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1")
635 list (APPEND _includeDirs "${_dir}")
638 list (APPEND _includeDirs "${_dir}")
641 list (REMOVE_DUPLICATES _includeDirs)
642 list (REMOVE_DUPLICATES _systemIncludeDirs)
643 if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES)
644 list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES})
646 if (WIN32 AND NOT MINGW)
647 # convert Windows paths in include directories to CMake paths
650 foreach (_dir ${_includeDirs})
651 file (TO_CMAKE_PATH "${_dir}" _path)
652 list (APPEND _paths "${_path}")
654 set (_includeDirs ${_paths})
656 if (_systemIncludeDirs)
658 foreach (_dir ${_systemIncludeDirs})
659 file (TO_CMAKE_PATH "${_dir}" _path)
660 list (APPEND _paths "${_path}")
662 set (_systemIncludeDirs ${_paths})
665 if (COTIRE_DEBUG AND _includeDirs)
666 message (STATUS "Target ${_target} include dirs: ${_includeDirs}")
668 set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE)
669 if (COTIRE_DEBUG AND _systemIncludeDirs)
670 message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}")
672 set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE)
675 function (cotire_get_target_export_symbol _target _exportSymbolVar)
676 set (_exportSymbol "")
677 get_target_property(_targetType ${_target} TYPE)
678 get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
679 if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
680 (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
681 get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
682 if (NOT _exportSymbol)
683 set (_exportSymbol "${_target}_EXPORTS")
685 string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol)
687 set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
690 function (cotire_get_target_compile_definitions _config _language _target _definitionsVar)
691 string (TOUPPER "${_config}" _upperConfig)
692 set (_configDefinitions "")
693 # CMAKE_INTDIR for multi-configuration build systems
694 if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
695 list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
697 # target export define symbol
698 cotire_get_target_export_symbol("${_target}" _defineSymbol)
700 list (APPEND _configDefinitions "${_defineSymbol}")
702 # directory compile definitions
703 get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS)
705 list (APPEND _configDefinitions ${_definitions})
707 get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig})
709 list (APPEND _configDefinitions ${_definitions})
711 # target compile definitions
712 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS)
714 list (APPEND _configDefinitions ${_definitions})
716 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig})
718 list (APPEND _configDefinitions ${_definitions})
720 # interface compile definitions from linked library targets
721 set (_linkedTargets "")
722 cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets)
723 foreach (_linkedTarget ${_linkedTargets})
724 get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS)
726 list (APPEND _configDefinitions ${_definitions})
729 # parse additional compile definitions from target compile flags
730 # and do not look at directory compile definitions, which we already handled
731 set (_targetFlags "")
732 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
733 cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags})
735 list (APPEND _configDefinitions ${_definitions})
737 list (REMOVE_DUPLICATES _configDefinitions)
738 if (COTIRE_DEBUG AND _configDefinitions)
739 message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}")
741 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
744 function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar)
745 # parse target compile flags omitting compile definitions and include directives
746 set (_targetFlags "")
747 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
748 set (_flagFilter "D")
749 if (CMAKE_INCLUDE_FLAG_${_language})
750 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
751 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
753 set (_flagFilter "${_flagFilter}|${_includeFlag}")
756 if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language})
757 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag)
758 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
760 set (_flagFilter "${_flagFilter}|${_includeFlag}")
763 set (_compilerFlags "")
764 cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags})
765 if (COTIRE_DEBUG AND _compilerFlags)
766 message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}")
768 set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE)
771 function (cotire_add_sys_root_paths _pathsVar)
773 if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT)
774 foreach (_path IN LISTS ${_pathsVar})
775 if (IS_ABSOLUTE "${_path}")
776 get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE)
777 if (EXISTS "${_path}")
778 list (APPEND ${_pathsVar} "${_path}")
784 set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE)
787 function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar)
788 set (_extraProperties ${ARGN})
790 if (_extraProperties)
791 list (FIND _extraProperties "${_sourceFile}" _index)
792 if (_index GREATER -1)
793 math (EXPR _index "${_index} + 1")
794 list (LENGTH _extraProperties _len)
795 math (EXPR _len "${_len} - 1")
796 foreach (_index RANGE ${_index} ${_len})
797 list (GET _extraProperties ${_index} _value)
798 if (_value MATCHES "${_pattern}")
799 list (APPEND _result "${_value}")
806 set (${_resultVar} ${_result} PARENT_SCOPE)
809 function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
810 set (_compileDefinitions "")
811 if (NOT CMAKE_SCRIPT_MODE_FILE)
812 string (TOUPPER "${_config}" _upperConfig)
813 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
815 list (APPEND _compileDefinitions ${_definitions})
817 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig})
819 list (APPEND _compileDefinitions ${_definitions})
822 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN})
824 list (APPEND _compileDefinitions ${_definitions})
826 if (COTIRE_DEBUG AND _compileDefinitions)
827 message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}")
829 set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE)
832 function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
833 set (_configDefinitions "")
834 foreach (_sourceFile ${ARGN})
835 cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
836 if (_sourceDefinitions)
837 list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
840 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
843 function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
844 set (_sourceUndefs "")
845 if (NOT CMAKE_SCRIPT_MODE_FILE)
846 get_source_file_property(_undefs "${_sourceFile}" ${_property})
848 list (APPEND _sourceUndefs ${_undefs})
851 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN})
853 list (APPEND _sourceUndefs ${_undefs})
855 if (COTIRE_DEBUG AND _sourceUndefs)
856 message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}")
858 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
861 function (cotire_get_source_files_undefs _property _sourceUndefsVar)
862 set (_sourceUndefs "")
863 foreach (_sourceFile ${ARGN})
864 cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs)
866 list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-")
869 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
872 macro (cotire_set_cmd_to_prologue _cmdVar)
873 set (${_cmdVar} "${CMAKE_COMMAND}")
875 list (APPEND ${_cmdVar} "--warn-uninitialized")
877 list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>")
879 list (APPEND ${_cmdVar} "-DXCODE:BOOL=TRUE")
882 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON")
883 elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles")
884 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)")
888 function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1)
889 if (NOT _compilerLauncher)
890 set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER})
892 if (NOT _compilerExe)
893 set (_compilerExe "${CMAKE_${_language}_COMPILER}")
895 if (NOT _compilerArg1)
896 set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1})
899 file (TO_NATIVE_PATH "${_compilerExe}" _compilerExe)
901 string (STRIP "${_compilerArg1}" _compilerArg1)
902 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
903 # compiler launcher is only supported for Makefile and Ninja
904 set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
906 set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
910 macro (cotire_add_definitions_to_cmd _cmdVar _language)
911 foreach (_definition ${ARGN})
912 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
913 list (APPEND ${_cmdVar} "/D${_definition}")
915 list (APPEND ${_cmdVar} "-D${_definition}")
920 function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar)
921 set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}})
923 list (REMOVE_DUPLICATES _includeDirs)
924 foreach (_include ${_includeDirs})
925 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
926 file (TO_NATIVE_PATH "${_include}" _include)
927 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}")
930 if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+")
931 list (FIND ${_systemIncludesVar} "${_include}" _index)
933 if (_index GREATER -1)
934 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}")
936 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}")
941 set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE)
944 function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar)
946 set (_frameworkDirs "")
947 foreach (_include ${${_includesVar}})
948 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
949 get_filename_component(_frameworkDir "${_include}" DIRECTORY)
950 list (APPEND _frameworkDirs "${_frameworkDir}")
953 set (_systemFrameworkDirs "")
954 foreach (_include ${${_systemIncludesVar}})
955 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
956 get_filename_component(_frameworkDir "${_include}" DIRECTORY)
957 list (APPEND _systemFrameworkDirs "${_frameworkDir}")
960 if (_systemFrameworkDirs)
961 list (APPEND _frameworkDirs ${_systemFrameworkDirs})
964 list (REMOVE_DUPLICATES _frameworkDirs)
965 foreach (_frameworkDir ${_frameworkDirs})
967 if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+")
968 list (FIND _systemFrameworkDirs "${_frameworkDir}" _index)
970 if (_index GREATER -1)
971 list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}")
973 list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}")
978 set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE)
981 macro (cotire_add_compile_flags_to_cmd _cmdVar)
982 foreach (_flag ${ARGN})
983 list (APPEND ${_cmdVar} "${_flag}")
987 function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
988 if (EXISTS "${_file}")
989 set (_triggerFile "")
990 foreach (_dependencyFile ${ARGN})
991 if (EXISTS "${_dependencyFile}")
992 # IS_NEWER_THAN returns TRUE if both files have the same timestamp
993 # thus we do the comparison in both directions to exclude ties
994 if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND
995 NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}")
996 set (_triggerFile "${_dependencyFile}")
1003 get_filename_component(_fileName "${_file}" NAME)
1004 message (STATUS "${_fileName} update triggered by ${_triggerFile} change.")
1006 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
1009 get_filename_component(_fileName "${_file}" NAME)
1010 message (STATUS "${_fileName} is up-to-date.")
1012 set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE)
1016 get_filename_component(_fileName "${_file}" NAME)
1017 message (STATUS "${_fileName} does not exist yet.")
1019 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
1023 macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
1024 set (${_relPathVar} "")
1025 foreach (_includeDir ${_includeDirs})
1026 if (IS_DIRECTORY "${_includeDir}")
1027 file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
1028 if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
1029 string (LENGTH "${${_relPathVar}}" _closestLen)
1030 string (LENGTH "${_relPath}" _relLen)
1031 if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
1032 set (${_relPathVar} "${_relPath}")
1035 elseif ("${_includeDir}" STREQUAL "${_headerFile}")
1036 # if path matches exactly, return short non-empty string
1037 set (${_relPathVar} "1")
1043 macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside)
1044 # check header path against ignored and honored include directories
1045 cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath)
1047 # header is inside, but could be become outside if there is a shorter outside match
1048 cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath)
1049 if (_outsideRelPath)
1050 string (LENGTH "${_insideRelPath}" _insideRelPathLen)
1051 string (LENGTH "${_outsideRelPath}" _outsideRelPathLen)
1052 if (_outsideRelPathLen LESS _insideRelPathLen)
1053 set (${_headerIsInside} FALSE)
1055 set (${_headerIsInside} TRUE)
1058 set (${_headerIsInside} TRUE)
1062 set (${_headerIsInside} FALSE)
1066 macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
1067 if (NOT EXISTS "${_headerFile}")
1068 set (${_headerIsIgnoredVar} TRUE)
1069 elseif (IS_DIRECTORY "${_headerFile}")
1070 set (${_headerIsIgnoredVar} TRUE)
1071 elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$")
1072 # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path
1073 # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
1074 # with the error message "error: no include path in which to search for header.h"
1075 set (${_headerIsIgnoredVar} TRUE)
1077 set (${_headerIsIgnoredVar} FALSE)
1081 macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
1082 # check header file extension
1083 cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
1084 set (${_headerIsIgnoredVar} FALSE)
1086 list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
1087 if (_index GREATER -1)
1088 set (${_headerIsIgnoredVar} TRUE)
1093 macro (cotire_parse_line _line _headerFileVar _headerDepthVar)
1095 # cl.exe /showIncludes produces different output, depending on the language pack used, e.g.:
1096 # English: "Note: including file: C:\directory\file"
1097 # German: "Hinweis: Einlesen der Datei: C:\directory\file"
1098 # We use a very general regular expression, relying on the presence of the : characters
1099 if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$")
1100 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
1101 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE)
1103 set (${_headerFileVar} "")
1104 set (${_headerDepthVar} 0)
1107 if (_line MATCHES "^(\\.+) (.*)$")
1109 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
1110 if (IS_ABSOLUTE "${CMAKE_MATCH_2}")
1111 set (${_headerFileVar} "${CMAKE_MATCH_2}")
1113 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH)
1116 set (${_headerFileVar} "")
1117 set (${_headerDepthVar} 0)
1122 function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar)
1124 # prevent CMake macro invocation errors due to backslash characters in Windows paths
1125 string (REPLACE "\\" "/" _scanOutput "${_scanOutput}")
1128 string (REPLACE "//" "/" _scanOutput "${_scanOutput}")
1129 # prevent semicolon from being interpreted as a line separator
1130 string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}")
1131 # then separate lines
1132 string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}")
1133 list (LENGTH _scanOutput _len)
1134 # remove duplicate lines to speed up parsing
1135 list (REMOVE_DUPLICATES _scanOutput)
1136 list (LENGTH _scanOutput _uniqueLen)
1137 if (COTIRE_VERBOSE OR COTIRE_DEBUG)
1138 message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes")
1139 if (_ignoredExtensions)
1140 message (STATUS "Ignored extensions: ${_ignoredExtensions}")
1142 if (_ignoredIncludeDirs)
1143 message (STATUS "Ignored paths: ${_ignoredIncludeDirs}")
1145 if (_honoredIncludeDirs)
1146 message (STATUS "Included paths: ${_honoredIncludeDirs}")
1149 set (_sourceFiles ${ARGN})
1150 set (_selectedIncludes "")
1151 set (_unparsedLines "")
1152 # stack keeps track of inside/outside project status of processed header files
1153 set (_headerIsInsideStack "")
1154 foreach (_line IN LISTS _scanOutput)
1156 cotire_parse_line("${_line}" _headerFile _headerDepth)
1158 cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside)
1160 message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}")
1163 list (LENGTH _headerIsInsideStack _stackLen)
1164 if (_headerDepth GREATER _stackLen)
1165 math (EXPR _stackLen "${_stackLen} + 1")
1166 foreach (_index RANGE ${_stackLen} ${_headerDepth})
1167 list (APPEND _headerIsInsideStack ${_headerIsInside})
1170 foreach (_index RANGE ${_headerDepth} ${_stackLen})
1171 list (REMOVE_AT _headerIsInsideStack -1)
1173 list (APPEND _headerIsInsideStack ${_headerIsInside})
1176 message (STATUS "${_headerIsInsideStack}")
1178 # header is a candidate if it is outside project
1179 if (NOT _headerIsInside)
1180 # get parent header file's inside/outside status
1181 if (_headerDepth GREATER 1)
1182 math (EXPR _index "${_headerDepth} - 2")
1183 list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside)
1185 set (_parentHeaderIsInside TRUE)
1187 # select header file if parent header file is inside project
1188 # (e.g., a project header file that includes a standard header file)
1189 if (_parentHeaderIsInside)
1190 cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored)
1191 if (NOT _headerIsIgnored)
1192 cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored)
1193 if (NOT _headerIsIgnored)
1194 list (APPEND _selectedIncludes "${_headerFile}")
1196 # fix header's inside status on stack, it is ignored by extension now
1197 list (REMOVE_AT _headerIsInsideStack -1)
1198 list (APPEND _headerIsInsideStack TRUE)
1202 message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}")
1208 # for cl.exe do not keep unparsed lines which solely consist of a source file name
1209 string (FIND "${_sourceFiles}" "${_line}" _index)
1211 list (APPEND _unparsedLines "${_line}")
1214 list (APPEND _unparsedLines "${_line}")
1219 list (REMOVE_DUPLICATES _selectedIncludes)
1220 set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE)
1221 set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE)
1224 function (cotire_scan_includes _includesVar)
1226 set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT)
1227 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES
1228 IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER)
1229 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1230 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1231 if (NOT _option_LANGUAGE)
1232 set (_option_LANGUAGE "CXX")
1234 if (NOT _option_COMPILER_ID)
1235 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1237 if (NOT _option_COMPILER_VERSION)
1238 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1240 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1241 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1242 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1243 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1244 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1245 cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd)
1246 # only consider existing source files for scanning
1247 set (_existingSourceFiles "")
1248 foreach (_sourceFile ${_sourceFiles})
1249 if (EXISTS "${_sourceFile}")
1250 list (APPEND _existingSourceFiles "${_sourceFile}")
1253 if (NOT _existingSourceFiles)
1254 set (${_includesVar} "" PARENT_SCOPE)
1257 # add source files to be scanned
1259 foreach (_sourceFile ${_existingSourceFiles})
1260 file (TO_NATIVE_PATH "${_sourceFile}" _sourceFileNative)
1261 list (APPEND _cmd "${_sourceFileNative}")
1264 list (APPEND _cmd ${_existingSourceFiles})
1267 message (STATUS "execute_process: ${_cmd}")
1269 if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC")
1270 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1271 unset (ENV{VS_UNICODE_OUTPUT})
1275 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1276 RESULT_VARIABLE _result
1278 ERROR_VARIABLE _output)
1280 message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.")
1282 cotire_parse_includes(
1283 "${_option_LANGUAGE}" "${_output}"
1284 "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}"
1285 "${_option_IGNORE_EXTENSIONS}"
1286 _includes _unparsedLines
1288 if (_option_INCLUDE_PRIORITY_PATH)
1289 set (_sortedIncludes "")
1290 foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH})
1291 foreach (_include ${_includes})
1292 string (FIND ${_include} ${_priorityPath} _position)
1293 if (_position GREATER -1)
1294 list (APPEND _sortedIncludes ${_include})
1298 if (_sortedIncludes)
1299 list (INSERT _includes 0 ${_sortedIncludes})
1300 list (REMOVE_DUPLICATES _includes)
1303 set (${_includesVar} ${_includes} PARENT_SCOPE)
1304 if (_option_UNPARSED_LINES)
1305 set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE)
1307 if (_option_SCAN_RESULT)
1308 set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE)
1312 macro (cotire_append_undefs _contentsVar)
1313 set (_undefs ${ARGN})
1315 list (REMOVE_DUPLICATES _undefs)
1316 foreach (_definition ${_undefs})
1317 list (APPEND ${_contentsVar} "#undef ${_definition}")
1322 macro (cotire_comment_str _language _commentText _commentVar)
1323 if ("${_language}" STREQUAL "CMAKE")
1324 set (${_commentVar} "# ${_commentText}")
1326 set (${_commentVar} "/* ${_commentText} */")
1330 function (cotire_write_file _language _file _contents _force)
1331 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1332 cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
1333 cotire_comment_str("${_language}" "${_file}" _header2)
1334 set (_contents "${_header1}\n${_header2}\n${_contents}")
1336 message (STATUS "${_contents}")
1338 if (_force OR NOT EXISTS "${_file}")
1339 file (WRITE "${_file}" "${_contents}")
1341 file (READ "${_file}" _oldContents)
1342 if (NOT "${_oldContents}" STREQUAL "${_contents}")
1343 file (WRITE "${_file}" "${_contents}")
1346 message (STATUS "${_file} unchanged")
1352 function (cotire_generate_unity_source _unityFile)
1354 set(_oneValueArgs LANGUAGE)
1356 DEPENDS SOURCES_COMPILE_DEFINITIONS
1357 PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE)
1358 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1359 if (_option_DEPENDS)
1360 cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS})
1361 if (_unityFileIsUpToDate)
1365 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1366 if (NOT _option_PRE_UNDEFS)
1367 set (_option_PRE_UNDEFS "")
1369 if (NOT _option_SOURCES_PRE_UNDEFS)
1370 set (_option_SOURCES_PRE_UNDEFS "")
1372 if (NOT _option_POST_UNDEFS)
1373 set (_option_POST_UNDEFS "")
1375 if (NOT _option_SOURCES_POST_UNDEFS)
1376 set (_option_SOURCES_POST_UNDEFS "")
1379 if (_option_PROLOGUE)
1380 list (APPEND _contents ${_option_PROLOGUE})
1382 if (_option_LANGUAGE AND _sourceFiles)
1383 if ("${_option_LANGUAGE}" STREQUAL "CXX")
1384 list (APPEND _contents "#ifdef __cplusplus")
1385 elseif ("${_option_LANGUAGE}" STREQUAL "C")
1386 list (APPEND _contents "#ifndef __cplusplus")
1389 set (_compileUndefinitions "")
1390 foreach (_sourceFile ${_sourceFiles})
1391 cotire_get_source_compile_definitions(
1392 "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions
1393 ${_option_SOURCES_COMPILE_DEFINITIONS})
1394 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS})
1395 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS})
1396 if (_option_PRE_UNDEFS)
1397 list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS})
1399 if (_sourcePreUndefs)
1400 list (APPEND _compileUndefinitions ${_sourcePreUndefs})
1402 if (_compileUndefinitions)
1403 cotire_append_undefs(_contents ${_compileUndefinitions})
1404 set (_compileUndefinitions "")
1406 if (_sourcePostUndefs)
1407 list (APPEND _compileUndefinitions ${_sourcePostUndefs})
1409 if (_option_POST_UNDEFS)
1410 list (APPEND _compileUndefinitions ${_option_POST_UNDEFS})
1412 foreach (_definition ${_compileDefinitions})
1413 if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$")
1414 list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}")
1415 list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}")
1417 list (APPEND _contents "#define ${_definition}")
1418 list (INSERT _compileUndefinitions 0 "${_definition}")
1421 # use absolute path as source file location
1422 get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE)
1424 file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation)
1426 list (APPEND _contents "#include \"${_sourceFileLocation}\"")
1428 if (_compileUndefinitions)
1429 cotire_append_undefs(_contents ${_compileUndefinitions})
1430 set (_compileUndefinitions "")
1432 if (_option_LANGUAGE AND _sourceFiles)
1433 list (APPEND _contents "#endif")
1435 if (_option_EPILOGUE)
1436 list (APPEND _contents ${_option_EPILOGUE})
1438 list (APPEND _contents "")
1439 string (REPLACE ";" "\n" _contents "${_contents}")
1441 message ("${_contents}")
1443 cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE)
1446 function (cotire_generate_prefix_header _prefixFile)
1448 set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION)
1449 set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS
1450 INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH
1451 IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER)
1452 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1453 if (NOT _option_COMPILER_ID)
1454 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1456 if (NOT _option_COMPILER_VERSION)
1457 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1459 if (_option_DEPENDS)
1460 cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS})
1461 if (_prefixFileIsUpToDate)
1462 # create empty log file
1463 set (_unparsedLinesFile "${_prefixFile}.log")
1464 file (WRITE "${_unparsedLinesFile}" "")
1470 if (_option_COMPILER_ID MATCHES "Clang")
1471 set (_prologue "#pragma clang system_header")
1472 elseif (_option_COMPILER_ID MATCHES "GNU")
1473 set (_prologue "#pragma GCC system_header")
1474 elseif (_option_COMPILER_ID MATCHES "MSVC")
1475 set (_prologue "#pragma warning(push, 0)")
1476 set (_epilogue "#pragma warning(pop)")
1477 elseif (_option_COMPILER_ID MATCHES "Intel")
1478 # Intel compiler requires hdrstop pragma to stop generating PCH file
1479 set (_epilogue "#pragma hdrstop")
1481 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1482 cotire_scan_includes(_selectedHeaders ${_sourceFiles}
1483 LANGUAGE "${_option_LANGUAGE}"
1484 COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}"
1485 COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}"
1486 COMPILER_ARG1 "${_option_COMPILER_ARG1}"
1487 COMPILER_ID "${_option_COMPILER_ID}"
1488 COMPILER_VERSION "${_option_COMPILER_VERSION}"
1489 COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS}
1490 COMPILE_FLAGS ${_option_COMPILE_FLAGS}
1491 INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES}
1492 SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES}
1493 IGNORE_PATH ${_option_IGNORE_PATH}
1494 INCLUDE_PATH ${_option_INCLUDE_PATH}
1495 IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS}
1496 INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH}
1497 UNPARSED_LINES _unparsedLines
1498 SCAN_RESULT _scanResult)
1499 cotire_generate_unity_source("${_prefixFile}"
1500 PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders})
1501 set (_unparsedLinesFile "${_prefixFile}.log")
1503 if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders)
1504 list (LENGTH _unparsedLines _skippedLineCount)
1506 file (TO_NATIVE_PATH "${_unparsedLinesFile}" _unparsedLinesLogPath)
1508 set (_unparsedLinesLogPath "${_unparsedLinesFile}")
1510 message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesLogPath}")
1512 string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}")
1514 file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n")
1517 function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
1518 set (_flags ${${_flagsVar}})
1519 if (_compilerID MATCHES "MSVC")
1520 # cl.exe options used
1521 # /nologo suppresses display of sign-on banner
1522 # /TC treat all files named on the command line as C source files
1523 # /TP treat all files named on the command line as C++ source files
1524 # /EP preprocess to stdout without #line directives
1525 # /showIncludes list include files
1526 set (_sourceFileTypeC "/TC")
1527 set (_sourceFileTypeCXX "/TP")
1530 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes)
1532 # return as a flag string
1533 set (_flags "${_sourceFileType${_language}} /EP /showIncludes")
1535 elseif (_compilerID MATCHES "GNU")
1537 # -H print the name of each header file used
1538 # -E invoke preprocessor
1539 # -fdirectives-only do not expand macros, requires GCC >= 4.3
1542 list (APPEND _flags -H -E)
1543 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1544 list (APPEND _flags -fdirectives-only)
1547 # return as a flag string
1548 set (_flags "-H -E")
1549 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1550 set (_flags "${_flags} -fdirectives-only")
1553 elseif (_compilerID MATCHES "Clang")
1555 # Clang options used
1556 # -H print the name of each header file used
1557 # -E invoke preprocessor
1558 # -fno-color-diagnostics do not print diagnostics in color
1559 # -Eonly just run preprocessor, no output
1562 list (APPEND _flags -H -E -fno-color-diagnostics -Xclang -Eonly)
1564 # return as a flag string
1565 set (_flags "-H -E -fno-color-diagnostics -Xclang -Eonly")
1568 # Clang-cl.exe options used
1569 # /TC treat all files named on the command line as C source files
1570 # /TP treat all files named on the command line as C++ source files
1571 # /EP preprocess to stdout without #line directives
1572 # -H print the name of each header file used
1573 # -fno-color-diagnostics do not print diagnostics in color
1574 # -Eonly just run preprocessor, no output
1575 set (_sourceFileTypeC "/TC")
1576 set (_sourceFileTypeCXX "/TP")
1579 list (APPEND _flags "${_sourceFileType${_language}}" /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly)
1581 # return as a flag string
1582 set (_flags "${_sourceFileType${_language}} /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly")
1585 elseif (_compilerID MATCHES "Intel")
1587 # Windows Intel options used
1588 # /nologo do not display compiler version information
1589 # /QH display the include file order
1590 # /EP preprocess to stdout, omitting #line directives
1591 # /TC process all source or unrecognized file types as C source files
1592 # /TP process all source or unrecognized file types as C++ source files
1593 set (_sourceFileTypeC "/TC")
1594 set (_sourceFileTypeCXX "/TP")
1597 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH)
1599 # return as a flag string
1600 set (_flags "${_sourceFileType${_language}} /EP /QH")
1603 # Linux / Mac OS X Intel options used
1604 # -H print the name of each header file used
1605 # -EP preprocess to stdout, omitting #line directives
1606 # -Kc++ process all source or unrecognized file types as C++ source files
1609 if ("${_language}" STREQUAL "CXX")
1610 list (APPEND _flags -Kc++)
1612 list (APPEND _flags -H -EP)
1614 # return as a flag string
1615 if ("${_language}" STREQUAL "CXX")
1616 set (_flags "-Kc++ ")
1618 set (_flags "${_flags}-H -EP")
1622 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1624 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1627 function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
1628 set (_flags ${${_flagsVar}})
1629 if (_compilerID MATCHES "MSVC")
1630 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1631 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1632 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1633 # cl.exe options used
1634 # /Yc creates a precompiled header file
1635 # /Fp specifies precompiled header binary file name
1636 # /FI forces inclusion of file
1637 # /TC treat all files named on the command line as C source files
1638 # /TP treat all files named on the command line as C++ source files
1639 # /Zs syntax check only
1640 # /Zm precompiled header memory allocation scaling factor
1641 set (_sourceFileTypeC "/TC")
1642 set (_sourceFileTypeCXX "/TP")
1645 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1646 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1647 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1648 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1651 # return as a flag string
1652 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1653 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1654 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1657 elseif (_compilerID MATCHES "GNU")
1659 # -x specify the source language
1660 # -c compile but do not link
1661 # -o place output in file
1662 # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may
1663 # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings)
1664 set (_xLanguage_C "c-header")
1665 set (_xLanguage_CXX "c++-header")
1668 list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}")
1670 # return as a flag string
1671 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1673 elseif (_compilerID MATCHES "Clang")
1675 # Clang options used
1676 # -x specify the source language
1677 # -c compile but do not link
1678 # -o place output in file
1679 # -fno-pch-timestamp disable inclusion of timestamp in precompiled headers (clang 4.0.0+)
1680 set (_xLanguage_C "c-header")
1681 set (_xLanguage_CXX "c++-header")
1684 list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}")
1685 if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0")
1686 list (APPEND _flags -Xclang -fno-pch-timestamp)
1689 # return as a flag string
1690 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1691 if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0")
1692 set (_flags "${_flags} -Xclang -fno-pch-timestamp")
1696 # Clang-cl.exe options used
1697 # /Yc creates a precompiled header file
1698 # /Fp specifies precompiled header binary file name
1699 # /FI forces inclusion of file
1700 # /Zs syntax check only
1701 # /TC treat all files named on the command line as C source files
1702 # /TP treat all files named on the command line as C++ source files
1703 set (_sourceFileTypeC "/TC")
1704 set (_sourceFileTypeCXX "/TP")
1707 list (APPEND _flags "${_sourceFileType${_language}}"
1708 "/Yc${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}" /Zs "${_hostFile}")
1710 # return as a flag string
1711 set (_flags "/Yc\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"")
1714 elseif (_compilerID MATCHES "Intel")
1716 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1717 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1718 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1719 # Windows Intel options used
1720 # /nologo do not display compiler version information
1721 # /Yc create a precompiled header (PCH) file
1722 # /Fp specify a path or file name for precompiled header files
1723 # /FI tells the preprocessor to include a specified file name as the header file
1724 # /TC process all source or unrecognized file types as C source files
1725 # /TP process all source or unrecognized file types as C++ source files
1726 # /Zs syntax check only
1727 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1728 set (_sourceFileTypeC "/TC")
1729 set (_sourceFileTypeCXX "/TP")
1732 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1733 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1734 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1735 list (APPEND _flags "/Wpch-messages")
1738 # return as a flag string
1739 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1740 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1741 set (_flags "${_flags} /Wpch-messages")
1745 # Linux / Mac OS X Intel options used
1746 # -pch-dir location for precompiled header files
1747 # -pch-create name of the precompiled header (PCH) to create
1748 # -Kc++ process all source or unrecognized file types as C++ source files
1749 # -fsyntax-only check only for correct syntax
1750 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1751 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1752 get_filename_component(_pchName "${_pchFile}" NAME)
1753 set (_xLanguage_C "c-header")
1754 set (_xLanguage_CXX "c++-header")
1755 set (_pchSuppressMessages FALSE)
1756 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1757 set(_pchSuppressMessages TRUE)
1761 if ("${_language}" STREQUAL "CXX")
1762 list (APPEND _flags -Kc++)
1764 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}")
1765 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1766 if (NOT _pchSuppressMessages)
1767 list (APPEND _flags -Wpch-messages)
1771 # return as a flag string
1772 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1773 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1774 if (NOT _pchSuppressMessages)
1775 set (_flags "${_flags} -Wpch-messages")
1781 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1783 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1786 function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1787 set (_flags ${${_flagsVar}})
1788 if (_compilerID MATCHES "MSVC")
1789 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1790 # cl.exe options used
1791 # /Yu uses a precompiled header file during build
1792 # /Fp specifies precompiled header binary file name
1793 # /FI forces inclusion of file
1794 # /Zm precompiled header memory allocation scaling factor
1796 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1799 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1800 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1801 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1804 # return as a flag string
1805 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1806 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1807 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1811 # no precompiled header, force inclusion of prefix header
1814 list (APPEND _flags "/FI${_prefixFileNative}")
1816 # return as a flag string
1817 set (_flags "/FI\"${_prefixFileNative}\"")
1820 elseif (_compilerID MATCHES "GNU")
1822 # -include process include file as the first line of the primary source file
1823 # -Winvalid-pch warns if precompiled header is found but cannot be used
1824 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1827 list (APPEND _flags -Winvalid-pch -include "${_prefixFile}")
1829 # return as a flag string
1830 set (_flags "-Winvalid-pch -include \"${_prefixFile}\"")
1832 elseif (_compilerID MATCHES "Clang")
1834 # Clang options used
1835 # -include process include file as the first line of the primary source file
1836 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1839 list (APPEND _flags -include "${_prefixFile}")
1841 # return as a flag string
1842 set (_flags "-include \"${_prefixFile}\"")
1845 # Clang-cl.exe options used
1846 # /Yu uses a precompiled header file during build
1847 # /Fp specifies precompiled header binary file name
1848 # /FI forces inclusion of file
1852 list (APPEND _flags "/Yu${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}")
1854 # return as a flag string
1855 set (_flags "/Yu\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"")
1858 # no precompiled header, force inclusion of prefix header
1861 list (APPEND _flags "/FI${_prefixFile}")
1863 # return as a flag string
1864 set (_flags "/FI\"${_prefixFile}\"")
1868 elseif (_compilerID MATCHES "Intel")
1870 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1871 # Windows Intel options used
1872 # /Yu use a precompiled header (PCH) file
1873 # /Fp specify a path or file name for precompiled header files
1874 # /FI tells the preprocessor to include a specified file name as the header file
1875 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1877 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1880 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1881 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1882 list (APPEND _flags "/Wpch-messages")
1885 # return as a flag string
1886 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1887 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1888 set (_flags "${_flags} /Wpch-messages")
1892 # no precompiled header, force inclusion of prefix header
1895 list (APPEND _flags "/FI${_prefixFileNative}")
1897 # return as a flag string
1898 set (_flags "/FI\"${_prefixFileNative}\"")
1902 # Linux / Mac OS X Intel options used
1903 # -pch-dir location for precompiled header files
1904 # -pch-use name of the precompiled header (PCH) to use
1905 # -include process include file as the first line of the primary source file
1906 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1908 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1909 get_filename_component(_pchName "${_pchFile}" NAME)
1910 set (_pchSuppressMessages FALSE)
1911 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1912 set(_pchSuppressMessages TRUE)
1916 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}")
1917 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1918 if (NOT _pchSuppressMessages)
1919 list (APPEND _flags -Wpch-messages)
1923 # return as a flag string
1924 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1925 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1926 if (NOT _pchSuppressMessages)
1927 set (_flags "${_flags} -Wpch-messages")
1932 # no precompiled header, force inclusion of prefix header
1935 list (APPEND _flags -include "${_prefixFile}")
1937 # return as a flag string
1938 set (_flags "-include \"${_prefixFile}\"")
1943 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1945 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1948 function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1950 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE)
1951 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER)
1952 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1953 if (NOT _option_LANGUAGE)
1954 set (_option_LANGUAGE "CXX")
1956 if (NOT _option_COMPILER_ID)
1957 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1959 if (NOT _option_COMPILER_VERSION)
1960 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1962 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1963 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1964 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1965 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1966 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1967 cotire_add_pch_compilation_flags(
1968 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1969 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1971 message (STATUS "execute_process: ${_cmd}")
1973 if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC")
1974 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1975 unset (ENV{VS_UNICODE_OUTPUT})
1976 elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0")
1977 if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR
1978 _option_COMPILER_EXECUTABLE MATCHES "ccache")
1979 # Newer versions of Clang embed a compilation timestamp into the precompiled header binary,
1980 # which results in "file has been modified since the precompiled header was built" errors if ccache is used.
1981 # We work around the problem by disabling ccache upon pre-compiling the prefix header.
1982 set (ENV{CCACHE_DISABLE} "true")
1987 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1988 RESULT_VARIABLE _result)
1990 message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.")
1994 function (cotire_check_precompiled_header_support _language _target _msgVar)
1995 set (_unsupportedCompiler
1996 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
1997 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1998 # PCH supported since Visual Studio C++ 6.0
1999 # and CMake does not support an earlier version
2000 set (${_msgVar} "" PARENT_SCOPE)
2001 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2002 # GCC PCH support requires version >= 3.4
2003 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
2004 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2006 set (${_msgVar} "" PARENT_SCOPE)
2008 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2010 # all Unix Clang versions have PCH support
2011 set (${_msgVar} "" PARENT_SCOPE)
2013 # only clang-cl is supported under Windows
2014 get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE)
2015 if (NOT _compilerName MATCHES "cl$")
2016 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE)
2019 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2020 # Intel PCH support requires version >= 8.0.0
2021 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
2022 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2024 set (${_msgVar} "" PARENT_SCOPE)
2027 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
2029 # check if ccache is used as a compiler launcher
2030 get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER)
2031 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH)
2032 if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache")
2033 # verify that ccache configuration is compatible with precompiled headers
2034 # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache
2035 # do not report the "sloppiness" setting correctly upon printing ccache configuration
2036 if (DEFINED ENV{CCACHE_SLOPPINESS})
2037 if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR
2038 NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros")
2040 "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"."
2044 if (_realCompilerExe MATCHES "ccache")
2045 set (_ccacheExe "${_realCompilerExe}")
2047 set (_ccacheExe "${_launcher}")
2050 COMMAND "${_ccacheExe}" "--print-config"
2051 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
2052 RESULT_VARIABLE _result
2053 OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE
2056 set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE)
2057 elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR
2058 NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines")
2060 "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"."
2066 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
2067 cotire_get_configuration_types(_configs)
2068 foreach (_config ${_configs})
2069 set (_targetFlags "")
2070 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
2071 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
2072 list (LENGTH _architectures _numberOfArchitectures)
2073 if (_numberOfArchitectures GREATER 1)
2074 string (REPLACE ";" ", " _architectureStr "${_architectures}")
2076 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
2084 macro (cotire_get_intermediate_dir _cotireDir)
2085 # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types
2086 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
2089 macro (cotire_setup_file_extension_variables)
2090 set (_unityFileExt_C ".c")
2091 set (_unityFileExt_CXX ".cxx")
2092 set (_prefixFileExt_C ".h")
2093 set (_prefixFileExt_CXX ".hxx")
2094 set (_prefixSourceFileExt_C ".c")
2095 set (_prefixSourceFileExt_CXX ".cxx")
2098 function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
2099 cotire_setup_file_extension_variables()
2100 if (NOT DEFINED _unityFileExt_${_language})
2101 set (${_unityFileVar} "" PARENT_SCOPE)
2104 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2105 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
2106 cotire_get_intermediate_dir(_baseDir)
2107 set (_unityFile "${_baseDir}/${_unityFileName}")
2108 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
2111 function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
2112 cotire_setup_file_extension_variables()
2113 if (NOT DEFINED _unityFileExt_${_language})
2114 set (${_unityFileVar} "" PARENT_SCOPE)
2117 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2118 cotire_get_intermediate_dir(_baseDir)
2121 set (_unityFiles "")
2122 set (_sourceFiles ${ARGN})
2123 foreach (_sourceFile ${_sourceFiles})
2124 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
2125 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
2126 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
2127 if (_index GREATER 0)
2128 # start new unity file segment
2129 math (EXPR _endIndex "${_index} - 1")
2130 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2131 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2133 set (_startIndex ${_index})
2135 math (EXPR _index "${_index} + 1")
2137 list (LENGTH _sourceFiles _numberOfSources)
2138 if (_startIndex EQUAL 0)
2139 # there is only a single unity file
2140 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
2141 elseif (_startIndex LESS _numberOfSources)
2142 # end with final unity file segment
2143 math (EXPR _endIndex "${_index} - 1")
2144 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2145 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2147 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
2148 if (COTIRE_DEBUG AND _unityFiles)
2149 message (STATUS "unity files: ${_unityFiles}")
2153 function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
2154 cotire_setup_file_extension_variables()
2155 if (NOT DEFINED _unityFileExt_${_language})
2156 set (${_prefixFileVar} "" PARENT_SCOPE)
2159 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2160 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2161 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
2162 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
2163 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
2166 function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar)
2167 cotire_setup_file_extension_variables()
2168 if (NOT DEFINED _prefixSourceFileExt_${_language})
2169 set (${_prefixSourceFileVar} "" PARENT_SCOPE)
2172 string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}")
2173 set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE)
2176 function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
2177 cotire_setup_file_extension_variables()
2179 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2180 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
2181 elseif (DEFINED _prefixFileExt_${_language})
2182 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2183 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
2185 set (_prefixFileBaseName "")
2186 set (_prefixFileName "")
2188 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
2189 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
2192 function (cotire_make_prefix_file_path _language _target _prefixFileVar)
2193 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2194 set (${_prefixFileVar} "" PARENT_SCOPE)
2195 if (_prefixFileName)
2199 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC")
2200 cotire_get_intermediate_dir(_baseDir)
2201 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
2206 function (cotire_make_pch_file_path _language _target _pchFileVar)
2207 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2208 set (${_pchFileVar} "" PARENT_SCOPE)
2209 if (_prefixFileBaseName AND _prefixFileName)
2210 cotire_check_precompiled_header_support("${_language}" "${_target}" _msg)
2213 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
2216 cotire_get_intermediate_dir(_baseDir)
2217 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2218 # MSVC uses the extension .pch added to the prefix header base name
2219 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
2220 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2221 # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended
2222 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE)
2223 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2224 # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended
2225 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
2226 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2227 # Intel uses the extension .pchi added to the prefix header base name
2228 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
2234 function (cotire_select_unity_source_files _unityFile _sourcesVar)
2235 set (_sourceFiles ${ARGN})
2236 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
2237 set (_startIndex ${CMAKE_MATCH_1})
2238 set (_endIndex ${CMAKE_MATCH_2})
2239 list (LENGTH _sourceFiles _numberOfSources)
2240 if (NOT _startIndex LESS _numberOfSources)
2241 math (EXPR _startIndex "${_numberOfSources} - 1")
2243 if (NOT _endIndex LESS _numberOfSources)
2244 math (EXPR _endIndex "${_numberOfSources} - 1")
2247 foreach (_index RANGE ${_startIndex} ${_endIndex})
2248 list (GET _sourceFiles ${_index} _file)
2249 list (APPEND _files "${_file}")
2252 set (_files ${_sourceFiles})
2254 set (${_sourcesVar} ${_files} PARENT_SCOPE)
2257 function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
2258 set (_dependencySources "")
2259 # depend on target's generated source files
2260 get_target_property(_targetSourceFiles ${_target} SOURCES)
2261 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2262 if (_generatedSources)
2263 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
2264 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
2265 if (_excludedGeneratedSources)
2266 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
2268 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
2269 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
2270 if (_excludedNonDependencySources)
2271 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
2273 if (_generatedSources)
2274 list (APPEND _dependencySources ${_generatedSources})
2277 if (COTIRE_DEBUG AND _dependencySources)
2278 message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}")
2280 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2283 function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
2284 set (_dependencySources "")
2285 # depend on target source files marked with custom COTIRE_DEPENDENCY property
2286 get_target_property(_targetSourceFiles ${_target} SOURCES)
2287 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles})
2288 if (COTIRE_DEBUG AND _dependencySources)
2289 message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}")
2291 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2294 function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar)
2295 set (_targetSources ${ARGN})
2296 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources})
2297 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources})
2298 # set up variables to be configured
2299 set (COTIRE_TARGET_LANGUAGE "${_language}")
2300 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
2301 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
2302 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
2303 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
2304 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
2305 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
2306 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2307 get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH)
2308 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources})
2309 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources})
2310 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
2311 foreach (_config ${_configurations})
2312 string (TOUPPER "${_config}" _upperConfig)
2313 cotire_get_target_include_directories(
2314 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig})
2315 cotire_get_target_compile_definitions(
2316 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
2317 cotire_get_target_compiler_flags(
2318 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
2319 cotire_get_source_files_compile_definitions(
2320 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources})
2322 get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER)
2323 # set up COTIRE_TARGET_SOURCES
2324 set (COTIRE_TARGET_SOURCES "")
2325 foreach (_sourceFile ${_targetSources})
2326 get_source_file_property(_generated "${_sourceFile}" GENERATED)
2328 # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation
2329 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2330 list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}")
2332 list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}")
2335 # copy variable definitions to cotire target script
2336 get_cmake_property(_vars VARIABLES)
2337 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
2338 # omit COTIRE_*_INIT variables
2339 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}")
2341 list (REMOVE_ITEM _matchVars ${_initVars})
2343 # omit COTIRE_VERBOSE which is passed as a CMake define on command line
2344 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
2346 set (_contentsHasGeneratorExpressions FALSE)
2347 foreach (_var IN LISTS _matchVars ITEMS
2348 XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
2349 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION
2350 CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
2351 CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language}
2352 CMAKE_INCLUDE_SYSTEM_FLAG_${_language}
2353 CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG
2354 CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG
2355 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
2356 if (DEFINED ${_var})
2357 string (REPLACE "\"" "\\\"" _value "${${_var}}")
2358 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
2359 if (NOT _contentsHasGeneratorExpressions)
2360 if ("${_value}" MATCHES "\\$<.*>")
2361 set (_contentsHasGeneratorExpressions TRUE)
2366 # generate target script file
2367 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
2368 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
2369 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
2370 if (_contentsHasGeneratorExpressions)
2371 # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time
2372 set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>")
2373 set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}")
2374 file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}")
2376 set (_targetCotireConfigScript "${_targetCotireScript}")
2378 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
2379 set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE)
2382 function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile)
2383 set (_sourceFiles ${ARGN})
2384 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2385 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2386 # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file
2387 # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion
2390 cotire_add_pch_compilation_flags(
2391 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2392 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
2393 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2394 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
2395 # make object file generated from host file depend on prefix header
2396 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2397 # mark host file as cotired to prevent it from being used in another cotired target
2398 set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}")
2400 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2401 # for makefile based generator, we add a custom command to precompile the prefix header
2403 cotire_set_cmd_to_prologue(_cmds)
2404 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
2406 file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath)
2408 file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
2410 # make precompiled header compilation depend on the actual compiler executable used to force
2411 # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable"
2412 # warnings when the precompiled header is included.
2413 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2415 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
2417 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
2419 OUTPUT "${_pchFile}"
2421 DEPENDS "${_prefixFile}" "${_realCompilerExe}"
2422 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
2423 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2424 COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}"
2430 function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile)
2431 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2432 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2433 # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file
2434 # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation
2435 set (_sourceFiles ${ARGN})
2436 list (LENGTH _sourceFiles _numberOfSourceFiles)
2437 if (_numberOfSourceFiles GREATER 0)
2438 # mark sources as cotired to prevent them from being used in another cotired target
2439 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2441 cotire_add_prefix_pch_inclusion_flags(
2442 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2443 "${_prefixFile}" "${_pchFile}" _flags)
2444 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2445 # make object files generated from source files depend on precompiled header
2446 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2448 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2449 set (_sourceFiles ${_hostFile} ${ARGN})
2450 if (NOT _wholeTarget)
2451 # for makefile based generator, we force the inclusion of the prefix header for a subset
2452 # of the source files, if this is a multi-language target or has excluded files
2454 cotire_add_prefix_pch_inclusion_flags(
2455 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2456 "${_prefixFile}" "${_pchFile}" _flags)
2457 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2458 # mark sources as cotired to prevent them from being used in another cotired target
2459 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2461 # make object files generated from source files depend on precompiled header
2462 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2466 function (cotire_setup_prefix_file_inclusion _language _target _prefixFile)
2467 set (_sourceFiles ${ARGN})
2468 # force the inclusion of the prefix header for the given source files
2471 cotire_add_prefix_pch_inclusion_flags(
2472 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2473 "${_prefixFile}" "${_pchFile}" _flags)
2474 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2475 # mark sources as cotired to prevent them from being used in another cotired target
2476 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2477 # make object files generated from source files depend on prefix header
2478 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2481 function (cotire_get_first_set_property_value _propertyValueVar _type _object)
2482 set (_properties ${ARGN})
2483 foreach (_property ${_properties})
2484 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
2486 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
2490 set (${_propertyValueVar} "" PARENT_SCOPE)
2493 function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar)
2494 set (_files ${ARGN})
2495 set (_filesPaths "")
2496 foreach (_file ${_files})
2497 get_filename_component(_filePath "${_file}" ABSOLUTE)
2498 list (APPEND _filesPaths "${_filePath}")
2500 cotire_set_cmd_to_prologue(_prefixCmd)
2501 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
2503 list (APPEND _prefixCmd "${_targetScript}")
2505 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
2507 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
2509 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
2511 file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath)
2513 file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
2515 get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE)
2516 get_filename_component(_joinedFileExt "${_joinedFile}" EXT)
2517 if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
2518 set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}")
2519 elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$")
2520 if (_joinedFileExt MATCHES "^\\.c")
2521 set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}")
2523 set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}")
2526 set (_comment "Generating ${_joinedFileLogPath}")
2529 OUTPUT "${_joinedFile}"
2530 COMMAND ${_prefixCmd}
2532 COMMENT "${_comment}"
2533 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2535 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2536 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2539 function (cotire_setup_target_pch_usage _languages _target _wholeTarget)
2541 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
2542 set (_prefixFiles "")
2543 foreach (_language ${_languages})
2544 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2546 list (APPEND _prefixFiles "${_prefixFile}")
2550 list (LENGTH _prefixFiles _numberOfPrefixFiles)
2551 if (_numberOfPrefixFiles GREATER 1)
2552 # we also generate a generic, single prefix header which includes all language specific prefix headers
2554 set (_targetScript "")
2555 cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader)
2556 cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles})
2558 set (_prefixHeader "${_prefixFiles}")
2561 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
2563 # because CMake PRE_BUILD command does not support dependencies,
2564 # we check dependencies explicity in cotire script mode when the pre-build action is run
2568 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2569 COMMENT "Updating target ${_target} prefix headers"
2571 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
2572 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
2573 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
2574 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2575 # for makefile based generator, we force inclusion of the prefix header for all target source files
2576 # if this is a single-language target without any excluded files
2578 set (_language "${_languages}")
2579 # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level
2580 # see cotire_setup_pch_file_inclusion
2581 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
2582 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2583 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2585 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
2586 set (_options COMPILE_OPTIONS)
2587 cotire_add_prefix_pch_inclusion_flags(
2588 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2589 "${_prefixFile}" "${_pchFile}" _options)
2590 set_property(TARGET ${_target} APPEND PROPERTY ${_options})
2597 function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar)
2598 set (_dependencySources "")
2599 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
2600 foreach (_unityFile ${_unityFiles})
2601 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
2602 # set up compiled unity source dependencies via OBJECT_DEPENDS
2603 # this ensures that missing source files are generated before the unity file is compiled
2604 if (COTIRE_DEBUG AND _dependencySources)
2605 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
2607 if (_dependencySources)
2608 # the OBJECT_DEPENDS property requires a list of full paths
2609 set (_objectDependsPaths "")
2610 foreach (_sourceFile ${_dependencySources})
2611 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2612 list (APPEND _objectDependsPaths "${_sourceLocation}")
2614 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths})
2616 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2617 # unity file compilation results in potentially huge object file,
2618 # thus use /bigobj by default unter cl.exe and Windows Intel
2619 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
2621 cotire_set_cmd_to_prologue(_unityCmd)
2622 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}")
2623 if (CMAKE_VERSION VERSION_LESS "3.1.0")
2624 set (_unityCmdDepends "${_targetScript}")
2626 # CMake 3.1.0 supports generator expressions in arguments to DEPENDS
2627 set (_unityCmdDepends "${_targetConfigScript}")
2630 file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath)
2632 file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
2635 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}")
2638 OUTPUT "${_unityFile}"
2639 COMMAND ${_unityCmd}
2640 DEPENDS ${_unityCmdDepends}
2641 COMMENT "Generating ${_language} unity source ${_unityFileLogPath}"
2642 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2644 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
2646 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2649 function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2650 set (_sourceFiles ${ARGN})
2651 set (_dependencySources "")
2652 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
2653 cotire_set_cmd_to_prologue(_prefixCmd)
2654 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles})
2655 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
2656 # make prefix header generation depend on the actual compiler executable used to force
2657 # re-generation when the compiler executable is updated. This prevents "file not found"
2658 # errors for compiler version specific system header files.
2659 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2661 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}")
2664 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath)
2666 file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
2668 get_filename_component(_prefixFileExt "${_prefixFile}" EXT)
2669 if (_prefixFileExt MATCHES "^\\.c")
2670 set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}")
2672 set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}")
2674 # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist
2675 # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence
2676 # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files
2677 set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre")
2678 if (TARGET ${_preTargetName})
2679 # custom helper target has already been generated while processing a different language
2680 list (APPEND _dependencySources ${_preTargetName})
2682 get_target_property(_targetSourceFiles ${_target} SOURCES)
2683 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2684 if (_generatedSources)
2685 add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources})
2686 cotire_init_target("${_preTargetName}")
2687 list (APPEND _dependencySources ${_preTargetName})
2691 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
2692 COMMAND ${_prefixCmd}
2693 DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}"
2694 COMMENT "${_comment}"
2695 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2697 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2698 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2701 function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2702 set (_sourceFiles ${ARGN})
2703 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2704 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2705 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2707 set (_prefixSourceFile "${_prefixFile}")
2709 cotire_setup_prefix_generation_command(
2710 ${_language} ${_target} "${_targetScript}"
2711 "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2712 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2713 # set up generation of a prefix source file which includes the prefix header
2714 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2716 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2719 function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar)
2720 set (_prefixHeaderFiles ${ARGN})
2721 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2722 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2723 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2725 set (_prefixSourceFile "${_prefixFile}")
2727 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles})
2728 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2729 # set up generation of a prefix source file which includes the prefix header
2730 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2732 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2735 function (cotire_init_cotire_target_properties _target)
2736 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2738 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2740 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2742 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2744 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2746 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2748 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2750 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2751 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2752 if (NOT _isRelative)
2753 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2756 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2758 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2760 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET)
2762 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "")
2764 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2766 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2768 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2770 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2772 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET)
2774 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY")
2776 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2778 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2779 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2781 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2786 function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2787 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2788 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2789 string (REPLACE ";" " " _languagesStr "${_languages}")
2790 math (EXPR _numberOfExcludedFiles "${ARGC} - 4")
2791 if (_numberOfExcludedFiles EQUAL 0)
2792 set (_excludedStr "")
2793 elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4)
2794 string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}")
2796 set (_excludedStr "excluding ${_numberOfExcludedFiles} files")
2800 set (_targetMsg "Target ${_target} cannot be cotired.")
2802 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2804 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2805 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2807 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2809 elseif (NOT _targetUsePCH)
2811 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.")
2813 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2816 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2818 elseif (NOT _targetAddSCU)
2820 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.")
2822 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2825 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2829 set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.")
2831 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2834 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2837 function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar)
2838 set (_languages ${ARGN})
2839 set (_allSourceFiles "")
2840 set (_allExcludedSourceFiles "")
2841 set (_allCotiredSourceFiles "")
2842 set (_targetLanguages "")
2843 set (_pchEligibleTargetLanguages "")
2844 get_target_property(_targetType ${_target} TYPE)
2845 get_target_property(_targetSourceFiles ${_target} SOURCES)
2846 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2847 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2848 set (_disableMsg "")
2849 foreach (_language ${_languages})
2850 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2851 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2852 if (_prefixHeader OR _unityBuildFile)
2853 message (STATUS "cotire: target ${_target} has already been cotired.")
2854 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2857 if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID)
2858 if (CMAKE_${_language}_COMPILER_ID)
2859 cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg)
2861 set (_targetUsePCH FALSE)
2865 set (_sourceFiles "")
2866 set (_excludedSources "")
2867 set (_cotiredSources "")
2868 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2869 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2870 list (APPEND _targetLanguages ${_language})
2873 list (APPEND _allSourceFiles ${_sourceFiles})
2875 list (LENGTH _sourceFiles _numberOfSources)
2876 if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2877 list (APPEND _pchEligibleTargetLanguages ${_language})
2879 if (_excludedSources)
2880 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2882 if (_cotiredSources)
2883 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2886 set (_targetMsgLevel STATUS)
2887 if (NOT _targetLanguages)
2888 string (REPLACE ";" " or " _languagesStr "${_languages}")
2889 set (_disableMsg "No ${_languagesStr} source files.")
2890 set (_targetUsePCH FALSE)
2891 set (_targetAddSCU FALSE)
2894 if (_allCotiredSourceFiles)
2895 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2896 list (REMOVE_DUPLICATES _cotireTargets)
2897 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2898 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2899 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2900 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2901 set (_targetMsgLevel SEND_ERROR)
2902 set (_targetUsePCH FALSE)
2903 elseif (NOT _pchEligibleTargetLanguages)
2904 set (_disableMsg "Too few applicable sources.")
2905 set (_targetUsePCH FALSE)
2906 elseif (XCODE AND _allExcludedSourceFiles)
2907 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2908 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2909 set (_targetUsePCH FALSE)
2910 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2911 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2912 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2913 set (_targetUsePCH FALSE)
2917 # disable unity builds if automatic Qt processing is used
2918 get_target_property(_targetAutoMoc ${_target} AUTOMOC)
2919 get_target_property(_targetAutoUic ${_target} AUTOUIC)
2920 get_target_property(_targetAutoRcc ${_target} AUTORCC)
2921 if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc)
2923 set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.")
2925 set (_disableMsg "Target uses automatic CMake Qt processing.")
2927 set (_targetAddSCU FALSE)
2930 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2931 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2932 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2934 if (NOT DEFINED COTIREMSG_${_target})
2935 set (COTIREMSG_${_target} "")
2937 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2938 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2939 # cache message to avoid redundant messages on re-configure
2940 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2941 message (${_targetMsgLevel} "${_targetMsg}")
2944 list (LENGTH _targetLanguages _numberOfLanguages)
2945 if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles)
2946 set (${_wholeTargetVar} FALSE PARENT_SCOPE)
2948 set (${_wholeTargetVar} TRUE PARENT_SCOPE)
2950 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2953 function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2954 set (_sourceFiles ${ARGN})
2955 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2956 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2957 if (DEFINED CMAKE_MATCH_2)
2958 set (_numberOfThreads "${CMAKE_MATCH_2}")
2960 set (_numberOfThreads "")
2962 if (NOT _numberOfThreads)
2963 # use all available cores
2964 ProcessorCount(_numberOfThreads)
2966 list (LENGTH _sourceFiles _numberOfSources)
2967 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2968 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2969 set (_maxIncludes 0)
2972 message (STATUS "${_target} unity source max includes: ${_maxIncludes}")
2974 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2977 function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar)
2978 set (${_cmdsVar} "" PARENT_SCOPE)
2979 get_target_property(_targetSourceFiles ${_target} SOURCES)
2980 set (_sourceFiles "")
2981 set (_excludedSources "")
2982 set (_cotiredSources "")
2983 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2984 if (NOT _sourceFiles AND NOT _cotiredSources)
2988 # check for user provided unity source file list
2989 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
2990 if (NOT _unitySourceFiles)
2991 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
2993 cotire_generate_target_script(
2994 ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles})
2995 # set up unity files for parallel compilation
2996 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
2997 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
2998 list (LENGTH _unityFiles _numberOfUnityFiles)
2999 if (_numberOfUnityFiles EQUAL 0)
3001 elseif (_numberOfUnityFiles GREATER 1)
3002 cotire_setup_unity_generation_commands(
3003 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
3005 # set up single unity file for prefix header generation
3006 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
3007 cotire_setup_unity_generation_commands(
3008 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles})
3009 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
3010 # set up prefix header
3012 # check for user provided prefix header files
3013 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3014 if (_prefixHeaderFiles)
3015 cotire_setup_prefix_generation_from_provided_command(
3016 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
3018 cotire_setup_prefix_generation_from_unity_command(
3019 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles})
3021 # check if selected language has enough sources at all
3022 list (LENGTH _sourceFiles _numberOfSources)
3023 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
3024 set (_targetUsePCH FALSE)
3026 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3029 cotire_make_pch_file_path(${_language} ${_target} _pchFile)
3031 # first file in _sourceFiles is passed as the host file
3032 cotire_setup_pch_file_compilation(
3033 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3034 cotire_setup_pch_file_inclusion(
3035 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3037 elseif (_prefixHeaderFiles)
3038 # user provided prefix header must be included unconditionally
3039 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles})
3042 # mark target as cotired for language
3043 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
3045 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
3046 if (_targetUsePCH AND _pchFile)
3047 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
3050 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
3053 function (cotire_setup_clean_target _target)
3054 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
3055 if (NOT TARGET "${_cleanTargetName}")
3056 cotire_set_cmd_to_prologue(_cmds)
3057 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
3058 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
3059 add_custom_target(${_cleanTargetName}
3061 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3062 COMMENT "Cleaning up target ${_target} cotire generated files"
3064 cotire_init_target("${_cleanTargetName}")
3068 function (cotire_setup_pch_target _languages _configurations _target)
3069 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
3070 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
3071 set (_dependsFiles "")
3072 foreach (_language ${_languages})
3073 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
3074 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
3075 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
3076 # MSVC, Intel and clang-cl only create precompiled header as a side effect
3077 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
3079 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
3081 list (APPEND _dependsFiles "${_dependsFile}")
3085 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
3086 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
3087 cotire_init_target("${_pchTargetName}")
3088 cotire_add_to_pch_all_target(${_pchTargetName})
3091 # for other generators, we add the "clean all" target to clean up the precompiled header
3092 cotire_setup_clean_all_target()
3096 function (cotire_filter_object_libraries _target _objectLibrariesVar)
3097 set (_objectLibraries "")
3098 foreach (_source ${ARGN})
3099 if (_source MATCHES "^\\$<TARGET_OBJECTS:.+>$")
3100 list (APPEND _objectLibraries "${_source}")
3103 set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE)
3106 function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar)
3107 get_target_property(_targetSourceFiles ${_target} SOURCES)
3108 set (_unityTargetSources ${_targetSourceFiles})
3109 foreach (_language ${_languages})
3110 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3112 # remove source files that are included in the unity source
3113 set (_sourceFiles "")
3114 set (_excludedSources "")
3115 set (_cotiredSources "")
3116 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
3117 if (_sourceFiles OR _cotiredSources)
3118 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
3120 # add unity source files instead
3121 list (APPEND _unityTargetSources ${_unityFiles})
3124 # handle object libraries which are part of the target's sources
3125 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3126 if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$")
3127 cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles})
3128 if (_objectLibraries)
3129 cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries})
3130 list (REMOVE_ITEM _unityTargetSources ${_objectLibraries})
3131 list (APPEND _unityTargetSources ${_unityObjectLibraries})
3134 set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE)
3137 function (cotire_setup_unity_target_pch_usage _languages _target)
3138 foreach (_language ${_languages})
3139 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3141 get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3142 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
3143 if (_userPrefixFile AND _prefixFile)
3144 # user provided prefix header must be included unconditionally by unity sources
3145 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles})
3151 function (cotire_setup_unity_build_target _languages _configurations _target)
3152 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3153 if (NOT _unityTargetName)
3154 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
3156 # determine unity target sub type
3157 get_target_property(_targetType ${_target} TYPE)
3158 if ("${_targetType}" STREQUAL "EXECUTABLE")
3159 set (_unityTargetSubType "")
3160 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
3161 set (_unityTargetSubType "${CMAKE_MATCH_1}")
3163 message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.")
3166 # determine unity target sources
3167 set (_unityTargetSources "")
3168 cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources)
3169 # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created
3170 set (CMAKE_AUTOMOC OFF)
3171 set (CMAKE_AUTOUIC OFF)
3172 set (CMAKE_AUTORCC OFF)
3174 message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
3176 # generate unity target
3177 if ("${_targetType}" STREQUAL "EXECUTABLE")
3178 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3180 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3182 # copy output location properties
3183 set (_outputDirProperties
3184 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
3185 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
3186 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
3187 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
3188 set (_setDefaultOutputDir TRUE)
3189 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3190 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3192 # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory
3193 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
3194 cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties})
3195 foreach (_property ${_properties})
3196 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
3198 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3199 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
3200 set (_setDefaultOutputDir FALSE)
3203 if (_setDefaultOutputDir)
3204 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3207 if (_setDefaultOutputDir)
3208 set_target_properties(${_unityTargetName} PROPERTIES
3209 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
3210 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
3211 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
3214 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3215 ${_outputDirProperties})
3218 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3219 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
3220 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
3221 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
3222 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
3223 PREFIX <CONFIG>_POSTFIX SUFFIX
3224 IMPORT_PREFIX IMPORT_SUFFIX)
3225 # copy compile stuff
3226 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3227 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
3228 COMPILE_FLAGS COMPILE_OPTIONS
3229 Fortran_FORMAT Fortran_MODULE_DIRECTORY
3231 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
3232 POSITION_INDEPENDENT_CODE
3233 C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER
3234 C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE
3235 C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN
3236 C_CLANG_TIDY CXX_CLANG_TIDY)
3237 # copy compile features
3238 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3239 C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED
3240 CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED
3242 # copy interface stuff
3243 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3244 COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN
3245 COMPATIBLE_INTERFACE_STRING
3246 INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS
3247 INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES
3248 INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
3249 INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED)
3251 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3252 BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR
3253 INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
3254 LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED
3255 LINK_FLAGS LINK_FLAGS_<CONFIG>
3256 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
3257 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
3258 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
3259 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
3260 NO_SONAME SOVERSION VERSION
3261 LINK_WHAT_YOU_USE BUILD_RPATH)
3263 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3264 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
3265 # copy Apple platform specific stuff
3266 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3267 BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR
3268 MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH
3269 OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST
3270 IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE)
3271 # copy Windows platform specific stuff
3272 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3274 COMPILE_PDB_NAME COMPILE_PDB_NAME_<CONFIG>
3275 COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
3276 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
3277 VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION
3278 VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE
3279 VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK
3280 VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION
3281 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
3282 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
3283 VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES
3284 WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS
3285 DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE
3286 VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY)
3287 # copy Android platform specific stuff
3288 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3289 ANDROID_API ANDROID_API_MIN ANDROID_GUI
3290 ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES
3291 ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR
3292 ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES
3293 ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH
3294 ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE)
3295 # copy CUDA platform specific stuff
3296 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3297 CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS
3298 CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED)
3299 # use output name from original target
3300 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
3301 if (NOT _targetOutputName)
3302 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
3304 # use export symbol from original target
3305 cotire_get_target_export_symbol("${_target}" _defineSymbol)
3307 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
3308 if ("${_targetType}" STREQUAL "EXECUTABLE")
3309 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
3312 # enable parallel compilation for MSVC
3313 if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
3314 list (LENGTH _unityTargetSources _numberOfUnityTargetSources)
3315 if (_numberOfUnityTargetSources GREATER 1)
3316 set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP")
3319 cotire_init_target(${_unityTargetName})
3320 cotire_add_to_unity_all_target(${_unityTargetName})
3321 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
3322 endfunction(cotire_setup_unity_build_target)
3324 function (cotire_target _target)
3326 set(_oneValueArgs "")
3327 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3328 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3329 if (NOT _option_LANGUAGES)
3330 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
3332 if (NOT _option_CONFIGURATIONS)
3333 cotire_get_configuration_types(_option_CONFIGURATIONS)
3335 # check if cotire can be applied to target at all
3336 cotire_is_target_supported(${_target} _isSupported)
3337 if (NOT _isSupported)
3338 get_target_property(_imported ${_target} IMPORTED)
3339 get_target_property(_targetType ${_target} TYPE)
3341 message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.")
3343 message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.")
3348 get_target_property(_aliasName ${_target} ALIASED_TARGET)
3351 message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.")
3353 set (_target ${_aliasName})
3355 # check if target needs to be cotired for build type
3356 # when using configuration types, the test is performed at build time
3357 cotire_init_cotire_target_properties(${_target})
3358 if (NOT CMAKE_CONFIGURATION_TYPES)
3359 if (CMAKE_BUILD_TYPE)
3360 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
3362 list (FIND _option_CONFIGURATIONS "None" _index)
3364 if (_index EQUAL -1)
3366 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
3371 # when not using configuration types, immediately create cotire intermediate dir
3372 if (NOT CMAKE_CONFIGURATION_TYPES)
3373 cotire_get_intermediate_dir(_baseDir)
3374 file (MAKE_DIRECTORY "${_baseDir}")
3376 # choose languages that apply to the target
3377 cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES})
3378 if (NOT _targetLanguages)
3382 foreach (_language ${_targetLanguages})
3383 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd)
3385 list (APPEND _cmds ${_cmd})
3388 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
3390 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3392 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3394 cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds})
3395 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3397 cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target})
3400 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
3401 if (_targetAddCleanTarget)
3402 cotire_setup_clean_target(${_target})
3404 endfunction(cotire_target)
3406 function (cotire_map_libraries _strategy _mappedLibrariesVar)
3407 set (_mappedLibraries "")
3408 foreach (_library ${ARGN})
3409 if (_library MATCHES "^\\$<LINK_ONLY:(.+)>$")
3410 set (_libraryName "${CMAKE_MATCH_1}")
3411 set (_linkOnly TRUE)
3412 set (_objectLibrary FALSE)
3413 elseif (_library MATCHES "^\\$<TARGET_OBJECTS:(.+)>$")
3414 set (_libraryName "${CMAKE_MATCH_1}")
3415 set (_linkOnly FALSE)
3416 set (_objectLibrary TRUE)
3418 set (_libraryName "${_library}")
3419 set (_linkOnly FALSE)
3420 set (_objectLibrary FALSE)
3422 if ("${_strategy}" MATCHES "COPY_UNITY")
3423 cotire_is_target_supported(${_libraryName} _isSupported)
3425 # use target's corresponding unity target, if available
3426 get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME)
3427 if (TARGET "${_libraryUnityTargetName}")
3429 list (APPEND _mappedLibraries "$<LINK_ONLY:${_libraryUnityTargetName}>")
3430 elseif (_objectLibrary)
3431 list (APPEND _mappedLibraries "$<TARGET_OBJECTS:${_libraryUnityTargetName}>")
3433 list (APPEND _mappedLibraries "${_libraryUnityTargetName}")
3436 list (APPEND _mappedLibraries "${_library}")
3439 list (APPEND _mappedLibraries "${_library}")
3442 list (APPEND _mappedLibraries "${_library}")
3445 list (REMOVE_DUPLICATES _mappedLibraries)
3446 set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE)
3449 function (cotire_target_link_libraries _target)
3450 cotire_is_target_supported(${_target} _isSupported)
3451 if (NOT _isSupported)
3454 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3455 if (TARGET "${_unityTargetName}")
3456 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3458 message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}")
3460 if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$")
3461 get_target_property(_linkLibraries ${_target} LINK_LIBRARIES)
3463 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries})
3464 set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}")
3466 message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}")
3469 get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES)
3470 if (_interfaceLinkLibraries)
3471 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries})
3472 set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}")
3474 message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}")
3477 get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES)
3478 if (_manualDependencies)
3479 cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies})
3480 if (_unityManualDependencies)
3481 add_dependencies("${_unityTargetName}" ${_unityManualDependencies})
3486 endfunction(cotire_target_link_libraries)
3488 function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
3490 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
3492 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
3494 # filter files in intermediate directory
3495 set (_filesToRemove "")
3496 foreach (_file ${_cotireFiles})
3497 get_filename_component(_dir "${_file}" DIRECTORY)
3498 get_filename_component(_dirName "${_dir}" NAME)
3499 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
3500 list (APPEND _filesToRemove "${_file}")
3505 message (STATUS "cleaning up ${_filesToRemove}")
3507 file (REMOVE ${_filesToRemove})
3511 function (cotire_init_target _targetName)
3512 if (COTIRE_TARGETS_FOLDER)
3513 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
3515 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE)
3517 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
3521 function (cotire_add_to_pch_all_target _pchTargetName)
3522 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
3523 if (NOT TARGET "${_targetName}")
3524 add_custom_target("${_targetName}"
3525 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3527 cotire_init_target("${_targetName}")
3529 cotire_setup_clean_all_target()
3530 add_dependencies(${_targetName} ${_pchTargetName})
3533 function (cotire_add_to_unity_all_target _unityTargetName)
3534 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
3535 if (NOT TARGET "${_targetName}")
3536 add_custom_target("${_targetName}"
3537 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3539 cotire_init_target("${_targetName}")
3541 cotire_setup_clean_all_target()
3542 add_dependencies(${_targetName} ${_unityTargetName})
3545 function (cotire_setup_clean_all_target)
3546 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
3547 if (NOT TARGET "${_targetName}")
3548 cotire_set_cmd_to_prologue(_cmds)
3549 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
3550 add_custom_target(${_targetName}
3552 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3553 COMMENT "Cleaning up all cotire generated files"
3555 cotire_init_target("${_targetName}")
3561 set(_oneValueArgs "")
3562 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3563 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3564 set (_targets ${_option_UNPARSED_ARGUMENTS})
3565 foreach (_target ${_targets})
3566 if (TARGET ${_target})
3567 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS})
3569 message (WARNING "cotire: ${_target} is not a target.")
3572 foreach (_target ${_targets})
3573 if (TARGET ${_target})
3574 cotire_target_link_libraries(${_target})
3579 if (CMAKE_SCRIPT_MODE_FILE)
3581 # cotire is being run in script mode
3582 # locate -P on command args
3583 set (COTIRE_ARGC -1)
3584 foreach (_index RANGE ${CMAKE_ARGC})
3585 if (COTIRE_ARGC GREATER -1)
3586 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
3587 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
3588 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
3593 # include target script if available
3594 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
3595 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
3596 include("${COTIRE_ARGV2}")
3600 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
3603 if (NOT COTIRE_BUILD_TYPE)
3604 set (COTIRE_BUILD_TYPE "None")
3606 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
3607 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
3608 set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}})
3609 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
3610 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
3611 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
3612 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
3613 if (_index GREATER -1)
3614 set (_sources ${COTIRE_TARGET_SOURCES})
3615 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
3618 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
3621 set (_sourcesDefinitions "")
3623 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
3624 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
3625 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
3626 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
3628 if ("${COTIRE_ARGV1}" STREQUAL "unity")
3631 # executing pre-build action under Xcode, check dependency on target script
3632 set (_dependsOption DEPENDS "${COTIRE_ARGV2}")
3634 # executing custom command, no need to re-check for dependencies
3635 set (_dependsOption "")
3638 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
3640 cotire_generate_unity_source(
3641 "${COTIRE_ARGV3}" ${_sources}
3642 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3643 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
3644 PRE_UNDEFS ${_targetPreUndefs}
3645 POST_UNDEFS ${_targetPostUndefs}
3646 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
3647 SOURCES_POST_UNDEFS ${_sourcesPostUndefs}
3650 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
3653 # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies
3654 set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS})
3656 # executing custom command, no need to re-check for dependencies
3657 set (_dependsOption "")
3661 foreach (_index RANGE 4 ${COTIRE_ARGC})
3662 if (COTIRE_ARGV${_index})
3663 list (APPEND _files "${COTIRE_ARGV${_index}}")
3667 cotire_generate_prefix_header(
3668 "${COTIRE_ARGV3}" ${_files}
3669 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3670 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3671 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3672 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3673 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3674 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3675 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
3676 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
3677 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
3678 INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH}
3679 INCLUDE_DIRECTORIES ${_includeDirs}
3680 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3681 COMPILE_DEFINITIONS ${_compileDefinitions}
3682 COMPILE_FLAGS ${_compileFlags}
3685 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
3688 foreach (_index RANGE 5 ${COTIRE_ARGC})
3689 if (COTIRE_ARGV${_index})
3690 list (APPEND _files "${COTIRE_ARGV${_index}}")
3694 cotire_precompile_prefix_header(
3695 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
3696 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3697 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3698 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3699 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3700 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3701 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3702 INCLUDE_DIRECTORIES ${_includeDirs}
3703 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3704 COMPILE_DEFINITIONS ${_compileDefinitions}
3705 COMPILE_FLAGS ${_compileFlags})
3707 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
3709 if (COTIRE_TARGET_LANGUAGE)
3710 set (_combinedFile "${COTIRE_ARGV3}")
3713 set (_combinedFile "${COTIRE_ARGV2}")
3717 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
3718 if (COTIRE_ARGV${_index})
3719 list (APPEND _files "${COTIRE_ARGV${_index}}")
3724 # executing pre-build action under Xcode, check dependency on files to be combined
3725 set (_dependsOption DEPENDS ${_files})
3727 # executing custom command, no need to re-check for dependencies
3728 set (_dependsOption "")
3731 if (COTIRE_TARGET_LANGUAGE)
3732 cotire_generate_unity_source(
3733 "${_combinedFile}" ${_files}
3734 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3737 cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption})
3740 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
3742 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
3745 message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".")
3750 # cotire is being run in include mode
3751 # set up all variable and property definitions
3753 if (NOT DEFINED COTIRE_DEBUG_INIT)
3754 if (DEFINED COTIRE_DEBUG)
3755 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
3757 set (COTIRE_DEBUG_INIT FALSE)
3760 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
3762 if (NOT DEFINED COTIRE_VERBOSE_INIT)
3763 if (DEFINED COTIRE_VERBOSE)
3764 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
3766 set (COTIRE_VERBOSE_INIT FALSE)
3769 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
3771 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
3772 "Ignore headers with the listed file extensions from the generated prefix header.")
3774 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
3775 "Ignore headers from these directories when generating the prefix header.")
3777 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
3778 "Ignore sources with the listed file extensions from the generated unity source.")
3780 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING
3781 "Minimum number of sources in target required to enable use of precompiled header.")
3783 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
3784 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
3785 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
3786 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
3787 # enable parallelization for generators that run multiple jobs by default
3788 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
3790 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
3793 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
3794 "Maximum number of source files to include in a single unity source file.")
3796 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
3797 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
3799 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
3800 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
3802 if (NOT COTIRE_INTDIR)
3803 set (COTIRE_INTDIR "cotire")
3805 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
3806 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
3808 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
3809 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
3811 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
3812 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
3814 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
3815 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
3817 if (NOT COTIRE_PCH_TARGET_SUFFIX)
3818 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
3821 # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code
3822 # use a bigger default factor of 170 percent (128 MB)
3823 if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR)
3824 set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170")
3827 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
3828 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
3830 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
3831 set (COTIRE_TARGETS_FOLDER "cotire")
3833 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
3834 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
3835 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
3836 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
3838 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
3842 # define cotire cache variables
3845 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
3846 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3848 "The variable can be set to a semicolon separated list of include directories."
3849 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3850 "If not defined, defaults to empty list."
3854 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
3855 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
3857 "The variable can be set to a semicolon separated list of file extensions."
3858 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
3859 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
3860 "If not defined, defaults to inc;inl;ipp."
3864 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
3865 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
3867 "The variable can be set to a semicolon separated list of file extensions."
3868 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
3869 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
3870 "If not defined, defaults to m;mm."
3874 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
3875 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
3877 "The variable can be set to an integer > 0."
3878 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
3879 "If not defined, defaults to 2."
3883 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
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 0, cotire will only create a single unity source file."
3888 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
3889 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
3890 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
3891 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3892 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
3895 # define cotire directory properties
3898 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
3899 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
3901 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
3905 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
3906 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
3908 "See target property COTIRE_ADD_UNITY_BUILD."
3912 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
3913 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
3915 "See target property COTIRE_ADD_CLEAN."
3919 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
3920 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3922 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
3926 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
3927 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3929 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
3933 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH"
3934 BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header."
3936 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH."
3940 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3941 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
3943 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
3947 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3948 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
3950 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
3954 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
3955 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3957 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3961 DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT"
3962 BRIEF_DOCS "Define strategy for setting up the unity target's link libraries."
3964 "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT."
3967 # define cotire target properties
3970 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
3971 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
3973 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
3974 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
3975 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
3976 "The target name will be set to this target's name with the suffix _pch appended."
3977 "Inherited from directory."
3982 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
3983 BRIEF_DOCS "Add a new target that performs a unity build for this target."
3985 "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."
3986 "Most of the relevant target properties will be copied from this target to the new unity build target."
3987 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
3988 "The unity target name will be set to this target's name with the suffix _unity appended."
3989 "Inherited from directory."
3994 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
3995 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
3997 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
3998 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
3999 "Inherited from directory."
4000 "Defaults to FALSE."
4004 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
4005 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
4007 "The property can be set to a list of directories."
4008 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
4009 "Inherited from directory."
4010 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
4014 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
4015 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
4017 "The property can be set to a list of directories."
4018 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
4019 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
4020 "the option which yields the closer relative path match wins."
4021 "Inherited from directory."
4022 "If not set, this property is initialized to the empty list."
4026 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED
4027 BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header."
4029 "The property can be set to a list of directories."
4030 "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header."
4031 "Header files are sorted according to the order of the directories in the property."
4032 "If not set, this property is initialized to the empty list."
4036 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
4037 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
4039 "This may be set to a semicolon-separated list of preprocessor symbols."
4040 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
4041 "Inherited from directory."
4042 "Defaults to empty string."
4046 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
4047 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
4049 "This may be set to a semicolon-separated list of preprocessor symbols."
4050 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
4051 "Inherited from directory."
4052 "Defaults to empty string."
4056 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
4057 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
4059 "This may be set to an integer > 0."
4060 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
4061 "If not set, cotire will only create a single unity source file."
4062 "Inherited from directory."
4063 "Defaults to empty."
4067 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
4068 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
4070 "If set, cotire will only add the given file(s) to the generated unity source file."
4071 "If not set, cotire will add all the target source files to the generated unity source file."
4072 "The property can be set to a user provided unity source file."
4073 "Defaults to empty."
4077 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
4078 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
4080 "If set, cotire will add the given header file(s) to the generated prefix header file."
4081 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
4082 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
4083 "Defaults to empty."
4087 TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED
4088 BRIEF_DOCS "Define strategy for setting up unity target's link libraries."
4090 "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually."
4091 "If this property is set to COPY, the unity target's link libraries will be copied from this target."
4092 "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."
4093 "Inherited from directory."
4094 "Defaults to empty."
4098 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
4099 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
4101 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
4102 "Defaults to empty string."
4106 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
4107 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
4109 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
4110 "Defaults to empty string."
4114 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
4115 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
4117 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
4118 "Defaults to empty string."
4122 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
4123 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
4125 "This property can be set to the desired name of the unity target that will be created by cotire."
4126 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
4127 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
4128 "Defaults to empty string."
4131 # define cotire source properties
4134 SOURCE PROPERTY "COTIRE_EXCLUDED"
4135 BRIEF_DOCS "Do not modify source file's build command."
4137 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
4138 "The source file will also be excluded from the generated unity source file."
4139 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
4140 "Defaults to FALSE."
4144 SOURCE PROPERTY "COTIRE_DEPENDENCY"
4145 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
4147 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
4148 "If the file is modified, cotire will re-generate the prefix header source upon build."
4149 "Defaults to FALSE."
4153 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
4154 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
4156 "This may be set to a semicolon-separated list of preprocessor symbols."
4157 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
4158 "Defaults to empty string."
4162 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
4163 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
4165 "This may be set to a semicolon-separated list of preprocessor symbols."
4166 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
4167 "Defaults to empty string."
4171 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
4172 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
4174 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
4175 "The new unity source file will include this source file as the first one."
4176 "This property essentially works as a separator for unity source files."
4177 "Defaults to FALSE."
4181 SOURCE PROPERTY "COTIRE_TARGET"
4182 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
4184 "cotire sets this property to the name of target, that the source file's build command has been altered for."
4185 "Defaults to empty string."
4188 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")