1 # - cotire (compile time reducer)
3 # See the cotire manual for usage hints.
5 #=============================================================================
6 # Copyright 2012-2013 Sascha Kratky
8 # Permission is hereby granted, free of charge, to any person
9 # obtaining a copy of this software and associated documentation
10 # files (the "Software"), to deal in the Software without
11 # restriction, including without limitation the rights to use,
12 # copy, modify, merge, publish, distribute, sublicense, and/or sell
13 # copies of the Software, and to permit persons to whom the
14 # Software is furnished to do so, subject to the following
17 # The above copyright notice and this permission notice shall be
18 # included in all copies or substantial portions of the Software.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 # OTHER DEALINGS IN THE SOFTWARE.
28 #=============================================================================
33 set(__COTIRE_INCLUDED TRUE)
35 # call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode
36 # cmake_minimum_required also sets the policy version as a side effect, which we have to avoid
37 if (NOT CMAKE_SCRIPT_MODE_FILE)
40 # we need the CMake variables CMAKE_SCRIPT_MODE_FILE and CMAKE_ARGV available since 2.8.5
41 # we need APPEND_STRING option for set_property available since 2.8.6
42 cmake_minimum_required(VERSION 2.8.6)
43 if (NOT CMAKE_SCRIPT_MODE_FILE)
47 set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
48 set (COTIRE_CMAKE_MODULE_VERSION "1.4.1")
50 include(CMakeParseArguments)
51 include(ProcessorCount)
53 function (cotire_determine_compiler_version _language _versionPrefix)
54 if (NOT ${_versionPrefix}_VERSION)
55 # use CMake's predefined compiler version variable (available since CMake 2.8.8)
56 if (DEFINED CMAKE_${_language}_COMPILER_VERSION)
57 set (${_versionPrefix}_VERSION "${CMAKE_${_language}_COMPILER_VERSION}")
59 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
60 unset (ENV{VS_UNICODE_OUTPUT})
61 string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1)
62 execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1}
63 ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10)
64 string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}")
66 # assume GCC like command line interface
67 string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1)
68 execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion"
69 OUTPUT_VARIABLE ${_versionPrefix}_VERSION
70 RESULT_VARIABLE _result
71 OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10)
73 set (${_versionPrefix}_VERSION "")
76 if (${_versionPrefix}_VERSION)
77 set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" CACHE INTERNAL "${_language} compiler version")
79 set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" PARENT_SCOPE)
81 message (STATUS "${CMAKE_${_language}_COMPILER} version ${${_versionPrefix}_VERSION}")
86 function (cotire_get_source_file_extension _sourceFile _extVar)
87 # get_filename_component returns extension from first occurrence of . in file name
88 # this function computes the extension from last occurrence of . in file name
89 string (FIND "${_sourceFile}" "." _index REVERSE)
90 if (_index GREATER -1)
91 math (EXPR _index "${_index} + 1")
92 string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
96 set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
99 macro (cotire_check_is_path_relative_to _path _isRelativeVar)
100 set (${_isRelativeVar} FALSE)
101 if (IS_ABSOLUTE "${_path}")
102 foreach (_dir ${ARGN})
103 file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
104 if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
105 set (${_isRelativeVar} TRUE)
112 function (cotire_filter_language_source_files _language _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
113 set (_sourceFiles "")
114 set (_excludedSourceFiles "")
115 set (_cotiredSourceFiles "")
116 if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
117 set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
119 set (_languageExtensions "")
121 if (CMAKE_${_language}_IGNORE_EXTENSIONS)
122 set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}")
124 set (_ignoreExtensions "")
126 if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS)
127 set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}")
129 set (_excludeExtensions "")
132 message (STATUS "${_language} source file extensions: ${_languageExtensions}")
133 message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}")
134 message (STATUS "${_language} exclude extensions: ${_excludeExtensions}")
136 foreach (_sourceFile ${ARGN})
137 get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY)
138 get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT)
139 get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC)
140 get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE)
141 set (_sourceIsFiltered FALSE)
142 if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic)
143 cotire_get_source_file_extension("${_sourceFile}" _sourceExt)
145 list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex)
146 if (_ignoreIndex LESS 0)
147 list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex)
148 if (_excludeIndex GREATER -1)
149 list (APPEND _excludedSourceFiles "${_sourceFile}")
151 list (FIND _languageExtensions "${_sourceExt}" _sourceIndex)
152 if (_sourceIndex GREATER -1)
153 set (_sourceIsFiltered TRUE)
154 elseif ("${_sourceLanguage}" STREQUAL "${_language}")
155 # add to excluded sources, if file is not ignored and has correct language without having the correct extension
156 list (APPEND _excludedSourceFiles "${_sourceFile}")
163 message (STATUS "${_sourceFile} filtered=${_sourceIsFiltered} language=${_sourceLanguage} header=${_sourceIsHeaderOnly}")
165 if (_sourceIsFiltered)
166 get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED)
167 get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET)
168 get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS)
170 message (STATUS "${_sourceFile} excluded=${_sourceIsExcluded} cotired=${_sourceIsCotired}")
172 if (_sourceIsCotired)
173 list (APPEND _cotiredSourceFiles "${_sourceFile}")
174 elseif (_sourceIsExcluded OR _sourceCompileFlags)
175 list (APPEND _excludedSourceFiles "${_sourceFile}")
177 list (APPEND _sourceFiles "${_sourceFile}")
182 message (STATUS "All: ${ARGN}")
183 message (STATUS "${_language}: ${_sourceFiles}")
184 message (STATUS "Excluded: ${_excludedSourceFiles}")
185 message (STATUS "Cotired: ${_cotiredSourceFiles}")
187 set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE)
188 set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE)
189 set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE)
192 function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
193 set (_filteredObjects "")
194 foreach (_object ${ARGN})
195 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
197 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
199 list (APPEND _filteredObjects "${_object}")
203 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
206 function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
207 set (_filteredObjects "")
208 foreach (_object ${ARGN})
209 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
211 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
212 if (NOT _propertyValue)
213 list (APPEND _filteredObjects "${_object}")
217 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
220 function (cotire_get_source_file_property_values _valuesVar _property)
222 foreach (_sourceFile ${ARGN})
223 get_source_file_property(_propertyValue "${_sourceFile}" ${_property})
225 list (APPEND _values "${_propertyValue}")
228 set (${_valuesVar} ${_values} PARENT_SCOPE)
231 function (cotrie_resolve_config_properites _configurations _propertiesVar)
233 foreach (_property ${ARGN})
234 if ("${_property}" MATCHES "<CONFIG>")
235 foreach (_config ${_configurations})
236 string (TOUPPER "${_config}" _upperConfig)
237 string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}")
238 list (APPEND _properties ${_configProperty})
241 list (APPEND _properties ${_property})
244 set (${_propertiesVar} ${_properties} PARENT_SCOPE)
247 function (cotrie_copy_set_properites _configurations _type _source _target)
248 cotrie_resolve_config_properites("${_configurations}" _properties ${ARGN})
249 foreach (_property ${_properties})
250 get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
252 get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
253 set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
258 function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar)
259 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
260 set (_flagPrefix "[/-]")
262 set (_flagPrefix "--?")
265 set (_matchedOptions "")
266 set (_unmatchedOptions "")
267 foreach (_compileFlag ${ARGN})
269 if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}")
270 # option with separate argument
271 list (APPEND _matchedOptions "${_compileFlag}")
273 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$")
275 set (_optionFlag "${CMAKE_MATCH_2}")
276 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$")
277 # option with joined argument
278 list (APPEND _matchedOptions "${CMAKE_MATCH_3}")
281 # flush remembered option
283 list (APPEND _matchedOptions "${_optionFlag}")
286 # add to unfiltered options
287 list (APPEND _unmatchedOptions "${_compileFlag}")
292 list (APPEND _matchedOptions "${_optionFlag}")
295 message (STATUS "Filter ${_flagFilter}")
297 message (STATUS "Matched ${_matchedOptions}")
299 if (_unmatchedOptions)
300 message (STATUS "Unmatched ${_unmatchedOptions}")
303 set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE)
304 set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE)
307 function (cotire_get_target_compile_flags _config _language _directory _target _flagsVar)
308 string (TOUPPER "${_config}" _upperConfig)
309 # collect options from CMake language variables
310 set (_compileFlags "")
311 if (CMAKE_${_language}_FLAGS)
312 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
314 if (CMAKE_${_language}_FLAGS_${_upperConfig})
315 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}")
318 # add option from CMake target type variable
319 get_target_property(_targetType ${_target} TYPE)
321 # handle POSITION_INDEPENDENT_CODE property introduced with CMake 2.8.9 if policy CMP0018 is turned on
322 cmake_policy(GET CMP0018 _PIC_Policy)
324 # default to old behavior
325 set (_PIC_Policy "OLD")
328 message(STATUS "CMP0018=${_PIC_Policy}")
330 if (_PIC_Policy STREQUAL "NEW")
331 # NEW behavior: honor the POSITION_INDEPENDENT_CODE target property
332 get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE)
334 if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE)
335 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIE}")
336 elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC)
337 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIC}")
341 # OLD behavior or policy not set: use the value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS
342 if (_targetType STREQUAL "MODULE_LIBRARY")
343 # flags variable for module library uses different name SHARED_MODULE
344 # (e.g., CMAKE_SHARED_MODULE_C_FLAGS)
345 set (_targetType SHARED_MODULE)
347 if (CMAKE_${_targetType}_${_language}_FLAGS)
348 set (_compileFlags "${_compileFlags} ${CMAKE_${_targetType}_${_language}_FLAGS}")
353 # add_definitions may have been used to add flags to the compiler command
354 get_directory_property(_dirDefinitions DIRECTORY "${_directory}" DEFINITIONS)
356 set (_compileFlags "${_compileFlags} ${_dirDefinitions}")
360 # add target compile options
361 get_target_property(_targetflags ${_target} COMPILE_FLAGS)
363 set (_compileFlags "${_compileFlags} ${_targetflags}")
367 separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}")
369 separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}")
371 separate_arguments(_compileFlags)
373 # platform specific flags
375 get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig})
376 if (NOT _architectures)
377 get_target_property(_architectures ${_target} OSX_ARCHITECTURES)
379 foreach (_arch ${_architectures})
380 list (APPEND _compileFlags "-arch" "${_arch}")
382 if (CMAKE_OSX_SYSROOT AND CMAKE_OSX_SYSROOT_DEFAULT AND CMAKE_${_language}_HAS_ISYSROOT)
383 if (NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "${CMAKE_OSX_SYSROOT_DEFAULT}")
384 list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}")
387 if (CMAKE_OSX_DEPLOYMENT_TARGET AND CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG)
388 list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
391 if (COTIRE_DEBUG AND _compileFlags)
392 message (STATUS "Target ${_target} compile flags ${_compileFlags}")
394 set (${_flagsVar} ${_compileFlags} PARENT_SCOPE)
397 function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar)
398 set (_includeDirs "")
399 # default include dirs
400 if (CMAKE_INCLUDE_CURRENT_DIR)
401 list (APPEND _includeDirs "${_targetBinaryDir}")
402 list (APPEND _includeDirs "${_targetSourceDir}")
404 # parse additional include directories from target compile flags
405 set (_targetFlags "")
406 cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags)
407 cotire_filter_compile_flags("${_language}" "I" _dirs _ignore ${_targetFlags})
409 list (APPEND _includeDirs ${_dirs})
411 # target include directories
412 get_directory_property(_dirs DIRECTORY "${_targetSourceDir}" INCLUDE_DIRECTORIES)
414 get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES)
416 list (APPEND _dirs ${_targetDirs})
417 list (REMOVE_DUPLICATES _dirs)
420 list (LENGTH _includeDirs _projectInsertIndex)
421 foreach (_dir ${_dirs})
422 if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE)
423 cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
425 list (LENGTH _includeDirs _len)
426 if (_len EQUAL _projectInsertIndex)
427 list (APPEND _includeDirs "${_dir}")
429 list (INSERT _includeDirs _projectInsertIndex "${_dir}")
431 math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1")
433 list (APPEND _includeDirs "${_dir}")
436 list (APPEND _includeDirs "${_dir}")
439 list (REMOVE_DUPLICATES _includeDirs)
440 if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES)
441 list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES})
443 if (COTIRE_DEBUG AND _includeDirs)
444 message (STATUS "Target ${_target} include dirs ${_includeDirs}")
446 set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE)
449 macro (cotire_make_C_identifier _identifierVar _str)
450 # mimic CMake SystemTools::MakeCindentifier behavior
451 if ("${_str}" MATCHES "^[0-9].+$")
454 string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}")
457 function (cotire_get_target_export_symbol _target _exportSymbolVar)
458 set (_exportSymbol "")
459 get_target_property(_targetType ${_target} TYPE)
460 get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
461 if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
462 (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
463 get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
464 if (NOT _exportSymbol)
465 set (_exportSymbol "${_target}_EXPORTS")
467 cotire_make_C_identifier(_exportSymbol "${_exportSymbol}")
469 set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
472 function (cotire_get_target_compile_definitions _config _language _directory _target _definitionsVar)
473 string (TOUPPER "${_config}" _upperConfig)
474 set (_configDefinitions "")
475 # CMAKE_INTDIR for multi-configuration build systems
476 if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
477 list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
479 # target export define symbol
480 cotire_get_target_export_symbol("${_target}" _defineSymbol)
482 list (APPEND _configDefinitions "${_defineSymbol}")
484 # directory compile definitions
485 get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS)
487 list (APPEND _configDefinitions ${_definitions})
489 get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS_${_upperConfig})
491 list (APPEND _configDefinitions ${_definitions})
493 # target compile definitions
494 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS)
496 list (APPEND _configDefinitions ${_definitions})
498 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig})
500 list (APPEND _configDefinitions ${_definitions})
502 # parse additional compile definitions from target compile flags
503 # and don't look at directory compile definitions, which we already handled
504 set (_targetFlags "")
505 cotire_get_target_compile_flags("${_config}" "${_language}" "" "${_target}" _targetFlags)
506 cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags})
508 list (APPEND _configDefinitions ${_definitions})
510 list (REMOVE_DUPLICATES _configDefinitions)
511 if (COTIRE_DEBUG AND _configDefinitions)
512 message (STATUS "Target ${_target} compile definitions ${_configDefinitions}")
514 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
517 function (cotire_get_target_compiler_flags _config _language _directory _target _compilerFlagsVar)
518 # parse target compile flags omitting compile definitions and include directives
519 set (_targetFlags "")
520 cotire_get_target_compile_flags("${_config}" "${_language}" "${_directory}" "${_target}" _targetFlags)
521 set (_compilerFlags "")
522 cotire_filter_compile_flags("${_language}" "[ID]" _ignore _compilerFlags ${_targetFlags})
523 if (COTIRE_DEBUG AND _compilerFlags)
524 message (STATUS "Target ${_target} compiler flags ${_compilerFlags}")
526 set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE)
529 function (cotire_add_sys_root_paths _pathsVar)
531 if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT)
532 foreach (_path IN LISTS ${_pathsVar})
533 if (IS_ABSOLUTE "${_path}")
534 get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE)
535 if (EXISTS "${_path}")
536 list (APPEND ${_pathsVar} "${_path}")
542 set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE)
544 message (STATUS "${_pathsVar}=${${_pathsVar}}")
548 function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar)
549 set (_extraProperties ${ARGN})
551 if (_extraProperties)
552 list (FIND _extraProperties "${_sourceFile}" _index)
553 if (_index GREATER -1)
554 math (EXPR _index "${_index} + 1")
555 list (LENGTH _extraProperties _len)
556 math (EXPR _len "${_len} - 1")
557 foreach (_index RANGE ${_index} ${_len})
558 list (GET _extraProperties ${_index} _value)
559 if ("${_value}" MATCHES "${_pattern}")
560 list (APPEND _result "${_value}")
567 set (${_resultVar} ${_result} PARENT_SCOPE)
570 function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
571 set (_compileDefinitions "")
572 if (NOT CMAKE_SCRIPT_MODE_FILE)
573 string (TOUPPER "${_config}" _upperConfig)
574 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
576 list (APPEND _compileDefinitions ${_definitions})
578 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig})
580 list (APPEND _compileDefinitions ${_definitions})
583 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN})
585 list (APPEND _compileDefinitions ${_definitions})
587 if (COTIRE_DEBUG AND _compileDefinitions)
588 message (STATUS "Source ${_sourceFile} compile definitions ${_compileDefinitions}")
590 set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE)
593 function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
594 set (_configDefinitions "")
595 foreach (_sourceFile ${ARGN})
596 cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
597 if (_sourceDefinitions)
598 list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
601 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
604 function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
605 set (_sourceUndefs "")
606 if (NOT CMAKE_SCRIPT_MODE_FILE)
607 get_source_file_property(_undefs "${_sourceFile}" ${_property})
609 list (APPEND _sourceUndefs ${_undefs})
612 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN})
614 list (APPEND _sourceUndefs ${_undefs})
616 if (COTIRE_DEBUG AND _sourceUndefs)
617 message (STATUS "Source ${_sourceFile} ${_property} undefs ${_sourceUndefs}")
619 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
622 function (cotire_get_source_files_undefs _property _sourceUndefsVar)
623 set (_sourceUndefs "")
624 foreach (_sourceFile ${ARGN})
625 cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs)
627 list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-")
630 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
633 macro (cotire_set_cmd_to_prologue _cmdVar)
634 set (${_cmdVar} "${CMAKE_COMMAND}")
636 list (APPEND ${_cmdVar} "--warn-uninitialized")
638 list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>")
640 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON")
641 elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles")
642 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)")
646 function (cotire_init_compile_cmd _cmdVar _language _compilerExe _compilerArg1)
647 if (NOT _compilerExe)
648 set (_compilerExe "${CMAKE_${_language}_COMPILER}")
650 if (NOT _compilerArg1)
651 set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1})
653 string (STRIP "${_compilerArg1}" _compilerArg1)
654 set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
657 macro (cotire_add_definitions_to_cmd _cmdVar _language)
658 foreach (_definition ${ARGN})
659 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
660 list (APPEND ${_cmdVar} "/D${_definition}")
662 list (APPEND ${_cmdVar} "-D${_definition}")
667 macro (cotire_add_includes_to_cmd _cmdVar _language)
668 foreach (_include ${ARGN})
669 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
670 file (TO_NATIVE_PATH "${_include}" _include)
671 list (APPEND ${_cmdVar} "/I${_include}")
673 list (APPEND ${_cmdVar} "-I${_include}")
678 macro (cotire_add_compile_flags_to_cmd _cmdVar)
679 foreach (_flag ${ARGN})
680 list (APPEND ${_cmdVar} "${_flag}")
684 function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
685 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
686 set (_triggerFile "")
687 foreach (_dependencyFile ${ARGN})
688 if (EXISTS "${_dependencyFile}" AND "${_dependencyFile}" IS_NEWER_THAN "${_file}")
689 set (_triggerFile "${_dependencyFile}")
693 get_filename_component(_fileName "${_file}" NAME)
694 if (EXISTS "${_file}")
697 message (STATUS "${_fileName} update triggered by ${_triggerFile} change.")
701 message (STATUS "${_fileName} is up-to-date.")
703 set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE)
707 message (STATUS "${_fileName} does not exist yet.")
712 macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
713 set (${_relPathVar} "")
714 foreach (_includeDir ${_includeDirs})
715 if (IS_DIRECTORY "${_includeDir}")
716 file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
717 if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
718 string (LENGTH "${${_relPathVar}}" _closestLen)
719 string (LENGTH "${_relPath}" _relLen)
720 if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
721 set (${_relPathVar} "${_relPath}")
724 elseif ("${_includeDir}" STREQUAL "${_headerFile}")
725 # if path matches exactly, return short non-empty string
726 set (${_relPathVar} "1")
732 macro (cotire_check_header_file_location _headerFile _insideIncudeDirs _outsideIncudeDirs _headerIsInside)
733 # check header path against ignored and honored include directories
734 cotire_find_closest_relative_path("${_headerFile}" "${_insideIncudeDirs}" _insideRelPath)
736 # header is inside, but could be become outside if there is a shorter outside match
737 cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncudeDirs}" _outsideRelPath)
739 string (LENGTH "${_insideRelPath}" _insideRelPathLen)
740 string (LENGTH "${_outsideRelPath}" _outsideRelPathLen)
741 if (_outsideRelPathLen LESS _insideRelPathLen)
742 set (${_headerIsInside} FALSE)
744 set (${_headerIsInside} TRUE)
747 set (${_headerIsInside} TRUE)
751 set (${_headerIsInside} FALSE)
755 macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
756 if (NOT EXISTS "${_headerFile}")
757 set (${_headerIsIgnoredVar} TRUE)
758 elseif (IS_DIRECTORY "${_headerFile}")
759 set (${_headerIsIgnoredVar} TRUE)
760 elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$")
761 # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path
762 # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
763 # with the error message "error: no include path in which to search for header.h"
764 set (${_headerIsIgnoredVar} TRUE)
766 set (${_headerIsIgnoredVar} FALSE)
770 macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
771 # check header file extension
772 cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
773 set (${_headerIsIgnoredVar} FALSE)
775 list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
776 if (_index GREATER -1)
777 set (${_headerIsIgnoredVar} TRUE)
782 macro (cotire_parse_line _line _headerFileVar _headerDepthVar)
784 # cl.exe /showIncludes output looks different depending on the language pack used, e.g.:
785 # English: "Note: including file: C:\directory\file"
786 # German: "Hinweis: Einlesen der Datei: C:\directory\file"
787 # We use a very general regular expression, relying on the presence of the : characters
788 if ("${_line}" MATCHES ":( +)([^:]+:[^:]+)$")
789 # Visual Studio compiler output
790 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
791 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE)
793 set (${_headerFileVar} "")
794 set (${_headerDepthVar} 0)
797 if ("${_line}" MATCHES "^(\\.+) (.*)$")
799 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
800 if (IS_ABSOLUTE "${CMAKE_MATCH_2}")
801 set (${_headerFileVar} "${CMAKE_MATCH_2}")
803 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH)
806 set (${_headerFileVar} "")
807 set (${_headerDepthVar} 0)
812 function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honoredIncudeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar)
814 # prevent CMake macro invocation errors due to backslash characters in Windows paths
815 string (REPLACE "\\" "/" _scanOutput "${_scanOutput}")
818 string (REPLACE "//" "/" _scanOutput "${_scanOutput}")
819 # prevent semicolon from being interpreted as a line separator
820 string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}")
821 # then separate lines
822 string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}")
823 list (LENGTH _scanOutput _len)
824 # remove duplicate lines to speed up parsing
825 list (REMOVE_DUPLICATES _scanOutput)
826 list (LENGTH _scanOutput _uniqueLen)
828 message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes")
829 if (_ignoredExtensions)
830 message (STATUS "Ignored extensions: ${_ignoredExtensions}")
832 if (_ignoredIncudeDirs)
833 message (STATUS "Ignored paths: ${_ignoredIncudeDirs}")
835 if (_honoredIncudeDirs)
836 message (STATUS "Included paths: ${_honoredIncudeDirs}")
839 set (_sourceFiles ${ARGN})
840 set (_selectedIncludes "")
841 set (_unparsedLines "")
842 # stack keeps track of inside/outside project status of processed header files
843 set (_headerIsInsideStack "")
844 foreach (_line IN LISTS _scanOutput)
846 cotire_parse_line("${_line}" _headerFile _headerDepth)
848 cotire_check_header_file_location("${_headerFile}" "${_ignoredIncudeDirs}" "${_honoredIncudeDirs}" _headerIsInside)
850 message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}")
853 list (LENGTH _headerIsInsideStack _stackLen)
854 if (_headerDepth GREATER _stackLen)
855 math (EXPR _stackLen "${_stackLen} + 1")
856 foreach (_index RANGE ${_stackLen} ${_headerDepth})
857 list (APPEND _headerIsInsideStack ${_headerIsInside})
860 foreach (_index RANGE ${_headerDepth} ${_stackLen})
861 list (REMOVE_AT _headerIsInsideStack -1)
863 list (APPEND _headerIsInsideStack ${_headerIsInside})
866 message (STATUS "${_headerIsInsideStack}")
868 # header is a candidate if it is outside project
869 if (NOT _headerIsInside)
870 # get parent header file's inside/outside status
871 if (_headerDepth GREATER 1)
872 math (EXPR _index "${_headerDepth} - 2")
873 list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside)
875 set (_parentHeaderIsInside TRUE)
877 # select header file if parent header file is inside project
878 # (e.g., a project header file that includes a standard header file)
879 if (_parentHeaderIsInside)
880 cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored)
881 if (NOT _headerIsIgnored)
882 cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored)
883 if (NOT _headerIsIgnored)
884 list (APPEND _selectedIncludes "${_headerFile}")
886 # fix header's inside status on stack, it is ignored by extension now
887 list (REMOVE_AT _headerIsInsideStack -1)
888 list (APPEND _headerIsInsideStack TRUE)
892 message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}")
898 # for cl.exe do not keep unparsed lines which solely consist of a source file name
899 string (FIND "${_sourceFiles}" "${_line}" _index)
901 list (APPEND _unparsedLines "${_line}")
904 list (APPEND _unparsedLines "${_line}")
909 list (REMOVE_DUPLICATES _selectedIncludes)
910 set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE)
911 set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE)
914 function (cotire_scan_includes _includesVar)
916 set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION LANGUAGE UNPARSED_LINES)
917 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS)
918 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
919 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
920 if (NOT _option_LANGUAGE)
921 set (_option_LANGUAGE "CXX")
923 if (NOT _option_COMPILER_ID)
924 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
926 set (_cmd "${_option_COMPILER_EXECUTABLE}" ${_option_COMPILER_ARG1})
927 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
928 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
929 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
930 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES})
931 cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd)
932 # only consider existing source files for scanning
933 set (_existingSourceFiles "")
934 foreach (_sourceFile ${_sourceFiles})
935 if (EXISTS "${_sourceFile}")
936 list (APPEND _existingSourceFiles "${_sourceFile}")
939 if (NOT _existingSourceFiles)
940 set (${_includesVar} "" PARENT_SCOPE)
943 list (APPEND _cmd ${_existingSourceFiles})
945 message (STATUS "execute_process: ${_cmd}")
947 if (_option_COMPILER_ID MATCHES "MSVC")
949 message (STATUS "clearing VS_UNICODE_OUTPUT")
951 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
952 unset (ENV{VS_UNICODE_OUTPUT})
954 execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
955 RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output)
957 message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.")
959 cotire_parse_includes(
960 "${_option_LANGUAGE}" "${_output}"
961 "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}"
962 "${_option_IGNORE_EXTENSIONS}"
963 _includes _unparsedLines
965 set (${_includesVar} ${_includes} PARENT_SCOPE)
966 if (_option_UNPARSED_LINES)
967 set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE)
971 macro (cotire_append_undefs _contentsVar)
972 set (_undefs ${ARGN})
974 list (REMOVE_DUPLICATES _undefs)
975 foreach (_definition ${_undefs})
976 list (APPEND ${_contentsVar} "#undef ${_definition}")
981 macro (cotire_comment_str _language _commentText _commentVar)
982 if ("${_language}" STREQUAL "CMAKE")
983 set (${_commentVar} "# ${_commentText}")
985 set (${_commentVar} "/* ${_commentText} */")
989 function (cotire_write_file _language _file _contents _force)
990 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
991 cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
992 cotire_comment_str("${_language}" "${_file}" _header2)
993 set (_contents "${_header1}\n${_header2}\n${_contents}")
995 message (STATUS "${_contents}")
997 if (_force OR NOT EXISTS "${_file}")
998 file (WRITE "${_file}" "${_contents}")
1000 file (READ "${_file}" _oldContents)
1001 if (NOT "${_oldContents}" STREQUAL "${_contents}")
1002 file (WRITE "${_file}" "${_contents}")
1005 message (STATUS "${_file} unchanged")
1011 function (cotire_generate_unity_source _unityFile)
1013 set(_oneValueArgs LANGUAGE)
1015 DEPENDS SOURCES_COMPILE_DEFINITIONS
1016 PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE)
1017 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1018 if (_option_DEPENDS)
1019 cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS})
1020 if (_unityFileIsUpToDate)
1024 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1025 if (NOT _option_PRE_UNDEFS)
1026 set (_option_PRE_UNDEFS "")
1028 if (NOT _option_SOURCES_PRE_UNDEFS)
1029 set (_option_SOURCES_PRE_UNDEFS "")
1031 if (NOT _option_POST_UNDEFS)
1032 set (_option_POST_UNDEFS "")
1034 if (NOT _option_SOURCES_POST_UNDEFS)
1035 set (_option_SOURCES_POST_UNDEFS "")
1038 if (_option_PROLOGUE)
1039 list (APPEND _contents ${_option_PROLOGUE})
1041 if (_option_LANGUAGE AND _sourceFiles)
1042 if ("${_option_LANGUAGE}" STREQUAL "CXX")
1043 list (APPEND _contents "#ifdef __cplusplus")
1044 elseif ("${_option_LANGUAGE}" STREQUAL "C")
1045 list (APPEND _contents "#ifndef __cplusplus")
1048 set (_compileUndefinitions "")
1049 foreach (_sourceFile ${_sourceFiles})
1050 cotire_get_source_compile_definitions(
1051 "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions
1052 ${_option_SOURCES_COMPILE_DEFINITIONS})
1053 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS})
1054 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS})
1055 if (_option_PRE_UNDEFS)
1056 list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS})
1058 if (_sourcePreUndefs)
1059 list (APPEND _compileUndefinitions ${_sourcePreUndefs})
1061 if (_compileUndefinitions)
1062 cotire_append_undefs(_contents ${_compileUndefinitions})
1063 set (_compileUndefinitions "")
1065 if (_sourcePostUndefs)
1066 list (APPEND _compileUndefinitions ${_sourcePostUndefs})
1068 if (_option_POST_UNDEFS)
1069 list (APPEND _compileUndefinitions ${_option_POST_UNDEFS})
1071 foreach (_definition ${_compileDefinitions})
1072 if ("${_definition}" MATCHES "^([a-zA-Z0-9_]+)=(.+)$")
1073 list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}")
1074 list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}")
1076 list (APPEND _contents "#define ${_definition}")
1077 list (INSERT _compileUndefinitions 0 "${_definition}")
1080 get_filename_component(_sourceFile "${_sourceFile}" ABSOLUTE)
1082 file (TO_NATIVE_PATH "${_sourceFile}" _sourceFile)
1084 list (APPEND _contents "#include \"${_sourceFile}\"")
1086 if (_compileUndefinitions)
1087 cotire_append_undefs(_contents ${_compileUndefinitions})
1088 set (_compileUndefinitions "")
1090 if (_option_LANGUAGE AND _sourceFiles)
1091 list (APPEND _contents "#endif")
1093 if (_option_EPILOGUE)
1094 list (APPEND _contents ${_option_EPILOGUE})
1096 list (APPEND _contents "")
1097 string (REPLACE ";" "\n" _contents "${_contents}")
1099 message ("${_contents}")
1101 cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE)
1104 function (cotire_generate_prefix_header _prefixFile)
1106 set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION)
1107 set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS
1108 INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS)
1109 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1110 if (_option_DEPENDS)
1111 cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS})
1112 if (_prefixFileIsUpToDate)
1117 if (_option_COMPILER_ID MATCHES "Intel")
1118 # Intel compiler requires hdrstop pragma to stop generating PCH file
1119 set (_epilogue "#pragma hdrstop")
1121 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1122 cotire_scan_includes(_selectedHeaders ${_sourceFiles}
1123 LANGUAGE "${_option_LANGUAGE}"
1124 COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}"
1125 COMPILER_ID "${_option_COMPILER_ID}"
1126 COMPILER_VERSION "${_option_COMPILER_VERSION}"
1127 COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS}
1128 COMPILE_FLAGS ${_option_COMPILE_FLAGS}
1129 INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES}
1130 IGNORE_PATH ${_option_IGNORE_PATH}
1131 INCLUDE_PATH ${_option_INCLUDE_PATH}
1132 IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS}
1133 UNPARSED_LINES _unparsedLines)
1134 cotire_generate_unity_source("${_prefixFile}" EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders})
1135 set (_unparsedLinesFile "${_prefixFile}.log")
1137 if (COTIRE_VERBOSE OR NOT _selectedHeaders)
1138 list (LENGTH _unparsedLines _skippedLineCount)
1139 file (RELATIVE_PATH _unparsedLinesFileRelPath "${CMAKE_BINARY_DIR}" "${_unparsedLinesFile}")
1140 message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFileRelPath}")
1142 string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}")
1144 file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n")
1147 function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
1148 set (_flags ${${_flagsVar}})
1149 if (_compilerID MATCHES "MSVC")
1150 # cl.exe options used
1151 # /nologo suppresses display of sign-on banner
1152 # /TC treat all files named on the command line as C source files
1153 # /TP treat all files named on the command line as C++ source files
1154 # /EP preprocess to stdout without #line directives
1155 # /showIncludes list include files
1156 set (_sourceFileTypeC "/TC")
1157 set (_sourceFileTypeCXX "/TP")
1160 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes)
1162 # return as a flag string
1163 set (_flags "${_sourceFileType${_language}} /EP /showIncludes")
1165 elseif (_compilerID MATCHES "GNU")
1167 # -H print the name of each header file used
1168 # -E invoke preprocessor
1169 # -fdirectives-only do not expand macros, requires GCC >= 4.3
1172 list (APPEND _flags -H -E)
1173 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1174 list (APPEND _flags "-fdirectives-only")
1177 # return as a flag string
1178 set (_flags "-H -E")
1179 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1180 set (_flags "${_flags} -fdirectives-only")
1183 elseif (_compilerID MATCHES "Clang")
1184 # Clang options used
1185 # -H print the name of each header file used
1186 # -E invoke preprocessor
1189 list (APPEND _flags -H -E)
1191 # return as a flag string
1192 set (_flags "-H -E")
1194 elseif (_compilerID MATCHES "Intel")
1196 # Windows Intel options used
1197 # /nologo do not display compiler version information
1198 # /QH display the include file order
1199 # /EP preprocess to stdout, omitting #line directives
1200 # /TC process all source or unrecognized file types as C source files
1201 # /TP process all source or unrecognized file types as C++ source files
1202 set (_sourceFileTypeC "/TC")
1203 set (_sourceFileTypeCXX "/TP")
1206 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH)
1208 # return as a flag string
1209 set (_flags "${_sourceFileType${_language}} /EP /QH")
1212 # Linux / Mac OS X Intel options used
1213 # -H print the name of each header file used
1214 # -EP preprocess to stdout, omitting #line directives
1215 # -Kc++ process all source or unrecognized file types as C++ source files
1218 if ("${_language}" STREQUAL "CXX")
1219 list (APPEND _flags -Kc++)
1221 list (APPEND _flags -H -EP)
1223 # return as a flag string
1224 if ("${_language}" STREQUAL "CXX")
1225 set (_flags "-Kc++ ")
1227 set (_flags "${_flags}-H -EP")
1231 message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1233 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1236 function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
1237 set (_flags ${${_flagsVar}})
1238 if (_compilerID MATCHES "MSVC")
1239 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1240 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1241 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1242 # cl.exe options used
1243 # /Yc creates a precompiled header file
1244 # /Fp specifies precompiled header binary file name
1245 # /FI forces inclusion of file
1246 # /TC treat all files named on the command line as C source files
1247 # /TP treat all files named on the command line as C++ source files
1248 # /Zs syntax check only
1249 set (_sourceFileTypeC "/TC")
1250 set (_sourceFileTypeCXX "/TP")
1253 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1254 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1256 # return as a flag string
1257 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1259 elseif (_compilerID MATCHES "GNU|Clang")
1260 # GCC / Clang options used
1261 # -x specify the source language
1262 # -c compile but do not link
1263 # -o place output in file
1264 set (_xLanguage_C "c-header")
1265 set (_xLanguage_CXX "c++-header")
1268 list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}")
1270 # return as a flag string
1271 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1273 elseif (_compilerID MATCHES "Intel")
1275 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1276 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1277 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1278 # Windows Intel options used
1279 # /nologo do not display compiler version information
1280 # /Yc create a precompiled header (PCH) file
1281 # /Fp specify a path or file name for precompiled header files
1282 # /FI tells the preprocessor to include a specified file name as the header file
1283 # /TC process all source or unrecognized file types as C source files
1284 # /TP process all source or unrecognized file types as C++ source files
1285 # /Zs syntax check only
1286 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1287 set (_sourceFileTypeC "/TC")
1288 set (_sourceFileTypeCXX "/TP")
1291 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1292 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1293 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1294 list (APPEND _flags "/Wpch-messages")
1297 # return as a flag string
1298 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1299 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1300 set (_flags "${_flags} /Wpch-messages")
1304 # Linux / Mac OS X Intel options used
1305 # -pch-dir location for precompiled header files
1306 # -pch-create name of the precompiled header (PCH) to create
1307 # -Kc++ process all source or unrecognized file types as C++ source files
1308 # -fsyntax-only check only for correct syntax
1309 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1310 get_filename_component(_pchDir "${_pchFile}" PATH)
1311 get_filename_component(_pchName "${_pchFile}" NAME)
1312 set (_xLanguage_C "c-header")
1313 set (_xLanguage_CXX "c++-header")
1316 if ("${_language}" STREQUAL "CXX")
1317 list (APPEND _flags -Kc++)
1319 list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}")
1320 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1321 list (APPEND _flags "-Wpch-messages")
1324 # return as a flag string
1325 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1326 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1327 set (_flags "${_flags} -Wpch-messages")
1332 message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1334 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1337 function (cotire_add_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1338 set (_flags ${${_flagsVar}})
1339 if (_compilerID MATCHES "MSVC")
1340 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1341 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1342 # cl.exe options used
1343 # /Yu uses a precompiled header file during build
1344 # /Fp specifies precompiled header binary file name
1345 # /FI forces inclusion of file
1348 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1350 # return as a flag string
1351 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1353 elseif (_compilerID MATCHES "GNU")
1355 # -include process include file as the first line of the primary source file
1356 # -Winvalid-pch warns if precompiled header is found but cannot be used
1359 list (APPEND _flags "-include" "${_prefixFile}" "-Winvalid-pch")
1361 # return as a flag string
1362 set (_flags "-include \"${_prefixFile}\" -Winvalid-pch")
1364 elseif (_compilerID MATCHES "Clang")
1365 # Clang options used
1366 # -include process include file as the first line of the primary source file
1367 # -Qunused-arguments don't emit warning for unused driver arguments
1370 list (APPEND _flags "-include" "${_prefixFile}" "-Qunused-arguments")
1372 # return as a flag string
1373 set (_flags "-include \"${_prefixFile}\" -Qunused-arguments")
1375 elseif (_compilerID MATCHES "Intel")
1377 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1378 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1379 # Windows Intel options used
1380 # /Yu use a precompiled header (PCH) file
1381 # /Fp specify a path or file name for precompiled header files
1382 # /FI tells the preprocessor to include a specified file name as the header file
1383 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1386 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1387 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1388 list (APPEND _flags "/Wpch-messages")
1391 # return as a flag string
1392 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1393 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1394 set (_flags "${_flags} /Wpch-messages")
1398 # Linux / Mac OS X Intel options used
1399 # -pch-dir location for precompiled header files
1400 # -pch-use name of the precompiled header (PCH) to use
1401 # -include process include file as the first line of the primary source file
1402 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1403 get_filename_component(_pchDir "${_pchFile}" PATH)
1404 get_filename_component(_pchName "${_pchFile}" NAME)
1407 list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}")
1408 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1409 list (APPEND _flags "-Wpch-messages")
1412 # return as a flag string
1413 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1414 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1415 set (_flags "${_flags} -Wpch-messages")
1420 message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1422 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1425 function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1427 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION LANGUAGE)
1428 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES)
1429 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1430 if (NOT _option_LANGUAGE)
1431 set (_option_LANGUAGE "CXX")
1433 if (NOT _option_COMPILER_ID)
1434 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1436 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1437 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1438 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1439 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES})
1440 cotire_add_pch_compilation_flags(
1441 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1442 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1444 message (STATUS "execute_process: ${_cmd}")
1446 if (_option_COMPILER_ID MATCHES "MSVC")
1448 message (STATUS "clearing VS_UNICODE_OUTPUT")
1450 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1451 unset (ENV{VS_UNICODE_OUTPUT})
1453 execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result)
1455 message (FATAL_ERROR "Error ${_result} precompiling ${_prefixFile}.")
1459 function (cotire_check_precompiled_header_support _language _targetSourceDir _target _msgVar)
1460 set (_unsupportedCompiler
1461 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
1462 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1463 # supported since Visual Studio C++ 6.0
1464 # and CMake does not support an earlier version
1465 set (${_msgVar} "" PARENT_SCOPE)
1466 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
1467 # GCC PCH support requires version >= 3.4
1468 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1469 if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND
1470 "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
1471 set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
1473 set (${_msgVar} "" PARENT_SCOPE)
1475 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
1476 # all Clang versions have PCH support
1477 set (${_msgVar} "" PARENT_SCOPE)
1478 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
1479 # Intel PCH support requires version >= 8.0.0
1480 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1481 if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND
1482 "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
1483 set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
1485 set (${_msgVar} "" PARENT_SCOPE)
1488 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
1491 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
1492 if (CMAKE_CONFIGURATION_TYPES)
1493 set (_configs ${CMAKE_CONFIGURATION_TYPES})
1494 elseif (CMAKE_BUILD_TYPE)
1495 set (_configs ${CMAKE_BUILD_TYPE})
1497 set (_configs "None")
1499 foreach (_config ${_configs})
1500 set (_targetFlags "")
1501 cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags)
1502 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
1503 list (LENGTH _architectures _numberOfArchitectures)
1504 if (_numberOfArchitectures GREATER 1)
1505 string (REPLACE ";" ", " _architectureStr "${_architectures}")
1507 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
1515 macro (cotire_get_intermediate_dir _cotireDir)
1516 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
1519 macro (cotire_setup_file_extension_variables)
1520 set (_unityFileExt_C ".c")
1521 set (_unityFileExt_CXX ".cxx")
1522 set (_prefixFileExt_C ".h")
1523 set (_prefixFileExt_CXX ".hxx")
1526 function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
1527 cotire_setup_file_extension_variables()
1528 if (NOT DEFINED _unityFileExt_${_language})
1529 set (${_unityFileVar} "" PARENT_SCOPE)
1532 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1533 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
1534 cotire_get_intermediate_dir(_baseDir)
1535 set (_unityFile "${_baseDir}/${_unityFileName}")
1536 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
1538 message(STATUS "${_unityFile}")
1542 function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
1543 cotire_setup_file_extension_variables()
1544 if (NOT DEFINED _unityFileExt_${_language})
1545 set (${_unityFileVar} "" PARENT_SCOPE)
1548 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1549 cotire_get_intermediate_dir(_baseDir)
1552 set (_unityFiles "")
1553 set (_sourceFiles ${ARGN})
1554 foreach (_sourceFile ${_sourceFiles})
1555 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
1556 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
1557 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
1558 if (_index GREATER 0)
1559 # start new unity file segment
1560 math (EXPR _endIndex "${_index} - 1")
1561 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
1562 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
1564 set (_startIndex ${_index})
1566 math (EXPR _index "${_index} + 1")
1568 list (LENGTH _sourceFiles _numberOfSources)
1569 if (_startIndex EQUAL 0)
1570 # there is only a single unity file
1571 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
1572 elseif (_startIndex LESS _numberOfSources)
1573 # end with final unity file segment
1574 math (EXPR _endIndex "${_index} - 1")
1575 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
1576 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
1578 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
1580 message(STATUS "${_unityFiles}")
1584 function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
1585 cotire_setup_file_extension_variables()
1586 if (NOT DEFINED _unityFileExt_${_language})
1587 set (${_prefixFileVar} "" PARENT_SCOPE)
1590 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
1591 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
1592 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
1593 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
1594 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
1597 function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
1598 cotire_setup_file_extension_variables()
1600 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
1601 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
1602 elseif (DEFINED _prefixFileExt_${_language})
1603 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
1604 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
1606 set (_prefixFileBaseName "")
1607 set (_prefixFileName "")
1609 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
1610 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
1613 function (cotire_make_prefix_file_path _language _target _prefixFileVar)
1614 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
1615 set (${_prefixFileVar} "" PARENT_SCOPE)
1616 if (_prefixFileName)
1620 if (MSVC OR CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel")
1621 cotire_get_intermediate_dir(_baseDir)
1622 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
1627 function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileVar)
1628 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
1629 set (${_pchFileVar} "" PARENT_SCOPE)
1630 if (_prefixFileBaseName AND _prefixFileName)
1631 cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _msg)
1634 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
1637 cotire_get_intermediate_dir(_baseDir)
1638 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1639 # MSVC uses the extension .pch added to the prefix header base name
1640 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
1641 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
1642 # GCC / Clang look for a precompiled header corresponding to the prefix header with the extension .gch appended
1643 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
1644 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
1645 # Intel uses the extension .pchi added to the prefix header base name
1646 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
1652 function (cotire_select_unity_source_files _unityFile _sourcesVar)
1653 set (_sourceFiles ${ARGN})
1654 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
1655 set (_startIndex ${CMAKE_MATCH_1})
1656 set (_endIndex ${CMAKE_MATCH_2})
1657 list (LENGTH _sourceFiles _numberOfSources)
1658 if (NOT _startIndex LESS _numberOfSources)
1659 math (EXPR _startIndex "${_numberOfSources} - 1")
1661 if (NOT _endIndex LESS _numberOfSources)
1662 math (EXPR _endIndex "${_numberOfSources} - 1")
1665 foreach (_index RANGE ${_startIndex} ${_endIndex})
1666 list (GET _sourceFiles ${_index} _file)
1667 list (APPEND _files "${_file}")
1670 set (_files ${_sourceFiles})
1672 set (${_sourcesVar} ${_files} PARENT_SCOPE)
1675 function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
1676 set (_dependencySources "")
1677 # depend on target's generated source files
1678 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN})
1679 if (_generatedSources)
1680 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
1681 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
1682 if (_excludedGeneratedSources)
1683 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
1685 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
1686 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
1687 if (_excludedNonDependencySources)
1688 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
1690 if (_generatedSources)
1691 list (APPEND _dependencySources ${_generatedSources})
1694 if (COTIRE_DEBUG AND _dependencySources)
1695 message (STATUS "${_language} ${_target} unity source depends on ${_dependencySources}")
1697 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
1700 function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
1701 # depend on target source files marked with custom COTIRE_DEPENDENCY property
1702 set (_dependencySources "")
1703 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN})
1704 if (COTIRE_DEBUG AND _dependencySources)
1705 message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}")
1707 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
1710 function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar)
1711 set (COTIRE_TARGET_SOURCES ${ARGN})
1712 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1713 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
1714 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES})
1715 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES})
1716 # set up variables to be configured
1717 set (COTIRE_TARGET_LANGUAGE "${_language}")
1718 cotire_determine_compiler_version("${COTIRE_TARGET_LANGUAGE}" COTIRE_${_language}_COMPILER)
1719 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
1720 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
1721 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
1722 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
1723 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
1724 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
1725 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
1726 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES})
1727 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES})
1728 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
1729 foreach (_config ${_configurations})
1730 string (TOUPPER "${_config}" _upperConfig)
1731 cotire_get_target_include_directories(
1732 "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig})
1733 cotire_get_target_compile_definitions(
1734 "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
1735 cotire_get_target_compiler_flags(
1736 "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
1737 cotire_get_source_files_compile_definitions(
1738 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${COTIRE_TARGET_SOURCES})
1740 get_cmake_property(_vars VARIABLES)
1741 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
1742 # remove COTIRE_VERBOSE which is passed as a CMake define on command line
1743 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
1745 foreach (_var IN LISTS _matchVars ITEMS
1746 MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
1747 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
1748 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
1749 if (DEFINED ${_var})
1750 string (REPLACE "\"" "\\\"" _value "${${_var}}")
1751 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
1754 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
1755 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
1758 function (cotire_setup_pch_file_compilation _language _targetBinaryDir _targetScript _prefixFile _pchFile)
1759 set (_sourceFiles ${ARGN})
1760 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
1761 # for Visual Studio and Intel, we attach the precompiled header compilation to the first source file
1762 # the remaining files include the precompiled header, see cotire_setup_prefix_file_inclusion
1764 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1765 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1766 list (GET _sourceFiles 0 _hostFile)
1768 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1769 cotire_add_pch_compilation_flags(
1770 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
1771 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
1772 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
1773 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
1774 # make first source file depend on prefix header
1775 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
1777 elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
1778 # for makefile based generator, we add a custom command to precompile the prefix header
1780 cotire_set_cmd_to_prologue(_cmds)
1781 list (GET _sourceFiles 0 _hostFile)
1782 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
1783 file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
1785 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
1787 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
1788 add_custom_command(OUTPUT "${_pchFile}"
1790 DEPENDS "${_prefixFile}"
1791 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
1792 WORKING_DIRECTORY "${_targetSourceDir}"
1793 COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM)
1798 function (cotire_setup_prefix_file_inclusion _language _target _wholeTarget _prefixFile _pchFile)
1799 set (_sourceFiles ${ARGN})
1800 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
1801 # for Visual Studio and Intel, we include the precompiled header in all but the first source file
1802 # the first source file does the precompiled header compilation, see cotire_setup_pch_file_compilation
1803 list (LENGTH _sourceFiles _numberOfSourceFiles)
1804 if (_numberOfSourceFiles GREATER 1)
1805 # mark sources as cotired to prevent them from being used in another cotired target
1806 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
1807 list (REMOVE_AT _sourceFiles 0)
1809 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1810 cotire_add_pch_inclusion_flags(
1811 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
1812 "${_prefixFile}" "${_pchFile}" _flags)
1813 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
1814 # make source files depend on precompiled header
1815 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
1817 elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
1818 if (NOT _wholeTarget)
1819 # for makefile based generator, we force the inclusion of the prefix header for a subset
1820 # of the source files, if this is a multi-language target or has excluded files
1822 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1823 cotire_add_pch_inclusion_flags(
1824 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
1825 "${_prefixFile}" "${_pchFile}" _flags)
1826 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
1827 # mark sources as cotired to prevent them from being used in another cotired target
1828 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
1830 # make source files depend on precompiled header
1831 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
1835 function (cotire_get_first_set_property_value _propertyValueVar _type _object)
1836 set (_properties ${ARGN})
1837 foreach (_property ${_properties})
1838 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
1840 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
1844 set (${_propertyValueVar} "" PARENT_SCOPE)
1847 function (cotire_setup_combine_command _language _sourceDir _targetScript _joinedFile _cmdsVar)
1848 set (_files ${ARGN})
1849 set (_filesPaths "")
1850 foreach (_file ${_files})
1851 if (IS_ABSOLUTE "${_file}")
1852 set (_filePath "${_file}")
1854 get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE)
1856 file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}")
1857 if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.")
1858 list (APPEND _filesPaths "${_fileRelPath}")
1860 list (APPEND _filesPaths "${_filePath}")
1863 cotire_set_cmd_to_prologue(_prefixCmd)
1864 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
1866 list (APPEND _prefixCmd "${_targetScript}")
1868 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
1870 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
1872 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
1873 file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
1874 get_filename_component(_joinedFileName "${_joinedFileRelPath}" NAME_WE)
1875 if (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
1876 set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}")
1877 elseif (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
1878 set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}")
1880 set (_comment "Generating ${_joinedFileRelPath}")
1883 OUTPUT "${_joinedFile}"
1884 COMMAND ${_prefixCmd}
1886 COMMENT "${_comment}"
1887 WORKING_DIRECTORY "${_sourceDir}" VERBATIM)
1888 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
1889 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
1892 function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget)
1894 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
1895 # if necessary, we also generate a single prefix header which includes all language specific prefix headers
1896 set (_prefixFiles "")
1897 foreach (_language ${_languages})
1898 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
1900 list (APPEND _prefixFiles "${_prefixFile}")
1904 list (LENGTH _prefixFiles _numberOfPrefixFiles)
1905 if (_numberOfPrefixFiles GREATER 1)
1906 cotire_make_prefix_file_path("" ${_target} _prefixHeader)
1907 cotire_setup_combine_command("" "${_targetSourceDir}" "" "${_prefixHeader}" _cmds ${_prefixFiles})
1909 set (_prefixHeader "${_prefixFiles}")
1912 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
1914 add_custom_command(TARGET "${_target}"
1916 WORKING_DIRECTORY "${_targetSourceDir}"
1917 COMMENT "Updating target ${_target} prefix headers" VERBATIM)
1918 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
1919 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
1920 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
1921 elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
1922 # for makefile based generator, we force inclusion of the prefix header for all target source files
1923 # if this is a single-language target without any excluded files
1925 set (_language "${_languages}")
1926 # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level
1927 # see cotire_setup_prefix_file_inclusion
1928 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
1929 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
1930 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
1932 cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
1933 cotire_add_pch_inclusion_flags(
1934 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
1935 "${_prefixFile}" "${_pchFile}" _flags)
1936 set_property (TARGET ${_target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
1942 function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _unityFiles _cmdsVar)
1943 set (_dependencySources "")
1944 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
1945 foreach (_unityFile ${_unityFiles})
1946 file (RELATIVE_PATH _unityFileRelPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
1947 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
1948 # set up compiled unity source dependencies
1949 # this ensures that missing source files are generated before the unity file is compiled
1950 if (COTIRE_DEBUG AND _dependencySources)
1951 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
1953 if (_dependencySources)
1954 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_dependencySources})
1956 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
1957 # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel
1958 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
1960 cotire_set_cmd_to_prologue(_unityCmd)
1961 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetScript}" "${_unityFile}")
1963 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_targetScript}")
1966 OUTPUT "${_unityFile}"
1967 COMMAND ${_unityCmd}
1968 DEPENDS "${_targetScript}"
1969 COMMENT "Generating ${_language} unity source ${_unityFileRelPath}"
1970 WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM)
1971 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
1973 list (LENGTH _unityFiles _numberOfUnityFiles)
1974 if (_numberOfUnityFiles GREATER 1)
1975 # create a joint unity file from all unity file segments
1976 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
1977 cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles})
1979 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
1982 function (cotire_setup_single_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar)
1983 set (_sourceFiles ${ARGN})
1984 set (_dependencySources "")
1985 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
1986 cotire_set_cmd_to_prologue(_prefixCmd)
1987 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}")
1988 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
1990 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_targetScript} ${_unityFile} ${_dependencySources}")
1992 file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
1994 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
1995 COMMAND ${_prefixCmd}
1996 DEPENDS "${_targetScript}" "${_unityFile}" ${_dependencySources}
1997 COMMENT "Generating ${_language} prefix header ${_prefixFileRelPath}"
1998 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
1999 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2000 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2003 function (cotire_setup_multi_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar)
2004 set (_sourceFiles ${ARGN})
2005 list (LENGTH _unityFiles _numberOfUnityFiles)
2006 if (_numberOfUnityFiles GREATER 1)
2007 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
2008 cotire_setup_single_prefix_generation_command(
2009 ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
2010 "${_prefixFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles})
2012 cotire_setup_single_prefix_generation_command(
2013 ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
2014 "${_prefixFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2016 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2019 function (cotire_init_cotire_target_properties _target)
2020 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2022 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2024 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2026 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2028 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2030 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2032 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2034 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2035 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2036 if (NOT _isRelative)
2037 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2040 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2042 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2044 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2046 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2048 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2050 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2052 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2054 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2055 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2057 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2062 function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2063 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2064 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2065 string (REPLACE ";" " " _languagesStr "${_languages}")
2066 string (REPLACE ";" ", " _excludedStr "${ARGN}")
2069 set (_targetMsg "Target ${_target} cannot be cotired.")
2071 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2073 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2074 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2076 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2078 elseif (NOT _targetUsePCH)
2079 if (_allExcludedSourceFiles)
2080 set (_targetMsg "${_languagesStr} target ${_target} cotired excluding files ${_excludedStr} without precompiled header.")
2082 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2085 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2087 elseif (NOT _targetAddSCU)
2088 if (_allExcludedSourceFiles)
2089 set (_targetMsg "${_languagesStr} target ${_target} cotired excluding files ${_excludedStr} without unity build.")
2091 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2094 if (_allExcludedSourceFiles)
2095 set (_targetMsg "${_languagesStr} target ${_target} cotired excluding files ${_excludedStr}.")
2097 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2100 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2103 function (cotire_choose_target_languages _targetSourceDir _target _targetLanguagesVar)
2104 set (_languages ${ARGN})
2105 set (_allSourceFiles "")
2106 set (_allExcludedSourceFiles "")
2107 set (_allCotiredSourceFiles "")
2108 set (_targetLanguages "")
2109 get_target_property(_targetType ${_target} TYPE)
2110 get_target_property(_targetSourceFiles ${_target} SOURCES)
2111 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2112 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2113 set (_disableMsg "")
2114 foreach (_language ${_languages})
2115 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2116 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2117 if (_prefixHeader OR _unityBuildFile)
2118 message (WARNING "Target ${_target} has already been cotired.")
2119 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2122 if (_targetUsePCH AND "${_language}" STREQUAL "C" OR "${_language}" STREQUAL "CXX")
2123 cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg)
2125 set (_targetUsePCH FALSE)
2128 set (_sourceFiles "")
2129 set (_excludedSources "")
2130 set (_cotiredSources "")
2131 cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2132 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2133 list (APPEND _targetLanguages ${_language})
2136 list (APPEND _allSourceFiles ${_sourceFiles})
2138 if (_excludedSources)
2139 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2141 if (_cotiredSources)
2142 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2145 set (_targetMsgLevel STATUS)
2146 if (NOT _targetLanguages)
2147 string (REPLACE ";" " or " _languagesStr "${_languages}")
2148 set (_disableMsg "No ${_languagesStr} source files.")
2149 set (_targetUsePCH FALSE)
2150 set (_targetAddSCU FALSE)
2153 list (LENGTH _allSourceFiles _numberOfSources)
2154 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2155 set (_disableMsg "Too few applicable sources.")
2156 set (_targetUsePCH FALSE)
2157 elseif (_allCotiredSourceFiles)
2158 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2159 list (REMOVE_DUPLICATES _cotireTargets)
2160 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2161 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2162 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2163 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2164 set (_targetMsgLevel SEND_ERROR)
2165 set (_targetUsePCH FALSE)
2166 elseif (XCODE AND _allExcludedSourceFiles)
2167 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2168 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2169 set (_targetUsePCH FALSE)
2170 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2171 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2172 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2173 set (_targetUsePCH FALSE)
2176 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2177 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2178 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2180 if (NOT DEFINED COTIREMSG_${_target})
2181 set (COTIREMSG_${_target} "")
2183 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2184 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2185 # cache message to avoid redundant messages on re-configure
2186 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2187 message (${_targetMsgLevel} "${_targetMsg}")
2190 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2193 function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2194 set (_sourceFiles ${ARGN})
2195 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2196 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2197 set (_numberOfThreads "${CMAKE_MATCH_2}")
2198 if (NOT _numberOfThreads)
2199 # use all available cores
2200 ProcessorCount(_numberOfThreads)
2202 list (LENGTH _sourceFiles _numberOfSources)
2203 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2204 # a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files
2205 if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2206 set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2208 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2209 set (_maxIncludes 0)
2212 message (STATUS "${_target} unity source max includes = ${_maxIncludes}")
2214 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2217 function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTargetVar _cmdsVar)
2218 set (${_cmdsVar} "" PARENT_SCOPE)
2219 get_target_property(_targetSourceFiles ${_target} SOURCES)
2220 set (_sourceFiles "")
2221 set (_excludedSources "")
2222 set (_cotiredSources "")
2223 cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2224 if (NOT _sourceFiles AND NOT _cotiredSources)
2227 set (_wholeTarget ${${_wholeTargetVar}})
2229 # check for user provided unity source file list
2230 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
2231 if (NOT _unitySourceFiles)
2232 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
2234 cotire_generate_target_script(
2235 ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript ${_unitySourceFiles})
2236 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
2237 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
2238 if (NOT _unityFiles)
2241 cotire_setup_unity_generation_commands(
2242 ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
2243 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
2245 # check for user provided prefix header files
2246 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
2247 if (_prefixHeaderFiles)
2248 cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
2250 cotire_setup_multi_prefix_generation_command(
2251 ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles})
2253 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2255 cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile)
2257 cotire_setup_pch_file_compilation(
2258 ${_language} "${_targetBinaryDir}" "${_targetScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
2259 if (_excludedSources)
2260 set (_wholeTarget FALSE)
2262 cotire_setup_prefix_file_inclusion(
2263 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
2267 # mark target as cotired for language
2268 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
2270 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
2271 if (_targetUsePCH AND _pchFile)
2272 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
2275 set (${_wholeTargetVar} ${_wholeTarget} PARENT_SCOPE)
2276 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
2279 function (cotire_setup_clean_target _target)
2280 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
2281 if (NOT TARGET "${_cleanTargetName}")
2282 cotire_set_cmd_to_prologue(_cmds)
2283 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
2284 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
2285 add_custom_target(${_cleanTargetName} COMMAND ${_cmds} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2286 COMMENT "Cleaning up target ${_target} cotire generated files" VERBATIM)
2287 cotire_init_target("${_cleanTargetName}")
2291 function (cotire_setup_pch_target _languages _configurations _target)
2292 if ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
2293 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
2294 set (_dependsFiles "")
2295 foreach (_language ${_languages})
2296 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
2297 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2298 # Visual Studio and Intel only create precompiled header as a side effect
2299 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
2301 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
2303 list (APPEND _dependsFiles "${_dependsFile}")
2307 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
2308 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
2309 cotire_init_target("${_pchTargetName}")
2310 cotire_add_to_pch_all_target(${_pchTargetName})
2313 # for other generators, we add the "clean all" target to clean up the precompiled header
2314 cotire_setup_clean_all_target()
2318 function (cotire_setup_unity_build_target _languages _configurations _targetSourceDir _target)
2319 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
2320 if (NOT _unityTargetName)
2321 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
2323 # determine unity target sub type
2324 get_target_property(_targetType ${_target} TYPE)
2325 if ("${_targetType}" STREQUAL "EXECUTABLE")
2326 get_target_property(_isWin32 ${_target} WIN32_EXECUTABLE)
2327 get_target_property(_isMacOSX_Bundle ${_target} MACOSX_BUNDLE)
2329 set (_unityTargetSubType WIN32)
2330 elseif (_isMacOSX_Bundle)
2331 set (_unityTargetSubType MACOSX_BUNDLE)
2333 set (_unityTargetSubType "")
2335 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
2336 set (_unityTargetSubType "${CMAKE_MATCH_1}")
2338 message (WARNING "Unknown target type ${_targetType}.")
2341 # determine unity target sources
2342 get_target_property(_targetSourceFiles ${_target} SOURCES)
2343 set (_unityTargetSources ${_targetSourceFiles})
2344 foreach (_language ${_languages})
2345 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
2347 # remove source files that are included in the unity source
2348 set (_sourceFiles "")
2349 set (_excludedSources "")
2350 set (_cotiredSources "")
2351 cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2352 if (_sourceFiles OR _cotiredSources)
2353 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
2355 # if cotire is applied to a target which has not been added in the current source dir,
2356 # non-existing files cannot be referenced from the unity build target (this is a CMake restriction)
2357 if (NOT "${_targetSourceDir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
2358 set (_nonExistingFiles "")
2359 foreach (_file ${_unityTargetSources})
2360 if (NOT EXISTS "${_file}")
2361 list (APPEND _nonExistingFiles "${_file}")
2364 if (_nonExistingFiles)
2366 message (STATUS "removing non-existing ${_nonExistingFiles} from ${_unityTargetName}")
2368 list (REMOVE_ITEM _unityTargetSources ${_nonExistingFiles})
2371 # add unity source files instead
2372 list (APPEND _unityTargetSources ${_unityFiles})
2376 message (STATUS "add ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
2378 # generate unity target
2379 if ("${_targetType}" STREQUAL "EXECUTABLE")
2380 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
2382 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
2384 set (_outputDirProperties
2385 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
2386 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
2387 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
2388 # copy output location properties
2389 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
2390 set (_setDefaultOutputDir TRUE)
2391 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
2392 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
2394 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
2395 cotrie_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties})
2396 foreach (_property ${_properties})
2397 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
2399 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
2400 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
2401 set (_setDefaultOutputDir FALSE)
2404 if (_setDefaultOutputDir)
2405 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
2408 if (_setDefaultOutputDir)
2409 set_target_properties(${_unityTargetName} PROPERTIES
2410 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
2411 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
2412 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
2415 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
2418 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2419 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
2420 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
2421 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
2422 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
2423 PREFIX <CONFIG>_POSTFIX SUFFIX)
2424 # copy compile stuff
2425 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2426 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
2427 COMPILE_FLAGS Fortran_FORMAT
2429 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
2430 POSITION_INDEPENDENT_CODE)
2432 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2433 BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
2434 LINKER_LANGUAGE LINK_DEPENDS
2435 LINK_FLAGS LINK_FLAGS_<CONFIG>
2436 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
2437 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
2438 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
2439 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
2440 NO_SONAME SOVERSION VERSION)
2442 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2443 AUTOMOC AUTOMOC_MOC_OPTIONS)
2445 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2446 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
2447 # copy platform stuff
2449 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2450 BUNDLE BUNDLE_EXTENSION FRAMEWORK INSTALL_NAME_DIR MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST
2451 OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE)
2453 cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
2455 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
2456 VS_DOTNET_REFERENCES VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_KEYWORD
2457 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
2458 VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES)
2460 # use output name from original target
2461 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
2462 if (NOT _targetOutputName)
2463 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
2465 # use export symbol from original target
2466 cotire_get_target_export_symbol("${_target}" _defineSymbol)
2468 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
2469 if ("${_targetType}" STREQUAL "EXECUTABLE")
2470 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
2473 cotire_init_target(${_unityTargetName})
2474 cotire_add_to_unity_all_target(${_unityTargetName})
2475 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
2476 endfunction(cotire_setup_unity_build_target)
2478 function (cotire_target _target)
2480 set(_oneValueArgs SOURCE_DIR BINARY_DIR)
2481 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
2482 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
2483 if (NOT _option_SOURCE_DIR)
2484 set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
2486 if (NOT _option_BINARY_DIR)
2487 set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
2489 if (NOT _option_LANGUAGES)
2490 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
2492 if (NOT _option_CONFIGURATIONS)
2493 if (CMAKE_CONFIGURATION_TYPES)
2494 set (_option_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
2495 elseif (CMAKE_BUILD_TYPE)
2496 set (_option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}")
2498 set (_option_CONFIGURATIONS "None")
2502 get_target_property(_imported ${_target} IMPORTED)
2504 message (WARNING "Imported target ${_target} cannot be cotired.")
2507 # check if target needs to be cotired for build type
2508 # when using configuration types, the test is performed at build time
2509 cotire_init_cotire_target_properties(${_target})
2510 if (NOT CMAKE_CONFIGURATION_TYPES)
2511 if (CMAKE_BUILD_TYPE)
2512 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
2514 list (FIND _option_CONFIGURATIONS "None" _index)
2516 if (_index EQUAL -1)
2518 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
2523 # choose languages that apply to the target
2524 cotire_choose_target_languages("${_option_SOURCE_DIR}" "${_target}" _targetLanguages ${_option_LANGUAGES})
2525 if (NOT _targetLanguages)
2528 list (LENGTH _targetLanguages _numberOfLanguages)
2529 if (_numberOfLanguages GREATER 1)
2530 set (_wholeTarget FALSE)
2532 set (_wholeTarget TRUE)
2535 foreach (_language ${_targetLanguages})
2536 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}"
2537 "${_option_SOURCE_DIR}" "${_option_BINARY_DIR}" ${_target} _wholeTarget _cmd)
2539 list (APPEND _cmds ${_cmd})
2542 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2544 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" "${_option_SOURCE_DIR}" ${_target})
2546 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2548 cotire_setup_target_pch_usage("${_targetLanguages}" "${_option_SOURCE_DIR}" ${_target} ${_wholeTarget} ${_cmds})
2549 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
2551 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
2552 if (_targetAddCleanTarget)
2553 cotire_setup_clean_target(${_target})
2557 function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
2559 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
2561 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
2563 # filter files in intermediate directory
2564 set (_filesToRemove "")
2565 foreach (_file ${_cotireFiles})
2566 get_filename_component(_dir "${_file}" PATH)
2567 get_filename_component(_dirName "${_dir}" NAME)
2568 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
2569 list (APPEND _filesToRemove "${_file}")
2574 message (STATUS "removing ${_filesToRemove}")
2576 file (REMOVE ${_filesToRemove})
2580 function (cotire_init_target _targetName)
2581 if (COTIRE_TARGETS_FOLDER)
2582 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
2585 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
2589 function (cotire_add_to_pch_all_target _pchTargetName)
2590 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
2591 if (NOT TARGET "${_targetName}")
2592 add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
2593 cotire_init_target("${_targetName}")
2595 cotire_setup_clean_all_target()
2596 add_dependencies(${_targetName} ${_pchTargetName})
2599 function (cotire_add_to_unity_all_target _unityTargetName)
2600 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
2601 if (NOT TARGET "${_targetName}")
2602 add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
2603 cotire_init_target("${_targetName}")
2605 cotire_setup_clean_all_target()
2606 add_dependencies(${_targetName} ${_unityTargetName})
2609 function (cotire_setup_clean_all_target)
2610 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
2611 if (NOT TARGET "${_targetName}")
2612 cotire_set_cmd_to_prologue(_cmds)
2613 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
2614 add_custom_target(${_targetName} COMMAND ${_cmds}
2615 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Cleaning up all cotire generated files" VERBATIM)
2616 cotire_init_target("${_targetName}")
2622 set(_oneValueArgs SOURCE_DIR BINARY_DIR)
2623 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
2624 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
2625 set (_targets ${_option_UNPARSED_ARGUMENTS})
2626 if (NOT _option_SOURCE_DIR)
2627 set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
2629 if (NOT _option_BINARY_DIR)
2630 set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
2632 foreach (_target ${_targets})
2633 if (TARGET ${_target})
2634 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}
2635 SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}")
2637 message (WARNING "${_target} is not a target")
2642 if (CMAKE_SCRIPT_MODE_FILE)
2644 # cotire is being run in script mode
2645 # locate -P on command args
2646 set (COTIRE_ARGC -1)
2647 foreach (_index RANGE ${CMAKE_ARGC})
2648 if (COTIRE_ARGC GREATER -1)
2649 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
2650 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
2651 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
2656 # include target script if available
2657 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
2658 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
2659 include("${COTIRE_ARGV2}")
2663 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
2667 # for MSVC, compiler IDs may not always be set correctly
2669 set (CMAKE_C_COMPILER_ID "MSVC")
2670 set (CMAKE_CXX_COMPILER_ID "MSVC")
2674 if (NOT COTIRE_BUILD_TYPE)
2675 set (COTIRE_BUILD_TYPE "None")
2677 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
2678 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
2679 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
2680 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
2681 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
2682 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
2683 if (_index GREATER -1)
2684 set (_sources ${COTIRE_TARGET_SOURCES})
2685 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
2688 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
2691 set (_sourcesDefinitions "")
2693 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
2694 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
2695 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
2696 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
2698 if ("${COTIRE_ARGV1}" STREQUAL "unity")
2700 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
2701 cotire_generate_unity_source(
2702 "${COTIRE_ARGV3}" ${_sources}
2703 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
2704 DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV2}"
2705 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
2706 PRE_UNDEFS ${_targetPreUndefs}
2707 POST_UNDEFS ${_targetPostUndefs}
2708 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
2709 SOURCES_POST_UNDEFS ${_sourcesPostUndefs})
2711 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
2714 foreach (_index RANGE 4 ${COTIRE_ARGC})
2715 if (COTIRE_ARGV${_index})
2716 list (APPEND _files "${COTIRE_ARGV${_index}}")
2720 cotire_generate_prefix_header(
2721 "${COTIRE_ARGV3}" ${_files}
2722 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
2723 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
2724 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
2725 COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
2726 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
2727 DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}
2728 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
2729 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
2730 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
2731 INCLUDE_DIRECTORIES ${_includeDirs}
2732 COMPILE_DEFINITIONS ${_compileDefinitions}
2733 COMPILE_FLAGS ${_compileFlags})
2735 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
2738 foreach (_index RANGE 5 ${COTIRE_ARGC})
2739 if (COTIRE_ARGV${_index})
2740 list (APPEND _files "${COTIRE_ARGV${_index}}")
2744 cotire_precompile_prefix_header(
2745 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
2746 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
2747 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
2748 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
2749 COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
2750 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
2751 INCLUDE_DIRECTORIES ${_includeDirs}
2752 COMPILE_DEFINITIONS ${_compileDefinitions}
2753 COMPILE_FLAGS ${_compileFlags})
2755 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
2757 if (COTIRE_TARGET_LANGUAGE)
2763 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
2764 if (COTIRE_ARGV${_index})
2765 list (APPEND _files "${COTIRE_ARGV${_index}}")
2768 if (COTIRE_TARGET_LANGUAGE)
2769 cotire_generate_unity_source(${_files} LANGUAGE "${COTIRE_TARGET_LANGUAGE}")
2771 cotire_generate_unity_source(${_files})
2774 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
2776 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
2779 message (FATAL_ERROR "Unknown cotire command \"${COTIRE_ARGV1}\".")
2784 # cotire is being run in include mode
2785 # set up all variable and property definitions
2787 unset (COTIRE_C_COMPILER_VERSION CACHE)
2788 unset (COTIRE_CXX_COMPILER_VERSION CACHE)
2790 if (NOT DEFINED COTIRE_DEBUG_INIT)
2791 if (DEFINED COTIRE_DEBUG)
2792 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
2794 set (COTIRE_DEBUG_INIT FALSE)
2797 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
2799 if (NOT DEFINED COTIRE_VERBOSE_INIT)
2800 if (DEFINED COTIRE_VERBOSE)
2801 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
2803 set (COTIRE_VERBOSE_INIT FALSE)
2806 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
2808 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
2809 "Ignore headers with the listed file extensions from the generated prefix header.")
2811 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
2812 "Ignore headers from these directories when generating the prefix header.")
2814 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
2815 "Ignore sources with the listed file extensions from the generated unity source.")
2817 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING
2818 "Minimum number of sources in target required to enable use of precompiled header.")
2820 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
2821 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2822 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
2823 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
2824 # enable parallelization for generators that run multiple jobs by default
2825 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
2827 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
2830 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
2831 "Maximum number of source files to include in a single unity source file.")
2833 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
2834 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
2836 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
2837 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
2839 if (NOT COTIRE_INTDIR)
2840 set (COTIRE_INTDIR "cotire")
2842 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
2843 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
2845 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
2846 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
2848 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
2849 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
2851 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
2852 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
2854 if (NOT COTIRE_PCH_TARGET_SUFFIX)
2855 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
2857 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
2858 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
2860 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
2861 set (COTIRE_TARGETS_FOLDER "cotire")
2863 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
2864 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
2865 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
2866 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
2868 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
2872 # define cotire cache variables
2875 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
2876 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
2878 "The variable can be set to a semicolon separated list of include directories."
2879 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
2880 "If not defined, defaults to empty list."
2884 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
2885 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
2887 "The variable can be set to a semicolon separated list of file extensions."
2888 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
2889 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
2890 "If not defined, defaults to inc;inl;ipp."
2894 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
2895 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
2897 "The variable can be set to a semicolon separated list of file extensions."
2898 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
2899 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
2900 "If not defined, defaults to m;mm."
2904 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
2905 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
2907 "The variable can be set to an integer > 0."
2908 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
2909 "If not defined, defaults to 3."
2913 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
2914 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
2916 "This may be set to an integer >= 0."
2917 "If 0, cotire will only create a single unity source file."
2918 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
2919 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
2920 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
2921 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
2922 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
2925 # define cotire directory properties
2928 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
2929 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
2931 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
2935 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
2936 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
2938 "See target property COTIRE_ADD_UNITY_BUILD."
2942 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
2943 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
2945 "See target property COTIRE_ADD_CLEAN."
2949 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
2950 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
2952 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
2956 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
2957 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
2959 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
2963 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
2964 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
2966 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
2970 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
2971 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
2973 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
2977 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
2978 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
2980 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
2983 # define cotire target properties
2986 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
2987 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
2989 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
2990 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
2991 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
2992 "The target name will be set to this target's name with the suffix _pch appended."
2993 "Inherited from directory."
2998 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
2999 BRIEF_DOCS "Add a new target that performs a unity build for this target."
3001 "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."
3002 "Most of the relevant target properties will be copied from this target to the new unity build target."
3003 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
3004 "The unity target name will be set to this target's name with the suffix _unity appended."
3005 "Inherited from directory."
3010 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
3011 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
3013 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
3014 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
3015 "Inherited from directory."
3016 "Defaults to FALSE."
3020 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
3021 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3023 "The property can be set to a list of directories."
3024 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3025 "Inherited from directory."
3026 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
3030 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
3031 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3033 "The property can be set to a list of directories."
3034 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
3035 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
3036 "the option which yields the closer relative path match wins."
3037 "Inherited from directory."
3038 "If not set, this property is initialized to the empty list."
3042 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
3043 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
3045 "This may be set to a semicolon-separated list of preprocessor symbols."
3046 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
3047 "Inherited from directory."
3048 "Defaults to empty string."
3052 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
3053 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
3055 "This may be set to a semicolon-separated list of preprocessor symbols."
3056 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
3057 "Inherited from directory."
3058 "Defaults to empty string."
3062 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
3063 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3065 "This may be set to an integer > 0."
3066 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
3067 "If not set, cotire will only create a single unity source file."
3068 "Inherited from directory."
3069 "Defaults to empty."
3073 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
3074 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
3076 "If set, cotire will only add the given file(s) to the generated unity source file."
3077 "If not set, cotire will add all the target source files to the generated unity source file."
3078 "The property can be set to a user provided unity source file."
3079 "Defaults to empty."
3083 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
3084 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
3086 "If set, cotire will add the given header file(s) to the generated prefix header file."
3087 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
3088 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
3089 "Defaults to empty."
3093 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
3094 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
3096 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
3097 "Defaults to empty string."
3101 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
3102 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
3104 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
3105 "Defaults to empty string."
3109 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
3110 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
3112 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
3113 "Defaults to empty string."
3117 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
3118 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
3120 "This property can be set to the desired name of the unity target that will be created by cotire."
3121 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
3122 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
3123 "Defaults to empty string."
3126 # define cotire source properties
3129 SOURCE PROPERTY "COTIRE_EXCLUDED"
3130 BRIEF_DOCS "Do not modify source file's build command."
3132 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
3133 "The source file will also be excluded from the generated unity source file."
3134 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
3135 "Defaults to FALSE."
3139 SOURCE PROPERTY "COTIRE_DEPENDENCY"
3140 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
3142 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
3143 "If the file is modified, cotire will re-generate the prefix header source upon build."
3144 "Defaults to FALSE."
3148 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3149 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
3151 "This may be set to a semicolon-separated list of preprocessor symbols."
3152 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
3153 "Defaults to empty string."
3157 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3158 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
3160 "This may be set to a semicolon-separated list of preprocessor symbols."
3161 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
3162 "Defaults to empty string."
3166 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
3167 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
3169 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
3170 "The new unity source file will include this source file as the first one."
3171 "This property essentially works as a separator for unity source files."
3172 "Defaults to FALSE."
3176 SOURCE PROPERTY "COTIRE_TARGET"
3177 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
3179 "cotire sets this property to the name of target, that the source file's build command has been altered for."
3180 "Defaults to empty string."
3183 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")