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#=============================================================================
33set(__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
37if (NOT CMAKE_SCRIPT_MODE_FILE)
40cmake_minimum_required(VERSION 3.5.0)
41if (NOT CMAKE_SCRIPT_MODE_FILE)
45set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
46set (COTIRE_CMAKE_MODULE_VERSION "1.8.1")
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)
114include(CMakeParseArguments)
115include(ProcessorCount)
117function (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)
133function (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)
146macro (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)
159function (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)
268function (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)
282function (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)
296function (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)
307function (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)
323function (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}")
334function (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)
362function (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)
408function (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)
426function (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)
543function (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)
675function (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)
690function (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)
744function (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)
771function (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)
787function (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)
809function (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)
832function (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)
843function (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)
861function (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)
872macro (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)")
888function (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)
910macro (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}")
920function (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)
944function (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)
981macro (cotire_add_compile_flags_to_cmd _cmdVar)
982 foreach (_flag ${ARGN})
983 list (APPEND ${_cmdVar} "${_flag}")
987function (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)
1023macro (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")
1043macro (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)
1066macro (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")
1072 # heuristic: ignore 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"
1075 set (${_headerIsIgnoredVar} TRUE)
1077 set (${_headerIsIgnoredVar} FALSE)
1081macro (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)
1093macro (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)
1122function (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)
1224function (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)
1312macro (cotire_append_undefs _contentsVar)
1313 set (_undefs ${ARGN})
1315 list (REMOVE_DUPLICATES _undefs)
1316 foreach (_definition ${_undefs})
1317 list (APPEND ${_contentsVar} "#undef ${_definition}")
1322macro (cotire_comment_str _language _commentText _commentVar)
1323 if ("${_language}" STREQUAL "CMAKE")
1324 set (${_commentVar} "# ${_commentText}")
1326 set (${_commentVar} "/* ${_commentText} */")
1330function (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")
1352function (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)
1446function (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")
1517function (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)
1627function (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 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1697 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1698 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1699 # Clang-cl.exe options used
1700 # /Yc creates a precompiled header file
1701 # /Fp specifies precompiled header binary file name
1702 # /FI forces inclusion of file
1703 # /Zs syntax check only
1704 # /TC treat all files named on the command line as C source files
1705 # /TP treat all files named on the command line as C++ source files
1706 set (_sourceFileTypeC "/TC")
1707 set (_sourceFileTypeCXX "/TP")
1710 list (APPEND _flags "${_sourceFileType${_language}}"
1711 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1713 # return as a flag string
1714 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1717 elseif (_compilerID MATCHES "Intel")
1719 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1720 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1721 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1722 # Windows Intel options used
1723 # /nologo do not display compiler version information
1724 # /Yc create a precompiled header (PCH) file
1725 # /Fp specify a path or file name for precompiled header files
1726 # /FI tells the preprocessor to include a specified file name as the header file
1727 # /TC process all source or unrecognized file types as C source files
1728 # /TP process all source or unrecognized file types as C++ source files
1729 # /Zs syntax check only
1730 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1731 set (_sourceFileTypeC "/TC")
1732 set (_sourceFileTypeCXX "/TP")
1735 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1736 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1737 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1738 list (APPEND _flags "/Wpch-messages")
1741 # return as a flag string
1742 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1743 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1744 set (_flags "${_flags} /Wpch-messages")
1748 # Linux / Mac OS X Intel options used
1749 # -pch-dir location for precompiled header files
1750 # -pch-create name of the precompiled header (PCH) to create
1751 # -Kc++ process all source or unrecognized file types as C++ source files
1752 # -fsyntax-only check only for correct syntax
1753 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1754 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1755 get_filename_component(_pchName "${_pchFile}" NAME)
1756 set (_xLanguage_C "c-header")
1757 set (_xLanguage_CXX "c++-header")
1758 set (_pchSuppressMessages FALSE)
1759 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1760 set(_pchSuppressMessages TRUE)
1764 if ("${_language}" STREQUAL "CXX")
1765 list (APPEND _flags -Kc++)
1767 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}")
1768 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1769 if (NOT _pchSuppressMessages)
1770 list (APPEND _flags -Wpch-messages)
1774 # return as a flag string
1775 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1776 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1777 if (NOT _pchSuppressMessages)
1778 set (_flags "${_flags} -Wpch-messages")
1784 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1786 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1789function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1790 set (_flags ${${_flagsVar}})
1791 if (_compilerID MATCHES "MSVC")
1792 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1793 # cl.exe options used
1794 # /Yu uses a precompiled header file during build
1795 # /Fp specifies precompiled header binary file name
1796 # /FI forces inclusion of file
1797 # /Zm precompiled header memory allocation scaling factor
1799 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1802 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1803 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1804 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1807 # return as a flag string
1808 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1809 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1810 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1814 # no precompiled header, force inclusion of prefix header
1817 list (APPEND _flags "/FI${_prefixFileNative}")
1819 # return as a flag string
1820 set (_flags "/FI\"${_prefixFileNative}\"")
1823 elseif (_compilerID MATCHES "GNU")
1825 # -include process include file as the first line of the primary source file
1826 # -Winvalid-pch warns if precompiled header is found but cannot be used
1827 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1830 list (APPEND _flags -Winvalid-pch -include "${_prefixFile}")
1832 # return as a flag string
1833 set (_flags "-Winvalid-pch -include \"${_prefixFile}\"")
1835 elseif (_compilerID MATCHES "Clang")
1837 # Clang options used
1838 # -include process include file as the first line of the primary source file
1839 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1842 list (APPEND _flags -include "${_prefixFile}")
1844 # return as a flag string
1845 set (_flags "-include \"${_prefixFile}\"")
1848 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1849 # Clang-cl.exe options used
1850 # /Yu uses a precompiled header file during build
1851 # /Fp specifies precompiled header binary file name
1852 # /FI forces inclusion of file
1854 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1857 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1859 # return as a flag string
1860 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1863 # no precompiled header, force inclusion of prefix header
1866 list (APPEND _flags "/FI${_prefixFileNative}")
1868 # return as a flag string
1869 set (_flags "/FI\"${_prefixFileNative}\"")
1873 elseif (_compilerID MATCHES "Intel")
1875 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1876 # Windows Intel options used
1877 # /Yu use a precompiled header (PCH) file
1878 # /Fp specify a path or file name for precompiled header files
1879 # /FI tells the preprocessor to include a specified file name as the header file
1880 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1882 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1885 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1886 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1887 list (APPEND _flags "/Wpch-messages")
1890 # return as a flag string
1891 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1892 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1893 set (_flags "${_flags} /Wpch-messages")
1897 # no precompiled header, force inclusion of prefix header
1900 list (APPEND _flags "/FI${_prefixFileNative}")
1902 # return as a flag string
1903 set (_flags "/FI\"${_prefixFileNative}\"")
1907 # Linux / Mac OS X Intel options used
1908 # -pch-dir location for precompiled header files
1909 # -pch-use name of the precompiled header (PCH) to use
1910 # -include process include file as the first line of the primary source file
1911 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1913 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1914 get_filename_component(_pchName "${_pchFile}" NAME)
1915 set (_pchSuppressMessages FALSE)
1916 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1917 set(_pchSuppressMessages TRUE)
1921 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}")
1922 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1923 if (NOT _pchSuppressMessages)
1924 list (APPEND _flags -Wpch-messages)
1928 # return as a flag string
1929 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1930 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1931 if (NOT _pchSuppressMessages)
1932 set (_flags "${_flags} -Wpch-messages")
1937 # no precompiled header, force inclusion of prefix header
1940 list (APPEND _flags -include "${_prefixFile}")
1942 # return as a flag string
1943 set (_flags "-include \"${_prefixFile}\"")
1948 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1950 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1953function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1955 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE)
1956 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER)
1957 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1958 if (NOT _option_LANGUAGE)
1959 set (_option_LANGUAGE "CXX")
1961 if (NOT _option_COMPILER_ID)
1962 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1964 if (NOT _option_COMPILER_VERSION)
1965 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1967 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1968 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1969 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1970 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1971 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1972 cotire_add_pch_compilation_flags(
1973 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1974 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1976 message (STATUS "execute_process: ${_cmd}")
1978 if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC")
1979 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1980 unset (ENV{VS_UNICODE_OUTPUT})
1981 elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0")
1982 if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR
1983 _option_COMPILER_EXECUTABLE MATCHES "ccache")
1984 # Newer versions of Clang embed a compilation timestamp into the precompiled header binary,
1985 # which results in "file has been modified since the precompiled header was built" errors if ccache is used.
1986 # We work around the problem by disabling ccache upon pre-compiling the prefix header.
1987 set (ENV{CCACHE_DISABLE} "true")
1992 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1993 RESULT_VARIABLE _result)
1995 message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.")
1999function (cotire_check_precompiled_header_support _language _target _msgVar)
2000 set (_unsupportedCompiler
2001 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
2002 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2003 # PCH supported since Visual Studio C++ 6.0
2004 # and CMake does not support an earlier version
2005 set (${_msgVar} "" PARENT_SCOPE)
2006 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2007 # GCC PCH support requires version >= 3.4
2008 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
2009 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2011 set (${_msgVar} "" PARENT_SCOPE)
2013 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2015 # all Unix Clang versions have PCH support
2016 set (${_msgVar} "" PARENT_SCOPE)
2018 # only clang-cl is supported under Windows
2019 get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE)
2020 if (NOT _compilerName MATCHES "cl$")
2021 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE)
2024 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2025 # Intel PCH support requires version >= 8.0.0
2026 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
2027 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2029 set (${_msgVar} "" PARENT_SCOPE)
2032 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
2034 # check if ccache is used as a compiler launcher
2035 get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER)
2036 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH)
2037 if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache")
2038 # verify that ccache configuration is compatible with precompiled headers
2039 # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache
2040 # do not report the "sloppiness" setting correctly upon printing ccache configuration
2041 if (DEFINED ENV{CCACHE_SLOPPINESS})
2042 if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR
2043 NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros")
2045 "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"."
2049 if (_realCompilerExe MATCHES "ccache")
2050 set (_ccacheExe "${_realCompilerExe}")
2052 set (_ccacheExe "${_launcher}")
2054 # ccache 3.7.0 replaced --print-config with --show-config
2055 # use -p instead, which seems to work for all version for now, sigh
2057 COMMAND "${_ccacheExe}" "-p"
2058 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
2059 RESULT_VARIABLE _result
2060 OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE
2063 set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE)
2064 elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR
2065 NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines")
2067 "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"."
2073 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
2074 cotire_get_configuration_types(_configs)
2075 foreach (_config ${_configs})
2076 set (_targetFlags "")
2077 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
2078 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
2079 list (LENGTH _architectures _numberOfArchitectures)
2080 if (_numberOfArchitectures GREATER 1)
2081 string (REPLACE ";" ", " _architectureStr "${_architectures}")
2083 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
2091macro (cotire_get_intermediate_dir _cotireDir)
2092 # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types
2093 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
2096macro (cotire_setup_file_extension_variables)
2097 set (_unityFileExt_C ".c")
2098 set (_unityFileExt_CXX ".cxx")
2099 set (_prefixFileExt_C ".h")
2100 set (_prefixFileExt_CXX ".hxx")
2101 set (_prefixSourceFileExt_C ".c")
2102 set (_prefixSourceFileExt_CXX ".cxx")
2105function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
2106 cotire_setup_file_extension_variables()
2107 if (NOT DEFINED _unityFileExt_${_language})
2108 set (${_unityFileVar} "" PARENT_SCOPE)
2111 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2112 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
2113 cotire_get_intermediate_dir(_baseDir)
2114 set (_unityFile "${_baseDir}/${_unityFileName}")
2115 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
2118function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
2119 cotire_setup_file_extension_variables()
2120 if (NOT DEFINED _unityFileExt_${_language})
2121 set (${_unityFileVar} "" PARENT_SCOPE)
2124 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2125 cotire_get_intermediate_dir(_baseDir)
2128 set (_unityFiles "")
2129 set (_sourceFiles ${ARGN})
2130 foreach (_sourceFile ${_sourceFiles})
2131 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
2132 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
2133 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
2134 if (_index GREATER 0)
2135 # start new unity file segment
2136 math (EXPR _endIndex "${_index} - 1")
2137 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2138 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2140 set (_startIndex ${_index})
2142 math (EXPR _index "${_index} + 1")
2144 list (LENGTH _sourceFiles _numberOfSources)
2145 if (_startIndex EQUAL 0)
2146 # there is only a single unity file
2147 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
2148 elseif (_startIndex LESS _numberOfSources)
2149 # end with final unity file segment
2150 math (EXPR _endIndex "${_index} - 1")
2151 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2152 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2154 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
2155 if (COTIRE_DEBUG AND _unityFiles)
2156 message (STATUS "unity files: ${_unityFiles}")
2160function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
2161 cotire_setup_file_extension_variables()
2162 if (NOT DEFINED _unityFileExt_${_language})
2163 set (${_prefixFileVar} "" PARENT_SCOPE)
2166 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2167 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2168 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
2169 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
2170 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
2173function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar)
2174 cotire_setup_file_extension_variables()
2175 if (NOT DEFINED _prefixSourceFileExt_${_language})
2176 set (${_prefixSourceFileVar} "" PARENT_SCOPE)
2179 string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}")
2180 set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE)
2183function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
2184 cotire_setup_file_extension_variables()
2186 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2187 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
2188 elseif (DEFINED _prefixFileExt_${_language})
2189 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2190 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
2192 set (_prefixFileBaseName "")
2193 set (_prefixFileName "")
2195 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
2196 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
2199function (cotire_make_prefix_file_path _language _target _prefixFileVar)
2200 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2201 set (${_prefixFileVar} "" PARENT_SCOPE)
2202 if (_prefixFileName)
2206 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC")
2207 cotire_get_intermediate_dir(_baseDir)
2208 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
2213function (cotire_make_pch_file_path _language _target _pchFileVar)
2214 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2215 set (${_pchFileVar} "" PARENT_SCOPE)
2216 if (_prefixFileBaseName AND _prefixFileName)
2217 cotire_check_precompiled_header_support("${_language}" "${_target}" _msg)
2220 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
2223 cotire_get_intermediate_dir(_baseDir)
2224 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2225 # MSVC uses the extension .pch added to the prefix header base name
2226 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
2227 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2228 # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended
2229 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE)
2230 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2231 # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended
2232 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
2233 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2234 # Intel uses the extension .pchi added to the prefix header base name
2235 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
2241function (cotire_select_unity_source_files _unityFile _sourcesVar)
2242 set (_sourceFiles ${ARGN})
2243 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
2244 set (_startIndex ${CMAKE_MATCH_1})
2245 set (_endIndex ${CMAKE_MATCH_2})
2246 list (LENGTH _sourceFiles _numberOfSources)
2247 if (NOT _startIndex LESS _numberOfSources)
2248 math (EXPR _startIndex "${_numberOfSources} - 1")
2250 if (NOT _endIndex LESS _numberOfSources)
2251 math (EXPR _endIndex "${_numberOfSources} - 1")
2254 foreach (_index RANGE ${_startIndex} ${_endIndex})
2255 list (GET _sourceFiles ${_index} _file)
2256 list (APPEND _files "${_file}")
2259 set (_files ${_sourceFiles})
2261 set (${_sourcesVar} ${_files} PARENT_SCOPE)
2264function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
2265 set (_dependencySources "")
2266 # depend on target's generated source files
2267 get_target_property(_targetSourceFiles ${_target} SOURCES)
2268 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2269 if (_generatedSources)
2270 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
2271 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
2272 if (_excludedGeneratedSources)
2273 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
2275 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
2276 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
2277 if (_excludedNonDependencySources)
2278 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
2280 if (_generatedSources)
2281 list (APPEND _dependencySources ${_generatedSources})
2284 if (COTIRE_DEBUG AND _dependencySources)
2285 message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}")
2287 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2290function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
2291 set (_dependencySources "")
2292 # depend on target source files marked with custom COTIRE_DEPENDENCY property
2293 get_target_property(_targetSourceFiles ${_target} SOURCES)
2294 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles})
2295 if (COTIRE_DEBUG AND _dependencySources)
2296 message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}")
2298 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2301function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar)
2302 set (_targetSources ${ARGN})
2303 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources})
2304 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources})
2305 # set up variables to be configured
2306 set (COTIRE_TARGET_LANGUAGE "${_language}")
2307 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
2308 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
2309 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
2310 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
2311 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
2312 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
2313 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2314 get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH)
2315 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources})
2316 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources})
2317 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
2318 foreach (_config ${_configurations})
2319 string (TOUPPER "${_config}" _upperConfig)
2320 cotire_get_target_include_directories(
2321 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig})
2322 cotire_get_target_compile_definitions(
2323 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
2324 cotire_get_target_compiler_flags(
2325 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
2326 cotire_get_source_files_compile_definitions(
2327 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources})
2329 get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER)
2330 # set up COTIRE_TARGET_SOURCES
2331 set (COTIRE_TARGET_SOURCES "")
2332 foreach (_sourceFile ${_targetSources})
2333 get_source_file_property(_generated "${_sourceFile}" GENERATED)
2335 # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation
2336 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2337 list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}")
2339 list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}")
2342 # copy variable definitions to cotire target script
2343 get_cmake_property(_vars VARIABLES)
2344 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
2345 # omit COTIRE_*_INIT variables
2346 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}")
2348 list (REMOVE_ITEM _matchVars ${_initVars})
2350 # omit COTIRE_VERBOSE which is passed as a CMake define on command line
2351 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
2353 set (_contentsHasGeneratorExpressions FALSE)
2354 foreach (_var IN LISTS _matchVars ITEMS
2355 XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
2356 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION
2357 CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
2358 CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language}
2359 CMAKE_INCLUDE_SYSTEM_FLAG_${_language}
2360 CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG
2361 CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG
2362 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
2363 if (DEFINED ${_var})
2364 string (REPLACE "\"" "\\\"" _value "${${_var}}")
2365 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
2366 if (NOT _contentsHasGeneratorExpressions)
2367 if ("${_value}" MATCHES "\\$<.*>")
2368 set (_contentsHasGeneratorExpressions TRUE)
2373 # generate target script file
2374 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
2375 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
2376 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
2377 if (_contentsHasGeneratorExpressions)
2378 # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time
2379 set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>")
2380 set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}")
2381 file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}")
2383 set (_targetCotireConfigScript "${_targetCotireScript}")
2385 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
2386 set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE)
2389function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile)
2390 set (_sourceFiles ${ARGN})
2391 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2392 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2393 # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file
2394 # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion
2397 cotire_add_pch_compilation_flags(
2398 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2399 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
2400 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2402 message (STATUS "set_property: SOURCE ${_hostFile} APPEND_STRING COMPILE_FLAGS ${_flags}")
2404 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
2405 # make object file generated from host file depend on prefix header
2406 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2407 # mark host file as cotired to prevent it from being used in another cotired target
2408 set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}")
2410 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2411 # for makefile based generator, we add a custom command to precompile the prefix header
2413 cotire_set_cmd_to_prologue(_cmds)
2414 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
2416 file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath)
2418 file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
2420 # make precompiled header compilation depend on the actual compiler executable used to force
2421 # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable"
2422 # warnings when the precompiled header is included.
2423 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2425 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
2427 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
2429 OUTPUT "${_pchFile}"
2431 DEPENDS "${_prefixFile}" "${_realCompilerExe}"
2432 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
2433 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2434 COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}"
2440function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile)
2441 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2442 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2443 # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file
2444 # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation
2445 set (_sourceFiles ${ARGN})
2446 list (LENGTH _sourceFiles _numberOfSourceFiles)
2447 if (_numberOfSourceFiles GREATER 0)
2448 # mark sources as cotired to prevent them from being used in another cotired target
2449 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2451 cotire_add_prefix_pch_inclusion_flags(
2452 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2453 "${_prefixFile}" "${_pchFile}" _flags)
2454 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2456 message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}")
2458 # make object files generated from source files depend on precompiled header
2459 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2461 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2462 set (_sourceFiles ${_hostFile} ${ARGN})
2463 if (NOT _wholeTarget)
2464 # for makefile based generator, we force the inclusion of the prefix header for a subset
2465 # of the source files, if this is a multi-language target or has excluded files
2467 cotire_add_prefix_pch_inclusion_flags(
2468 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2469 "${_prefixFile}" "${_pchFile}" _flags)
2470 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2472 message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}")
2474 # mark sources as cotired to prevent them from being used in another cotired target
2475 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2477 # make object files generated from source files depend on precompiled header
2478 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2482function (cotire_setup_prefix_file_inclusion _language _target _prefixFile)
2483 set (_sourceFiles ${ARGN})
2484 # force the inclusion of the prefix header for the given source files
2487 cotire_add_prefix_pch_inclusion_flags(
2488 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2489 "${_prefixFile}" "${_pchFile}" _flags)
2490 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2492 message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}")
2494 # mark sources as cotired to prevent them from being used in another cotired target
2495 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2496 # make object files generated from source files depend on prefix header
2497 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2500function (cotire_get_first_set_property_value _propertyValueVar _type _object)
2501 set (_properties ${ARGN})
2502 foreach (_property ${_properties})
2503 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
2505 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
2509 set (${_propertyValueVar} "" PARENT_SCOPE)
2512function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar)
2513 set (_files ${ARGN})
2514 set (_filesPaths "")
2515 foreach (_file ${_files})
2516 get_filename_component(_filePath "${_file}" ABSOLUTE)
2517 list (APPEND _filesPaths "${_filePath}")
2519 cotire_set_cmd_to_prologue(_prefixCmd)
2520 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
2522 list (APPEND _prefixCmd "${_targetScript}")
2524 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
2526 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
2528 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
2530 file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath)
2532 file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
2534 get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE)
2535 get_filename_component(_joinedFileExt "${_joinedFile}" EXT)
2536 if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
2537 set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}")
2538 elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$")
2539 if (_joinedFileExt MATCHES "^\\.c")
2540 set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}")
2542 set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}")
2545 set (_comment "Generating ${_joinedFileLogPath}")
2548 OUTPUT "${_joinedFile}"
2549 COMMAND ${_prefixCmd}
2551 COMMENT "${_comment}"
2552 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2554 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2555 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2558function (cotire_setup_target_pch_usage _languages _target _wholeTarget)
2560 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
2561 set (_prefixFiles "")
2562 foreach (_language ${_languages})
2563 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2565 list (APPEND _prefixFiles "${_prefixFile}")
2569 list (LENGTH _prefixFiles _numberOfPrefixFiles)
2570 if (_numberOfPrefixFiles GREATER 1)
2571 # we also generate a generic, single prefix header which includes all language specific prefix headers
2573 set (_targetScript "")
2574 cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader)
2575 cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles})
2577 set (_prefixHeader "${_prefixFiles}")
2580 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
2582 # because CMake PRE_BUILD command does not support dependencies,
2583 # we check dependencies explicity in cotire script mode when the pre-build action is run
2587 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2588 COMMENT "Updating target ${_target} prefix headers"
2590 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
2591 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
2592 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
2593 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2594 # for makefile based generator, we force inclusion of the prefix header for all target source files
2595 # if this is a single-language target without any excluded files
2597 set (_language "${_languages}")
2598 # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level
2599 # see cotire_setup_pch_file_inclusion
2600 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
2601 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2602 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2604 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
2605 set (_options COMPILE_OPTIONS)
2606 cotire_add_prefix_pch_inclusion_flags(
2607 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2608 "${_prefixFile}" "${_pchFile}" _options)
2609 set_property(TARGET ${_target} APPEND PROPERTY ${_options})
2611 message (STATUS "set_property: TARGET ${_target} APPEND PROPERTY ${_options}")
2619function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar)
2620 set (_dependencySources "")
2621 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
2622 foreach (_unityFile ${_unityFiles})
2623 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
2624 # set up compiled unity source dependencies via OBJECT_DEPENDS
2625 # this ensures that missing source files are generated before the unity file is compiled
2626 if (COTIRE_DEBUG AND _dependencySources)
2627 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
2629 if (_dependencySources)
2630 # the OBJECT_DEPENDS property requires a list of full paths
2631 set (_objectDependsPaths "")
2632 foreach (_sourceFile ${_dependencySources})
2633 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2634 list (APPEND _objectDependsPaths "${_sourceLocation}")
2636 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths})
2638 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2639 # unity file compilation results in potentially huge object file,
2640 # thus use /bigobj by default unter cl.exe and Windows Intel
2641 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
2643 cotire_set_cmd_to_prologue(_unityCmd)
2644 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}")
2645 if (CMAKE_VERSION VERSION_LESS "3.1.0")
2646 set (_unityCmdDepends "${_targetScript}")
2648 # CMake 3.1.0 supports generator expressions in arguments to DEPENDS
2649 set (_unityCmdDepends "${_targetConfigScript}")
2652 file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath)
2654 file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
2657 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}")
2660 OUTPUT "${_unityFile}"
2661 COMMAND ${_unityCmd}
2662 DEPENDS ${_unityCmdDepends}
2663 COMMENT "Generating ${_language} unity source ${_unityFileLogPath}"
2664 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2666 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
2668 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2671function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2672 set (_sourceFiles ${ARGN})
2673 set (_dependencySources "")
2674 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
2675 cotire_set_cmd_to_prologue(_prefixCmd)
2676 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles})
2677 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
2678 # make prefix header generation depend on the actual compiler executable used to force
2679 # re-generation when the compiler executable is updated. This prevents "file not found"
2680 # errors for compiler version specific system header files.
2681 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2683 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}")
2686 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath)
2688 file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
2690 get_filename_component(_prefixFileExt "${_prefixFile}" EXT)
2691 if (_prefixFileExt MATCHES "^\\.c")
2692 set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}")
2694 set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}")
2696 # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist
2697 # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence
2698 # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files
2699 set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre")
2700 if (TARGET ${_preTargetName})
2701 # custom helper target has already been generated while processing a different language
2702 list (APPEND _dependencySources ${_preTargetName})
2704 get_target_property(_targetSourceFiles ${_target} SOURCES)
2705 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2706 if (_generatedSources)
2707 add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources})
2708 cotire_init_target("${_preTargetName}")
2709 list (APPEND _dependencySources ${_preTargetName})
2713 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
2714 COMMAND ${_prefixCmd}
2715 DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}"
2716 COMMENT "${_comment}"
2717 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2719 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2720 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2723function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2724 set (_sourceFiles ${ARGN})
2725 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2726 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2727 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2729 set (_prefixSourceFile "${_prefixFile}")
2731 cotire_setup_prefix_generation_command(
2732 ${_language} ${_target} "${_targetScript}"
2733 "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2734 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2735 # set up generation of a prefix source file which includes the prefix header
2736 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2738 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2741function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar)
2742 set (_prefixHeaderFiles ${ARGN})
2743 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2744 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2745 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2747 set (_prefixSourceFile "${_prefixFile}")
2749 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles})
2750 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2751 # set up generation of a prefix source file which includes the prefix header
2752 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2754 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2757function (cotire_init_cotire_target_properties _target)
2758 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2760 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2762 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2764 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2766 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2768 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2770 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2772 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2773 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2774 if (NOT _isRelative)
2775 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2778 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2780 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2782 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET)
2784 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "")
2786 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2788 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2790 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2792 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2794 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET)
2796 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY")
2798 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2800 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2801 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2803 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2808function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2809 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2810 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2811 string (REPLACE ";" " " _languagesStr "${_languages}")
2812 math (EXPR _numberOfExcludedFiles "${ARGC} - 4")
2813 if (_numberOfExcludedFiles EQUAL 0)
2814 set (_excludedStr "")
2815 elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4)
2816 string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}")
2818 set (_excludedStr "excluding ${_numberOfExcludedFiles} files")
2822 set (_targetMsg "Target ${_target} cannot be cotired.")
2824 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2826 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2827 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2829 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2831 elseif (NOT _targetUsePCH)
2833 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.")
2835 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2838 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2840 elseif (NOT _targetAddSCU)
2842 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.")
2844 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2847 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2851 set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.")
2853 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2856 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2859function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar)
2860 set (_languages ${ARGN})
2861 set (_allSourceFiles "")
2862 set (_allExcludedSourceFiles "")
2863 set (_allCotiredSourceFiles "")
2864 set (_targetLanguages "")
2865 set (_pchEligibleTargetLanguages "")
2866 get_target_property(_targetType ${_target} TYPE)
2867 get_target_property(_targetSourceFiles ${_target} SOURCES)
2868 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2869 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2870 set (_disableMsg "")
2871 foreach (_language ${_languages})
2872 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2873 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2874 if (_prefixHeader OR _unityBuildFile)
2875 message (STATUS "cotire: target ${_target} has already been cotired.")
2876 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2879 if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID)
2880 if (CMAKE_${_language}_COMPILER_ID)
2881 cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg)
2883 set (_targetUsePCH FALSE)
2887 set (_sourceFiles "")
2888 set (_excludedSources "")
2889 set (_cotiredSources "")
2890 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2891 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2892 list (APPEND _targetLanguages ${_language})
2895 list (APPEND _allSourceFiles ${_sourceFiles})
2897 list (LENGTH _sourceFiles _numberOfSources)
2898 if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2899 list (APPEND _pchEligibleTargetLanguages ${_language})
2901 if (_excludedSources)
2902 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2904 if (_cotiredSources)
2905 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2908 set (_targetMsgLevel STATUS)
2909 if (NOT _targetLanguages)
2910 string (REPLACE ";" " or " _languagesStr "${_languages}")
2911 set (_disableMsg "No ${_languagesStr} source files.")
2912 set (_targetUsePCH FALSE)
2913 set (_targetAddSCU FALSE)
2916 if (_allCotiredSourceFiles)
2917 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2918 list (REMOVE_DUPLICATES _cotireTargets)
2919 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2920 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2921 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2922 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2923 set (_targetMsgLevel SEND_ERROR)
2924 set (_targetUsePCH FALSE)
2925 elseif (NOT _pchEligibleTargetLanguages)
2926 set (_disableMsg "Too few applicable sources.")
2927 set (_targetUsePCH FALSE)
2928 elseif (XCODE AND _allExcludedSourceFiles)
2929 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2930 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2931 set (_targetUsePCH FALSE)
2932 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2933 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2934 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2935 set (_targetUsePCH FALSE)
2939 # disable unity builds if automatic Qt processing is used
2940 get_target_property(_targetAutoMoc ${_target} AUTOMOC)
2941 get_target_property(_targetAutoUic ${_target} AUTOUIC)
2942 get_target_property(_targetAutoRcc ${_target} AUTORCC)
2943 if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc)
2945 set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.")
2947 set (_disableMsg "Target uses automatic CMake Qt processing.")
2949 set (_targetAddSCU FALSE)
2952 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2953 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2954 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2956 if (NOT DEFINED COTIREMSG_${_target})
2957 set (COTIREMSG_${_target} "")
2959 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2960 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2961 # cache message to avoid redundant messages on re-configure
2962 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2963 message (${_targetMsgLevel} "${_targetMsg}")
2966 list (LENGTH _targetLanguages _numberOfLanguages)
2967 if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles)
2968 set (${_wholeTargetVar} FALSE PARENT_SCOPE)
2970 set (${_wholeTargetVar} TRUE PARENT_SCOPE)
2972 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2975function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2976 set (_sourceFiles ${ARGN})
2977 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2978 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2979 if (DEFINED CMAKE_MATCH_2)
2980 set (_numberOfThreads "${CMAKE_MATCH_2}")
2982 set (_numberOfThreads "")
2984 if (NOT _numberOfThreads)
2985 # use all available cores
2986 ProcessorCount(_numberOfThreads)
2988 list (LENGTH _sourceFiles _numberOfSources)
2989 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2990 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2991 set (_maxIncludes 0)
2994 message (STATUS "${_target} unity source max includes: ${_maxIncludes}")
2996 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2999function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar)
3000 set (${_cmdsVar} "" PARENT_SCOPE)
3001 get_target_property(_targetSourceFiles ${_target} SOURCES)
3002 set (_sourceFiles "")
3003 set (_excludedSources "")
3004 set (_cotiredSources "")
3005 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
3006 if (NOT _sourceFiles AND NOT _cotiredSources)
3010 # check for user provided unity source file list
3011 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
3012 if (NOT _unitySourceFiles)
3013 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
3015 cotire_generate_target_script(
3016 ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles})
3017 # set up unity files for parallel compilation
3018 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
3019 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
3020 list (LENGTH _unityFiles _numberOfUnityFiles)
3021 if (_numberOfUnityFiles EQUAL 0)
3023 elseif (_numberOfUnityFiles GREATER 1)
3024 cotire_setup_unity_generation_commands(
3025 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
3027 # set up single unity file for prefix header generation
3028 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
3029 cotire_setup_unity_generation_commands(
3030 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles})
3031 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
3032 # set up prefix header
3034 # check for user provided prefix header files
3035 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3036 if (_prefixHeaderFiles)
3037 cotire_setup_prefix_generation_from_provided_command(
3038 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
3040 cotire_setup_prefix_generation_from_unity_command(
3041 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles})
3043 # check if selected language has enough sources at all
3044 list (LENGTH _sourceFiles _numberOfSources)
3045 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
3046 set (_targetUsePCH FALSE)
3048 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3051 cotire_make_pch_file_path(${_language} ${_target} _pchFile)
3053 # first file in _sourceFiles is passed as the host file
3054 cotire_setup_pch_file_compilation(
3055 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3056 cotire_setup_pch_file_inclusion(
3057 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3059 elseif (_prefixHeaderFiles)
3060 # user provided prefix header must be included unconditionally
3061 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles})
3064 # mark target as cotired for language
3065 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
3067 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
3068 if (_targetUsePCH AND _pchFile)
3069 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
3072 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
3075function (cotire_setup_clean_target _target)
3076 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
3077 if (NOT TARGET "${_cleanTargetName}")
3078 cotire_set_cmd_to_prologue(_cmds)
3079 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
3080 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
3081 add_custom_target(${_cleanTargetName}
3083 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3084 COMMENT "Cleaning up target ${_target} cotire generated files"
3086 cotire_init_target("${_cleanTargetName}")
3090function (cotire_setup_pch_target _languages _configurations _target)
3091 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
3092 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
3093 set (_dependsFiles "")
3094 foreach (_language ${_languages})
3095 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
3096 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
3097 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
3098 # MSVC, Intel and clang-cl only create precompiled header as a side effect
3099 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
3101 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
3103 list (APPEND _dependsFiles "${_dependsFile}")
3107 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
3108 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
3109 cotire_init_target("${_pchTargetName}")
3110 cotire_add_to_pch_all_target(${_pchTargetName})
3113 # for other generators, we add the "clean all" target to clean up the precompiled header
3114 cotire_setup_clean_all_target()
3118function (cotire_filter_object_libraries _target _objectLibrariesVar)
3119 set (_objectLibraries "")
3120 foreach (_source ${ARGN})
3121 if (_source MATCHES "^\\$<TARGET_OBJECTS:.+>$")
3122 list (APPEND _objectLibraries "${_source}")
3125 set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE)
3128function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar)
3129 get_target_property(_targetSourceFiles ${_target} SOURCES)
3130 set (_unityTargetSources ${_targetSourceFiles})
3131 foreach (_language ${_languages})
3132 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3134 # remove source files that are included in the unity source
3135 set (_sourceFiles "")
3136 set (_excludedSources "")
3137 set (_cotiredSources "")
3138 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
3139 if (_sourceFiles OR _cotiredSources)
3140 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
3142 # add unity source files instead
3143 list (APPEND _unityTargetSources ${_unityFiles})
3146 # handle object libraries which are part of the target's sources
3147 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3148 if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$")
3149 cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles})
3150 if (_objectLibraries)
3151 cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries})
3152 list (REMOVE_ITEM _unityTargetSources ${_objectLibraries})
3153 list (APPEND _unityTargetSources ${_unityObjectLibraries})
3156 set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE)
3159function (cotire_setup_unity_target_pch_usage _languages _target)
3160 foreach (_language ${_languages})
3161 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3163 get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3164 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
3165 if (_userPrefixFile AND _prefixFile)
3166 # user provided prefix header must be included unconditionally by unity sources
3167 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles})
3173function (cotire_setup_unity_build_target _languages _configurations _target)
3174 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3175 if (NOT _unityTargetName)
3176 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
3178 # determine unity target sub type
3179 get_target_property(_targetType ${_target} TYPE)
3180 if ("${_targetType}" STREQUAL "EXECUTABLE")
3181 set (_unityTargetSubType "")
3182 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
3183 set (_unityTargetSubType "${CMAKE_MATCH_1}")
3185 message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.")
3188 # determine unity target sources
3189 set (_unityTargetSources "")
3190 cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources)
3191 # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created
3192 set (CMAKE_AUTOMOC OFF)
3193 set (CMAKE_AUTOUIC OFF)
3194 set (CMAKE_AUTORCC OFF)
3196 message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
3198 # generate unity target
3199 if ("${_targetType}" STREQUAL "EXECUTABLE")
3200 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3202 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3204 # copy output location properties
3205 set (_outputDirProperties
3206 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
3207 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
3208 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
3209 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
3210 set (_setDefaultOutputDir TRUE)
3211 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3212 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3214 # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory
3215 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
3216 cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties})
3217 foreach (_property ${_properties})
3218 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
3220 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3221 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
3222 set (_setDefaultOutputDir FALSE)
3225 if (_setDefaultOutputDir)
3226 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3229 if (_setDefaultOutputDir)
3230 set_target_properties(${_unityTargetName} PROPERTIES
3231 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
3232 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
3233 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
3236 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3237 ${_outputDirProperties})
3240 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3241 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
3242 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
3243 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
3244 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
3245 PREFIX <CONFIG>_POSTFIX SUFFIX
3246 IMPORT_PREFIX IMPORT_SUFFIX)
3247 # copy compile stuff
3248 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3249 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
3250 COMPILE_FLAGS COMPILE_OPTIONS
3251 Fortran_FORMAT Fortran_MODULE_DIRECTORY
3253 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
3254 POSITION_INDEPENDENT_CODE
3255 C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER
3256 C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE
3257 C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN
3258 C_CLANG_TIDY CXX_CLANG_TIDY)
3259 # copy compile features
3260 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3261 C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED
3262 CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED
3264 # copy interface stuff
3265 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3266 COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN
3267 COMPATIBLE_INTERFACE_STRING
3268 INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS
3269 INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES
3270 INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
3271 INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED)
3273 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3274 BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR
3275 INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
3276 LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED
3277 LINK_FLAGS LINK_FLAGS_<CONFIG>
3278 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
3279 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
3280 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
3281 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
3282 NO_SONAME SOVERSION VERSION
3283 LINK_WHAT_YOU_USE BUILD_RPATH)
3285 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3286 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
3287 # copy Apple platform specific stuff
3288 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3289 BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR
3290 MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH
3291 OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST
3292 IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE)
3293 # copy Windows platform specific stuff
3294 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3296 COMPILE_PDB_NAME COMPILE_PDB_NAME_<CONFIG>
3297 COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
3298 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
3299 VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION
3300 VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE
3301 VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK
3302 VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION
3303 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
3304 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
3305 VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES
3306 WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS
3307 DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE
3308 VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY)
3309 # copy Android platform specific stuff
3310 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3311 ANDROID_API ANDROID_API_MIN ANDROID_GUI
3312 ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES
3313 ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR
3314 ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES
3315 ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH
3316 ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE)
3317 # copy CUDA platform specific stuff
3318 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3319 CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS
3320 CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED)
3321 # use output name from original target
3322 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
3323 if (NOT _targetOutputName)
3324 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
3326 # use export symbol from original target
3327 cotire_get_target_export_symbol("${_target}" _defineSymbol)
3329 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
3330 if ("${_targetType}" STREQUAL "EXECUTABLE")
3331 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
3334 # enable parallel compilation for MSVC
3335 if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
3336 list (LENGTH _unityTargetSources _numberOfUnityTargetSources)
3337 if (_numberOfUnityTargetSources GREATER 1)
3338 set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP")
3341 cotire_init_target(${_unityTargetName})
3342 cotire_add_to_unity_all_target(${_unityTargetName})
3343 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
3344endfunction(cotire_setup_unity_build_target)
3346function (cotire_target _target)
3348 set(_oneValueArgs "")
3349 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3350 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3351 if (NOT _option_LANGUAGES)
3352 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
3354 if (NOT _option_CONFIGURATIONS)
3355 cotire_get_configuration_types(_option_CONFIGURATIONS)
3357 # check if cotire can be applied to target at all
3358 cotire_is_target_supported(${_target} _isSupported)
3359 if (NOT _isSupported)
3360 get_target_property(_imported ${_target} IMPORTED)
3361 get_target_property(_targetType ${_target} TYPE)
3363 message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.")
3365 message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.")
3370 get_target_property(_aliasName ${_target} ALIASED_TARGET)
3373 message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.")
3375 set (_target ${_aliasName})
3377 # check if target needs to be cotired for build type
3378 # when using configuration types, the test is performed at build time
3379 cotire_init_cotire_target_properties(${_target})
3380 if (NOT CMAKE_CONFIGURATION_TYPES)
3381 if (CMAKE_BUILD_TYPE)
3382 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
3384 list (FIND _option_CONFIGURATIONS "None" _index)
3386 if (_index EQUAL -1)
3388 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
3393 # when not using configuration types, immediately create cotire intermediate dir
3394 if (NOT CMAKE_CONFIGURATION_TYPES)
3395 cotire_get_intermediate_dir(_baseDir)
3396 file (MAKE_DIRECTORY "${_baseDir}")
3398 # choose languages that apply to the target
3399 cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES})
3400 if (NOT _targetLanguages)
3404 foreach (_language ${_targetLanguages})
3405 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd)
3407 list (APPEND _cmds ${_cmd})
3410 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
3412 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3414 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3416 cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds})
3417 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3419 cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target})
3422 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
3423 if (_targetAddCleanTarget)
3424 cotire_setup_clean_target(${_target})
3426endfunction(cotire_target)
3428function (cotire_map_libraries _strategy _mappedLibrariesVar)
3429 set (_mappedLibraries "")
3430 foreach (_library ${ARGN})
3431 if (_library MATCHES "^\\$<LINK_ONLY:(.+)>$")
3432 set (_libraryName "${CMAKE_MATCH_1}")
3433 set (_linkOnly TRUE)
3434 set (_objectLibrary FALSE)
3435 elseif (_library MATCHES "^\\$<TARGET_OBJECTS:(.+)>$")
3436 set (_libraryName "${CMAKE_MATCH_1}")
3437 set (_linkOnly FALSE)
3438 set (_objectLibrary TRUE)
3440 set (_libraryName "${_library}")
3441 set (_linkOnly FALSE)
3442 set (_objectLibrary FALSE)
3444 if ("${_strategy}" MATCHES "COPY_UNITY")
3445 cotire_is_target_supported(${_libraryName} _isSupported)
3447 # use target's corresponding unity target, if available
3448 get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME)
3449 if (TARGET "${_libraryUnityTargetName}")
3451 list (APPEND _mappedLibraries "$<LINK_ONLY:${_libraryUnityTargetName}>")
3452 elseif (_objectLibrary)
3453 list (APPEND _mappedLibraries "$<TARGET_OBJECTS:${_libraryUnityTargetName}>")
3455 list (APPEND _mappedLibraries "${_libraryUnityTargetName}")
3458 list (APPEND _mappedLibraries "${_library}")
3461 list (APPEND _mappedLibraries "${_library}")
3464 list (APPEND _mappedLibraries "${_library}")
3467 list (REMOVE_DUPLICATES _mappedLibraries)
3468 set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE)
3471function (cotire_target_link_libraries _target)
3472 cotire_is_target_supported(${_target} _isSupported)
3473 if (NOT _isSupported)
3476 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3477 if (TARGET "${_unityTargetName}")
3478 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3480 message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}")
3482 if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$")
3483 get_target_property(_linkLibraries ${_target} LINK_LIBRARIES)
3485 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries})
3486 set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}")
3488 message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}")
3491 get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES)
3492 if (_interfaceLinkLibraries)
3493 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries})
3494 set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}")
3496 message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}")
3499 get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES)
3500 if (_manualDependencies)
3501 cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies})
3502 if (_unityManualDependencies)
3503 add_dependencies("${_unityTargetName}" ${_unityManualDependencies})
3508endfunction(cotire_target_link_libraries)
3510function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
3512 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
3514 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
3516 # filter files in intermediate directory
3517 set (_filesToRemove "")
3518 foreach (_file ${_cotireFiles})
3519 get_filename_component(_dir "${_file}" DIRECTORY)
3520 get_filename_component(_dirName "${_dir}" NAME)
3521 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
3522 list (APPEND _filesToRemove "${_file}")
3527 message (STATUS "cleaning up ${_filesToRemove}")
3529 file (REMOVE ${_filesToRemove})
3533function (cotire_init_target _targetName)
3534 if (COTIRE_TARGETS_FOLDER)
3535 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
3537 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE)
3539 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
3543function (cotire_add_to_pch_all_target _pchTargetName)
3544 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
3545 if (NOT TARGET "${_targetName}")
3546 add_custom_target("${_targetName}"
3547 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3549 cotire_init_target("${_targetName}")
3551 cotire_setup_clean_all_target()
3552 add_dependencies(${_targetName} ${_pchTargetName})
3555function (cotire_add_to_unity_all_target _unityTargetName)
3556 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
3557 if (NOT TARGET "${_targetName}")
3558 add_custom_target("${_targetName}"
3559 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3561 cotire_init_target("${_targetName}")
3563 cotire_setup_clean_all_target()
3564 add_dependencies(${_targetName} ${_unityTargetName})
3567function (cotire_setup_clean_all_target)
3568 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
3569 if (NOT TARGET "${_targetName}")
3570 cotire_set_cmd_to_prologue(_cmds)
3571 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
3572 add_custom_target(${_targetName}
3574 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3575 COMMENT "Cleaning up all cotire generated files"
3577 cotire_init_target("${_targetName}")
3583 set(_oneValueArgs "")
3584 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3585 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3586 set (_targets ${_option_UNPARSED_ARGUMENTS})
3587 foreach (_target ${_targets})
3588 if (TARGET ${_target})
3589 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS})
3591 message (WARNING "cotire: ${_target} is not a target.")
3594 foreach (_target ${_targets})
3595 if (TARGET ${_target})
3596 cotire_target_link_libraries(${_target})
3601if (CMAKE_SCRIPT_MODE_FILE)
3603 # cotire is being run in script mode
3604 # locate -P on command args
3605 set (COTIRE_ARGC -1)
3606 foreach (_index RANGE ${CMAKE_ARGC})
3607 if (COTIRE_ARGC GREATER -1)
3608 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
3609 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
3610 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
3615 # include target script if available
3616 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
3617 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
3618 include("${COTIRE_ARGV2}")
3622 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
3625 if (NOT COTIRE_BUILD_TYPE)
3626 set (COTIRE_BUILD_TYPE "None")
3628 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
3629 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
3630 set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}})
3631 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
3632 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
3633 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
3634 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
3635 if (_index GREATER -1)
3636 set (_sources ${COTIRE_TARGET_SOURCES})
3637 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
3640 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
3643 set (_sourcesDefinitions "")
3645 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
3646 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
3647 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
3648 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
3650 if ("${COTIRE_ARGV1}" STREQUAL "unity")
3653 # executing pre-build action under Xcode, check dependency on target script
3654 set (_dependsOption DEPENDS "${COTIRE_ARGV2}")
3656 # executing custom command, no need to re-check for dependencies
3657 set (_dependsOption "")
3660 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
3662 cotire_generate_unity_source(
3663 "${COTIRE_ARGV3}" ${_sources}
3664 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3665 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
3666 PRE_UNDEFS ${_targetPreUndefs}
3667 POST_UNDEFS ${_targetPostUndefs}
3668 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
3669 SOURCES_POST_UNDEFS ${_sourcesPostUndefs}
3672 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
3675 # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies
3676 set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS})
3678 # executing custom command, no need to re-check for dependencies
3679 set (_dependsOption "")
3683 foreach (_index RANGE 4 ${COTIRE_ARGC})
3684 if (COTIRE_ARGV${_index})
3685 list (APPEND _files "${COTIRE_ARGV${_index}}")
3689 cotire_generate_prefix_header(
3690 "${COTIRE_ARGV3}" ${_files}
3691 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3692 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3693 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3694 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3695 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3696 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3697 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
3698 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
3699 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
3700 INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH}
3701 INCLUDE_DIRECTORIES ${_includeDirs}
3702 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3703 COMPILE_DEFINITIONS ${_compileDefinitions}
3704 COMPILE_FLAGS ${_compileFlags}
3707 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
3710 foreach (_index RANGE 5 ${COTIRE_ARGC})
3711 if (COTIRE_ARGV${_index})
3712 list (APPEND _files "${COTIRE_ARGV${_index}}")
3716 cotire_precompile_prefix_header(
3717 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
3718 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3719 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3720 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3721 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3722 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3723 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3724 INCLUDE_DIRECTORIES ${_includeDirs}
3725 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3726 COMPILE_DEFINITIONS ${_compileDefinitions}
3727 COMPILE_FLAGS ${_compileFlags})
3729 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
3731 if (COTIRE_TARGET_LANGUAGE)
3732 set (_combinedFile "${COTIRE_ARGV3}")
3735 set (_combinedFile "${COTIRE_ARGV2}")
3739 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
3740 if (COTIRE_ARGV${_index})
3741 list (APPEND _files "${COTIRE_ARGV${_index}}")
3746 # executing pre-build action under Xcode, check dependency on files to be combined
3747 set (_dependsOption DEPENDS ${_files})
3749 # executing custom command, no need to re-check for dependencies
3750 set (_dependsOption "")
3753 if (COTIRE_TARGET_LANGUAGE)
3754 cotire_generate_unity_source(
3755 "${_combinedFile}" ${_files}
3756 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3759 cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption})
3762 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
3764 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
3767 message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".")
3772 # cotire is being run in include mode
3773 # set up all variable and property definitions
3775 if (NOT DEFINED COTIRE_DEBUG_INIT)
3776 if (DEFINED COTIRE_DEBUG)
3777 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
3779 set (COTIRE_DEBUG_INIT FALSE)
3782 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
3784 if (NOT DEFINED COTIRE_VERBOSE_INIT)
3785 if (DEFINED COTIRE_VERBOSE)
3786 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
3788 set (COTIRE_VERBOSE_INIT FALSE)
3791 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
3793 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
3794 "Ignore headers with the listed file extensions from the generated prefix header.")
3796 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
3797 "Ignore headers from these directories when generating the prefix header.")
3799 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
3800 "Ignore sources with the listed file extensions from the generated unity source.")
3802 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING
3803 "Minimum number of sources in target required to enable use of precompiled header.")
3805 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
3806 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
3807 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
3808 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
3809 # enable parallelization for generators that run multiple jobs by default
3810 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
3812 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
3815 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
3816 "Maximum number of source files to include in a single unity source file.")
3818 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
3819 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
3821 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
3822 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
3824 if (NOT COTIRE_INTDIR)
3825 set (COTIRE_INTDIR "cotire")
3827 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
3828 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
3830 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
3831 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
3833 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
3834 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
3836 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
3837 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
3839 if (NOT COTIRE_PCH_TARGET_SUFFIX)
3840 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
3843 # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code
3844 # use a bigger default factor of 170 percent (128 MB)
3845 if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR)
3846 set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170")
3849 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
3850 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
3852 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
3853 set (COTIRE_TARGETS_FOLDER "cotire")
3855 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
3856 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
3857 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
3858 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
3860 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
3864 # define cotire cache variables
3867 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
3868 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3870 "The variable can be set to a semicolon separated list of include directories."
3871 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3872 "If not defined, defaults to empty list."
3876 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
3877 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
3879 "The variable can be set to a semicolon separated list of file extensions."
3880 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
3881 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
3882 "If not defined, defaults to inc;inl;ipp."
3886 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
3887 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
3889 "The variable can be set to a semicolon separated list of file extensions."
3890 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
3891 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
3892 "If not defined, defaults to m;mm."
3896 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
3897 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
3899 "The variable can be set to an integer > 0."
3900 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
3901 "If not defined, defaults to 2."
3905 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
3906 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3908 "This may be set to an integer >= 0."
3909 "If 0, cotire will only create a single unity source file."
3910 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
3911 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
3912 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
3913 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3914 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
3917 # define cotire directory properties
3920 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
3921 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
3923 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
3927 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
3928 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
3930 "See target property COTIRE_ADD_UNITY_BUILD."
3934 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
3935 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
3937 "See target property COTIRE_ADD_CLEAN."
3941 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
3942 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3944 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
3948 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
3949 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3951 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
3955 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH"
3956 BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header."
3958 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH."
3962 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3963 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
3965 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
3969 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3970 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
3972 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
3976 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
3977 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3979 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3983 DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT"
3984 BRIEF_DOCS "Define strategy for setting up the unity target's link libraries."
3986 "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT."
3989 # define cotire target properties
3992 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
3993 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
3995 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
3996 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
3997 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
3998 "The target name will be set to this target's name with the suffix _pch appended."
3999 "Inherited from directory."
4004 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
4005 BRIEF_DOCS "Add a new target that performs a unity build for this target."
4007 "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."
4008 "Most of the relevant target properties will be copied from this target to the new unity build target."
4009 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
4010 "The unity target name will be set to this target's name with the suffix _unity appended."
4011 "Inherited from directory."
4016 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
4017 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
4019 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
4020 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
4021 "Inherited from directory."
4022 "Defaults to FALSE."
4026 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
4027 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
4029 "The property can be set to a list of directories."
4030 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
4031 "Inherited from directory."
4032 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
4036 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
4037 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
4039 "The property can be set to a list of directories."
4040 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
4041 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
4042 "the option which yields the closer relative path match wins."
4043 "Inherited from directory."
4044 "If not set, this property is initialized to the empty list."
4048 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED
4049 BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header."
4051 "The property can be set to a list of directories."
4052 "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header."
4053 "Header files are sorted according to the order of the directories in the property."
4054 "If not set, this property is initialized to the empty list."
4058 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
4059 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
4061 "This may be set to a semicolon-separated list of preprocessor symbols."
4062 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
4063 "Inherited from directory."
4064 "Defaults to empty string."
4068 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
4069 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
4071 "This may be set to a semicolon-separated list of preprocessor symbols."
4072 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
4073 "Inherited from directory."
4074 "Defaults to empty string."
4078 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
4079 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
4081 "This may be set to an integer > 0."
4082 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
4083 "If not set, cotire will only create a single unity source file."
4084 "Inherited from directory."
4085 "Defaults to empty."
4089 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
4090 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
4092 "If set, cotire will only add the given file(s) to the generated unity source file."
4093 "If not set, cotire will add all the target source files to the generated unity source file."
4094 "The property can be set to a user provided unity source file."
4095 "Defaults to empty."
4099 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
4100 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
4102 "If set, cotire will add the given header file(s) to the generated prefix header file."
4103 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
4104 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
4105 "Defaults to empty."
4109 TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED
4110 BRIEF_DOCS "Define strategy for setting up unity target's link libraries."
4112 "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually."
4113 "If this property is set to COPY, the unity target's link libraries will be copied from this target."
4114 "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."
4115 "Inherited from directory."
4116 "Defaults to empty."
4120 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
4121 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
4123 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
4124 "Defaults to empty string."
4128 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
4129 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
4131 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
4132 "Defaults to empty string."
4136 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
4137 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
4139 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
4140 "Defaults to empty string."
4144 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
4145 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
4147 "This property can be set to the desired name of the unity target that will be created by cotire."
4148 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
4149 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
4150 "Defaults to empty string."
4153 # define cotire source properties
4156 SOURCE PROPERTY "COTIRE_EXCLUDED"
4157 BRIEF_DOCS "Do not modify source file's build command."
4159 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
4160 "The source file will also be excluded from the generated unity source file."
4161 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
4162 "Defaults to FALSE."
4166 SOURCE PROPERTY "COTIRE_DEPENDENCY"
4167 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
4169 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
4170 "If the file is modified, cotire will re-generate the prefix header source upon build."
4171 "Defaults to FALSE."
4175 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
4176 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
4178 "This may be set to a semicolon-separated list of preprocessor symbols."
4179 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
4180 "Defaults to empty string."
4184 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
4185 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
4187 "This may be set to a semicolon-separated list of preprocessor symbols."
4188 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
4189 "Defaults to empty string."
4193 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
4194 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
4196 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
4197 "The new unity source file will include this source file as the first one."
4198 "This property essentially works as a separator for unity source files."
4199 "Defaults to FALSE."
4203 SOURCE PROPERTY "COTIRE_TARGET"
4204 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
4206 "cotire sets this property to the name of target, that the source file's build command has been altered for."
4207 "Defaults to empty string."
4210 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")