ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
cotire.cmake
1# - cotire (compile time reducer)
2#
3# See the cotire manual for usage hints.
4#
5#=============================================================================
6# Copyright 2012-2018 Sascha Kratky
7#
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
15# conditions:
16#
17# The above copyright notice and this permission notice shall be
18# included in all copies or substantial portions of the Software.
19#
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#=============================================================================
29
30if(__COTIRE_INCLUDED)
31 return()
32endif()
33set(__COTIRE_INCLUDED TRUE)
34
35# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode
36# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid
37if (NOT CMAKE_SCRIPT_MODE_FILE)
38 cmake_policy(PUSH)
39endif()
40cmake_minimum_required(VERSION 3.5.0)
41if (NOT CMAKE_SCRIPT_MODE_FILE)
42 cmake_policy(POP)
43endif()
44
45set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
46set (COTIRE_CMAKE_MODULE_VERSION "1.8.1")
47
48# activate select policies
49if (POLICY CMP0025)
50 # Compiler id for Apple Clang is now AppleClang
51 cmake_policy(SET CMP0025 NEW)
52endif()
53
54if (POLICY CMP0026)
55 # disallow use of the LOCATION target property
56 cmake_policy(SET CMP0026 NEW)
57endif()
58
59if (POLICY CMP0038)
60 # targets may not link directly to themselves
61 cmake_policy(SET CMP0038 NEW)
62endif()
63
64if (POLICY CMP0039)
65 # utility targets may not have link dependencies
66 cmake_policy(SET CMP0039 NEW)
67endif()
68
69if (POLICY CMP0040)
70 # target in the TARGET signature of add_custom_command() must exist
71 cmake_policy(SET CMP0040 NEW)
72endif()
73
74if (POLICY CMP0045)
75 # error on non-existent target in get_target_property
76 cmake_policy(SET CMP0045 NEW)
77endif()
78
79if (POLICY CMP0046)
80 # error on non-existent dependency in add_dependencies
81 cmake_policy(SET CMP0046 NEW)
82endif()
83
84if (POLICY CMP0049)
85 # do not expand variables in target source entries
86 cmake_policy(SET CMP0049 NEW)
87endif()
88
89if (POLICY CMP0050)
90 # disallow add_custom_command SOURCE signatures
91 cmake_policy(SET CMP0050 NEW)
92endif()
93
94if (POLICY CMP0051)
95 # include TARGET_OBJECTS expressions in a target's SOURCES property
96 cmake_policy(SET CMP0051 NEW)
97endif()
98
99if (POLICY CMP0053)
100 # simplify variable reference and escape sequence evaluation
101 cmake_policy(SET CMP0053 NEW)
102endif()
103
104if (POLICY CMP0054)
105 # only interpret if() arguments as variables or keywords when unquoted
106 cmake_policy(SET CMP0054 NEW)
107endif()
108
109if (POLICY CMP0055)
110 # strict checking for break() command
111 cmake_policy(SET CMP0055 NEW)
112endif()
113
114include(CMakeParseArguments)
115include(ProcessorCount)
116
117function (cotire_get_configuration_types _configsVar)
118 set (_configs "")
119 if (CMAKE_CONFIGURATION_TYPES)
120 list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES})
121 endif()
122 if (CMAKE_BUILD_TYPE)
123 list (APPEND _configs "${CMAKE_BUILD_TYPE}")
124 endif()
125 if (_configs)
126 list (REMOVE_DUPLICATES _configs)
127 set (${_configsVar} ${_configs} PARENT_SCOPE)
128 else()
129 set (${_configsVar} "None" PARENT_SCOPE)
130 endif()
131endfunction()
132
133function (cotire_get_source_file_extension _sourceFile _extVar)
134 # get_filename_component returns extension from first occurrence of . in file name
135 # this function computes the extension from last occurrence of . in file name
136 string (FIND "${_sourceFile}" "." _index REVERSE)
137 if (_index GREATER -1)
138 math (EXPR _index "${_index} + 1")
139 string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
140 else()
141 set (_sourceExt "")
142 endif()
143 set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
144endfunction()
145
146macro (cotire_check_is_path_relative_to _path _isRelativeVar)
147 set (${_isRelativeVar} FALSE)
148 if (IS_ABSOLUTE "${_path}")
149 foreach (_dir ${ARGN})
150 file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
151 if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
152 set (${_isRelativeVar} TRUE)
153 break()
154 endif()
155 endforeach()
156 endif()
157endmacro()
158
159function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
160 if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
161 set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
162 else()
163 set (_languageExtensions "")
164 endif()
165 if (CMAKE_${_language}_IGNORE_EXTENSIONS)
166 set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}")
167 else()
168 set (_ignoreExtensions "")
169 endif()
170 if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS)
171 set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}")
172 else()
173 set (_excludeExtensions "")
174 endif()
175 if (COTIRE_DEBUG AND _languageExtensions)
176 message (STATUS "${_language} source file extensions: ${_languageExtensions}")
177 endif()
178 if (COTIRE_DEBUG AND _ignoreExtensions)
179 message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}")
180 endif()
181 if (COTIRE_DEBUG AND _excludeExtensions)
182 message (STATUS "${_language} exclude extensions: ${_excludeExtensions}")
183 endif()
184 if (CMAKE_VERSION VERSION_LESS "3.1.0")
185 set (_allSourceFiles ${ARGN})
186 else()
187 # as of CMake 3.1 target sources may contain generator expressions
188 # since we cannot obtain required property information about source files added
189 # through generator expressions at configure time, we filter them out
190 string (GENEX_STRIP "${ARGN}" _allSourceFiles)
191 endif()
192 set (_filteredSourceFiles "")
193 set (_excludedSourceFiles "")
194 foreach (_sourceFile ${_allSourceFiles})
195 get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY)
196 get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT)
197 get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC)
198 if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic)
199 cotire_get_source_file_extension("${_sourceFile}" _sourceExt)
200 if (_sourceExt)
201 list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex)
202 if (_ignoreIndex LESS 0)
203 list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex)
204 if (_excludeIndex GREATER -1)
205 list (APPEND _excludedSourceFiles "${_sourceFile}")
206 else()
207 list (FIND _languageExtensions "${_sourceExt}" _sourceIndex)
208 if (_sourceIndex GREATER -1)
209 # consider source file unless it is excluded explicitly
210 get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED)
211 if (_sourceIsExcluded)
212 list (APPEND _excludedSourceFiles "${_sourceFile}")
213 else()
214 list (APPEND _filteredSourceFiles "${_sourceFile}")
215 endif()
216 else()
217 get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE)
218 if ("${_sourceLanguage}" STREQUAL "${_language}")
219 # add to excluded sources, if file is not ignored and has correct language without having the correct extension
220 list (APPEND _excludedSourceFiles "${_sourceFile}")
221 endif()
222 endif()
223 endif()
224 endif()
225 endif()
226 endif()
227 endforeach()
228 # separate filtered source files from already cotired ones
229 # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire
230 set (_sourceFiles "")
231 set (_cotiredSourceFiles "")
232 foreach (_sourceFile ${_filteredSourceFiles})
233 get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET)
234 if (_sourceIsCotired)
235 list (APPEND _cotiredSourceFiles "${_sourceFile}")
236 else()
237 get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS)
238 if (_sourceCompileFlags)
239 # add to excluded sources, if file has custom compile flags
240 list (APPEND _excludedSourceFiles "${_sourceFile}")
241 else()
242 get_source_file_property(_sourceCompileOptions "${_sourceFile}" COMPILE_OPTIONS)
243 if (_sourceCompileOptions)
244 # add to excluded sources, if file has list of custom compile options
245 list (APPEND _excludedSourceFiles "${_sourceFile}")
246 else()
247 list (APPEND _sourceFiles "${_sourceFile}")
248 endif()
249 endif()
250 endif()
251 endforeach()
252 if (COTIRE_DEBUG)
253 if (_sourceFiles)
254 message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}")
255 endif()
256 if (_excludedSourceFiles)
257 message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}")
258 endif()
259 if (_cotiredSourceFiles)
260 message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}")
261 endif()
262 endif()
263 set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE)
264 set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE)
265 set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE)
266endfunction()
267
268function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
269 set (_filteredObjects "")
270 foreach (_object ${ARGN})
271 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
272 if (_isSet)
273 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
274 if (_propertyValue)
275 list (APPEND _filteredObjects "${_object}")
276 endif()
277 endif()
278 endforeach()
279 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
280endfunction()
281
282function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
283 set (_filteredObjects "")
284 foreach (_object ${ARGN})
285 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
286 if (_isSet)
287 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
288 if (NOT _propertyValue)
289 list (APPEND _filteredObjects "${_object}")
290 endif()
291 endif()
292 endforeach()
293 set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
294endfunction()
295
296function (cotire_get_source_file_property_values _valuesVar _property)
297 set (_values "")
298 foreach (_sourceFile ${ARGN})
299 get_source_file_property(_propertyValue "${_sourceFile}" ${_property})
300 if (_propertyValue)
301 list (APPEND _values "${_propertyValue}")
302 endif()
303 endforeach()
304 set (${_valuesVar} ${_values} PARENT_SCOPE)
305endfunction()
306
307function (cotire_resolve_config_properties _configurations _propertiesVar)
308 set (_properties "")
309 foreach (_property ${ARGN})
310 if ("${_property}" MATCHES "<CONFIG>")
311 foreach (_config ${_configurations})
312 string (TOUPPER "${_config}" _upperConfig)
313 string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}")
314 list (APPEND _properties ${_configProperty})
315 endforeach()
316 else()
317 list (APPEND _properties ${_property})
318 endif()
319 endforeach()
320 set (${_propertiesVar} ${_properties} PARENT_SCOPE)
321endfunction()
322
323function (cotire_copy_set_properties _configurations _type _source _target)
324 cotire_resolve_config_properties("${_configurations}" _properties ${ARGN})
325 foreach (_property ${_properties})
326 get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
327 if (_isSet)
328 get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
329 set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
330 endif()
331 endforeach()
332endfunction()
333
334function (cotire_get_target_usage_requirements _target _config _targetRequirementsVar)
335 set (_targetRequirements "")
336 get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES)
337 while (_librariesToProcess)
338 # remove from head
339 list (GET _librariesToProcess 0 _library)
340 list (REMOVE_AT _librariesToProcess 0)
341 if (_library MATCHES "^\\$<\\$<CONFIG:${_config}>:([A-Za-z0-9_:-]+)>$")
342 set (_library "${CMAKE_MATCH_1}")
343 elseif (_config STREQUAL "None" AND _library MATCHES "^\\$<\\$<CONFIG:>:([A-Za-z0-9_:-]+)>$")
344 set (_library "${CMAKE_MATCH_1}")
345 endif()
346 if (TARGET ${_library})
347 list (FIND _targetRequirements ${_library} _index)
348 if (_index LESS 0)
349 list (APPEND _targetRequirements ${_library})
350 # BFS traversal of transitive libraries
351 get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES)
352 if (_libraries)
353 list (APPEND _librariesToProcess ${_libraries})
354 list (REMOVE_DUPLICATES _librariesToProcess)
355 endif()
356 endif()
357 endif()
358 endwhile()
359 set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE)
360endfunction()
361
362function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar)
363 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
364 set (_flagPrefix "[/-]")
365 else()
366 set (_flagPrefix "--?")
367 endif()
368 set (_optionFlag "")
369 set (_matchedOptions "")
370 set (_unmatchedOptions "")
371 foreach (_compileFlag ${ARGN})
372 if (_compileFlag)
373 if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}")
374 # option with separate argument
375 list (APPEND _matchedOptions "${_compileFlag}")
376 set (_optionFlag "")
377 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$")
378 # remember option
379 set (_optionFlag "${CMAKE_MATCH_2}")
380 elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$")
381 # option with joined argument
382 list (APPEND _matchedOptions "${CMAKE_MATCH_3}")
383 set (_optionFlag "")
384 else()
385 # flush remembered option
386 if (_optionFlag)
387 list (APPEND _matchedOptions "${_optionFlag}")
388 set (_optionFlag "")
389 endif()
390 # add to unfiltered options
391 list (APPEND _unmatchedOptions "${_compileFlag}")
392 endif()
393 endif()
394 endforeach()
395 if (_optionFlag)
396 list (APPEND _matchedOptions "${_optionFlag}")
397 endif()
398 if (COTIRE_DEBUG AND _matchedOptions)
399 message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}")
400 endif()
401 if (COTIRE_DEBUG AND _unmatchedOptions)
402 message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}")
403 endif()
404 set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE)
405 set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE)
406endfunction()
407
408function (cotire_is_target_supported _target _isSupportedVar)
409 if (NOT TARGET "${_target}")
410 set (${_isSupportedVar} FALSE PARENT_SCOPE)
411 return()
412 endif()
413 get_target_property(_imported ${_target} IMPORTED)
414 if (_imported)
415 set (${_isSupportedVar} FALSE PARENT_SCOPE)
416 return()
417 endif()
418 get_target_property(_targetType ${_target} TYPE)
419 if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
420 set (${_isSupportedVar} FALSE PARENT_SCOPE)
421 return()
422 endif()
423 set (${_isSupportedVar} TRUE PARENT_SCOPE)
424endfunction()
425
426function (cotire_get_target_compile_flags _config _language _target _flagsVar)
427 string (TOUPPER "${_config}" _upperConfig)
428 # collect options from CMake language variables
429 set (_compileFlags "")
430 if (CMAKE_${_language}_FLAGS)
431 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
432 endif()
433 if (CMAKE_${_language}_FLAGS_${_upperConfig})
434 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}")
435 endif()
436 if (_target)
437 # add target compile flags
438 get_target_property(_targetflags ${_target} COMPILE_FLAGS)
439 if (_targetflags)
440 set (_compileFlags "${_compileFlags} ${_targetflags}")
441 endif()
442 endif()
443 if (UNIX)
444 separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}")
445 elseif(WIN32)
446 separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}")
447 else()
448 separate_arguments(_compileFlags)
449 endif()
450 # target compile options
451 if (_target)
452 get_target_property(_targetOptions ${_target} COMPILE_OPTIONS)
453 if (_targetOptions)
454 list (APPEND _compileFlags ${_targetOptions})
455 endif()
456 endif()
457 # interface compile options from linked library targets
458 if (_target)
459 set (_linkedTargets "")
460 cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets)
461 foreach (_linkedTarget ${_linkedTargets})
462 get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS)
463 if (_targetOptions)
464 list (APPEND _compileFlags ${_targetOptions})
465 endif()
466 endforeach()
467 endif()
468 # handle language standard properties
469 if (CMAKE_${_language}_STANDARD_DEFAULT)
470 # used compiler supports language standard levels
471 if (_target)
472 get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD)
473 if (_targetLanguageStandard)
474 set (_type "EXTENSION")
475 get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET)
476 if (_isSet)
477 get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS)
478 if (NOT _targetUseLanguageExtensions)
479 set (_type "STANDARD")
480 endif()
481 endif()
482 if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION)
483 list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}")
484 endif()
485 endif()
486 endif()
487 endif()
488 # handle the POSITION_INDEPENDENT_CODE target property
489 if (_target)
490 get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE)
491 if (_targetPIC)
492 get_target_property(_targetType ${_target} TYPE)
493 if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE)
494 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}")
495 elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC)
496 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}")
497 endif()
498 endif()
499 endif()
500 # handle visibility target properties
501 if (_target)
502 get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET)
503 if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY)
504 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}")
505 endif()
506 get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN)
507 if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN)
508 list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}")
509 endif()
510 endif()
511 # platform specific flags
512 if (APPLE)
513 get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig})
514 if (NOT _architectures)
515 get_target_property(_architectures ${_target} OSX_ARCHITECTURES)
516 endif()
517 if (_architectures)
518 foreach (_arch ${_architectures})
519 list (APPEND _compileFlags "-arch" "${_arch}")
520 endforeach()
521 endif()
522 if (CMAKE_OSX_SYSROOT)
523 if (CMAKE_${_language}_SYSROOT_FLAG)
524 list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}")
525 else()
526 list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}")
527 endif()
528 endif()
529 if (CMAKE_OSX_DEPLOYMENT_TARGET)
530 if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG)
531 list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
532 else()
533 list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
534 endif()
535 endif()
536 endif()
537 if (COTIRE_DEBUG AND _compileFlags)
538 message (STATUS "Target ${_target} compile flags: ${_compileFlags}")
539 endif()
540 set (${_flagsVar} ${_compileFlags} PARENT_SCOPE)
541endfunction()
542
543function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar)
544 set (_includeDirs "")
545 set (_systemIncludeDirs "")
546 # default include dirs
547 if (CMAKE_INCLUDE_CURRENT_DIR)
548 list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}")
549 list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}")
550 endif()
551 set (_targetFlags "")
552 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
553 # parse additional include directories from target compile flags
554 if (CMAKE_INCLUDE_FLAG_${_language})
555 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
556 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
557 if (_includeFlag)
558 set (_dirs "")
559 cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags})
560 if (_dirs)
561 list (APPEND _includeDirs ${_dirs})
562 endif()
563 endif()
564 endif()
565 # parse additional system include directories from target compile flags
566 if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language})
567 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag)
568 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
569 if (_includeFlag)
570 set (_dirs "")
571 cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags})
572 if (_dirs)
573 list (APPEND _systemIncludeDirs ${_dirs})
574 endif()
575 endif()
576 endif()
577 # target include directories
578 get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES)
579 if (_target)
580 get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES)
581 if (_targetDirs)
582 list (APPEND _dirs ${_targetDirs})
583 endif()
584 get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
585 if (_targetDirs)
586 list (APPEND _systemIncludeDirs ${_targetDirs})
587 endif()
588 endif()
589 # interface include directories from linked library targets
590 if (_target)
591 set (_linkedTargets "")
592 cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets)
593 foreach (_linkedTarget ${_linkedTargets})
594 get_target_property(_linkedTargetType ${_linkedTarget} TYPE)
595 if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND
596 _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
597 # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR
598 # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR
599 # which are only available with CMake 3.4 or later.
600 get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR)
601 if (_targetDirs)
602 list (APPEND _dirs ${_targetDirs})
603 endif()
604 get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR)
605 if (_targetDirs)
606 list (APPEND _dirs ${_targetDirs})
607 endif()
608 endif()
609 get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES)
610 if (_targetDirs)
611 list (APPEND _dirs ${_targetDirs})
612 endif()
613 get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
614 if (_targetDirs)
615 list (APPEND _systemIncludeDirs ${_targetDirs})
616 endif()
617 endforeach()
618 endif()
619 if (dirs)
620 list (REMOVE_DUPLICATES _dirs)
621 endif()
622 list (LENGTH _includeDirs _projectInsertIndex)
623 foreach (_dir ${_dirs})
624 if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE)
625 cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
626 if (_isRelative)
627 list (LENGTH _includeDirs _len)
628 if (_len EQUAL _projectInsertIndex)
629 list (APPEND _includeDirs "${_dir}")
630 else()
631 list (INSERT _includeDirs _projectInsertIndex "${_dir}")
632 endif()
633 math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1")
634 else()
635 list (APPEND _includeDirs "${_dir}")
636 endif()
637 else()
638 list (APPEND _includeDirs "${_dir}")
639 endif()
640 endforeach()
641 list (REMOVE_DUPLICATES _includeDirs)
642 list (REMOVE_DUPLICATES _systemIncludeDirs)
643 if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES)
644 list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES})
645 endif()
646 if (WIN32 AND NOT MINGW)
647 # convert Windows paths in include directories to CMake paths
648 if (_includeDirs)
649 set (_paths "")
650 foreach (_dir ${_includeDirs})
651 file (TO_CMAKE_PATH "${_dir}" _path)
652 list (APPEND _paths "${_path}")
653 endforeach()
654 set (_includeDirs ${_paths})
655 endif()
656 if (_systemIncludeDirs)
657 set (_paths "")
658 foreach (_dir ${_systemIncludeDirs})
659 file (TO_CMAKE_PATH "${_dir}" _path)
660 list (APPEND _paths "${_path}")
661 endforeach()
662 set (_systemIncludeDirs ${_paths})
663 endif()
664 endif()
665 if (COTIRE_DEBUG AND _includeDirs)
666 message (STATUS "Target ${_target} include dirs: ${_includeDirs}")
667 endif()
668 set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE)
669 if (COTIRE_DEBUG AND _systemIncludeDirs)
670 message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}")
671 endif()
672 set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE)
673endfunction()
674
675function (cotire_get_target_export_symbol _target _exportSymbolVar)
676 set (_exportSymbol "")
677 get_target_property(_targetType ${_target} TYPE)
678 get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
679 if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
680 (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
681 get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
682 if (NOT _exportSymbol)
683 set (_exportSymbol "${_target}_EXPORTS")
684 endif()
685 string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol)
686 endif()
687 set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
688endfunction()
689
690function (cotire_get_target_compile_definitions _config _language _target _definitionsVar)
691 string (TOUPPER "${_config}" _upperConfig)
692 set (_configDefinitions "")
693 # CMAKE_INTDIR for multi-configuration build systems
694 if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
695 list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
696 endif()
697 # target export define symbol
698 cotire_get_target_export_symbol("${_target}" _defineSymbol)
699 if (_defineSymbol)
700 list (APPEND _configDefinitions "${_defineSymbol}")
701 endif()
702 # directory compile definitions
703 get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS)
704 if (_definitions)
705 list (APPEND _configDefinitions ${_definitions})
706 endif()
707 get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig})
708 if (_definitions)
709 list (APPEND _configDefinitions ${_definitions})
710 endif()
711 # target compile definitions
712 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS)
713 if (_definitions)
714 list (APPEND _configDefinitions ${_definitions})
715 endif()
716 get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig})
717 if (_definitions)
718 list (APPEND _configDefinitions ${_definitions})
719 endif()
720 # interface compile definitions from linked library targets
721 set (_linkedTargets "")
722 cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets)
723 foreach (_linkedTarget ${_linkedTargets})
724 get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS)
725 if (_definitions)
726 list (APPEND _configDefinitions ${_definitions})
727 endif()
728 endforeach()
729 # parse additional compile definitions from target compile flags
730 # and do not look at directory compile definitions, which we already handled
731 set (_targetFlags "")
732 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
733 cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags})
734 if (_definitions)
735 list (APPEND _configDefinitions ${_definitions})
736 endif()
737 list (REMOVE_DUPLICATES _configDefinitions)
738 if (COTIRE_DEBUG AND _configDefinitions)
739 message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}")
740 endif()
741 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
742endfunction()
743
744function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar)
745 # parse target compile flags omitting compile definitions and include directives
746 set (_targetFlags "")
747 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
748 set (_flagFilter "D")
749 if (CMAKE_INCLUDE_FLAG_${_language})
750 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
751 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
752 if (_includeFlag)
753 set (_flagFilter "${_flagFilter}|${_includeFlag}")
754 endif()
755 endif()
756 if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language})
757 string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag)
758 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
759 if (_includeFlag)
760 set (_flagFilter "${_flagFilter}|${_includeFlag}")
761 endif()
762 endif()
763 set (_compilerFlags "")
764 cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags})
765 if (COTIRE_DEBUG AND _compilerFlags)
766 message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}")
767 endif()
768 set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE)
769endfunction()
770
771function (cotire_add_sys_root_paths _pathsVar)
772 if (APPLE)
773 if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT)
774 foreach (_path IN LISTS ${_pathsVar})
775 if (IS_ABSOLUTE "${_path}")
776 get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE)
777 if (EXISTS "${_path}")
778 list (APPEND ${_pathsVar} "${_path}")
779 endif()
780 endif()
781 endforeach()
782 endif()
783 endif()
784 set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE)
785endfunction()
786
787function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar)
788 set (_extraProperties ${ARGN})
789 set (_result "")
790 if (_extraProperties)
791 list (FIND _extraProperties "${_sourceFile}" _index)
792 if (_index GREATER -1)
793 math (EXPR _index "${_index} + 1")
794 list (LENGTH _extraProperties _len)
795 math (EXPR _len "${_len} - 1")
796 foreach (_index RANGE ${_index} ${_len})
797 list (GET _extraProperties ${_index} _value)
798 if (_value MATCHES "${_pattern}")
799 list (APPEND _result "${_value}")
800 else()
801 break()
802 endif()
803 endforeach()
804 endif()
805 endif()
806 set (${_resultVar} ${_result} PARENT_SCOPE)
807endfunction()
808
809function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
810 set (_compileDefinitions "")
811 if (NOT CMAKE_SCRIPT_MODE_FILE)
812 string (TOUPPER "${_config}" _upperConfig)
813 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
814 if (_definitions)
815 list (APPEND _compileDefinitions ${_definitions})
816 endif()
817 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig})
818 if (_definitions)
819 list (APPEND _compileDefinitions ${_definitions})
820 endif()
821 endif()
822 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN})
823 if (_definitions)
824 list (APPEND _compileDefinitions ${_definitions})
825 endif()
826 if (COTIRE_DEBUG AND _compileDefinitions)
827 message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}")
828 endif()
829 set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE)
830endfunction()
831
832function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
833 set (_configDefinitions "")
834 foreach (_sourceFile ${ARGN})
835 cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
836 if (_sourceDefinitions)
837 list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
838 endif()
839 endforeach()
840 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
841endfunction()
842
843function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
844 set (_sourceUndefs "")
845 if (NOT CMAKE_SCRIPT_MODE_FILE)
846 get_source_file_property(_undefs "${_sourceFile}" ${_property})
847 if (_undefs)
848 list (APPEND _sourceUndefs ${_undefs})
849 endif()
850 endif()
851 cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN})
852 if (_undefs)
853 list (APPEND _sourceUndefs ${_undefs})
854 endif()
855 if (COTIRE_DEBUG AND _sourceUndefs)
856 message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}")
857 endif()
858 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
859endfunction()
860
861function (cotire_get_source_files_undefs _property _sourceUndefsVar)
862 set (_sourceUndefs "")
863 foreach (_sourceFile ${ARGN})
864 cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs)
865 if (_undefs)
866 list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-")
867 endif()
868 endforeach()
869 set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
870endfunction()
871
872macro (cotire_set_cmd_to_prologue _cmdVar)
873 set (${_cmdVar} "${CMAKE_COMMAND}")
874 if (COTIRE_DEBUG)
875 list (APPEND ${_cmdVar} "--warn-uninitialized")
876 endif()
877 list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>")
878 if (XCODE)
879 list (APPEND ${_cmdVar} "-DXCODE:BOOL=TRUE")
880 endif()
881 if (COTIRE_VERBOSE)
882 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON")
883 elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles")
884 list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)")
885 endif()
886endmacro()
887
888function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1)
889 if (NOT _compilerLauncher)
890 set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER})
891 endif()
892 if (NOT _compilerExe)
893 set (_compilerExe "${CMAKE_${_language}_COMPILER}")
894 endif()
895 if (NOT _compilerArg1)
896 set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1})
897 endif()
898 if (WIN32)
899 file (TO_NATIVE_PATH "${_compilerExe}" _compilerExe)
900 endif()
901 string (STRIP "${_compilerArg1}" _compilerArg1)
902 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
903 # compiler launcher is only supported for Makefile and Ninja
904 set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
905 else()
906 set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
907 endif()
908endfunction()
909
910macro (cotire_add_definitions_to_cmd _cmdVar _language)
911 foreach (_definition ${ARGN})
912 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
913 list (APPEND ${_cmdVar} "/D${_definition}")
914 else()
915 list (APPEND ${_cmdVar} "-D${_definition}")
916 endif()
917 endforeach()
918endmacro()
919
920function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar)
921 set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}})
922 if (_includeDirs)
923 list (REMOVE_DUPLICATES _includeDirs)
924 foreach (_include ${_includeDirs})
925 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
926 file (TO_NATIVE_PATH "${_include}" _include)
927 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}")
928 else()
929 set (_index -1)
930 if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+")
931 list (FIND ${_systemIncludesVar} "${_include}" _index)
932 endif()
933 if (_index GREATER -1)
934 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}")
935 else()
936 list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}")
937 endif()
938 endif()
939 endforeach()
940 endif()
941 set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE)
942endfunction()
943
944function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar)
945 if (APPLE)
946 set (_frameworkDirs "")
947 foreach (_include ${${_includesVar}})
948 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
949 get_filename_component(_frameworkDir "${_include}" DIRECTORY)
950 list (APPEND _frameworkDirs "${_frameworkDir}")
951 endif()
952 endforeach()
953 set (_systemFrameworkDirs "")
954 foreach (_include ${${_systemIncludesVar}})
955 if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$")
956 get_filename_component(_frameworkDir "${_include}" DIRECTORY)
957 list (APPEND _systemFrameworkDirs "${_frameworkDir}")
958 endif()
959 endforeach()
960 if (_systemFrameworkDirs)
961 list (APPEND _frameworkDirs ${_systemFrameworkDirs})
962 endif()
963 if (_frameworkDirs)
964 list (REMOVE_DUPLICATES _frameworkDirs)
965 foreach (_frameworkDir ${_frameworkDirs})
966 set (_index -1)
967 if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+")
968 list (FIND _systemFrameworkDirs "${_frameworkDir}" _index)
969 endif()
970 if (_index GREATER -1)
971 list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}")
972 else()
973 list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}")
974 endif()
975 endforeach()
976 endif()
977 endif()
978 set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE)
979endfunction()
980
981macro (cotire_add_compile_flags_to_cmd _cmdVar)
982 foreach (_flag ${ARGN})
983 list (APPEND ${_cmdVar} "${_flag}")
984 endforeach()
985endmacro()
986
987function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
988 if (EXISTS "${_file}")
989 set (_triggerFile "")
990 foreach (_dependencyFile ${ARGN})
991 if (EXISTS "${_dependencyFile}")
992 # IS_NEWER_THAN returns TRUE if both files have the same timestamp
993 # thus we do the comparison in both directions to exclude ties
994 if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND
995 NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}")
996 set (_triggerFile "${_dependencyFile}")
997 break()
998 endif()
999 endif()
1000 endforeach()
1001 if (_triggerFile)
1002 if (COTIRE_VERBOSE)
1003 get_filename_component(_fileName "${_file}" NAME)
1004 message (STATUS "${_fileName} update triggered by ${_triggerFile} change.")
1005 endif()
1006 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
1007 else()
1008 if (COTIRE_VERBOSE)
1009 get_filename_component(_fileName "${_file}" NAME)
1010 message (STATUS "${_fileName} is up-to-date.")
1011 endif()
1012 set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE)
1013 endif()
1014 else()
1015 if (COTIRE_VERBOSE)
1016 get_filename_component(_fileName "${_file}" NAME)
1017 message (STATUS "${_fileName} does not exist yet.")
1018 endif()
1019 set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
1020 endif()
1021endfunction()
1022
1023macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
1024 set (${_relPathVar} "")
1025 foreach (_includeDir ${_includeDirs})
1026 if (IS_DIRECTORY "${_includeDir}")
1027 file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
1028 if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
1029 string (LENGTH "${${_relPathVar}}" _closestLen)
1030 string (LENGTH "${_relPath}" _relLen)
1031 if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
1032 set (${_relPathVar} "${_relPath}")
1033 endif()
1034 endif()
1035 elseif ("${_includeDir}" STREQUAL "${_headerFile}")
1036 # if path matches exactly, return short non-empty string
1037 set (${_relPathVar} "1")
1038 break()
1039 endif()
1040 endforeach()
1041endmacro()
1042
1043macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside)
1044 # check header path against ignored and honored include directories
1045 cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath)
1046 if (_insideRelPath)
1047 # header is inside, but could be become outside if there is a shorter outside match
1048 cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath)
1049 if (_outsideRelPath)
1050 string (LENGTH "${_insideRelPath}" _insideRelPathLen)
1051 string (LENGTH "${_outsideRelPath}" _outsideRelPathLen)
1052 if (_outsideRelPathLen LESS _insideRelPathLen)
1053 set (${_headerIsInside} FALSE)
1054 else()
1055 set (${_headerIsInside} TRUE)
1056 endif()
1057 else()
1058 set (${_headerIsInside} TRUE)
1059 endif()
1060 else()
1061 # header is outside
1062 set (${_headerIsInside} FALSE)
1063 endif()
1064endmacro()
1065
1066macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
1067 if (NOT EXISTS "${_headerFile}")
1068 set (${_headerIsIgnoredVar} TRUE)
1069 elseif (IS_DIRECTORY "${_headerFile}")
1070 set (${_headerIsIgnoredVar} TRUE)
1071 elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed")
1072 # heuristic: ignore headers with embedded parent directory references or "-fixed" or "_fixed" in path
1073 # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
1074 # with the error message "error: no include path in which to search for header"
1075 set (${_headerIsIgnoredVar} TRUE)
1076 else()
1077 set (${_headerIsIgnoredVar} FALSE)
1078 endif()
1079endmacro()
1080
1081macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
1082 # check header file extension
1083 cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
1084 set (${_headerIsIgnoredVar} FALSE)
1085 if (_headerFileExt)
1086 list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
1087 if (_index GREATER -1)
1088 set (${_headerIsIgnoredVar} TRUE)
1089 endif()
1090 endif()
1091endmacro()
1092
1093macro (cotire_parse_line _line _headerFileVar _headerDepthVar)
1094 if (MSVC)
1095 # cl.exe /showIncludes produces different output, depending on the language pack used, e.g.:
1096 # English: "Note: including file: C:\directory\file"
1097 # German: "Hinweis: Einlesen der Datei: C:\directory\file"
1098 # We use a very general regular expression, relying on the presence of the : characters
1099 if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$")
1100 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
1101 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE)
1102 else()
1103 set (${_headerFileVar} "")
1104 set (${_headerDepthVar} 0)
1105 endif()
1106 else()
1107 if (_line MATCHES "^(\\.+) (.*)$")
1108 # GCC like output
1109 string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
1110 if (IS_ABSOLUTE "${CMAKE_MATCH_2}")
1111 set (${_headerFileVar} "${CMAKE_MATCH_2}")
1112 else()
1113 get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH)
1114 endif()
1115 else()
1116 set (${_headerFileVar} "")
1117 set (${_headerDepthVar} 0)
1118 endif()
1119 endif()
1120endmacro()
1121
1122function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar)
1123 if (WIN32)
1124 # prevent CMake macro invocation errors due to backslash characters in Windows paths
1125 string (REPLACE "\\" "/" _scanOutput "${_scanOutput}")
1126 endif()
1127 # canonize slashes
1128 string (REPLACE "//" "/" _scanOutput "${_scanOutput}")
1129 # prevent semicolon from being interpreted as a line separator
1130 string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}")
1131 # then separate lines
1132 string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}")
1133 list (LENGTH _scanOutput _len)
1134 # remove duplicate lines to speed up parsing
1135 list (REMOVE_DUPLICATES _scanOutput)
1136 list (LENGTH _scanOutput _uniqueLen)
1137 if (COTIRE_VERBOSE OR COTIRE_DEBUG)
1138 message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes")
1139 if (_ignoredExtensions)
1140 message (STATUS "Ignored extensions: ${_ignoredExtensions}")
1141 endif()
1142 if (_ignoredIncludeDirs)
1143 message (STATUS "Ignored paths: ${_ignoredIncludeDirs}")
1144 endif()
1145 if (_honoredIncludeDirs)
1146 message (STATUS "Included paths: ${_honoredIncludeDirs}")
1147 endif()
1148 endif()
1149 set (_sourceFiles ${ARGN})
1150 set (_selectedIncludes "")
1151 set (_unparsedLines "")
1152 # stack keeps track of inside/outside project status of processed header files
1153 set (_headerIsInsideStack "")
1154 foreach (_line IN LISTS _scanOutput)
1155 if (_line)
1156 cotire_parse_line("${_line}" _headerFile _headerDepth)
1157 if (_headerFile)
1158 cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside)
1159 if (COTIRE_DEBUG)
1160 message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}")
1161 endif()
1162 # update stack
1163 list (LENGTH _headerIsInsideStack _stackLen)
1164 if (_headerDepth GREATER _stackLen)
1165 math (EXPR _stackLen "${_stackLen} + 1")
1166 foreach (_index RANGE ${_stackLen} ${_headerDepth})
1167 list (APPEND _headerIsInsideStack ${_headerIsInside})
1168 endforeach()
1169 else()
1170 foreach (_index RANGE ${_headerDepth} ${_stackLen})
1171 list (REMOVE_AT _headerIsInsideStack -1)
1172 endforeach()
1173 list (APPEND _headerIsInsideStack ${_headerIsInside})
1174 endif()
1175 if (COTIRE_DEBUG)
1176 message (STATUS "${_headerIsInsideStack}")
1177 endif()
1178 # header is a candidate if it is outside project
1179 if (NOT _headerIsInside)
1180 # get parent header file's inside/outside status
1181 if (_headerDepth GREATER 1)
1182 math (EXPR _index "${_headerDepth} - 2")
1183 list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside)
1184 else()
1185 set (_parentHeaderIsInside TRUE)
1186 endif()
1187 # select header file if parent header file is inside project
1188 # (e.g., a project header file that includes a standard header file)
1189 if (_parentHeaderIsInside)
1190 cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored)
1191 if (NOT _headerIsIgnored)
1192 cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored)
1193 if (NOT _headerIsIgnored)
1194 list (APPEND _selectedIncludes "${_headerFile}")
1195 else()
1196 # fix header's inside status on stack, it is ignored by extension now
1197 list (REMOVE_AT _headerIsInsideStack -1)
1198 list (APPEND _headerIsInsideStack TRUE)
1199 endif()
1200 endif()
1201 if (COTIRE_DEBUG)
1202 message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}")
1203 endif()
1204 endif()
1205 endif()
1206 else()
1207 if (MSVC)
1208 # for cl.exe do not keep unparsed lines which solely consist of a source file name
1209 string (FIND "${_sourceFiles}" "${_line}" _index)
1210 if (_index LESS 0)
1211 list (APPEND _unparsedLines "${_line}")
1212 endif()
1213 else()
1214 list (APPEND _unparsedLines "${_line}")
1215 endif()
1216 endif()
1217 endif()
1218 endforeach()
1219 list (REMOVE_DUPLICATES _selectedIncludes)
1220 set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE)
1221 set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE)
1222endfunction()
1223
1224function (cotire_scan_includes _includesVar)
1225 set(_options "")
1226 set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT)
1227 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES
1228 IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER)
1229 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1230 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1231 if (NOT _option_LANGUAGE)
1232 set (_option_LANGUAGE "CXX")
1233 endif()
1234 if (NOT _option_COMPILER_ID)
1235 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1236 endif()
1237 if (NOT _option_COMPILER_VERSION)
1238 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1239 endif()
1240 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1241 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1242 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1243 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1244 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1245 cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd)
1246 # only consider existing source files for scanning
1247 set (_existingSourceFiles "")
1248 foreach (_sourceFile ${_sourceFiles})
1249 if (EXISTS "${_sourceFile}")
1250 list (APPEND _existingSourceFiles "${_sourceFile}")
1251 endif()
1252 endforeach()
1253 if (NOT _existingSourceFiles)
1254 set (${_includesVar} "" PARENT_SCOPE)
1255 return()
1256 endif()
1257 # add source files to be scanned
1258 if (WIN32)
1259 foreach (_sourceFile ${_existingSourceFiles})
1260 file (TO_NATIVE_PATH "${_sourceFile}" _sourceFileNative)
1261 list (APPEND _cmd "${_sourceFileNative}")
1262 endforeach()
1263 else()
1264 list (APPEND _cmd ${_existingSourceFiles})
1265 endif()
1266 if (COTIRE_VERBOSE)
1267 message (STATUS "execute_process: ${_cmd}")
1268 endif()
1269 if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC")
1270 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1271 unset (ENV{VS_UNICODE_OUTPUT})
1272 endif()
1273 execute_process(
1274 COMMAND ${_cmd}
1275 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1276 RESULT_VARIABLE _result
1277 OUTPUT_QUIET
1278 ERROR_VARIABLE _output)
1279 if (_result)
1280 message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.")
1281 endif()
1282 cotire_parse_includes(
1283 "${_option_LANGUAGE}" "${_output}"
1284 "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}"
1285 "${_option_IGNORE_EXTENSIONS}"
1286 _includes _unparsedLines
1287 ${_sourceFiles})
1288 if (_option_INCLUDE_PRIORITY_PATH)
1289 set (_sortedIncludes "")
1290 foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH})
1291 foreach (_include ${_includes})
1292 string (FIND ${_include} ${_priorityPath} _position)
1293 if (_position GREATER -1)
1294 list (APPEND _sortedIncludes ${_include})
1295 endif()
1296 endforeach()
1297 endforeach()
1298 if (_sortedIncludes)
1299 list (INSERT _includes 0 ${_sortedIncludes})
1300 list (REMOVE_DUPLICATES _includes)
1301 endif()
1302 endif()
1303 set (${_includesVar} ${_includes} PARENT_SCOPE)
1304 if (_option_UNPARSED_LINES)
1305 set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE)
1306 endif()
1307 if (_option_SCAN_RESULT)
1308 set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE)
1309 endif()
1310endfunction()
1311
1312macro (cotire_append_undefs _contentsVar)
1313 set (_undefs ${ARGN})
1314 if (_undefs)
1315 list (REMOVE_DUPLICATES _undefs)
1316 foreach (_definition ${_undefs})
1317 list (APPEND ${_contentsVar} "#undef ${_definition}")
1318 endforeach()
1319 endif()
1320endmacro()
1321
1322macro (cotire_comment_str _language _commentText _commentVar)
1323 if ("${_language}" STREQUAL "CMAKE")
1324 set (${_commentVar} "# ${_commentText}")
1325 else()
1326 set (${_commentVar} "/* ${_commentText} */")
1327 endif()
1328endmacro()
1329
1330function (cotire_write_file _language _file _contents _force)
1331 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1332 cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
1333 cotire_comment_str("${_language}" "${_file}" _header2)
1334 set (_contents "${_header1}\n${_header2}\n${_contents}")
1335 if (COTIRE_DEBUG)
1336 message (STATUS "${_contents}")
1337 endif()
1338 if (_force OR NOT EXISTS "${_file}")
1339 file (WRITE "${_file}" "${_contents}")
1340 else()
1341 file (READ "${_file}" _oldContents)
1342 if (NOT "${_oldContents}" STREQUAL "${_contents}")
1343 file (WRITE "${_file}" "${_contents}")
1344 else()
1345 if (COTIRE_DEBUG)
1346 message (STATUS "${_file} unchanged")
1347 endif()
1348 endif()
1349 endif()
1350endfunction()
1351
1352function (cotire_generate_unity_source _unityFile)
1353 set(_options "")
1354 set(_oneValueArgs LANGUAGE)
1355 set(_multiValueArgs
1356 DEPENDS SOURCES_COMPILE_DEFINITIONS
1357 PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE)
1358 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1359 if (_option_DEPENDS)
1360 cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS})
1361 if (_unityFileIsUpToDate)
1362 return()
1363 endif()
1364 endif()
1365 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1366 if (NOT _option_PRE_UNDEFS)
1367 set (_option_PRE_UNDEFS "")
1368 endif()
1369 if (NOT _option_SOURCES_PRE_UNDEFS)
1370 set (_option_SOURCES_PRE_UNDEFS "")
1371 endif()
1372 if (NOT _option_POST_UNDEFS)
1373 set (_option_POST_UNDEFS "")
1374 endif()
1375 if (NOT _option_SOURCES_POST_UNDEFS)
1376 set (_option_SOURCES_POST_UNDEFS "")
1377 endif()
1378 set (_contents "")
1379 if (_option_PROLOGUE)
1380 list (APPEND _contents ${_option_PROLOGUE})
1381 endif()
1382 if (_option_LANGUAGE AND _sourceFiles)
1383 if ("${_option_LANGUAGE}" STREQUAL "CXX")
1384 list (APPEND _contents "#ifdef __cplusplus")
1385 elseif ("${_option_LANGUAGE}" STREQUAL "C")
1386 list (APPEND _contents "#ifndef __cplusplus")
1387 endif()
1388 endif()
1389 set (_compileUndefinitions "")
1390 foreach (_sourceFile ${_sourceFiles})
1391 cotire_get_source_compile_definitions(
1392 "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions
1393 ${_option_SOURCES_COMPILE_DEFINITIONS})
1394 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS})
1395 cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS})
1396 if (_option_PRE_UNDEFS)
1397 list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS})
1398 endif()
1399 if (_sourcePreUndefs)
1400 list (APPEND _compileUndefinitions ${_sourcePreUndefs})
1401 endif()
1402 if (_compileUndefinitions)
1403 cotire_append_undefs(_contents ${_compileUndefinitions})
1404 set (_compileUndefinitions "")
1405 endif()
1406 if (_sourcePostUndefs)
1407 list (APPEND _compileUndefinitions ${_sourcePostUndefs})
1408 endif()
1409 if (_option_POST_UNDEFS)
1410 list (APPEND _compileUndefinitions ${_option_POST_UNDEFS})
1411 endif()
1412 foreach (_definition ${_compileDefinitions})
1413 if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$")
1414 list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}")
1415 list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}")
1416 else()
1417 list (APPEND _contents "#define ${_definition}")
1418 list (INSERT _compileUndefinitions 0 "${_definition}")
1419 endif()
1420 endforeach()
1421 # use absolute path as source file location
1422 get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE)
1423 if (WIN32)
1424 file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation)
1425 endif()
1426 list (APPEND _contents "#include \"${_sourceFileLocation}\"")
1427 endforeach()
1428 if (_compileUndefinitions)
1429 cotire_append_undefs(_contents ${_compileUndefinitions})
1430 set (_compileUndefinitions "")
1431 endif()
1432 if (_option_LANGUAGE AND _sourceFiles)
1433 list (APPEND _contents "#endif")
1434 endif()
1435 if (_option_EPILOGUE)
1436 list (APPEND _contents ${_option_EPILOGUE})
1437 endif()
1438 list (APPEND _contents "")
1439 string (REPLACE ";" "\n" _contents "${_contents}")
1440 if (COTIRE_VERBOSE)
1441 message ("${_contents}")
1442 endif()
1443 cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE)
1444endfunction()
1445
1446function (cotire_generate_prefix_header _prefixFile)
1447 set(_options "")
1448 set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION)
1449 set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS
1450 INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH
1451 IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER)
1452 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1453 if (NOT _option_COMPILER_ID)
1454 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1455 endif()
1456 if (NOT _option_COMPILER_VERSION)
1457 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1458 endif()
1459 if (_option_DEPENDS)
1460 cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS})
1461 if (_prefixFileIsUpToDate)
1462 # create empty log file
1463 set (_unparsedLinesFile "${_prefixFile}.log")
1464 file (WRITE "${_unparsedLinesFile}" "")
1465 return()
1466 endif()
1467 endif()
1468 set (_prologue "")
1469 set (_epilogue "")
1470 if (_option_COMPILER_ID MATCHES "Clang")
1471 set (_prologue "#pragma clang system_header")
1472 elseif (_option_COMPILER_ID MATCHES "GNU")
1473 set (_prologue "#pragma GCC system_header")
1474 elseif (_option_COMPILER_ID MATCHES "MSVC")
1475 set (_prologue "#pragma warning(push, 0)")
1476 set (_epilogue "#pragma warning(pop)")
1477 elseif (_option_COMPILER_ID MATCHES "Intel")
1478 # Intel compiler requires hdrstop pragma to stop generating PCH file
1479 set (_epilogue "#pragma hdrstop")
1480 endif()
1481 set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
1482 cotire_scan_includes(_selectedHeaders ${_sourceFiles}
1483 LANGUAGE "${_option_LANGUAGE}"
1484 COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}"
1485 COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}"
1486 COMPILER_ARG1 "${_option_COMPILER_ARG1}"
1487 COMPILER_ID "${_option_COMPILER_ID}"
1488 COMPILER_VERSION "${_option_COMPILER_VERSION}"
1489 COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS}
1490 COMPILE_FLAGS ${_option_COMPILE_FLAGS}
1491 INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES}
1492 SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES}
1493 IGNORE_PATH ${_option_IGNORE_PATH}
1494 INCLUDE_PATH ${_option_INCLUDE_PATH}
1495 IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS}
1496 INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH}
1497 UNPARSED_LINES _unparsedLines
1498 SCAN_RESULT _scanResult)
1499 cotire_generate_unity_source("${_prefixFile}"
1500 PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders})
1501 set (_unparsedLinesFile "${_prefixFile}.log")
1502 if (_unparsedLines)
1503 if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders)
1504 list (LENGTH _unparsedLines _skippedLineCount)
1505 if (WIN32)
1506 file (TO_NATIVE_PATH "${_unparsedLinesFile}" _unparsedLinesLogPath)
1507 else()
1508 set (_unparsedLinesLogPath "${_unparsedLinesFile}")
1509 endif()
1510 message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesLogPath}")
1511 endif()
1512 string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}")
1513 endif()
1514 file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n")
1515endfunction()
1516
1517function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
1518 set (_flags ${${_flagsVar}})
1519 if (_compilerID MATCHES "MSVC")
1520 # cl.exe options used
1521 # /nologo suppresses display of sign-on banner
1522 # /TC treat all files named on the command line as C source files
1523 # /TP treat all files named on the command line as C++ source files
1524 # /EP preprocess to stdout without #line directives
1525 # /showIncludes list include files
1526 set (_sourceFileTypeC "/TC")
1527 set (_sourceFileTypeCXX "/TP")
1528 if (_flags)
1529 # append to list
1530 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes)
1531 else()
1532 # return as a flag string
1533 set (_flags "${_sourceFileType${_language}} /EP /showIncludes")
1534 endif()
1535 elseif (_compilerID MATCHES "GNU")
1536 # GCC options used
1537 # -H print the name of each header file used
1538 # -E invoke preprocessor
1539 # -fdirectives-only do not expand macros, requires GCC >= 4.3
1540 if (_flags)
1541 # append to list
1542 list (APPEND _flags -H -E)
1543 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1544 list (APPEND _flags -fdirectives-only)
1545 endif()
1546 else()
1547 # return as a flag string
1548 set (_flags "-H -E")
1549 if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
1550 set (_flags "${_flags} -fdirectives-only")
1551 endif()
1552 endif()
1553 elseif (_compilerID MATCHES "Clang")
1554 if (UNIX)
1555 # Clang options used
1556 # -H print the name of each header file used
1557 # -E invoke preprocessor
1558 # -fno-color-diagnostics do not print diagnostics in color
1559 # -Eonly just run preprocessor, no output
1560 if (_flags)
1561 # append to list
1562 list (APPEND _flags -H -E -fno-color-diagnostics -Xclang -Eonly)
1563 else()
1564 # return as a flag string
1565 set (_flags "-H -E -fno-color-diagnostics -Xclang -Eonly")
1566 endif()
1567 elseif (WIN32)
1568 # Clang-cl.exe options used
1569 # /TC treat all files named on the command line as C source files
1570 # /TP treat all files named on the command line as C++ source files
1571 # /EP preprocess to stdout without #line directives
1572 # -H print the name of each header file used
1573 # -fno-color-diagnostics do not print diagnostics in color
1574 # -Eonly just run preprocessor, no output
1575 set (_sourceFileTypeC "/TC")
1576 set (_sourceFileTypeCXX "/TP")
1577 if (_flags)
1578 # append to list
1579 list (APPEND _flags "${_sourceFileType${_language}}" /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly)
1580 else()
1581 # return as a flag string
1582 set (_flags "${_sourceFileType${_language}} /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly")
1583 endif()
1584 endif()
1585 elseif (_compilerID MATCHES "Intel")
1586 if (WIN32)
1587 # Windows Intel options used
1588 # /nologo do not display compiler version information
1589 # /QH display the include file order
1590 # /EP preprocess to stdout, omitting #line directives
1591 # /TC process all source or unrecognized file types as C source files
1592 # /TP process all source or unrecognized file types as C++ source files
1593 set (_sourceFileTypeC "/TC")
1594 set (_sourceFileTypeCXX "/TP")
1595 if (_flags)
1596 # append to list
1597 list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH)
1598 else()
1599 # return as a flag string
1600 set (_flags "${_sourceFileType${_language}} /EP /QH")
1601 endif()
1602 else()
1603 # Linux / Mac OS X Intel options used
1604 # -H print the name of each header file used
1605 # -EP preprocess to stdout, omitting #line directives
1606 # -Kc++ process all source or unrecognized file types as C++ source files
1607 if (_flags)
1608 # append to list
1609 if ("${_language}" STREQUAL "CXX")
1610 list (APPEND _flags -Kc++)
1611 endif()
1612 list (APPEND _flags -H -EP)
1613 else()
1614 # return as a flag string
1615 if ("${_language}" STREQUAL "CXX")
1616 set (_flags "-Kc++ ")
1617 endif()
1618 set (_flags "${_flags}-H -EP")
1619 endif()
1620 endif()
1621 else()
1622 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1623 endif()
1624 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1625endfunction()
1626
1627function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
1628 set (_flags ${${_flagsVar}})
1629 if (_compilerID MATCHES "MSVC")
1630 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1631 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1632 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1633 # cl.exe options used
1634 # /Yc creates a precompiled header file
1635 # /Fp specifies precompiled header binary file name
1636 # /FI forces inclusion of file
1637 # /TC treat all files named on the command line as C source files
1638 # /TP treat all files named on the command line as C++ source files
1639 # /Zs syntax check only
1640 # /Zm precompiled header memory allocation scaling factor
1641 set (_sourceFileTypeC "/TC")
1642 set (_sourceFileTypeCXX "/TP")
1643 if (_flags)
1644 # append to list
1645 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1646 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1647 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1648 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1649 endif()
1650 else()
1651 # return as a flag string
1652 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1653 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1654 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1655 endif()
1656 endif()
1657 elseif (_compilerID MATCHES "GNU")
1658 # GCC options used
1659 # -x specify the source language
1660 # -c compile but do not link
1661 # -o place output in file
1662 # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may
1663 # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings)
1664 set (_xLanguage_C "c-header")
1665 set (_xLanguage_CXX "c++-header")
1666 if (_flags)
1667 # append to list
1668 list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}")
1669 else()
1670 # return as a flag string
1671 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1672 endif()
1673 elseif (_compilerID MATCHES "Clang")
1674 if (UNIX)
1675 # Clang options used
1676 # -x specify the source language
1677 # -c compile but do not link
1678 # -o place output in file
1679 # -fno-pch-timestamp disable inclusion of timestamp in precompiled headers (clang 4.0.0+)
1680 set (_xLanguage_C "c-header")
1681 set (_xLanguage_CXX "c++-header")
1682 if (_flags)
1683 # append to list
1684 list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}")
1685 if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0")
1686 list (APPEND _flags -Xclang -fno-pch-timestamp)
1687 endif()
1688 else()
1689 # return as a flag string
1690 set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
1691 if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0")
1692 set (_flags "${_flags} -Xclang -fno-pch-timestamp")
1693 endif()
1694 endif()
1695 elseif (WIN32)
1696 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1697 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1698 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1699 # Clang-cl.exe options used
1700 # /Yc creates a precompiled header file
1701 # /Fp specifies precompiled header binary file name
1702 # /FI forces inclusion of file
1703 # /Zs syntax check only
1704 # /TC treat all files named on the command line as C source files
1705 # /TP treat all files named on the command line as C++ source files
1706 set (_sourceFileTypeC "/TC")
1707 set (_sourceFileTypeCXX "/TP")
1708 if (_flags)
1709 # append to list
1710 list (APPEND _flags "${_sourceFileType${_language}}"
1711 "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1712 else()
1713 # return as a flag string
1714 set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1715 endif()
1716 endif()
1717 elseif (_compilerID MATCHES "Intel")
1718 if (WIN32)
1719 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1720 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1721 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1722 # Windows Intel options used
1723 # /nologo do not display compiler version information
1724 # /Yc create a precompiled header (PCH) file
1725 # /Fp specify a path or file name for precompiled header files
1726 # /FI tells the preprocessor to include a specified file name as the header file
1727 # /TC process all source or unrecognized file types as C source files
1728 # /TP process all source or unrecognized file types as C++ source files
1729 # /Zs syntax check only
1730 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1731 set (_sourceFileTypeC "/TC")
1732 set (_sourceFileTypeCXX "/TP")
1733 if (_flags)
1734 # append to list
1735 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1736 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1737 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1738 list (APPEND _flags "/Wpch-messages")
1739 endif()
1740 else()
1741 # return as a flag string
1742 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1743 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1744 set (_flags "${_flags} /Wpch-messages")
1745 endif()
1746 endif()
1747 else()
1748 # Linux / Mac OS X Intel options used
1749 # -pch-dir location for precompiled header files
1750 # -pch-create name of the precompiled header (PCH) to create
1751 # -Kc++ process all source or unrecognized file types as C++ source files
1752 # -fsyntax-only check only for correct syntax
1753 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1754 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1755 get_filename_component(_pchName "${_pchFile}" NAME)
1756 set (_xLanguage_C "c-header")
1757 set (_xLanguage_CXX "c++-header")
1758 set (_pchSuppressMessages FALSE)
1759 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1760 set(_pchSuppressMessages TRUE)
1761 endif()
1762 if (_flags)
1763 # append to list
1764 if ("${_language}" STREQUAL "CXX")
1765 list (APPEND _flags -Kc++)
1766 endif()
1767 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}")
1768 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1769 if (NOT _pchSuppressMessages)
1770 list (APPEND _flags -Wpch-messages)
1771 endif()
1772 endif()
1773 else()
1774 # return as a flag string
1775 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1776 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1777 if (NOT _pchSuppressMessages)
1778 set (_flags "${_flags} -Wpch-messages")
1779 endif()
1780 endif()
1781 endif()
1782 endif()
1783 else()
1784 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1785 endif()
1786 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1787endfunction()
1788
1789function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1790 set (_flags ${${_flagsVar}})
1791 if (_compilerID MATCHES "MSVC")
1792 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1793 # cl.exe options used
1794 # /Yu uses a precompiled header file during build
1795 # /Fp specifies precompiled header binary file name
1796 # /FI forces inclusion of file
1797 # /Zm precompiled header memory allocation scaling factor
1798 if (_pchFile)
1799 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1800 if (_flags)
1801 # append to list
1802 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1803 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1804 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1805 endif()
1806 else()
1807 # return as a flag string
1808 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1809 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1810 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1811 endif()
1812 endif()
1813 else()
1814 # no precompiled header, force inclusion of prefix header
1815 if (_flags)
1816 # append to list
1817 list (APPEND _flags "/FI${_prefixFileNative}")
1818 else()
1819 # return as a flag string
1820 set (_flags "/FI\"${_prefixFileNative}\"")
1821 endif()
1822 endif()
1823 elseif (_compilerID MATCHES "GNU")
1824 # GCC options used
1825 # -include process include file as the first line of the primary source file
1826 # -Winvalid-pch warns if precompiled header is found but cannot be used
1827 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1828 if (_flags)
1829 # append to list
1830 list (APPEND _flags -Winvalid-pch -include "${_prefixFile}")
1831 else()
1832 # return as a flag string
1833 set (_flags "-Winvalid-pch -include \"${_prefixFile}\"")
1834 endif()
1835 elseif (_compilerID MATCHES "Clang")
1836 if (UNIX)
1837 # Clang options used
1838 # -include process include file as the first line of the primary source file
1839 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1840 if (_flags)
1841 # append to list
1842 list (APPEND _flags -include "${_prefixFile}")
1843 else()
1844 # return as a flag string
1845 set (_flags "-include \"${_prefixFile}\"")
1846 endif()
1847 elseif (WIN32)
1848 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1849 # Clang-cl.exe options used
1850 # /Yu uses a precompiled header file during build
1851 # /Fp specifies precompiled header binary file name
1852 # /FI forces inclusion of file
1853 if (_pchFile)
1854 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1855 if (_flags)
1856 # append to list
1857 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1858 else()
1859 # return as a flag string
1860 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1861 endif()
1862 else()
1863 # no precompiled header, force inclusion of prefix header
1864 if (_flags)
1865 # append to list
1866 list (APPEND _flags "/FI${_prefixFileNative}")
1867 else()
1868 # return as a flag string
1869 set (_flags "/FI\"${_prefixFileNative}\"")
1870 endif()
1871 endif()
1872 endif()
1873 elseif (_compilerID MATCHES "Intel")
1874 if (WIN32)
1875 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1876 # Windows Intel options used
1877 # /Yu use a precompiled header (PCH) file
1878 # /Fp specify a path or file name for precompiled header files
1879 # /FI tells the preprocessor to include a specified file name as the header file
1880 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1881 if (_pchFile)
1882 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1883 if (_flags)
1884 # append to list
1885 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1886 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1887 list (APPEND _flags "/Wpch-messages")
1888 endif()
1889 else()
1890 # return as a flag string
1891 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1892 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1893 set (_flags "${_flags} /Wpch-messages")
1894 endif()
1895 endif()
1896 else()
1897 # no precompiled header, force inclusion of prefix header
1898 if (_flags)
1899 # append to list
1900 list (APPEND _flags "/FI${_prefixFileNative}")
1901 else()
1902 # return as a flag string
1903 set (_flags "/FI\"${_prefixFileNative}\"")
1904 endif()
1905 endif()
1906 else()
1907 # Linux / Mac OS X Intel options used
1908 # -pch-dir location for precompiled header files
1909 # -pch-use name of the precompiled header (PCH) to use
1910 # -include process include file as the first line of the primary source file
1911 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1912 if (_pchFile)
1913 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1914 get_filename_component(_pchName "${_pchFile}" NAME)
1915 set (_pchSuppressMessages FALSE)
1916 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1917 set(_pchSuppressMessages TRUE)
1918 endif()
1919 if (_flags)
1920 # append to list
1921 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}")
1922 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1923 if (NOT _pchSuppressMessages)
1924 list (APPEND _flags -Wpch-messages)
1925 endif()
1926 endif()
1927 else()
1928 # return as a flag string
1929 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1930 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1931 if (NOT _pchSuppressMessages)
1932 set (_flags "${_flags} -Wpch-messages")
1933 endif()
1934 endif()
1935 endif()
1936 else()
1937 # no precompiled header, force inclusion of prefix header
1938 if (_flags)
1939 # append to list
1940 list (APPEND _flags -include "${_prefixFile}")
1941 else()
1942 # return as a flag string
1943 set (_flags "-include \"${_prefixFile}\"")
1944 endif()
1945 endif()
1946 endif()
1947 else()
1948 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1949 endif()
1950 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1951endfunction()
1952
1953function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1954 set(_options "")
1955 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE)
1956 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER)
1957 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1958 if (NOT _option_LANGUAGE)
1959 set (_option_LANGUAGE "CXX")
1960 endif()
1961 if (NOT _option_COMPILER_ID)
1962 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1963 endif()
1964 if (NOT _option_COMPILER_VERSION)
1965 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1966 endif()
1967 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1968 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1969 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1970 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1971 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1972 cotire_add_pch_compilation_flags(
1973 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1974 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1975 if (COTIRE_VERBOSE)
1976 message (STATUS "execute_process: ${_cmd}")
1977 endif()
1978 if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC")
1979 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1980 unset (ENV{VS_UNICODE_OUTPUT})
1981 elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0")
1982 if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR
1983 _option_COMPILER_EXECUTABLE MATCHES "ccache")
1984 # Newer versions of Clang embed a compilation timestamp into the precompiled header binary,
1985 # which results in "file has been modified since the precompiled header was built" errors if ccache is used.
1986 # We work around the problem by disabling ccache upon pre-compiling the prefix header.
1987 set (ENV{CCACHE_DISABLE} "true")
1988 endif()
1989 endif()
1990 execute_process(
1991 COMMAND ${_cmd}
1992 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1993 RESULT_VARIABLE _result)
1994 if (_result)
1995 message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.")
1996 endif()
1997endfunction()
1998
1999function (cotire_check_precompiled_header_support _language _target _msgVar)
2000 set (_unsupportedCompiler
2001 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
2002 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2003 # PCH supported since Visual Studio C++ 6.0
2004 # and CMake does not support an earlier version
2005 set (${_msgVar} "" PARENT_SCOPE)
2006 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2007 # GCC PCH support requires version >= 3.4
2008 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
2009 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2010 else()
2011 set (${_msgVar} "" PARENT_SCOPE)
2012 endif()
2013 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2014 if (UNIX)
2015 # all Unix Clang versions have PCH support
2016 set (${_msgVar} "" PARENT_SCOPE)
2017 elseif (WIN32)
2018 # only clang-cl is supported under Windows
2019 get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE)
2020 if (NOT _compilerName MATCHES "cl$")
2021 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE)
2022 endif()
2023 endif()
2024 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2025 # Intel PCH support requires version >= 8.0.0
2026 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
2027 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2028 else()
2029 set (${_msgVar} "" PARENT_SCOPE)
2030 endif()
2031 else()
2032 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
2033 endif()
2034 # check if ccache is used as a compiler launcher
2035 get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER)
2036 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH)
2037 if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache")
2038 # verify that ccache configuration is compatible with precompiled headers
2039 # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache
2040 # do not report the "sloppiness" setting correctly upon printing ccache configuration
2041 if (DEFINED ENV{CCACHE_SLOPPINESS})
2042 if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR
2043 NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros")
2044 set (${_msgVar}
2045 "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"."
2046 PARENT_SCOPE)
2047 endif()
2048 else()
2049 if (_realCompilerExe MATCHES "ccache")
2050 set (_ccacheExe "${_realCompilerExe}")
2051 else()
2052 set (_ccacheExe "${_launcher}")
2053 endif()
2054 # ccache 3.7.0 replaced --print-config with --show-config
2055 # use -p instead, which seems to work for all version for now, sigh
2056 execute_process(
2057 COMMAND "${_ccacheExe}" "-p"
2058 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
2059 RESULT_VARIABLE _result
2060 OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE
2061 ERROR_QUIET)
2062 if (_result)
2063 set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE)
2064 elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR
2065 NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines")
2066 set (${_msgVar}
2067 "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"."
2068 PARENT_SCOPE)
2069 endif()
2070 endif()
2071 endif()
2072 if (APPLE)
2073 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
2074 cotire_get_configuration_types(_configs)
2075 foreach (_config ${_configs})
2076 set (_targetFlags "")
2077 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
2078 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
2079 list (LENGTH _architectures _numberOfArchitectures)
2080 if (_numberOfArchitectures GREATER 1)
2081 string (REPLACE ";" ", " _architectureStr "${_architectures}")
2082 set (${_msgVar}
2083 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
2084 PARENT_SCOPE)
2085 break()
2086 endif()
2087 endforeach()
2088 endif()
2089endfunction()
2090
2091macro (cotire_get_intermediate_dir _cotireDir)
2092 # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types
2093 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
2094endmacro()
2095
2096macro (cotire_setup_file_extension_variables)
2097 set (_unityFileExt_C ".c")
2098 set (_unityFileExt_CXX ".cxx")
2099 set (_prefixFileExt_C ".h")
2100 set (_prefixFileExt_CXX ".hxx")
2101 set (_prefixSourceFileExt_C ".c")
2102 set (_prefixSourceFileExt_CXX ".cxx")
2103endmacro()
2104
2105function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
2106 cotire_setup_file_extension_variables()
2107 if (NOT DEFINED _unityFileExt_${_language})
2108 set (${_unityFileVar} "" PARENT_SCOPE)
2109 return()
2110 endif()
2111 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2112 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
2113 cotire_get_intermediate_dir(_baseDir)
2114 set (_unityFile "${_baseDir}/${_unityFileName}")
2115 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
2116endfunction()
2117
2118function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
2119 cotire_setup_file_extension_variables()
2120 if (NOT DEFINED _unityFileExt_${_language})
2121 set (${_unityFileVar} "" PARENT_SCOPE)
2122 return()
2123 endif()
2124 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2125 cotire_get_intermediate_dir(_baseDir)
2126 set (_startIndex 0)
2127 set (_index 0)
2128 set (_unityFiles "")
2129 set (_sourceFiles ${ARGN})
2130 foreach (_sourceFile ${_sourceFiles})
2131 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
2132 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
2133 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
2134 if (_index GREATER 0)
2135 # start new unity file segment
2136 math (EXPR _endIndex "${_index} - 1")
2137 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2138 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2139 endif()
2140 set (_startIndex ${_index})
2141 endif()
2142 math (EXPR _index "${_index} + 1")
2143 endforeach()
2144 list (LENGTH _sourceFiles _numberOfSources)
2145 if (_startIndex EQUAL 0)
2146 # there is only a single unity file
2147 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
2148 elseif (_startIndex LESS _numberOfSources)
2149 # end with final unity file segment
2150 math (EXPR _endIndex "${_index} - 1")
2151 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2152 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2153 endif()
2154 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
2155 if (COTIRE_DEBUG AND _unityFiles)
2156 message (STATUS "unity files: ${_unityFiles}")
2157 endif()
2158endfunction()
2159
2160function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
2161 cotire_setup_file_extension_variables()
2162 if (NOT DEFINED _unityFileExt_${_language})
2163 set (${_prefixFileVar} "" PARENT_SCOPE)
2164 return()
2165 endif()
2166 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2167 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2168 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
2169 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
2170 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
2171endfunction()
2172
2173function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar)
2174 cotire_setup_file_extension_variables()
2175 if (NOT DEFINED _prefixSourceFileExt_${_language})
2176 set (${_prefixSourceFileVar} "" PARENT_SCOPE)
2177 return()
2178 endif()
2179 string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}")
2180 set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE)
2181endfunction()
2182
2183function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
2184 cotire_setup_file_extension_variables()
2185 if (NOT _language)
2186 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2187 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
2188 elseif (DEFINED _prefixFileExt_${_language})
2189 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2190 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
2191 else()
2192 set (_prefixFileBaseName "")
2193 set (_prefixFileName "")
2194 endif()
2195 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
2196 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
2197endfunction()
2198
2199function (cotire_make_prefix_file_path _language _target _prefixFileVar)
2200 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2201 set (${_prefixFileVar} "" PARENT_SCOPE)
2202 if (_prefixFileName)
2203 if (NOT _language)
2204 set (_language "C")
2205 endif()
2206 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC")
2207 cotire_get_intermediate_dir(_baseDir)
2208 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
2209 endif()
2210 endif()
2211endfunction()
2212
2213function (cotire_make_pch_file_path _language _target _pchFileVar)
2214 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2215 set (${_pchFileVar} "" PARENT_SCOPE)
2216 if (_prefixFileBaseName AND _prefixFileName)
2217 cotire_check_precompiled_header_support("${_language}" "${_target}" _msg)
2218 if (NOT _msg)
2219 if (XCODE)
2220 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
2221 return()
2222 endif()
2223 cotire_get_intermediate_dir(_baseDir)
2224 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2225 # MSVC uses the extension .pch added to the prefix header base name
2226 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
2227 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2228 # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended
2229 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE)
2230 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2231 # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended
2232 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
2233 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2234 # Intel uses the extension .pchi added to the prefix header base name
2235 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
2236 endif()
2237 endif()
2238 endif()
2239endfunction()
2240
2241function (cotire_select_unity_source_files _unityFile _sourcesVar)
2242 set (_sourceFiles ${ARGN})
2243 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
2244 set (_startIndex ${CMAKE_MATCH_1})
2245 set (_endIndex ${CMAKE_MATCH_2})
2246 list (LENGTH _sourceFiles _numberOfSources)
2247 if (NOT _startIndex LESS _numberOfSources)
2248 math (EXPR _startIndex "${_numberOfSources} - 1")
2249 endif()
2250 if (NOT _endIndex LESS _numberOfSources)
2251 math (EXPR _endIndex "${_numberOfSources} - 1")
2252 endif()
2253 set (_files "")
2254 foreach (_index RANGE ${_startIndex} ${_endIndex})
2255 list (GET _sourceFiles ${_index} _file)
2256 list (APPEND _files "${_file}")
2257 endforeach()
2258 else()
2259 set (_files ${_sourceFiles})
2260 endif()
2261 set (${_sourcesVar} ${_files} PARENT_SCOPE)
2262endfunction()
2263
2264function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
2265 set (_dependencySources "")
2266 # depend on target's generated source files
2267 get_target_property(_targetSourceFiles ${_target} SOURCES)
2268 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2269 if (_generatedSources)
2270 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
2271 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
2272 if (_excludedGeneratedSources)
2273 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
2274 endif()
2275 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
2276 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
2277 if (_excludedNonDependencySources)
2278 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
2279 endif()
2280 if (_generatedSources)
2281 list (APPEND _dependencySources ${_generatedSources})
2282 endif()
2283 endif()
2284 if (COTIRE_DEBUG AND _dependencySources)
2285 message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}")
2286 endif()
2287 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2288endfunction()
2289
2290function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
2291 set (_dependencySources "")
2292 # depend on target source files marked with custom COTIRE_DEPENDENCY property
2293 get_target_property(_targetSourceFiles ${_target} SOURCES)
2294 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles})
2295 if (COTIRE_DEBUG AND _dependencySources)
2296 message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}")
2297 endif()
2298 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2299endfunction()
2300
2301function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar)
2302 set (_targetSources ${ARGN})
2303 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources})
2304 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources})
2305 # set up variables to be configured
2306 set (COTIRE_TARGET_LANGUAGE "${_language}")
2307 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
2308 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
2309 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
2310 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
2311 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
2312 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
2313 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2314 get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH)
2315 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources})
2316 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources})
2317 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
2318 foreach (_config ${_configurations})
2319 string (TOUPPER "${_config}" _upperConfig)
2320 cotire_get_target_include_directories(
2321 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig})
2322 cotire_get_target_compile_definitions(
2323 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
2324 cotire_get_target_compiler_flags(
2325 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
2326 cotire_get_source_files_compile_definitions(
2327 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources})
2328 endforeach()
2329 get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER)
2330 # set up COTIRE_TARGET_SOURCES
2331 set (COTIRE_TARGET_SOURCES "")
2332 foreach (_sourceFile ${_targetSources})
2333 get_source_file_property(_generated "${_sourceFile}" GENERATED)
2334 if (_generated)
2335 # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation
2336 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2337 list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}")
2338 else()
2339 list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}")
2340 endif()
2341 endforeach()
2342 # copy variable definitions to cotire target script
2343 get_cmake_property(_vars VARIABLES)
2344 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
2345 # omit COTIRE_*_INIT variables
2346 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}")
2347 if (_initVars)
2348 list (REMOVE_ITEM _matchVars ${_initVars})
2349 endif()
2350 # omit COTIRE_VERBOSE which is passed as a CMake define on command line
2351 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
2352 set (_contents "")
2353 set (_contentsHasGeneratorExpressions FALSE)
2354 foreach (_var IN LISTS _matchVars ITEMS
2355 XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
2356 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION
2357 CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
2358 CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language}
2359 CMAKE_INCLUDE_SYSTEM_FLAG_${_language}
2360 CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG
2361 CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG
2362 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
2363 if (DEFINED ${_var})
2364 string (REPLACE "\"" "\\\"" _value "${${_var}}")
2365 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
2366 if (NOT _contentsHasGeneratorExpressions)
2367 if ("${_value}" MATCHES "\\$<.*>")
2368 set (_contentsHasGeneratorExpressions TRUE)
2369 endif()
2370 endif()
2371 endif()
2372 endforeach()
2373 # generate target script file
2374 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
2375 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
2376 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
2377 if (_contentsHasGeneratorExpressions)
2378 # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time
2379 set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>")
2380 set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}")
2381 file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}")
2382 else()
2383 set (_targetCotireConfigScript "${_targetCotireScript}")
2384 endif()
2385 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
2386 set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE)
2387endfunction()
2388
2389function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile)
2390 set (_sourceFiles ${ARGN})
2391 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2392 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2393 # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file
2394 # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion
2395 if (_sourceFiles)
2396 set (_flags "")
2397 cotire_add_pch_compilation_flags(
2398 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2399 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
2400 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2401 if (COTIRE_DEBUG)
2402 message (STATUS "set_property: SOURCE ${_hostFile} APPEND_STRING COMPILE_FLAGS ${_flags}")
2403 endif()
2404 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
2405 # make object file generated from host file depend on prefix header
2406 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2407 # mark host file as cotired to prevent it from being used in another cotired target
2408 set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}")
2409 endif()
2410 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2411 # for makefile based generator, we add a custom command to precompile the prefix header
2412 if (_targetScript)
2413 cotire_set_cmd_to_prologue(_cmds)
2414 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
2415 if (MSVC_IDE)
2416 file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath)
2417 else()
2418 file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
2419 endif()
2420 # make precompiled header compilation depend on the actual compiler executable used to force
2421 # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable"
2422 # warnings when the precompiled header is included.
2423 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2424 if (COTIRE_DEBUG)
2425 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
2426 endif()
2427 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
2428 add_custom_command(
2429 OUTPUT "${_pchFile}"
2430 COMMAND ${_cmds}
2431 DEPENDS "${_prefixFile}" "${_realCompilerExe}"
2432 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
2433 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2434 COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}"
2435 VERBATIM)
2436 endif()
2437 endif()
2438endfunction()
2439
2440function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile)
2441 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2442 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2443 # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file
2444 # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation
2445 set (_sourceFiles ${ARGN})
2446 list (LENGTH _sourceFiles _numberOfSourceFiles)
2447 if (_numberOfSourceFiles GREATER 0)
2448 # mark sources as cotired to prevent them from being used in another cotired target
2449 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2450 set (_flags "")
2451 cotire_add_prefix_pch_inclusion_flags(
2452 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2453 "${_prefixFile}" "${_pchFile}" _flags)
2454 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2455 if (COTIRE_DEBUG)
2456 message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}")
2457 endif()
2458 # make object files generated from source files depend on precompiled header
2459 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2460 endif()
2461 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2462 set (_sourceFiles ${_hostFile} ${ARGN})
2463 if (NOT _wholeTarget)
2464 # for makefile based generator, we force the inclusion of the prefix header for a subset
2465 # of the source files, if this is a multi-language target or has excluded files
2466 set (_flags "")
2467 cotire_add_prefix_pch_inclusion_flags(
2468 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2469 "${_prefixFile}" "${_pchFile}" _flags)
2470 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2471 if (COTIRE_DEBUG)
2472 message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}")
2473 endif()
2474 # mark sources as cotired to prevent them from being used in another cotired target
2475 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2476 endif()
2477 # make object files generated from source files depend on precompiled header
2478 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2479 endif()
2480endfunction()
2481
2482function (cotire_setup_prefix_file_inclusion _language _target _prefixFile)
2483 set (_sourceFiles ${ARGN})
2484 # force the inclusion of the prefix header for the given source files
2485 set (_flags "")
2486 set (_pchFile "")
2487 cotire_add_prefix_pch_inclusion_flags(
2488 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2489 "${_prefixFile}" "${_pchFile}" _flags)
2490 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2491 if (COTIRE_DEBUG)
2492 message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}")
2493 endif()
2494 # mark sources as cotired to prevent them from being used in another cotired target
2495 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2496 # make object files generated from source files depend on prefix header
2497 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2498endfunction()
2499
2500function (cotire_get_first_set_property_value _propertyValueVar _type _object)
2501 set (_properties ${ARGN})
2502 foreach (_property ${_properties})
2503 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
2504 if (_propertyValue)
2505 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
2506 return()
2507 endif()
2508 endforeach()
2509 set (${_propertyValueVar} "" PARENT_SCOPE)
2510endfunction()
2511
2512function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar)
2513 set (_files ${ARGN})
2514 set (_filesPaths "")
2515 foreach (_file ${_files})
2516 get_filename_component(_filePath "${_file}" ABSOLUTE)
2517 list (APPEND _filesPaths "${_filePath}")
2518 endforeach()
2519 cotire_set_cmd_to_prologue(_prefixCmd)
2520 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
2521 if (_targetScript)
2522 list (APPEND _prefixCmd "${_targetScript}")
2523 endif()
2524 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
2525 if (COTIRE_DEBUG)
2526 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
2527 endif()
2528 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
2529 if (MSVC_IDE)
2530 file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath)
2531 else()
2532 file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
2533 endif()
2534 get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE)
2535 get_filename_component(_joinedFileExt "${_joinedFile}" EXT)
2536 if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
2537 set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}")
2538 elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$")
2539 if (_joinedFileExt MATCHES "^\\.c")
2540 set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}")
2541 else()
2542 set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}")
2543 endif()
2544 else()
2545 set (_comment "Generating ${_joinedFileLogPath}")
2546 endif()
2547 add_custom_command(
2548 OUTPUT "${_joinedFile}"
2549 COMMAND ${_prefixCmd}
2550 DEPENDS ${_files}
2551 COMMENT "${_comment}"
2552 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2553 VERBATIM)
2554 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2555 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2556endfunction()
2557
2558function (cotire_setup_target_pch_usage _languages _target _wholeTarget)
2559 if (XCODE)
2560 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
2561 set (_prefixFiles "")
2562 foreach (_language ${_languages})
2563 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2564 if (_prefixFile)
2565 list (APPEND _prefixFiles "${_prefixFile}")
2566 endif()
2567 endforeach()
2568 set (_cmds ${ARGN})
2569 list (LENGTH _prefixFiles _numberOfPrefixFiles)
2570 if (_numberOfPrefixFiles GREATER 1)
2571 # we also generate a generic, single prefix header which includes all language specific prefix headers
2572 set (_language "")
2573 set (_targetScript "")
2574 cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader)
2575 cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles})
2576 else()
2577 set (_prefixHeader "${_prefixFiles}")
2578 endif()
2579 if (COTIRE_DEBUG)
2580 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
2581 endif()
2582 # because CMake PRE_BUILD command does not support dependencies,
2583 # we check dependencies explicity in cotire script mode when the pre-build action is run
2584 add_custom_command(
2585 TARGET "${_target}"
2586 PRE_BUILD ${_cmds}
2587 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2588 COMMENT "Updating target ${_target} prefix headers"
2589 VERBATIM)
2590 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
2591 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
2592 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
2593 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2594 # for makefile based generator, we force inclusion of the prefix header for all target source files
2595 # if this is a single-language target without any excluded files
2596 if (_wholeTarget)
2597 set (_language "${_languages}")
2598 # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level
2599 # see cotire_setup_pch_file_inclusion
2600 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
2601 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2602 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2603 if (_prefixFile)
2604 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
2605 set (_options COMPILE_OPTIONS)
2606 cotire_add_prefix_pch_inclusion_flags(
2607 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2608 "${_prefixFile}" "${_pchFile}" _options)
2609 set_property(TARGET ${_target} APPEND PROPERTY ${_options})
2610 if (COTIRE_DEBUG)
2611 message (STATUS "set_property: TARGET ${_target} APPEND PROPERTY ${_options}")
2612 endif()
2613 endif()
2614 endif()
2615 endif()
2616 endif()
2617endfunction()
2618
2619function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar)
2620 set (_dependencySources "")
2621 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
2622 foreach (_unityFile ${_unityFiles})
2623 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
2624 # set up compiled unity source dependencies via OBJECT_DEPENDS
2625 # this ensures that missing source files are generated before the unity file is compiled
2626 if (COTIRE_DEBUG AND _dependencySources)
2627 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
2628 endif()
2629 if (_dependencySources)
2630 # the OBJECT_DEPENDS property requires a list of full paths
2631 set (_objectDependsPaths "")
2632 foreach (_sourceFile ${_dependencySources})
2633 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2634 list (APPEND _objectDependsPaths "${_sourceLocation}")
2635 endforeach()
2636 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths})
2637 endif()
2638 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2639 # unity file compilation results in potentially huge object file,
2640 # thus use /bigobj by default unter cl.exe and Windows Intel
2641 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
2642 endif()
2643 cotire_set_cmd_to_prologue(_unityCmd)
2644 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}")
2645 if (CMAKE_VERSION VERSION_LESS "3.1.0")
2646 set (_unityCmdDepends "${_targetScript}")
2647 else()
2648 # CMake 3.1.0 supports generator expressions in arguments to DEPENDS
2649 set (_unityCmdDepends "${_targetConfigScript}")
2650 endif()
2651 if (MSVC_IDE)
2652 file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath)
2653 else()
2654 file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
2655 endif()
2656 if (COTIRE_DEBUG)
2657 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}")
2658 endif()
2659 add_custom_command(
2660 OUTPUT "${_unityFile}"
2661 COMMAND ${_unityCmd}
2662 DEPENDS ${_unityCmdDepends}
2663 COMMENT "Generating ${_language} unity source ${_unityFileLogPath}"
2664 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2665 VERBATIM)
2666 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
2667 endforeach()
2668 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2669endfunction()
2670
2671function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2672 set (_sourceFiles ${ARGN})
2673 set (_dependencySources "")
2674 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
2675 cotire_set_cmd_to_prologue(_prefixCmd)
2676 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles})
2677 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
2678 # make prefix header generation depend on the actual compiler executable used to force
2679 # re-generation when the compiler executable is updated. This prevents "file not found"
2680 # errors for compiler version specific system header files.
2681 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2682 if (COTIRE_DEBUG)
2683 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}")
2684 endif()
2685 if (MSVC_IDE)
2686 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath)
2687 else()
2688 file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
2689 endif()
2690 get_filename_component(_prefixFileExt "${_prefixFile}" EXT)
2691 if (_prefixFileExt MATCHES "^\\.c")
2692 set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}")
2693 else()
2694 set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}")
2695 endif()
2696 # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist
2697 # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence
2698 # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files
2699 set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre")
2700 if (TARGET ${_preTargetName})
2701 # custom helper target has already been generated while processing a different language
2702 list (APPEND _dependencySources ${_preTargetName})
2703 else()
2704 get_target_property(_targetSourceFiles ${_target} SOURCES)
2705 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2706 if (_generatedSources)
2707 add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources})
2708 cotire_init_target("${_preTargetName}")
2709 list (APPEND _dependencySources ${_preTargetName})
2710 endif()
2711 endif()
2712 add_custom_command(
2713 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
2714 COMMAND ${_prefixCmd}
2715 DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}"
2716 COMMENT "${_comment}"
2717 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2718 VERBATIM)
2719 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2720 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2721endfunction()
2722
2723function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2724 set (_sourceFiles ${ARGN})
2725 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2726 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2727 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2728 else()
2729 set (_prefixSourceFile "${_prefixFile}")
2730 endif()
2731 cotire_setup_prefix_generation_command(
2732 ${_language} ${_target} "${_targetScript}"
2733 "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2734 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2735 # set up generation of a prefix source file which includes the prefix header
2736 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2737 endif()
2738 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2739endfunction()
2740
2741function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar)
2742 set (_prefixHeaderFiles ${ARGN})
2743 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2744 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2745 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2746 else()
2747 set (_prefixSourceFile "${_prefixFile}")
2748 endif()
2749 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles})
2750 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2751 # set up generation of a prefix source file which includes the prefix header
2752 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2753 endif()
2754 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2755endfunction()
2756
2757function (cotire_init_cotire_target_properties _target)
2758 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2759 if (NOT _isSet)
2760 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2761 endif()
2762 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2763 if (NOT _isSet)
2764 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2765 endif()
2766 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2767 if (NOT _isSet)
2768 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2769 endif()
2770 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2771 if (NOT _isSet)
2772 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2773 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2774 if (NOT _isRelative)
2775 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2776 endif()
2777 endif()
2778 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2779 if (NOT _isSet)
2780 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2781 endif()
2782 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET)
2783 if (NOT _isSet)
2784 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "")
2785 endif()
2786 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2787 if (NOT _isSet)
2788 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2789 endif()
2790 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2791 if (NOT _isSet)
2792 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2793 endif()
2794 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET)
2795 if (NOT _isSet)
2796 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY")
2797 endif()
2798 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2799 if (NOT _isSet)
2800 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2801 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2802 else()
2803 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2804 endif()
2805 endif()
2806endfunction()
2807
2808function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2809 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2810 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2811 string (REPLACE ";" " " _languagesStr "${_languages}")
2812 math (EXPR _numberOfExcludedFiles "${ARGC} - 4")
2813 if (_numberOfExcludedFiles EQUAL 0)
2814 set (_excludedStr "")
2815 elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4)
2816 string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}")
2817 else()
2818 set (_excludedStr "excluding ${_numberOfExcludedFiles} files")
2819 endif()
2820 set (_targetMsg "")
2821 if (NOT _languages)
2822 set (_targetMsg "Target ${_target} cannot be cotired.")
2823 if (_disableMsg)
2824 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2825 endif()
2826 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2827 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2828 if (_disableMsg)
2829 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2830 endif()
2831 elseif (NOT _targetUsePCH)
2832 if (_excludedStr)
2833 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.")
2834 else()
2835 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2836 endif()
2837 if (_disableMsg)
2838 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2839 endif()
2840 elseif (NOT _targetAddSCU)
2841 if (_excludedStr)
2842 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.")
2843 else()
2844 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2845 endif()
2846 if (_disableMsg)
2847 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2848 endif()
2849 else()
2850 if (_excludedStr)
2851 set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.")
2852 else()
2853 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2854 endif()
2855 endif()
2856 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2857endfunction()
2858
2859function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar)
2860 set (_languages ${ARGN})
2861 set (_allSourceFiles "")
2862 set (_allExcludedSourceFiles "")
2863 set (_allCotiredSourceFiles "")
2864 set (_targetLanguages "")
2865 set (_pchEligibleTargetLanguages "")
2866 get_target_property(_targetType ${_target} TYPE)
2867 get_target_property(_targetSourceFiles ${_target} SOURCES)
2868 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2869 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2870 set (_disableMsg "")
2871 foreach (_language ${_languages})
2872 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2873 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2874 if (_prefixHeader OR _unityBuildFile)
2875 message (STATUS "cotire: target ${_target} has already been cotired.")
2876 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2877 return()
2878 endif()
2879 if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID)
2880 if (CMAKE_${_language}_COMPILER_ID)
2881 cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg)
2882 if (_disableMsg)
2883 set (_targetUsePCH FALSE)
2884 endif()
2885 endif()
2886 endif()
2887 set (_sourceFiles "")
2888 set (_excludedSources "")
2889 set (_cotiredSources "")
2890 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2891 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2892 list (APPEND _targetLanguages ${_language})
2893 endif()
2894 if (_sourceFiles)
2895 list (APPEND _allSourceFiles ${_sourceFiles})
2896 endif()
2897 list (LENGTH _sourceFiles _numberOfSources)
2898 if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2899 list (APPEND _pchEligibleTargetLanguages ${_language})
2900 endif()
2901 if (_excludedSources)
2902 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2903 endif()
2904 if (_cotiredSources)
2905 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2906 endif()
2907 endforeach()
2908 set (_targetMsgLevel STATUS)
2909 if (NOT _targetLanguages)
2910 string (REPLACE ";" " or " _languagesStr "${_languages}")
2911 set (_disableMsg "No ${_languagesStr} source files.")
2912 set (_targetUsePCH FALSE)
2913 set (_targetAddSCU FALSE)
2914 endif()
2915 if (_targetUsePCH)
2916 if (_allCotiredSourceFiles)
2917 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2918 list (REMOVE_DUPLICATES _cotireTargets)
2919 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2920 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2921 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2922 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2923 set (_targetMsgLevel SEND_ERROR)
2924 set (_targetUsePCH FALSE)
2925 elseif (NOT _pchEligibleTargetLanguages)
2926 set (_disableMsg "Too few applicable sources.")
2927 set (_targetUsePCH FALSE)
2928 elseif (XCODE AND _allExcludedSourceFiles)
2929 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2930 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2931 set (_targetUsePCH FALSE)
2932 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2933 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2934 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2935 set (_targetUsePCH FALSE)
2936 endif()
2937 endif()
2938 if (_targetAddSCU)
2939 # disable unity builds if automatic Qt processing is used
2940 get_target_property(_targetAutoMoc ${_target} AUTOMOC)
2941 get_target_property(_targetAutoUic ${_target} AUTOUIC)
2942 get_target_property(_targetAutoRcc ${_target} AUTORCC)
2943 if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc)
2944 if (_disableMsg)
2945 set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.")
2946 else()
2947 set (_disableMsg "Target uses automatic CMake Qt processing.")
2948 endif()
2949 set (_targetAddSCU FALSE)
2950 endif()
2951 endif()
2952 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2953 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2954 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2955 if (_targetMsg)
2956 if (NOT DEFINED COTIREMSG_${_target})
2957 set (COTIREMSG_${_target} "")
2958 endif()
2959 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2960 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2961 # cache message to avoid redundant messages on re-configure
2962 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2963 message (${_targetMsgLevel} "${_targetMsg}")
2964 endif()
2965 endif()
2966 list (LENGTH _targetLanguages _numberOfLanguages)
2967 if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles)
2968 set (${_wholeTargetVar} FALSE PARENT_SCOPE)
2969 else()
2970 set (${_wholeTargetVar} TRUE PARENT_SCOPE)
2971 endif()
2972 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2973endfunction()
2974
2975function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2976 set (_sourceFiles ${ARGN})
2977 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2978 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2979 if (DEFINED CMAKE_MATCH_2)
2980 set (_numberOfThreads "${CMAKE_MATCH_2}")
2981 else()
2982 set (_numberOfThreads "")
2983 endif()
2984 if (NOT _numberOfThreads)
2985 # use all available cores
2986 ProcessorCount(_numberOfThreads)
2987 endif()
2988 list (LENGTH _sourceFiles _numberOfSources)
2989 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2990 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2991 set (_maxIncludes 0)
2992 endif()
2993 if (COTIRE_DEBUG)
2994 message (STATUS "${_target} unity source max includes: ${_maxIncludes}")
2995 endif()
2996 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2997endfunction()
2998
2999function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar)
3000 set (${_cmdsVar} "" PARENT_SCOPE)
3001 get_target_property(_targetSourceFiles ${_target} SOURCES)
3002 set (_sourceFiles "")
3003 set (_excludedSources "")
3004 set (_cotiredSources "")
3005 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
3006 if (NOT _sourceFiles AND NOT _cotiredSources)
3007 return()
3008 endif()
3009 set (_cmds "")
3010 # check for user provided unity source file list
3011 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
3012 if (NOT _unitySourceFiles)
3013 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
3014 endif()
3015 cotire_generate_target_script(
3016 ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles})
3017 # set up unity files for parallel compilation
3018 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
3019 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
3020 list (LENGTH _unityFiles _numberOfUnityFiles)
3021 if (_numberOfUnityFiles EQUAL 0)
3022 return()
3023 elseif (_numberOfUnityFiles GREATER 1)
3024 cotire_setup_unity_generation_commands(
3025 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
3026 endif()
3027 # set up single unity file for prefix header generation
3028 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
3029 cotire_setup_unity_generation_commands(
3030 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles})
3031 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
3032 # set up prefix header
3033 if (_prefixFile)
3034 # check for user provided prefix header files
3035 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3036 if (_prefixHeaderFiles)
3037 cotire_setup_prefix_generation_from_provided_command(
3038 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
3039 else()
3040 cotire_setup_prefix_generation_from_unity_command(
3041 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles})
3042 endif()
3043 # check if selected language has enough sources at all
3044 list (LENGTH _sourceFiles _numberOfSources)
3045 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
3046 set (_targetUsePCH FALSE)
3047 else()
3048 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3049 endif()
3050 if (_targetUsePCH)
3051 cotire_make_pch_file_path(${_language} ${_target} _pchFile)
3052 if (_pchFile)
3053 # first file in _sourceFiles is passed as the host file
3054 cotire_setup_pch_file_compilation(
3055 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3056 cotire_setup_pch_file_inclusion(
3057 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3058 endif()
3059 elseif (_prefixHeaderFiles)
3060 # user provided prefix header must be included unconditionally
3061 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles})
3062 endif()
3063 endif()
3064 # mark target as cotired for language
3065 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
3066 if (_prefixFile)
3067 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
3068 if (_targetUsePCH AND _pchFile)
3069 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
3070 endif()
3071 endif()
3072 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
3073endfunction()
3074
3075function (cotire_setup_clean_target _target)
3076 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
3077 if (NOT TARGET "${_cleanTargetName}")
3078 cotire_set_cmd_to_prologue(_cmds)
3079 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
3080 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
3081 add_custom_target(${_cleanTargetName}
3082 COMMAND ${_cmds}
3083 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3084 COMMENT "Cleaning up target ${_target} cotire generated files"
3085 VERBATIM)
3086 cotire_init_target("${_cleanTargetName}")
3087 endif()
3088endfunction()
3089
3090function (cotire_setup_pch_target _languages _configurations _target)
3091 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
3092 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
3093 set (_dependsFiles "")
3094 foreach (_language ${_languages})
3095 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
3096 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
3097 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
3098 # MSVC, Intel and clang-cl only create precompiled header as a side effect
3099 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
3100 endif()
3101 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
3102 if (_dependsFile)
3103 list (APPEND _dependsFiles "${_dependsFile}")
3104 endif()
3105 endforeach()
3106 if (_dependsFiles)
3107 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
3108 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
3109 cotire_init_target("${_pchTargetName}")
3110 cotire_add_to_pch_all_target(${_pchTargetName})
3111 endif()
3112 else()
3113 # for other generators, we add the "clean all" target to clean up the precompiled header
3114 cotire_setup_clean_all_target()
3115 endif()
3116endfunction()
3117
3118function (cotire_filter_object_libraries _target _objectLibrariesVar)
3119 set (_objectLibraries "")
3120 foreach (_source ${ARGN})
3121 if (_source MATCHES "^\\$<TARGET_OBJECTS:.+>$")
3122 list (APPEND _objectLibraries "${_source}")
3123 endif()
3124 endforeach()
3125 set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE)
3126endfunction()
3127
3128function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar)
3129 get_target_property(_targetSourceFiles ${_target} SOURCES)
3130 set (_unityTargetSources ${_targetSourceFiles})
3131 foreach (_language ${_languages})
3132 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3133 if (_unityFiles)
3134 # remove source files that are included in the unity source
3135 set (_sourceFiles "")
3136 set (_excludedSources "")
3137 set (_cotiredSources "")
3138 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
3139 if (_sourceFiles OR _cotiredSources)
3140 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
3141 endif()
3142 # add unity source files instead
3143 list (APPEND _unityTargetSources ${_unityFiles})
3144 endif()
3145 endforeach()
3146 # handle object libraries which are part of the target's sources
3147 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3148 if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$")
3149 cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles})
3150 if (_objectLibraries)
3151 cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries})
3152 list (REMOVE_ITEM _unityTargetSources ${_objectLibraries})
3153 list (APPEND _unityTargetSources ${_unityObjectLibraries})
3154 endif()
3155 endif()
3156 set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE)
3157endfunction()
3158
3159function (cotire_setup_unity_target_pch_usage _languages _target)
3160 foreach (_language ${_languages})
3161 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3162 if (_unityFiles)
3163 get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3164 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
3165 if (_userPrefixFile AND _prefixFile)
3166 # user provided prefix header must be included unconditionally by unity sources
3167 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles})
3168 endif()
3169 endif()
3170 endforeach()
3171endfunction()
3172
3173function (cotire_setup_unity_build_target _languages _configurations _target)
3174 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3175 if (NOT _unityTargetName)
3176 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
3177 endif()
3178 # determine unity target sub type
3179 get_target_property(_targetType ${_target} TYPE)
3180 if ("${_targetType}" STREQUAL "EXECUTABLE")
3181 set (_unityTargetSubType "")
3182 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
3183 set (_unityTargetSubType "${CMAKE_MATCH_1}")
3184 else()
3185 message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.")
3186 return()
3187 endif()
3188 # determine unity target sources
3189 set (_unityTargetSources "")
3190 cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources)
3191 # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created
3192 set (CMAKE_AUTOMOC OFF)
3193 set (CMAKE_AUTOUIC OFF)
3194 set (CMAKE_AUTORCC OFF)
3195 if (COTIRE_DEBUG)
3196 message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
3197 endif()
3198 # generate unity target
3199 if ("${_targetType}" STREQUAL "EXECUTABLE")
3200 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3201 else()
3202 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3203 endif()
3204 # copy output location properties
3205 set (_outputDirProperties
3206 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
3207 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
3208 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
3209 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
3210 set (_setDefaultOutputDir TRUE)
3211 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3212 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3213 else()
3214 # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory
3215 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
3216 cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties})
3217 foreach (_property ${_properties})
3218 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
3219 if (_outputDir)
3220 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3221 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
3222 set (_setDefaultOutputDir FALSE)
3223 endif()
3224 endforeach()
3225 if (_setDefaultOutputDir)
3226 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3227 endif()
3228 endif()
3229 if (_setDefaultOutputDir)
3230 set_target_properties(${_unityTargetName} PROPERTIES
3231 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
3232 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
3233 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
3234 endif()
3235 else()
3236 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3237 ${_outputDirProperties})
3238 endif()
3239 # copy output name
3240 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3241 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
3242 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
3243 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
3244 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
3245 PREFIX <CONFIG>_POSTFIX SUFFIX
3246 IMPORT_PREFIX IMPORT_SUFFIX)
3247 # copy compile stuff
3248 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3249 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
3250 COMPILE_FLAGS COMPILE_OPTIONS
3251 Fortran_FORMAT Fortran_MODULE_DIRECTORY
3252 INCLUDE_DIRECTORIES
3253 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
3254 POSITION_INDEPENDENT_CODE
3255 C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER
3256 C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE
3257 C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN
3258 C_CLANG_TIDY CXX_CLANG_TIDY)
3259 # copy compile features
3260 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3261 C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED
3262 CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED
3263 COMPILE_FEATURES)
3264 # copy interface stuff
3265 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3266 COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN
3267 COMPATIBLE_INTERFACE_STRING
3268 INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS
3269 INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES
3270 INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
3271 INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED)
3272 # copy link stuff
3273 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3274 BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR
3275 INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
3276 LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED
3277 LINK_FLAGS LINK_FLAGS_<CONFIG>
3278 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
3279 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
3280 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
3281 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
3282 NO_SONAME SOVERSION VERSION
3283 LINK_WHAT_YOU_USE BUILD_RPATH)
3284 # copy cmake stuff
3285 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3286 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
3287 # copy Apple platform specific stuff
3288 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3289 BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR
3290 MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH
3291 OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST
3292 IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE)
3293 # copy Windows platform specific stuff
3294 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3295 GNUtoMS
3296 COMPILE_PDB_NAME COMPILE_PDB_NAME_<CONFIG>
3297 COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
3298 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
3299 VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION
3300 VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE
3301 VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK
3302 VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION
3303 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
3304 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
3305 VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES
3306 WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS
3307 DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE
3308 VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY)
3309 # copy Android platform specific stuff
3310 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3311 ANDROID_API ANDROID_API_MIN ANDROID_GUI
3312 ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES
3313 ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR
3314 ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES
3315 ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH
3316 ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE)
3317 # copy CUDA platform specific stuff
3318 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3319 CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS
3320 CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED)
3321 # use output name from original target
3322 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
3323 if (NOT _targetOutputName)
3324 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
3325 endif()
3326 # use export symbol from original target
3327 cotire_get_target_export_symbol("${_target}" _defineSymbol)
3328 if (_defineSymbol)
3329 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
3330 if ("${_targetType}" STREQUAL "EXECUTABLE")
3331 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
3332 endif()
3333 endif()
3334 # enable parallel compilation for MSVC
3335 if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
3336 list (LENGTH _unityTargetSources _numberOfUnityTargetSources)
3337 if (_numberOfUnityTargetSources GREATER 1)
3338 set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP")
3339 endif()
3340 endif()
3341 cotire_init_target(${_unityTargetName})
3342 cotire_add_to_unity_all_target(${_unityTargetName})
3343 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
3344endfunction(cotire_setup_unity_build_target)
3345
3346function (cotire_target _target)
3347 set(_options "")
3348 set(_oneValueArgs "")
3349 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3350 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3351 if (NOT _option_LANGUAGES)
3352 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
3353 endif()
3354 if (NOT _option_CONFIGURATIONS)
3355 cotire_get_configuration_types(_option_CONFIGURATIONS)
3356 endif()
3357 # check if cotire can be applied to target at all
3358 cotire_is_target_supported(${_target} _isSupported)
3359 if (NOT _isSupported)
3360 get_target_property(_imported ${_target} IMPORTED)
3361 get_target_property(_targetType ${_target} TYPE)
3362 if (_imported)
3363 message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.")
3364 else()
3365 message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.")
3366 endif()
3367 return()
3368 endif()
3369 # resolve alias
3370 get_target_property(_aliasName ${_target} ALIASED_TARGET)
3371 if (_aliasName)
3372 if (COTIRE_DEBUG)
3373 message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.")
3374 endif()
3375 set (_target ${_aliasName})
3376 endif()
3377 # check if target needs to be cotired for build type
3378 # when using configuration types, the test is performed at build time
3379 cotire_init_cotire_target_properties(${_target})
3380 if (NOT CMAKE_CONFIGURATION_TYPES)
3381 if (CMAKE_BUILD_TYPE)
3382 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
3383 else()
3384 list (FIND _option_CONFIGURATIONS "None" _index)
3385 endif()
3386 if (_index EQUAL -1)
3387 if (COTIRE_DEBUG)
3388 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
3389 endif()
3390 return()
3391 endif()
3392 endif()
3393 # when not using configuration types, immediately create cotire intermediate dir
3394 if (NOT CMAKE_CONFIGURATION_TYPES)
3395 cotire_get_intermediate_dir(_baseDir)
3396 file (MAKE_DIRECTORY "${_baseDir}")
3397 endif()
3398 # choose languages that apply to the target
3399 cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES})
3400 if (NOT _targetLanguages)
3401 return()
3402 endif()
3403 set (_cmds "")
3404 foreach (_language ${_targetLanguages})
3405 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd)
3406 if (_cmd)
3407 list (APPEND _cmds ${_cmd})
3408 endif()
3409 endforeach()
3410 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
3411 if (_targetAddSCU)
3412 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3413 endif()
3414 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3415 if (_targetUsePCH)
3416 cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds})
3417 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3418 if (_targetAddSCU)
3419 cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target})
3420 endif()
3421 endif()
3422 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
3423 if (_targetAddCleanTarget)
3424 cotire_setup_clean_target(${_target})
3425 endif()
3426endfunction(cotire_target)
3427
3428function (cotire_map_libraries _strategy _mappedLibrariesVar)
3429 set (_mappedLibraries "")
3430 foreach (_library ${ARGN})
3431 if (_library MATCHES "^\\$<LINK_ONLY:(.+)>$")
3432 set (_libraryName "${CMAKE_MATCH_1}")
3433 set (_linkOnly TRUE)
3434 set (_objectLibrary FALSE)
3435 elseif (_library MATCHES "^\\$<TARGET_OBJECTS:(.+)>$")
3436 set (_libraryName "${CMAKE_MATCH_1}")
3437 set (_linkOnly FALSE)
3438 set (_objectLibrary TRUE)
3439 else()
3440 set (_libraryName "${_library}")
3441 set (_linkOnly FALSE)
3442 set (_objectLibrary FALSE)
3443 endif()
3444 if ("${_strategy}" MATCHES "COPY_UNITY")
3445 cotire_is_target_supported(${_libraryName} _isSupported)
3446 if (_isSupported)
3447 # use target's corresponding unity target, if available
3448 get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME)
3449 if (TARGET "${_libraryUnityTargetName}")
3450 if (_linkOnly)
3451 list (APPEND _mappedLibraries "$<LINK_ONLY:${_libraryUnityTargetName}>")
3452 elseif (_objectLibrary)
3453 list (APPEND _mappedLibraries "$<TARGET_OBJECTS:${_libraryUnityTargetName}>")
3454 else()
3455 list (APPEND _mappedLibraries "${_libraryUnityTargetName}")
3456 endif()
3457 else()
3458 list (APPEND _mappedLibraries "${_library}")
3459 endif()
3460 else()
3461 list (APPEND _mappedLibraries "${_library}")
3462 endif()
3463 else()
3464 list (APPEND _mappedLibraries "${_library}")
3465 endif()
3466 endforeach()
3467 list (REMOVE_DUPLICATES _mappedLibraries)
3468 set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE)
3469endfunction()
3470
3471function (cotire_target_link_libraries _target)
3472 cotire_is_target_supported(${_target} _isSupported)
3473 if (NOT _isSupported)
3474 return()
3475 endif()
3476 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3477 if (TARGET "${_unityTargetName}")
3478 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3479 if (COTIRE_DEBUG)
3480 message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}")
3481 endif()
3482 if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$")
3483 get_target_property(_linkLibraries ${_target} LINK_LIBRARIES)
3484 if (_linkLibraries)
3485 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries})
3486 set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}")
3487 if (COTIRE_DEBUG)
3488 message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}")
3489 endif()
3490 endif()
3491 get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES)
3492 if (_interfaceLinkLibraries)
3493 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries})
3494 set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}")
3495 if (COTIRE_DEBUG)
3496 message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}")
3497 endif()
3498 endif()
3499 get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES)
3500 if (_manualDependencies)
3501 cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies})
3502 if (_unityManualDependencies)
3503 add_dependencies("${_unityTargetName}" ${_unityManualDependencies})
3504 endif()
3505 endif()
3506 endif()
3507 endif()
3508endfunction(cotire_target_link_libraries)
3509
3510function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
3511 if (_targetName)
3512 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
3513 else()
3514 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
3515 endif()
3516 # filter files in intermediate directory
3517 set (_filesToRemove "")
3518 foreach (_file ${_cotireFiles})
3519 get_filename_component(_dir "${_file}" DIRECTORY)
3520 get_filename_component(_dirName "${_dir}" NAME)
3521 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
3522 list (APPEND _filesToRemove "${_file}")
3523 endif()
3524 endforeach()
3525 if (_filesToRemove)
3526 if (COTIRE_VERBOSE)
3527 message (STATUS "cleaning up ${_filesToRemove}")
3528 endif()
3529 file (REMOVE ${_filesToRemove})
3530 endif()
3531endfunction()
3532
3533function (cotire_init_target _targetName)
3534 if (COTIRE_TARGETS_FOLDER)
3535 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
3536 endif()
3537 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE)
3538 if (MSVC_IDE)
3539 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
3540 endif()
3541endfunction()
3542
3543function (cotire_add_to_pch_all_target _pchTargetName)
3544 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
3545 if (NOT TARGET "${_targetName}")
3546 add_custom_target("${_targetName}"
3547 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3548 VERBATIM)
3549 cotire_init_target("${_targetName}")
3550 endif()
3551 cotire_setup_clean_all_target()
3552 add_dependencies(${_targetName} ${_pchTargetName})
3553endfunction()
3554
3555function (cotire_add_to_unity_all_target _unityTargetName)
3556 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
3557 if (NOT TARGET "${_targetName}")
3558 add_custom_target("${_targetName}"
3559 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3560 VERBATIM)
3561 cotire_init_target("${_targetName}")
3562 endif()
3563 cotire_setup_clean_all_target()
3564 add_dependencies(${_targetName} ${_unityTargetName})
3565endfunction()
3566
3567function (cotire_setup_clean_all_target)
3568 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
3569 if (NOT TARGET "${_targetName}")
3570 cotire_set_cmd_to_prologue(_cmds)
3571 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
3572 add_custom_target(${_targetName}
3573 COMMAND ${_cmds}
3574 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3575 COMMENT "Cleaning up all cotire generated files"
3576 VERBATIM)
3577 cotire_init_target("${_targetName}")
3578 endif()
3579endfunction()
3580
3581function (cotire)
3582 set(_options "")
3583 set(_oneValueArgs "")
3584 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3585 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3586 set (_targets ${_option_UNPARSED_ARGUMENTS})
3587 foreach (_target ${_targets})
3588 if (TARGET ${_target})
3589 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS})
3590 else()
3591 message (WARNING "cotire: ${_target} is not a target.")
3592 endif()
3593 endforeach()
3594 foreach (_target ${_targets})
3595 if (TARGET ${_target})
3596 cotire_target_link_libraries(${_target})
3597 endif()
3598 endforeach()
3599endfunction()
3600
3601if (CMAKE_SCRIPT_MODE_FILE)
3602
3603 # cotire is being run in script mode
3604 # locate -P on command args
3605 set (COTIRE_ARGC -1)
3606 foreach (_index RANGE ${CMAKE_ARGC})
3607 if (COTIRE_ARGC GREATER -1)
3608 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
3609 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
3610 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
3611 set (COTIRE_ARGC 0)
3612 endif()
3613 endforeach()
3614
3615 # include target script if available
3616 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
3617 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
3618 include("${COTIRE_ARGV2}")
3619 endif()
3620
3621 if (COTIRE_DEBUG)
3622 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
3623 endif()
3624
3625 if (NOT COTIRE_BUILD_TYPE)
3626 set (COTIRE_BUILD_TYPE "None")
3627 endif()
3628 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
3629 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
3630 set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}})
3631 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
3632 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
3633 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
3634 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
3635 if (_index GREATER -1)
3636 set (_sources ${COTIRE_TARGET_SOURCES})
3637 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
3638 else()
3639 if (COTIRE_DEBUG)
3640 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
3641 endif()
3642 set (_sources "")
3643 set (_sourcesDefinitions "")
3644 endif()
3645 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
3646 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
3647 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
3648 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
3649
3650 if ("${COTIRE_ARGV1}" STREQUAL "unity")
3651
3652 if (XCODE)
3653 # executing pre-build action under Xcode, check dependency on target script
3654 set (_dependsOption DEPENDS "${COTIRE_ARGV2}")
3655 else()
3656 # executing custom command, no need to re-check for dependencies
3657 set (_dependsOption "")
3658 endif()
3659
3660 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
3661
3662 cotire_generate_unity_source(
3663 "${COTIRE_ARGV3}" ${_sources}
3664 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3665 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
3666 PRE_UNDEFS ${_targetPreUndefs}
3667 POST_UNDEFS ${_targetPostUndefs}
3668 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
3669 SOURCES_POST_UNDEFS ${_sourcesPostUndefs}
3670 ${_dependsOption})
3671
3672 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
3673
3674 if (XCODE)
3675 # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies
3676 set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS})
3677 else()
3678 # executing custom command, no need to re-check for dependencies
3679 set (_dependsOption "")
3680 endif()
3681
3682 set (_files "")
3683 foreach (_index RANGE 4 ${COTIRE_ARGC})
3684 if (COTIRE_ARGV${_index})
3685 list (APPEND _files "${COTIRE_ARGV${_index}}")
3686 endif()
3687 endforeach()
3688
3689 cotire_generate_prefix_header(
3690 "${COTIRE_ARGV3}" ${_files}
3691 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3692 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3693 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3694 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3695 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3696 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3697 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
3698 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
3699 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
3700 INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH}
3701 INCLUDE_DIRECTORIES ${_includeDirs}
3702 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3703 COMPILE_DEFINITIONS ${_compileDefinitions}
3704 COMPILE_FLAGS ${_compileFlags}
3705 ${_dependsOption})
3706
3707 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
3708
3709 set (_files "")
3710 foreach (_index RANGE 5 ${COTIRE_ARGC})
3711 if (COTIRE_ARGV${_index})
3712 list (APPEND _files "${COTIRE_ARGV${_index}}")
3713 endif()
3714 endforeach()
3715
3716 cotire_precompile_prefix_header(
3717 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
3718 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3719 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3720 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3721 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3722 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3723 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3724 INCLUDE_DIRECTORIES ${_includeDirs}
3725 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3726 COMPILE_DEFINITIONS ${_compileDefinitions}
3727 COMPILE_FLAGS ${_compileFlags})
3728
3729 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
3730
3731 if (COTIRE_TARGET_LANGUAGE)
3732 set (_combinedFile "${COTIRE_ARGV3}")
3733 set (_startIndex 4)
3734 else()
3735 set (_combinedFile "${COTIRE_ARGV2}")
3736 set (_startIndex 3)
3737 endif()
3738 set (_files "")
3739 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
3740 if (COTIRE_ARGV${_index})
3741 list (APPEND _files "${COTIRE_ARGV${_index}}")
3742 endif()
3743 endforeach()
3744
3745 if (XCODE)
3746 # executing pre-build action under Xcode, check dependency on files to be combined
3747 set (_dependsOption DEPENDS ${_files})
3748 else()
3749 # executing custom command, no need to re-check for dependencies
3750 set (_dependsOption "")
3751 endif()
3752
3753 if (COTIRE_TARGET_LANGUAGE)
3754 cotire_generate_unity_source(
3755 "${_combinedFile}" ${_files}
3756 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3757 ${_dependsOption})
3758 else()
3759 cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption})
3760 endif()
3761
3762 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
3763
3764 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
3765
3766 else()
3767 message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".")
3768 endif()
3769
3770else()
3771
3772 # cotire is being run in include mode
3773 # set up all variable and property definitions
3774
3775 if (NOT DEFINED COTIRE_DEBUG_INIT)
3776 if (DEFINED COTIRE_DEBUG)
3777 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
3778 else()
3779 set (COTIRE_DEBUG_INIT FALSE)
3780 endif()
3781 endif()
3782 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
3783
3784 if (NOT DEFINED COTIRE_VERBOSE_INIT)
3785 if (DEFINED COTIRE_VERBOSE)
3786 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
3787 else()
3788 set (COTIRE_VERBOSE_INIT FALSE)
3789 endif()
3790 endif()
3791 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
3792
3793 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
3794 "Ignore headers with the listed file extensions from the generated prefix header.")
3795
3796 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
3797 "Ignore headers from these directories when generating the prefix header.")
3798
3799 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
3800 "Ignore sources with the listed file extensions from the generated unity source.")
3801
3802 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING
3803 "Minimum number of sources in target required to enable use of precompiled header.")
3804
3805 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
3806 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
3807 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
3808 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
3809 # enable parallelization for generators that run multiple jobs by default
3810 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
3811 else()
3812 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
3813 endif()
3814 endif()
3815 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
3816 "Maximum number of source files to include in a single unity source file.")
3817
3818 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
3819 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
3820 endif()
3821 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
3822 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
3823 endif()
3824 if (NOT COTIRE_INTDIR)
3825 set (COTIRE_INTDIR "cotire")
3826 endif()
3827 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
3828 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
3829 endif()
3830 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
3831 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
3832 endif()
3833 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
3834 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
3835 endif()
3836 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
3837 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
3838 endif()
3839 if (NOT COTIRE_PCH_TARGET_SUFFIX)
3840 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
3841 endif()
3842 if (MSVC)
3843 # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code
3844 # use a bigger default factor of 170 percent (128 MB)
3845 if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR)
3846 set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170")
3847 endif()
3848 endif()
3849 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
3850 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
3851 endif()
3852 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
3853 set (COTIRE_TARGETS_FOLDER "cotire")
3854 endif()
3855 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
3856 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
3857 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
3858 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
3859 else()
3860 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
3861 endif()
3862 endif()
3863
3864 # define cotire cache variables
3865
3866 define_property(
3867 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
3868 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3869 FULL_DOCS
3870 "The variable can be set to a semicolon separated list of include directories."
3871 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3872 "If not defined, defaults to empty list."
3873 )
3874
3875 define_property(
3876 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
3877 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
3878 FULL_DOCS
3879 "The variable can be set to a semicolon separated list of file extensions."
3880 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
3881 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
3882 "If not defined, defaults to inc;inl;ipp."
3883 )
3884
3885 define_property(
3886 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
3887 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
3888 FULL_DOCS
3889 "The variable can be set to a semicolon separated list of file extensions."
3890 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
3891 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
3892 "If not defined, defaults to m;mm."
3893 )
3894
3895 define_property(
3896 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
3897 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
3898 FULL_DOCS
3899 "The variable can be set to an integer > 0."
3900 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
3901 "If not defined, defaults to 2."
3902 )
3903
3904 define_property(
3905 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
3906 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3907 FULL_DOCS
3908 "This may be set to an integer >= 0."
3909 "If 0, cotire will only create a single unity source file."
3910 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
3911 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
3912 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
3913 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3914 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
3915 )
3916
3917 # define cotire directory properties
3918
3919 define_property(
3920 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
3921 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
3922 FULL_DOCS
3923 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
3924 )
3925
3926 define_property(
3927 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
3928 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
3929 FULL_DOCS
3930 "See target property COTIRE_ADD_UNITY_BUILD."
3931 )
3932
3933 define_property(
3934 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
3935 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
3936 FULL_DOCS
3937 "See target property COTIRE_ADD_CLEAN."
3938 )
3939
3940 define_property(
3941 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
3942 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3943 FULL_DOCS
3944 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
3945 )
3946
3947 define_property(
3948 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
3949 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3950 FULL_DOCS
3951 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
3952 )
3953
3954 define_property(
3955 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH"
3956 BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header."
3957 FULL_DOCS
3958 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH."
3959 )
3960
3961 define_property(
3962 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3963 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
3964 FULL_DOCS
3965 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
3966 )
3967
3968 define_property(
3969 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3970 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
3971 FULL_DOCS
3972 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
3973 )
3974
3975 define_property(
3976 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
3977 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3978 FULL_DOCS
3979 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3980 )
3981
3982 define_property(
3983 DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT"
3984 BRIEF_DOCS "Define strategy for setting up the unity target's link libraries."
3985 FULL_DOCS
3986 "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT."
3987 )
3988
3989 # define cotire target properties
3990
3991 define_property(
3992 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
3993 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
3994 FULL_DOCS
3995 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
3996 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
3997 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
3998 "The target name will be set to this target's name with the suffix _pch appended."
3999 "Inherited from directory."
4000 "Defaults to TRUE."
4001 )
4002
4003 define_property(
4004 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
4005 BRIEF_DOCS "Add a new target that performs a unity build for this target."
4006 FULL_DOCS
4007 "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources."
4008 "Most of the relevant target properties will be copied from this target to the new unity build target."
4009 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
4010 "The unity target name will be set to this target's name with the suffix _unity appended."
4011 "Inherited from directory."
4012 "Defaults to TRUE."
4013 )
4014
4015 define_property(
4016 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
4017 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
4018 FULL_DOCS
4019 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
4020 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
4021 "Inherited from directory."
4022 "Defaults to FALSE."
4023 )
4024
4025 define_property(
4026 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
4027 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
4028 FULL_DOCS
4029 "The property can be set to a list of directories."
4030 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
4031 "Inherited from directory."
4032 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
4033 )
4034
4035 define_property(
4036 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
4037 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
4038 FULL_DOCS
4039 "The property can be set to a list of directories."
4040 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
4041 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
4042 "the option which yields the closer relative path match wins."
4043 "Inherited from directory."
4044 "If not set, this property is initialized to the empty list."
4045 )
4046
4047 define_property(
4048 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED
4049 BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header."
4050 FULL_DOCS
4051 "The property can be set to a list of directories."
4052 "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header."
4053 "Header files are sorted according to the order of the directories in the property."
4054 "If not set, this property is initialized to the empty list."
4055 )
4056
4057 define_property(
4058 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
4059 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
4060 FULL_DOCS
4061 "This may be set to a semicolon-separated list of preprocessor symbols."
4062 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
4063 "Inherited from directory."
4064 "Defaults to empty string."
4065 )
4066
4067 define_property(
4068 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
4069 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
4070 FULL_DOCS
4071 "This may be set to a semicolon-separated list of preprocessor symbols."
4072 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
4073 "Inherited from directory."
4074 "Defaults to empty string."
4075 )
4076
4077 define_property(
4078 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
4079 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
4080 FULL_DOCS
4081 "This may be set to an integer > 0."
4082 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
4083 "If not set, cotire will only create a single unity source file."
4084 "Inherited from directory."
4085 "Defaults to empty."
4086 )
4087
4088 define_property(
4089 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
4090 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
4091 FULL_DOCS
4092 "If set, cotire will only add the given file(s) to the generated unity source file."
4093 "If not set, cotire will add all the target source files to the generated unity source file."
4094 "The property can be set to a user provided unity source file."
4095 "Defaults to empty."
4096 )
4097
4098 define_property(
4099 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
4100 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
4101 FULL_DOCS
4102 "If set, cotire will add the given header file(s) to the generated prefix header file."
4103 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
4104 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
4105 "Defaults to empty."
4106 )
4107
4108 define_property(
4109 TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED
4110 BRIEF_DOCS "Define strategy for setting up unity target's link libraries."
4111 FULL_DOCS
4112 "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually."
4113 "If this property is set to COPY, the unity target's link libraries will be copied from this target."
4114 "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets."
4115 "Inherited from directory."
4116 "Defaults to empty."
4117 )
4118
4119 define_property(
4120 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
4121 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
4122 FULL_DOCS
4123 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
4124 "Defaults to empty string."
4125 )
4126
4127 define_property(
4128 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
4129 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
4130 FULL_DOCS
4131 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
4132 "Defaults to empty string."
4133 )
4134
4135 define_property(
4136 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
4137 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
4138 FULL_DOCS
4139 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
4140 "Defaults to empty string."
4141 )
4142
4143 define_property(
4144 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
4145 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
4146 FULL_DOCS
4147 "This property can be set to the desired name of the unity target that will be created by cotire."
4148 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
4149 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
4150 "Defaults to empty string."
4151 )
4152
4153 # define cotire source properties
4154
4155 define_property(
4156 SOURCE PROPERTY "COTIRE_EXCLUDED"
4157 BRIEF_DOCS "Do not modify source file's build command."
4158 FULL_DOCS
4159 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
4160 "The source file will also be excluded from the generated unity source file."
4161 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
4162 "Defaults to FALSE."
4163 )
4164
4165 define_property(
4166 SOURCE PROPERTY "COTIRE_DEPENDENCY"
4167 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
4168 FULL_DOCS
4169 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
4170 "If the file is modified, cotire will re-generate the prefix header source upon build."
4171 "Defaults to FALSE."
4172 )
4173
4174 define_property(
4175 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
4176 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
4177 FULL_DOCS
4178 "This may be set to a semicolon-separated list of preprocessor symbols."
4179 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
4180 "Defaults to empty string."
4181 )
4182
4183 define_property(
4184 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
4185 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
4186 FULL_DOCS
4187 "This may be set to a semicolon-separated list of preprocessor symbols."
4188 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
4189 "Defaults to empty string."
4190 )
4191
4192 define_property(
4193 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
4194 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
4195 FULL_DOCS
4196 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
4197 "The new unity source file will include this source file as the first one."
4198 "This property essentially works as a separator for unity source files."
4199 "Defaults to FALSE."
4200 )
4201
4202 define_property(
4203 SOURCE PROPERTY "COTIRE_TARGET"
4204 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
4205 FULL_DOCS
4206 "cotire sets this property to the name of target, that the source file's build command has been altered for."
4207 "Defaults to empty string."
4208 )
4209
4210 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")
4211
4212endif()