CMake/cotire.cmake

changeset 7
68443f5be176
equal deleted inserted replaced
6:73e448b2943d 7:68443f5be176
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
30 if(__COTIRE_INCLUDED)
31 return()
32 endif()
33 set(__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
37 if (NOT CMAKE_SCRIPT_MODE_FILE)
38 cmake_policy(PUSH)
39 endif()
40 cmake_minimum_required(VERSION 2.8.12)
41 if (NOT CMAKE_SCRIPT_MODE_FILE)
42 cmake_policy(POP)
43 endif()
44
45 set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
46 set (COTIRE_CMAKE_MODULE_VERSION "1.8.0")
47
48 # activate select policies
49 if (POLICY CMP0025)
50 # Compiler id for Apple Clang is now AppleClang
51 cmake_policy(SET CMP0025 NEW)
52 endif()
53
54 if (POLICY CMP0026)
55 # disallow use of the LOCATION target property
56 cmake_policy(SET CMP0026 NEW)
57 endif()
58
59 if (POLICY CMP0038)
60 # targets may not link directly to themselves
61 cmake_policy(SET CMP0038 NEW)
62 endif()
63
64 if (POLICY CMP0039)
65 # utility targets may not have link dependencies
66 cmake_policy(SET CMP0039 NEW)
67 endif()
68
69 if (POLICY CMP0040)
70 # target in the TARGET signature of add_custom_command() must exist
71 cmake_policy(SET CMP0040 NEW)
72 endif()
73
74 if (POLICY CMP0045)
75 # error on non-existent target in get_target_property
76 cmake_policy(SET CMP0045 NEW)
77 endif()
78
79 if (POLICY CMP0046)
80 # error on non-existent dependency in add_dependencies
81 cmake_policy(SET CMP0046 NEW)
82 endif()
83
84 if (POLICY CMP0049)
85 # do not expand variables in target source entries
86 cmake_policy(SET CMP0049 NEW)
87 endif()
88
89 if (POLICY CMP0050)
90 # disallow add_custom_command SOURCE signatures
91 cmake_policy(SET CMP0050 NEW)
92 endif()
93
94 if (POLICY CMP0051)
95 # include TARGET_OBJECTS expressions in a target's SOURCES property
96 cmake_policy(SET CMP0051 NEW)
97 endif()
98
99 if (POLICY CMP0053)
100 # simplify variable reference and escape sequence evaluation
101 cmake_policy(SET CMP0053 NEW)
102 endif()
103
104 if (POLICY CMP0054)
105 # only interpret if() arguments as variables or keywords when unquoted
106 cmake_policy(SET CMP0054 NEW)
107 endif()
108
109 if (POLICY CMP0055)
110 # strict checking for break() command
111 cmake_policy(SET CMP0055 NEW)
112 endif()
113
114 include(CMakeParseArguments)
115 include(ProcessorCount)
116
117 function (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()
131 endfunction()
132
133 function (cotire_get_source_file_extension _sourceFile _extVar)
134 # get_filename_component returns extension from first occurrence of . in file name
135 # this function computes the extension from last occurrence of . in file name
136 string (FIND "${_sourceFile}" "." _index REVERSE)
137 if (_index GREATER -1)
138 math (EXPR _index "${_index} + 1")
139 string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
140 else()
141 set (_sourceExt "")
142 endif()
143 set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
144 endfunction()
145
146 macro (cotire_check_is_path_relative_to _path _isRelativeVar)
147 set (${_isRelativeVar} FALSE)
148 if (IS_ABSOLUTE "${_path}")
149 foreach (_dir ${ARGN})
150 file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
151 if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
152 set (${_isRelativeVar} TRUE)
153 break()
154 endif()
155 endforeach()
156 endif()
157 endmacro()
158
159 function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
160 if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
161 set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
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)
266 endfunction()
267
268 function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
269 set (_filteredObjects "")
270 foreach (_object ${ARGN})
271 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
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)
280 endfunction()
281
282 function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
283 set (_filteredObjects "")
284 foreach (_object ${ARGN})
285 get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
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)
294 endfunction()
295
296 function (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)
305 endfunction()
306
307 function (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)
321 endfunction()
322
323 function (cotire_copy_set_properties _configurations _type _source _target)
324 cotire_resolve_config_properties("${_configurations}" _properties ${ARGN})
325 foreach (_property ${_properties})
326 get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
327 if (_isSet)
328 get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
329 set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
330 endif()
331 endforeach()
332 endfunction()
333
334 function (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)
360 endfunction()
361
362 function (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)
406 endfunction()
407
408 function (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)
424 endfunction()
425
426 function (cotire_get_target_compile_flags _config _language _target _flagsVar)
427 string (TOUPPER "${_config}" _upperConfig)
428 # collect options from CMake language variables
429 set (_compileFlags "")
430 if (CMAKE_${_language}_FLAGS)
431 set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
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)
541 endfunction()
542
543 function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar)
544 set (_includeDirs "")
545 set (_systemIncludeDirs "")
546 # default include dirs
547 if (CMAKE_INCLUDE_CURRENT_DIR)
548 list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}")
549 list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}")
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)
673 endfunction()
674
675 function (cotire_get_target_export_symbol _target _exportSymbolVar)
676 set (_exportSymbol "")
677 get_target_property(_targetType ${_target} TYPE)
678 get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
679 if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
680 (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
681 get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
682 if (NOT _exportSymbol)
683 set (_exportSymbol "${_target}_EXPORTS")
684 endif()
685 string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol)
686 endif()
687 set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
688 endfunction()
689
690 function (cotire_get_target_compile_definitions _config _language _target _definitionsVar)
691 string (TOUPPER "${_config}" _upperConfig)
692 set (_configDefinitions "")
693 # CMAKE_INTDIR for multi-configuration build systems
694 if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
695 list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
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)
742 endfunction()
743
744 function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar)
745 # parse target compile flags omitting compile definitions and include directives
746 set (_targetFlags "")
747 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
748 set (_flagFilter "D")
749 if (CMAKE_INCLUDE_FLAG_${_language})
750 string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag)
751 string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}")
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)
769 endfunction()
770
771 function (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)
785 endfunction()
786
787 function (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)
807 endfunction()
808
809 function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
810 set (_compileDefinitions "")
811 if (NOT CMAKE_SCRIPT_MODE_FILE)
812 string (TOUPPER "${_config}" _upperConfig)
813 get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
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)
830 endfunction()
831
832 function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
833 set (_configDefinitions "")
834 foreach (_sourceFile ${ARGN})
835 cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
836 if (_sourceDefinitions)
837 list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
838 endif()
839 endforeach()
840 set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
841 endfunction()
842
843 function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
844 set (_sourceUndefs "")
845 if (NOT CMAKE_SCRIPT_MODE_FILE)
846 get_source_file_property(_undefs "${_sourceFile}" ${_property})
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)
859 endfunction()
860
861 function (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)
870 endfunction()
871
872 macro (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()
886 endmacro()
887
888 function (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()
908 endfunction()
909
910 macro (cotire_add_definitions_to_cmd _cmdVar _language)
911 foreach (_definition ${ARGN})
912 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
913 list (APPEND ${_cmdVar} "/D${_definition}")
914 else()
915 list (APPEND ${_cmdVar} "-D${_definition}")
916 endif()
917 endforeach()
918 endmacro()
919
920 function (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)
942 endfunction()
943
944 function (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)
979 endfunction()
980
981 macro (cotire_add_compile_flags_to_cmd _cmdVar)
982 foreach (_flag ${ARGN})
983 list (APPEND ${_cmdVar} "${_flag}")
984 endforeach()
985 endmacro()
986
987 function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
988 if (EXISTS "${_file}")
989 set (_triggerFile "")
990 foreach (_dependencyFile ${ARGN})
991 if (EXISTS "${_dependencyFile}")
992 # IS_NEWER_THAN returns TRUE if both files have the same timestamp
993 # thus we do the comparison in both directions to exclude ties
994 if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND
995 NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}")
996 set (_triggerFile "${_dependencyFile}")
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()
1021 endfunction()
1022
1023 macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
1024 set (${_relPathVar} "")
1025 foreach (_includeDir ${_includeDirs})
1026 if (IS_DIRECTORY "${_includeDir}")
1027 file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
1028 if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
1029 string (LENGTH "${${_relPathVar}}" _closestLen)
1030 string (LENGTH "${_relPath}" _relLen)
1031 if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
1032 set (${_relPathVar} "${_relPath}")
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()
1041 endmacro()
1042
1043 macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside)
1044 # check header path against ignored and honored include directories
1045 cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath)
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()
1064 endmacro()
1065
1066 macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
1067 if (NOT EXISTS "${_headerFile}")
1068 set (${_headerIsIgnoredVar} TRUE)
1069 elseif (IS_DIRECTORY "${_headerFile}")
1070 set (${_headerIsIgnoredVar} TRUE)
1071 elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$")
1072 # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path
1073 # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
1074 # with the error message "error: no include path in which to search for header.h"
1075 set (${_headerIsIgnoredVar} TRUE)
1076 else()
1077 set (${_headerIsIgnoredVar} FALSE)
1078 endif()
1079 endmacro()
1080
1081 macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
1082 # check header file extension
1083 cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
1084 set (${_headerIsIgnoredVar} FALSE)
1085 if (_headerFileExt)
1086 list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
1087 if (_index GREATER -1)
1088 set (${_headerIsIgnoredVar} TRUE)
1089 endif()
1090 endif()
1091 endmacro()
1092
1093 macro (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()
1120 endmacro()
1121
1122 function (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)
1222 endfunction()
1223
1224 function (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()
1310 endfunction()
1311
1312 macro (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()
1320 endmacro()
1321
1322 macro (cotire_comment_str _language _commentText _commentVar)
1323 if ("${_language}" STREQUAL "CMAKE")
1324 set (${_commentVar} "# ${_commentText}")
1325 else()
1326 set (${_commentVar} "/* ${_commentText} */")
1327 endif()
1328 endmacro()
1329
1330 function (cotire_write_file _language _file _contents _force)
1331 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
1332 cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
1333 cotire_comment_str("${_language}" "${_file}" _header2)
1334 set (_contents "${_header1}\n${_header2}\n${_contents}")
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()
1350 endfunction()
1351
1352 function (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)
1444 endfunction()
1445
1446 function (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")
1515 endfunction()
1516
1517 function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
1518 set (_flags ${${_flagsVar}})
1519 if (_compilerID MATCHES "MSVC")
1520 # cl.exe options used
1521 # /nologo suppresses display of sign-on banner
1522 # /TC treat all files named on the command line as C source files
1523 # /TP treat all files named on the command line as C++ source files
1524 # /EP preprocess to stdout without #line directives
1525 # /showIncludes list include files
1526 set (_sourceFileTypeC "/TC")
1527 set (_sourceFileTypeCXX "/TP")
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)
1625 endfunction()
1626
1627 function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
1628 set (_flags ${${_flagsVar}})
1629 if (_compilerID MATCHES "MSVC")
1630 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1631 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1632 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1633 # cl.exe options used
1634 # /Yc creates a precompiled header file
1635 # /Fp specifies precompiled header binary file name
1636 # /FI forces inclusion of file
1637 # /TC treat all files named on the command line as C source files
1638 # /TP treat all files named on the command line as C++ source files
1639 # /Zs syntax check only
1640 # /Zm precompiled header memory allocation scaling factor
1641 set (_sourceFileTypeC "/TC")
1642 set (_sourceFileTypeCXX "/TP")
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 # Clang-cl.exe options used
1697 # /Yc creates a precompiled header file
1698 # /Fp specifies precompiled header binary file name
1699 # /FI forces inclusion of file
1700 # /Zs syntax check only
1701 # /TC treat all files named on the command line as C source files
1702 # /TP treat all files named on the command line as C++ source files
1703 set (_sourceFileTypeC "/TC")
1704 set (_sourceFileTypeCXX "/TP")
1705 if (_flags)
1706 # append to list
1707 list (APPEND _flags "${_sourceFileType${_language}}"
1708 "/Yc${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}" /Zs "${_hostFile}")
1709 else()
1710 # return as a flag string
1711 set (_flags "/Yc\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"")
1712 endif()
1713 endif()
1714 elseif (_compilerID MATCHES "Intel")
1715 if (WIN32)
1716 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1717 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1718 file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
1719 # Windows Intel options used
1720 # /nologo do not display compiler version information
1721 # /Yc create a precompiled header (PCH) file
1722 # /Fp specify a path or file name for precompiled header files
1723 # /FI tells the preprocessor to include a specified file name as the header file
1724 # /TC process all source or unrecognized file types as C source files
1725 # /TP process all source or unrecognized file types as C++ source files
1726 # /Zs syntax check only
1727 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1728 set (_sourceFileTypeC "/TC")
1729 set (_sourceFileTypeCXX "/TP")
1730 if (_flags)
1731 # append to list
1732 list (APPEND _flags /nologo "${_sourceFileType${_language}}"
1733 "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
1734 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1735 list (APPEND _flags "/Wpch-messages")
1736 endif()
1737 else()
1738 # return as a flag string
1739 set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1740 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1741 set (_flags "${_flags} /Wpch-messages")
1742 endif()
1743 endif()
1744 else()
1745 # Linux / Mac OS X Intel options used
1746 # -pch-dir location for precompiled header files
1747 # -pch-create name of the precompiled header (PCH) to create
1748 # -Kc++ process all source or unrecognized file types as C++ source files
1749 # -fsyntax-only check only for correct syntax
1750 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1751 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1752 get_filename_component(_pchName "${_pchFile}" NAME)
1753 set (_xLanguage_C "c-header")
1754 set (_xLanguage_CXX "c++-header")
1755 set (_pchSuppressMessages FALSE)
1756 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1757 set(_pchSuppressMessages TRUE)
1758 endif()
1759 if (_flags)
1760 # append to list
1761 if ("${_language}" STREQUAL "CXX")
1762 list (APPEND _flags -Kc++)
1763 endif()
1764 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}")
1765 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1766 if (NOT _pchSuppressMessages)
1767 list (APPEND _flags -Wpch-messages)
1768 endif()
1769 endif()
1770 else()
1771 # return as a flag string
1772 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
1773 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1774 if (NOT _pchSuppressMessages)
1775 set (_flags "${_flags} -Wpch-messages")
1776 endif()
1777 endif()
1778 endif()
1779 endif()
1780 else()
1781 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1782 endif()
1783 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1784 endfunction()
1785
1786 function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
1787 set (_flags ${${_flagsVar}})
1788 if (_compilerID MATCHES "MSVC")
1789 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1790 # cl.exe options used
1791 # /Yu uses a precompiled header file during build
1792 # /Fp specifies precompiled header binary file name
1793 # /FI forces inclusion of file
1794 # /Zm precompiled header memory allocation scaling factor
1795 if (_pchFile)
1796 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1797 if (_flags)
1798 # append to list
1799 list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1800 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1801 list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1802 endif()
1803 else()
1804 # return as a flag string
1805 set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1806 if (COTIRE_PCH_MEMORY_SCALING_FACTOR)
1807 set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}")
1808 endif()
1809 endif()
1810 else()
1811 # no precompiled header, force inclusion of prefix header
1812 if (_flags)
1813 # append to list
1814 list (APPEND _flags "/FI${_prefixFileNative}")
1815 else()
1816 # return as a flag string
1817 set (_flags "/FI\"${_prefixFileNative}\"")
1818 endif()
1819 endif()
1820 elseif (_compilerID MATCHES "GNU")
1821 # GCC options used
1822 # -include process include file as the first line of the primary source file
1823 # -Winvalid-pch warns if precompiled header is found but cannot be used
1824 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1825 if (_flags)
1826 # append to list
1827 list (APPEND _flags -Winvalid-pch -include "${_prefixFile}")
1828 else()
1829 # return as a flag string
1830 set (_flags "-Winvalid-pch -include \"${_prefixFile}\"")
1831 endif()
1832 elseif (_compilerID MATCHES "Clang")
1833 if (UNIX)
1834 # Clang options used
1835 # -include process include file as the first line of the primary source file
1836 # note: ccache requires the -include flag to be used in order to process precompiled header correctly
1837 if (_flags)
1838 # append to list
1839 list (APPEND _flags -include "${_prefixFile}")
1840 else()
1841 # return as a flag string
1842 set (_flags "-include \"${_prefixFile}\"")
1843 endif()
1844 elseif (WIN32)
1845 # Clang-cl.exe options used
1846 # /Yu uses a precompiled header file during build
1847 # /Fp specifies precompiled header binary file name
1848 # /FI forces inclusion of file
1849 if (_pchFile)
1850 if (_flags)
1851 # append to list
1852 list (APPEND _flags "/Yu${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}")
1853 else()
1854 # return as a flag string
1855 set (_flags "/Yu\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"")
1856 endif()
1857 else()
1858 # no precompiled header, force inclusion of prefix header
1859 if (_flags)
1860 # append to list
1861 list (APPEND _flags "/FI${_prefixFile}")
1862 else()
1863 # return as a flag string
1864 set (_flags "/FI\"${_prefixFile}\"")
1865 endif()
1866 endif()
1867 endif()
1868 elseif (_compilerID MATCHES "Intel")
1869 if (WIN32)
1870 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
1871 # Windows Intel options used
1872 # /Yu use a precompiled header (PCH) file
1873 # /Fp specify a path or file name for precompiled header files
1874 # /FI tells the preprocessor to include a specified file name as the header file
1875 # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1876 if (_pchFile)
1877 file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
1878 if (_flags)
1879 # append to list
1880 list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
1881 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1882 list (APPEND _flags "/Wpch-messages")
1883 endif()
1884 else()
1885 # return as a flag string
1886 set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
1887 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1888 set (_flags "${_flags} /Wpch-messages")
1889 endif()
1890 endif()
1891 else()
1892 # no precompiled header, force inclusion of prefix header
1893 if (_flags)
1894 # append to list
1895 list (APPEND _flags "/FI${_prefixFileNative}")
1896 else()
1897 # return as a flag string
1898 set (_flags "/FI\"${_prefixFileNative}\"")
1899 endif()
1900 endif()
1901 else()
1902 # Linux / Mac OS X Intel options used
1903 # -pch-dir location for precompiled header files
1904 # -pch-use name of the precompiled header (PCH) to use
1905 # -include process include file as the first line of the primary source file
1906 # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
1907 if (_pchFile)
1908 get_filename_component(_pchDir "${_pchFile}" DIRECTORY)
1909 get_filename_component(_pchName "${_pchFile}" NAME)
1910 set (_pchSuppressMessages FALSE)
1911 if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*")
1912 set(_pchSuppressMessages TRUE)
1913 endif()
1914 if (_flags)
1915 # append to list
1916 list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}")
1917 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1918 if (NOT _pchSuppressMessages)
1919 list (APPEND _flags -Wpch-messages)
1920 endif()
1921 endif()
1922 else()
1923 # return as a flag string
1924 set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
1925 if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
1926 if (NOT _pchSuppressMessages)
1927 set (_flags "${_flags} -Wpch-messages")
1928 endif()
1929 endif()
1930 endif()
1931 else()
1932 # no precompiled header, force inclusion of prefix header
1933 if (_flags)
1934 # append to list
1935 list (APPEND _flags -include "${_prefixFile}")
1936 else()
1937 # return as a flag string
1938 set (_flags "-include \"${_prefixFile}\"")
1939 endif()
1940 endif()
1941 endif()
1942 else()
1943 message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
1944 endif()
1945 set (${_flagsVar} ${_flags} PARENT_SCOPE)
1946 endfunction()
1947
1948 function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
1949 set(_options "")
1950 set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE)
1951 set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER)
1952 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
1953 if (NOT _option_LANGUAGE)
1954 set (_option_LANGUAGE "CXX")
1955 endif()
1956 if (NOT _option_COMPILER_ID)
1957 set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
1958 endif()
1959 if (NOT _option_COMPILER_VERSION)
1960 set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}")
1961 endif()
1962 cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
1963 cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
1964 cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
1965 cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1966 cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES)
1967 cotire_add_pch_compilation_flags(
1968 "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
1969 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
1970 if (COTIRE_VERBOSE)
1971 message (STATUS "execute_process: ${_cmd}")
1972 endif()
1973 if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC")
1974 # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
1975 unset (ENV{VS_UNICODE_OUTPUT})
1976 elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0")
1977 if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR
1978 _option_COMPILER_EXECUTABLE MATCHES "ccache")
1979 # Newer versions of Clang embed a compilation timestamp into the precompiled header binary,
1980 # which results in "file has been modified since the precompiled header was built" errors if ccache is used.
1981 # We work around the problem by disabling ccache upon pre-compiling the prefix header.
1982 set (ENV{CCACHE_DISABLE} "true")
1983 endif()
1984 endif()
1985 execute_process(
1986 COMMAND ${_cmd}
1987 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
1988 RESULT_VARIABLE _result)
1989 if (_result)
1990 message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.")
1991 endif()
1992 endfunction()
1993
1994 function (cotire_check_precompiled_header_support _language _target _msgVar)
1995 set (_unsupportedCompiler
1996 "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
1997 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
1998 # PCH supported since Visual Studio C++ 6.0
1999 # and CMake does not support an earlier version
2000 set (${_msgVar} "" PARENT_SCOPE)
2001 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2002 # GCC PCH support requires version >= 3.4
2003 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
2004 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2005 else()
2006 set (${_msgVar} "" PARENT_SCOPE)
2007 endif()
2008 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2009 if (UNIX)
2010 # all Unix Clang versions have PCH support
2011 set (${_msgVar} "" PARENT_SCOPE)
2012 elseif (WIN32)
2013 # only clang-cl is supported under Windows
2014 get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE)
2015 if (NOT _compilerName MATCHES "cl$")
2016 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE)
2017 endif()
2018 endif()
2019 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2020 # Intel PCH support requires version >= 8.0.0
2021 if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
2022 set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
2023 else()
2024 set (${_msgVar} "" PARENT_SCOPE)
2025 endif()
2026 else()
2027 set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
2028 endif()
2029 # check if ccache is used as a compiler launcher
2030 get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER)
2031 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH)
2032 if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache")
2033 # verify that ccache configuration is compatible with precompiled headers
2034 # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache
2035 # do not report the "sloppiness" setting correctly upon printing ccache configuration
2036 if (DEFINED ENV{CCACHE_SLOPPINESS})
2037 if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR
2038 NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros")
2039 set (${_msgVar}
2040 "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"."
2041 PARENT_SCOPE)
2042 endif()
2043 else()
2044 if (_realCompilerExe MATCHES "ccache")
2045 set (_ccacheExe "${_realCompilerExe}")
2046 else()
2047 set (_ccacheExe "${_launcher}")
2048 endif()
2049 execute_process(
2050 COMMAND "${_ccacheExe}" "--print-config"
2051 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
2052 RESULT_VARIABLE _result
2053 OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE
2054 ERROR_QUIET)
2055 if (_result)
2056 set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE)
2057 elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR
2058 NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines")
2059 set (${_msgVar}
2060 "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"."
2061 PARENT_SCOPE)
2062 endif()
2063 endif()
2064 endif()
2065 if (APPLE)
2066 # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
2067 cotire_get_configuration_types(_configs)
2068 foreach (_config ${_configs})
2069 set (_targetFlags "")
2070 cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags)
2071 cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
2072 list (LENGTH _architectures _numberOfArchitectures)
2073 if (_numberOfArchitectures GREATER 1)
2074 string (REPLACE ";" ", " _architectureStr "${_architectures}")
2075 set (${_msgVar}
2076 "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
2077 PARENT_SCOPE)
2078 break()
2079 endif()
2080 endforeach()
2081 endif()
2082 endfunction()
2083
2084 macro (cotire_get_intermediate_dir _cotireDir)
2085 # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types
2086 get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
2087 endmacro()
2088
2089 macro (cotire_setup_file_extension_variables)
2090 set (_unityFileExt_C ".c")
2091 set (_unityFileExt_CXX ".cxx")
2092 set (_prefixFileExt_C ".h")
2093 set (_prefixFileExt_CXX ".hxx")
2094 set (_prefixSourceFileExt_C ".c")
2095 set (_prefixSourceFileExt_CXX ".cxx")
2096 endmacro()
2097
2098 function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
2099 cotire_setup_file_extension_variables()
2100 if (NOT DEFINED _unityFileExt_${_language})
2101 set (${_unityFileVar} "" PARENT_SCOPE)
2102 return()
2103 endif()
2104 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2105 set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
2106 cotire_get_intermediate_dir(_baseDir)
2107 set (_unityFile "${_baseDir}/${_unityFileName}")
2108 set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
2109 endfunction()
2110
2111 function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
2112 cotire_setup_file_extension_variables()
2113 if (NOT DEFINED _unityFileExt_${_language})
2114 set (${_unityFileVar} "" PARENT_SCOPE)
2115 return()
2116 endif()
2117 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2118 cotire_get_intermediate_dir(_baseDir)
2119 set (_startIndex 0)
2120 set (_index 0)
2121 set (_unityFiles "")
2122 set (_sourceFiles ${ARGN})
2123 foreach (_sourceFile ${_sourceFiles})
2124 get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
2125 math (EXPR _unityFileCount "${_index} - ${_startIndex}")
2126 if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
2127 if (_index GREATER 0)
2128 # start new unity file segment
2129 math (EXPR _endIndex "${_index} - 1")
2130 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2131 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2132 endif()
2133 set (_startIndex ${_index})
2134 endif()
2135 math (EXPR _index "${_index} + 1")
2136 endforeach()
2137 list (LENGTH _sourceFiles _numberOfSources)
2138 if (_startIndex EQUAL 0)
2139 # there is only a single unity file
2140 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
2141 elseif (_startIndex LESS _numberOfSources)
2142 # end with final unity file segment
2143 math (EXPR _endIndex "${_index} - 1")
2144 set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
2145 list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
2146 endif()
2147 set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
2148 if (COTIRE_DEBUG AND _unityFiles)
2149 message (STATUS "unity files: ${_unityFiles}")
2150 endif()
2151 endfunction()
2152
2153 function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
2154 cotire_setup_file_extension_variables()
2155 if (NOT DEFINED _unityFileExt_${_language})
2156 set (${_prefixFileVar} "" PARENT_SCOPE)
2157 return()
2158 endif()
2159 set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
2160 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2161 string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
2162 string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
2163 set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
2164 endfunction()
2165
2166 function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar)
2167 cotire_setup_file_extension_variables()
2168 if (NOT DEFINED _prefixSourceFileExt_${_language})
2169 set (${_prefixSourceFileVar} "" PARENT_SCOPE)
2170 return()
2171 endif()
2172 string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}")
2173 set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE)
2174 endfunction()
2175
2176 function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
2177 cotire_setup_file_extension_variables()
2178 if (NOT _language)
2179 set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2180 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
2181 elseif (DEFINED _prefixFileExt_${_language})
2182 set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
2183 set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
2184 else()
2185 set (_prefixFileBaseName "")
2186 set (_prefixFileName "")
2187 endif()
2188 set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
2189 set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
2190 endfunction()
2191
2192 function (cotire_make_prefix_file_path _language _target _prefixFileVar)
2193 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2194 set (${_prefixFileVar} "" PARENT_SCOPE)
2195 if (_prefixFileName)
2196 if (NOT _language)
2197 set (_language "C")
2198 endif()
2199 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC")
2200 cotire_get_intermediate_dir(_baseDir)
2201 set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
2202 endif()
2203 endif()
2204 endfunction()
2205
2206 function (cotire_make_pch_file_path _language _target _pchFileVar)
2207 cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
2208 set (${_pchFileVar} "" PARENT_SCOPE)
2209 if (_prefixFileBaseName AND _prefixFileName)
2210 cotire_check_precompiled_header_support("${_language}" "${_target}" _msg)
2211 if (NOT _msg)
2212 if (XCODE)
2213 # For Xcode, we completely hand off the compilation of the prefix header to the IDE
2214 return()
2215 endif()
2216 cotire_get_intermediate_dir(_baseDir)
2217 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
2218 # MSVC uses the extension .pch added to the prefix header base name
2219 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
2220 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
2221 # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended
2222 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE)
2223 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
2224 # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended
2225 set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
2226 elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
2227 # Intel uses the extension .pchi added to the prefix header base name
2228 set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
2229 endif()
2230 endif()
2231 endif()
2232 endfunction()
2233
2234 function (cotire_select_unity_source_files _unityFile _sourcesVar)
2235 set (_sourceFiles ${ARGN})
2236 if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
2237 set (_startIndex ${CMAKE_MATCH_1})
2238 set (_endIndex ${CMAKE_MATCH_2})
2239 list (LENGTH _sourceFiles _numberOfSources)
2240 if (NOT _startIndex LESS _numberOfSources)
2241 math (EXPR _startIndex "${_numberOfSources} - 1")
2242 endif()
2243 if (NOT _endIndex LESS _numberOfSources)
2244 math (EXPR _endIndex "${_numberOfSources} - 1")
2245 endif()
2246 set (_files "")
2247 foreach (_index RANGE ${_startIndex} ${_endIndex})
2248 list (GET _sourceFiles ${_index} _file)
2249 list (APPEND _files "${_file}")
2250 endforeach()
2251 else()
2252 set (_files ${_sourceFiles})
2253 endif()
2254 set (${_sourcesVar} ${_files} PARENT_SCOPE)
2255 endfunction()
2256
2257 function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
2258 set (_dependencySources "")
2259 # depend on target's generated source files
2260 get_target_property(_targetSourceFiles ${_target} SOURCES)
2261 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2262 if (_generatedSources)
2263 # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
2264 cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
2265 if (_excludedGeneratedSources)
2266 list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
2267 endif()
2268 # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
2269 cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
2270 if (_excludedNonDependencySources)
2271 list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
2272 endif()
2273 if (_generatedSources)
2274 list (APPEND _dependencySources ${_generatedSources})
2275 endif()
2276 endif()
2277 if (COTIRE_DEBUG AND _dependencySources)
2278 message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}")
2279 endif()
2280 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2281 endfunction()
2282
2283 function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
2284 set (_dependencySources "")
2285 # depend on target source files marked with custom COTIRE_DEPENDENCY property
2286 get_target_property(_targetSourceFiles ${_target} SOURCES)
2287 cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles})
2288 if (COTIRE_DEBUG AND _dependencySources)
2289 message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}")
2290 endif()
2291 set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
2292 endfunction()
2293
2294 function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar)
2295 set (_targetSources ${ARGN})
2296 cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources})
2297 cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources})
2298 # set up variables to be configured
2299 set (COTIRE_TARGET_LANGUAGE "${_language}")
2300 get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
2301 cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
2302 get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
2303 cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
2304 get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
2305 get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
2306 get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2307 get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH)
2308 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources})
2309 cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources})
2310 set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
2311 foreach (_config ${_configurations})
2312 string (TOUPPER "${_config}" _upperConfig)
2313 cotire_get_target_include_directories(
2314 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig})
2315 cotire_get_target_compile_definitions(
2316 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
2317 cotire_get_target_compiler_flags(
2318 "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
2319 cotire_get_source_files_compile_definitions(
2320 "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources})
2321 endforeach()
2322 get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER)
2323 # set up COTIRE_TARGET_SOURCES
2324 set (COTIRE_TARGET_SOURCES "")
2325 foreach (_sourceFile ${_targetSources})
2326 get_source_file_property(_generated "${_sourceFile}" GENERATED)
2327 if (_generated)
2328 # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation
2329 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2330 list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}")
2331 else()
2332 list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}")
2333 endif()
2334 endforeach()
2335 # copy variable definitions to cotire target script
2336 get_cmake_property(_vars VARIABLES)
2337 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
2338 # omit COTIRE_*_INIT variables
2339 string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}")
2340 if (_initVars)
2341 list (REMOVE_ITEM _matchVars ${_initVars})
2342 endif()
2343 # omit COTIRE_VERBOSE which is passed as a CMake define on command line
2344 list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
2345 set (_contents "")
2346 set (_contentsHasGeneratorExpressions FALSE)
2347 foreach (_var IN LISTS _matchVars ITEMS
2348 XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
2349 CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION
2350 CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
2351 CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language}
2352 CMAKE_INCLUDE_SYSTEM_FLAG_${_language}
2353 CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG
2354 CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG
2355 CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
2356 if (DEFINED ${_var})
2357 string (REPLACE "\"" "\\\"" _value "${${_var}}")
2358 set (_contents "${_contents}set (${_var} \"${_value}\")\n")
2359 if (NOT _contentsHasGeneratorExpressions)
2360 if ("${_value}" MATCHES "\\$<.*>")
2361 set (_contentsHasGeneratorExpressions TRUE)
2362 endif()
2363 endif()
2364 endif()
2365 endforeach()
2366 # generate target script file
2367 get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
2368 set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
2369 cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
2370 if (_contentsHasGeneratorExpressions)
2371 # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time
2372 set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>")
2373 set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}")
2374 file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}")
2375 else()
2376 set (_targetCotireConfigScript "${_targetCotireScript}")
2377 endif()
2378 set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
2379 set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE)
2380 endfunction()
2381
2382 function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile)
2383 set (_sourceFiles ${ARGN})
2384 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2385 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2386 # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file
2387 # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion
2388 if (_sourceFiles)
2389 set (_flags "")
2390 cotire_add_pch_compilation_flags(
2391 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2392 "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
2393 set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2394 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
2395 # make object file generated from host file depend on prefix header
2396 set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2397 # mark host file as cotired to prevent it from being used in another cotired target
2398 set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}")
2399 endif()
2400 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2401 # for makefile based generator, we add a custom command to precompile the prefix header
2402 if (_targetScript)
2403 cotire_set_cmd_to_prologue(_cmds)
2404 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
2405 if (MSVC_IDE)
2406 file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath)
2407 else()
2408 file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
2409 endif()
2410 # make precompiled header compilation depend on the actual compiler executable used to force
2411 # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable"
2412 # warnings when the precompiled header is included.
2413 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2414 if (COTIRE_DEBUG)
2415 message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
2416 endif()
2417 set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
2418 add_custom_command(
2419 OUTPUT "${_pchFile}"
2420 COMMAND ${_cmds}
2421 DEPENDS "${_prefixFile}" "${_realCompilerExe}"
2422 IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
2423 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2424 COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}"
2425 VERBATIM)
2426 endif()
2427 endif()
2428 endfunction()
2429
2430 function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile)
2431 if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR
2432 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2433 # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file
2434 # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation
2435 set (_sourceFiles ${ARGN})
2436 list (LENGTH _sourceFiles _numberOfSourceFiles)
2437 if (_numberOfSourceFiles GREATER 0)
2438 # mark sources as cotired to prevent them from being used in another cotired target
2439 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2440 set (_flags "")
2441 cotire_add_prefix_pch_inclusion_flags(
2442 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2443 "${_prefixFile}" "${_pchFile}" _flags)
2444 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2445 # make object files generated from source files depend on precompiled header
2446 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2447 endif()
2448 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2449 set (_sourceFiles ${_hostFile} ${ARGN})
2450 if (NOT _wholeTarget)
2451 # for makefile based generator, we force the inclusion of the prefix header for a subset
2452 # of the source files, if this is a multi-language target or has excluded files
2453 set (_flags "")
2454 cotire_add_prefix_pch_inclusion_flags(
2455 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2456 "${_prefixFile}" "${_pchFile}" _flags)
2457 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2458 # mark sources as cotired to prevent them from being used in another cotired target
2459 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2460 endif()
2461 # make object files generated from source files depend on precompiled header
2462 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
2463 endif()
2464 endfunction()
2465
2466 function (cotire_setup_prefix_file_inclusion _language _target _prefixFile)
2467 set (_sourceFiles ${ARGN})
2468 # force the inclusion of the prefix header for the given source files
2469 set (_flags "")
2470 set (_pchFile "")
2471 cotire_add_prefix_pch_inclusion_flags(
2472 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2473 "${_prefixFile}" "${_pchFile}" _flags)
2474 set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
2475 # mark sources as cotired to prevent them from being used in another cotired target
2476 set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
2477 # make object files generated from source files depend on prefix header
2478 set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
2479 endfunction()
2480
2481 function (cotire_get_first_set_property_value _propertyValueVar _type _object)
2482 set (_properties ${ARGN})
2483 foreach (_property ${_properties})
2484 get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
2485 if (_propertyValue)
2486 set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
2487 return()
2488 endif()
2489 endforeach()
2490 set (${_propertyValueVar} "" PARENT_SCOPE)
2491 endfunction()
2492
2493 function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar)
2494 set (_files ${ARGN})
2495 set (_filesPaths "")
2496 foreach (_file ${_files})
2497 get_filename_component(_filePath "${_file}" ABSOLUTE)
2498 list (APPEND _filesPaths "${_filePath}")
2499 endforeach()
2500 cotire_set_cmd_to_prologue(_prefixCmd)
2501 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
2502 if (_targetScript)
2503 list (APPEND _prefixCmd "${_targetScript}")
2504 endif()
2505 list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
2506 if (COTIRE_DEBUG)
2507 message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
2508 endif()
2509 set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
2510 if (MSVC_IDE)
2511 file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath)
2512 else()
2513 file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
2514 endif()
2515 get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE)
2516 get_filename_component(_joinedFileExt "${_joinedFile}" EXT)
2517 if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
2518 set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}")
2519 elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$")
2520 if (_joinedFileExt MATCHES "^\\.c")
2521 set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}")
2522 else()
2523 set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}")
2524 endif()
2525 else()
2526 set (_comment "Generating ${_joinedFileLogPath}")
2527 endif()
2528 add_custom_command(
2529 OUTPUT "${_joinedFile}"
2530 COMMAND ${_prefixCmd}
2531 DEPENDS ${_files}
2532 COMMENT "${_comment}"
2533 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2534 VERBATIM)
2535 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2536 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2537 endfunction()
2538
2539 function (cotire_setup_target_pch_usage _languages _target _wholeTarget)
2540 if (XCODE)
2541 # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
2542 set (_prefixFiles "")
2543 foreach (_language ${_languages})
2544 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2545 if (_prefixFile)
2546 list (APPEND _prefixFiles "${_prefixFile}")
2547 endif()
2548 endforeach()
2549 set (_cmds ${ARGN})
2550 list (LENGTH _prefixFiles _numberOfPrefixFiles)
2551 if (_numberOfPrefixFiles GREATER 1)
2552 # we also generate a generic, single prefix header which includes all language specific prefix headers
2553 set (_language "")
2554 set (_targetScript "")
2555 cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader)
2556 cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles})
2557 else()
2558 set (_prefixHeader "${_prefixFiles}")
2559 endif()
2560 if (COTIRE_DEBUG)
2561 message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
2562 endif()
2563 # because CMake PRE_BUILD command does not support dependencies,
2564 # we check dependencies explicity in cotire script mode when the pre-build action is run
2565 add_custom_command(
2566 TARGET "${_target}"
2567 PRE_BUILD ${_cmds}
2568 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2569 COMMENT "Updating target ${_target} prefix headers"
2570 VERBATIM)
2571 # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
2572 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
2573 set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
2574 elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
2575 # for makefile based generator, we force inclusion of the prefix header for all target source files
2576 # if this is a single-language target without any excluded files
2577 if (_wholeTarget)
2578 set (_language "${_languages}")
2579 # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level
2580 # see cotire_setup_pch_file_inclusion
2581 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
2582 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
2583 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
2584 if (_prefixFile)
2585 get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
2586 set (_options COMPILE_OPTIONS)
2587 cotire_add_prefix_pch_inclusion_flags(
2588 "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}"
2589 "${_prefixFile}" "${_pchFile}" _options)
2590 set_property(TARGET ${_target} APPEND PROPERTY ${_options})
2591 endif()
2592 endif()
2593 endif()
2594 endif()
2595 endfunction()
2596
2597 function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar)
2598 set (_dependencySources "")
2599 cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
2600 foreach (_unityFile ${_unityFiles})
2601 set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
2602 # set up compiled unity source dependencies via OBJECT_DEPENDS
2603 # this ensures that missing source files are generated before the unity file is compiled
2604 if (COTIRE_DEBUG AND _dependencySources)
2605 message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
2606 endif()
2607 if (_dependencySources)
2608 # the OBJECT_DEPENDS property requires a list of full paths
2609 set (_objectDependsPaths "")
2610 foreach (_sourceFile ${_dependencySources})
2611 get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION)
2612 list (APPEND _objectDependsPaths "${_sourceLocation}")
2613 endforeach()
2614 set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths})
2615 endif()
2616 if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
2617 # unity file compilation results in potentially huge object file,
2618 # thus use /bigobj by default unter cl.exe and Windows Intel
2619 set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
2620 endif()
2621 cotire_set_cmd_to_prologue(_unityCmd)
2622 list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}")
2623 if (CMAKE_VERSION VERSION_LESS "3.1.0")
2624 set (_unityCmdDepends "${_targetScript}")
2625 else()
2626 # CMake 3.1.0 supports generator expressions in arguments to DEPENDS
2627 set (_unityCmdDepends "${_targetConfigScript}")
2628 endif()
2629 if (MSVC_IDE)
2630 file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath)
2631 else()
2632 file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
2633 endif()
2634 if (COTIRE_DEBUG)
2635 message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}")
2636 endif()
2637 add_custom_command(
2638 OUTPUT "${_unityFile}"
2639 COMMAND ${_unityCmd}
2640 DEPENDS ${_unityCmdDepends}
2641 COMMENT "Generating ${_language} unity source ${_unityFileLogPath}"
2642 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2643 VERBATIM)
2644 list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
2645 endforeach()
2646 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2647 endfunction()
2648
2649 function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2650 set (_sourceFiles ${ARGN})
2651 set (_dependencySources "")
2652 cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
2653 cotire_set_cmd_to_prologue(_prefixCmd)
2654 list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles})
2655 set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
2656 # make prefix header generation depend on the actual compiler executable used to force
2657 # re-generation when the compiler executable is updated. This prevents "file not found"
2658 # errors for compiler version specific system header files.
2659 get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE)
2660 if (COTIRE_DEBUG)
2661 message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}")
2662 endif()
2663 if (MSVC_IDE)
2664 file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath)
2665 else()
2666 file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
2667 endif()
2668 get_filename_component(_prefixFileExt "${_prefixFile}" EXT)
2669 if (_prefixFileExt MATCHES "^\\.c")
2670 set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}")
2671 else()
2672 set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}")
2673 endif()
2674 # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist
2675 # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence
2676 # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files
2677 set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre")
2678 if (TARGET ${_preTargetName})
2679 # custom helper target has already been generated while processing a different language
2680 list (APPEND _dependencySources ${_preTargetName})
2681 else()
2682 get_target_property(_targetSourceFiles ${_target} SOURCES)
2683 cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles})
2684 if (_generatedSources)
2685 add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources})
2686 cotire_init_target("${_preTargetName}")
2687 list (APPEND _dependencySources ${_preTargetName})
2688 endif()
2689 endif()
2690 add_custom_command(
2691 OUTPUT "${_prefixFile}" "${_prefixFile}.log"
2692 COMMAND ${_prefixCmd}
2693 DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}"
2694 COMMENT "${_comment}"
2695 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
2696 VERBATIM)
2697 list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
2698 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2699 endfunction()
2700
2701 function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar)
2702 set (_sourceFiles ${ARGN})
2703 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2704 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2705 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2706 else()
2707 set (_prefixSourceFile "${_prefixFile}")
2708 endif()
2709 cotire_setup_prefix_generation_command(
2710 ${_language} ${_target} "${_targetScript}"
2711 "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
2712 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2713 # set up generation of a prefix source file which includes the prefix header
2714 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2715 endif()
2716 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2717 endfunction()
2718
2719 function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar)
2720 set (_prefixHeaderFiles ${ARGN})
2721 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2722 # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma
2723 cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile)
2724 else()
2725 set (_prefixSourceFile "${_prefixFile}")
2726 endif()
2727 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles})
2728 if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
2729 # set up generation of a prefix source file which includes the prefix header
2730 cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile})
2731 endif()
2732 set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
2733 endfunction()
2734
2735 function (cotire_init_cotire_target_properties _target)
2736 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
2737 if (NOT _isSet)
2738 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
2739 endif()
2740 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
2741 if (NOT _isSet)
2742 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
2743 endif()
2744 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
2745 if (NOT _isSet)
2746 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
2747 endif()
2748 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
2749 if (NOT _isSet)
2750 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
2751 cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
2752 if (NOT _isRelative)
2753 set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
2754 endif()
2755 endif()
2756 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
2757 if (NOT _isSet)
2758 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
2759 endif()
2760 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET)
2761 if (NOT _isSet)
2762 set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "")
2763 endif()
2764 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
2765 if (NOT _isSet)
2766 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
2767 endif()
2768 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
2769 if (NOT _isSet)
2770 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
2771 endif()
2772 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET)
2773 if (NOT _isSet)
2774 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY")
2775 endif()
2776 get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
2777 if (NOT _isSet)
2778 if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
2779 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
2780 else()
2781 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
2782 endif()
2783 endif()
2784 endfunction()
2785
2786 function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
2787 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2788 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2789 string (REPLACE ";" " " _languagesStr "${_languages}")
2790 math (EXPR _numberOfExcludedFiles "${ARGC} - 4")
2791 if (_numberOfExcludedFiles EQUAL 0)
2792 set (_excludedStr "")
2793 elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4)
2794 string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}")
2795 else()
2796 set (_excludedStr "excluding ${_numberOfExcludedFiles} files")
2797 endif()
2798 set (_targetMsg "")
2799 if (NOT _languages)
2800 set (_targetMsg "Target ${_target} cannot be cotired.")
2801 if (_disableMsg)
2802 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2803 endif()
2804 elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
2805 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
2806 if (_disableMsg)
2807 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2808 endif()
2809 elseif (NOT _targetUsePCH)
2810 if (_excludedStr)
2811 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.")
2812 else()
2813 set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
2814 endif()
2815 if (_disableMsg)
2816 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2817 endif()
2818 elseif (NOT _targetAddSCU)
2819 if (_excludedStr)
2820 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.")
2821 else()
2822 set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
2823 endif()
2824 if (_disableMsg)
2825 set (_targetMsg "${_targetMsg} ${_disableMsg}")
2826 endif()
2827 else()
2828 if (_excludedStr)
2829 set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.")
2830 else()
2831 set (_targetMsg "${_languagesStr} target ${_target} cotired.")
2832 endif()
2833 endif()
2834 set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
2835 endfunction()
2836
2837 function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar)
2838 set (_languages ${ARGN})
2839 set (_allSourceFiles "")
2840 set (_allExcludedSourceFiles "")
2841 set (_allCotiredSourceFiles "")
2842 set (_targetLanguages "")
2843 set (_pchEligibleTargetLanguages "")
2844 get_target_property(_targetType ${_target} TYPE)
2845 get_target_property(_targetSourceFiles ${_target} SOURCES)
2846 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
2847 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
2848 set (_disableMsg "")
2849 foreach (_language ${_languages})
2850 get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
2851 get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
2852 if (_prefixHeader OR _unityBuildFile)
2853 message (STATUS "cotire: target ${_target} has already been cotired.")
2854 set (${_targetLanguagesVar} "" PARENT_SCOPE)
2855 return()
2856 endif()
2857 if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID)
2858 if (CMAKE_${_language}_COMPILER_ID)
2859 cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg)
2860 if (_disableMsg)
2861 set (_targetUsePCH FALSE)
2862 endif()
2863 endif()
2864 endif()
2865 set (_sourceFiles "")
2866 set (_excludedSources "")
2867 set (_cotiredSources "")
2868 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2869 if (_sourceFiles OR _excludedSources OR _cotiredSources)
2870 list (APPEND _targetLanguages ${_language})
2871 endif()
2872 if (_sourceFiles)
2873 list (APPEND _allSourceFiles ${_sourceFiles})
2874 endif()
2875 list (LENGTH _sourceFiles _numberOfSources)
2876 if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
2877 list (APPEND _pchEligibleTargetLanguages ${_language})
2878 endif()
2879 if (_excludedSources)
2880 list (APPEND _allExcludedSourceFiles ${_excludedSources})
2881 endif()
2882 if (_cotiredSources)
2883 list (APPEND _allCotiredSourceFiles ${_cotiredSources})
2884 endif()
2885 endforeach()
2886 set (_targetMsgLevel STATUS)
2887 if (NOT _targetLanguages)
2888 string (REPLACE ";" " or " _languagesStr "${_languages}")
2889 set (_disableMsg "No ${_languagesStr} source files.")
2890 set (_targetUsePCH FALSE)
2891 set (_targetAddSCU FALSE)
2892 endif()
2893 if (_targetUsePCH)
2894 if (_allCotiredSourceFiles)
2895 cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
2896 list (REMOVE_DUPLICATES _cotireTargets)
2897 string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
2898 set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
2899 set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
2900 set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
2901 set (_targetMsgLevel SEND_ERROR)
2902 set (_targetUsePCH FALSE)
2903 elseif (NOT _pchEligibleTargetLanguages)
2904 set (_disableMsg "Too few applicable sources.")
2905 set (_targetUsePCH FALSE)
2906 elseif (XCODE AND _allExcludedSourceFiles)
2907 # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
2908 set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
2909 set (_targetUsePCH FALSE)
2910 elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
2911 # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
2912 set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
2913 set (_targetUsePCH FALSE)
2914 endif()
2915 endif()
2916 if (_targetAddSCU)
2917 # disable unity builds if automatic Qt processing is used
2918 get_target_property(_targetAutoMoc ${_target} AUTOMOC)
2919 get_target_property(_targetAutoUic ${_target} AUTOUIC)
2920 get_target_property(_targetAutoRcc ${_target} AUTORCC)
2921 if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc)
2922 if (_disableMsg)
2923 set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.")
2924 else()
2925 set (_disableMsg "Target uses automatic CMake Qt processing.")
2926 endif()
2927 set (_targetAddSCU FALSE)
2928 endif()
2929 endif()
2930 set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
2931 set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
2932 cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
2933 if (_targetMsg)
2934 if (NOT DEFINED COTIREMSG_${_target})
2935 set (COTIREMSG_${_target} "")
2936 endif()
2937 if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
2938 NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
2939 # cache message to avoid redundant messages on re-configure
2940 set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
2941 message (${_targetMsgLevel} "${_targetMsg}")
2942 endif()
2943 endif()
2944 list (LENGTH _targetLanguages _numberOfLanguages)
2945 if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles)
2946 set (${_wholeTargetVar} FALSE PARENT_SCOPE)
2947 else()
2948 set (${_wholeTargetVar} TRUE PARENT_SCOPE)
2949 endif()
2950 set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
2951 endfunction()
2952
2953 function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
2954 set (_sourceFiles ${ARGN})
2955 get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
2956 if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
2957 if (DEFINED CMAKE_MATCH_2)
2958 set (_numberOfThreads "${CMAKE_MATCH_2}")
2959 else()
2960 set (_numberOfThreads "")
2961 endif()
2962 if (NOT _numberOfThreads)
2963 # use all available cores
2964 ProcessorCount(_numberOfThreads)
2965 endif()
2966 list (LENGTH _sourceFiles _numberOfSources)
2967 math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
2968 elseif (NOT _maxIncludes MATCHES "[0-9]+")
2969 set (_maxIncludes 0)
2970 endif()
2971 if (COTIRE_DEBUG)
2972 message (STATUS "${_target} unity source max includes: ${_maxIncludes}")
2973 endif()
2974 set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
2975 endfunction()
2976
2977 function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar)
2978 set (${_cmdsVar} "" PARENT_SCOPE)
2979 get_target_property(_targetSourceFiles ${_target} SOURCES)
2980 set (_sourceFiles "")
2981 set (_excludedSources "")
2982 set (_cotiredSources "")
2983 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
2984 if (NOT _sourceFiles AND NOT _cotiredSources)
2985 return()
2986 endif()
2987 set (_cmds "")
2988 # check for user provided unity source file list
2989 get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
2990 if (NOT _unitySourceFiles)
2991 set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
2992 endif()
2993 cotire_generate_target_script(
2994 ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles})
2995 # set up unity files for parallel compilation
2996 cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
2997 cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
2998 list (LENGTH _unityFiles _numberOfUnityFiles)
2999 if (_numberOfUnityFiles EQUAL 0)
3000 return()
3001 elseif (_numberOfUnityFiles GREATER 1)
3002 cotire_setup_unity_generation_commands(
3003 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
3004 endif()
3005 # set up single unity file for prefix header generation
3006 cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
3007 cotire_setup_unity_generation_commands(
3008 ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles})
3009 cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
3010 # set up prefix header
3011 if (_prefixFile)
3012 # check for user provided prefix header files
3013 get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3014 if (_prefixHeaderFiles)
3015 cotire_setup_prefix_generation_from_provided_command(
3016 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
3017 else()
3018 cotire_setup_prefix_generation_from_unity_command(
3019 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles})
3020 endif()
3021 # check if selected language has enough sources at all
3022 list (LENGTH _sourceFiles _numberOfSources)
3023 if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
3024 set (_targetUsePCH FALSE)
3025 else()
3026 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3027 endif()
3028 if (_targetUsePCH)
3029 cotire_make_pch_file_path(${_language} ${_target} _pchFile)
3030 if (_pchFile)
3031 # first file in _sourceFiles is passed as the host file
3032 cotire_setup_pch_file_compilation(
3033 ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3034 cotire_setup_pch_file_inclusion(
3035 ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
3036 endif()
3037 elseif (_prefixHeaderFiles)
3038 # user provided prefix header must be included unconditionally
3039 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles})
3040 endif()
3041 endif()
3042 # mark target as cotired for language
3043 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
3044 if (_prefixFile)
3045 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
3046 if (_targetUsePCH AND _pchFile)
3047 set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
3048 endif()
3049 endif()
3050 set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
3051 endfunction()
3052
3053 function (cotire_setup_clean_target _target)
3054 set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
3055 if (NOT TARGET "${_cleanTargetName}")
3056 cotire_set_cmd_to_prologue(_cmds)
3057 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
3058 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
3059 add_custom_target(${_cleanTargetName}
3060 COMMAND ${_cmds}
3061 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3062 COMMENT "Cleaning up target ${_target} cotire generated files"
3063 VERBATIM)
3064 cotire_init_target("${_cleanTargetName}")
3065 endif()
3066 endfunction()
3067
3068 function (cotire_setup_pch_target _languages _configurations _target)
3069 if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
3070 # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
3071 set (_dependsFiles "")
3072 foreach (_language ${_languages})
3073 set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
3074 if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT
3075 (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang"))
3076 # MSVC, Intel and clang-cl only create precompiled header as a side effect
3077 list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
3078 endif()
3079 cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
3080 if (_dependsFile)
3081 list (APPEND _dependsFiles "${_dependsFile}")
3082 endif()
3083 endforeach()
3084 if (_dependsFiles)
3085 set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
3086 add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
3087 cotire_init_target("${_pchTargetName}")
3088 cotire_add_to_pch_all_target(${_pchTargetName})
3089 endif()
3090 else()
3091 # for other generators, we add the "clean all" target to clean up the precompiled header
3092 cotire_setup_clean_all_target()
3093 endif()
3094 endfunction()
3095
3096 function (cotire_filter_object_libraries _target _objectLibrariesVar)
3097 set (_objectLibraries "")
3098 foreach (_source ${ARGN})
3099 if (_source MATCHES "^\\$<TARGET_OBJECTS:.+>$")
3100 list (APPEND _objectLibraries "${_source}")
3101 endif()
3102 endforeach()
3103 set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE)
3104 endfunction()
3105
3106 function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar)
3107 get_target_property(_targetSourceFiles ${_target} SOURCES)
3108 set (_unityTargetSources ${_targetSourceFiles})
3109 foreach (_language ${_languages})
3110 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3111 if (_unityFiles)
3112 # remove source files that are included in the unity source
3113 set (_sourceFiles "")
3114 set (_excludedSources "")
3115 set (_cotiredSources "")
3116 cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
3117 if (_sourceFiles OR _cotiredSources)
3118 list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
3119 endif()
3120 # add unity source files instead
3121 list (APPEND _unityTargetSources ${_unityFiles})
3122 endif()
3123 endforeach()
3124 # handle object libraries which are part of the target's sources
3125 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3126 if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$")
3127 cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles})
3128 if (_objectLibraries)
3129 cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries})
3130 list (REMOVE_ITEM _unityTargetSources ${_objectLibraries})
3131 list (APPEND _unityTargetSources ${_unityObjectLibraries})
3132 endif()
3133 endif()
3134 set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE)
3135 endfunction()
3136
3137 function (cotire_setup_unity_target_pch_usage _languages _target)
3138 foreach (_language ${_languages})
3139 get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
3140 if (_unityFiles)
3141 get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
3142 get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
3143 if (_userPrefixFile AND _prefixFile)
3144 # user provided prefix header must be included unconditionally by unity sources
3145 cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles})
3146 endif()
3147 endif()
3148 endforeach()
3149 endfunction()
3150
3151 function (cotire_setup_unity_build_target _languages _configurations _target)
3152 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3153 if (NOT _unityTargetName)
3154 set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
3155 endif()
3156 # determine unity target sub type
3157 get_target_property(_targetType ${_target} TYPE)
3158 if ("${_targetType}" STREQUAL "EXECUTABLE")
3159 set (_unityTargetSubType "")
3160 elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
3161 set (_unityTargetSubType "${CMAKE_MATCH_1}")
3162 else()
3163 message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.")
3164 return()
3165 endif()
3166 # determine unity target sources
3167 set (_unityTargetSources "")
3168 cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources)
3169 # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created
3170 set (CMAKE_AUTOMOC OFF)
3171 set (CMAKE_AUTOUIC OFF)
3172 set (CMAKE_AUTORCC OFF)
3173 if (COTIRE_DEBUG)
3174 message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
3175 endif()
3176 # generate unity target
3177 if ("${_targetType}" STREQUAL "EXECUTABLE")
3178 add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3179 else()
3180 add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
3181 endif()
3182 # copy output location properties
3183 set (_outputDirProperties
3184 ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
3185 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
3186 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
3187 if (COTIRE_UNITY_OUTPUT_DIRECTORY)
3188 set (_setDefaultOutputDir TRUE)
3189 if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3190 set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
3191 else()
3192 # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory
3193 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
3194 cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties})
3195 foreach (_property ${_properties})
3196 get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
3197 if (_outputDir)
3198 get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3199 set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
3200 set (_setDefaultOutputDir FALSE)
3201 endif()
3202 endforeach()
3203 if (_setDefaultOutputDir)
3204 get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
3205 endif()
3206 endif()
3207 if (_setDefaultOutputDir)
3208 set_target_properties(${_unityTargetName} PROPERTIES
3209 ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
3210 LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
3211 RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
3212 endif()
3213 else()
3214 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3215 ${_outputDirProperties})
3216 endif()
3217 # copy output name
3218 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3219 ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
3220 LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
3221 OUTPUT_NAME OUTPUT_NAME_<CONFIG>
3222 RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
3223 PREFIX <CONFIG>_POSTFIX SUFFIX
3224 IMPORT_PREFIX IMPORT_SUFFIX)
3225 # copy compile stuff
3226 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3227 COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
3228 COMPILE_FLAGS COMPILE_OPTIONS
3229 Fortran_FORMAT Fortran_MODULE_DIRECTORY
3230 INCLUDE_DIRECTORIES
3231 INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
3232 POSITION_INDEPENDENT_CODE
3233 C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER
3234 C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE
3235 C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN
3236 C_CLANG_TIDY CXX_CLANG_TIDY)
3237 # copy compile features
3238 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3239 C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED
3240 CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED
3241 COMPILE_FEATURES)
3242 # copy interface stuff
3243 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3244 COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN
3245 COMPATIBLE_INTERFACE_STRING
3246 INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS
3247 INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES
3248 INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
3249 INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED)
3250 # copy link stuff
3251 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3252 BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR
3253 INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
3254 LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED
3255 LINK_FLAGS LINK_FLAGS_<CONFIG>
3256 LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
3257 LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
3258 LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
3259 STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
3260 NO_SONAME SOVERSION VERSION
3261 LINK_WHAT_YOU_USE BUILD_RPATH)
3262 # copy cmake stuff
3263 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3264 IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
3265 # copy Apple platform specific stuff
3266 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3267 BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR
3268 MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH
3269 OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST
3270 IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE)
3271 # copy Windows platform specific stuff
3272 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3273 GNUtoMS
3274 COMPILE_PDB_NAME COMPILE_PDB_NAME_<CONFIG>
3275 COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
3276 PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
3277 VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION
3278 VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE
3279 VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK
3280 VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION
3281 VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
3282 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
3283 VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES
3284 WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS
3285 DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE
3286 VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY)
3287 # copy Android platform specific stuff
3288 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3289 ANDROID_API ANDROID_API_MIN ANDROID_GUI
3290 ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES
3291 ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR
3292 ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES
3293 ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH
3294 ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE)
3295 # copy CUDA platform specific stuff
3296 cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName}
3297 CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS
3298 CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED)
3299 # use output name from original target
3300 get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
3301 if (NOT _targetOutputName)
3302 set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
3303 endif()
3304 # use export symbol from original target
3305 cotire_get_target_export_symbol("${_target}" _defineSymbol)
3306 if (_defineSymbol)
3307 set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
3308 if ("${_targetType}" STREQUAL "EXECUTABLE")
3309 set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
3310 endif()
3311 endif()
3312 # enable parallel compilation for MSVC
3313 if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
3314 list (LENGTH _unityTargetSources _numberOfUnityTargetSources)
3315 if (_numberOfUnityTargetSources GREATER 1)
3316 set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP")
3317 endif()
3318 endif()
3319 cotire_init_target(${_unityTargetName})
3320 cotire_add_to_unity_all_target(${_unityTargetName})
3321 set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
3322 endfunction(cotire_setup_unity_build_target)
3323
3324 function (cotire_target _target)
3325 set(_options "")
3326 set(_oneValueArgs "")
3327 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3328 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3329 if (NOT _option_LANGUAGES)
3330 get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
3331 endif()
3332 if (NOT _option_CONFIGURATIONS)
3333 cotire_get_configuration_types(_option_CONFIGURATIONS)
3334 endif()
3335 # check if cotire can be applied to target at all
3336 cotire_is_target_supported(${_target} _isSupported)
3337 if (NOT _isSupported)
3338 get_target_property(_imported ${_target} IMPORTED)
3339 get_target_property(_targetType ${_target} TYPE)
3340 if (_imported)
3341 message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.")
3342 else()
3343 message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.")
3344 endif()
3345 return()
3346 endif()
3347 # resolve alias
3348 get_target_property(_aliasName ${_target} ALIASED_TARGET)
3349 if (_aliasName)
3350 if (COTIRE_DEBUG)
3351 message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.")
3352 endif()
3353 set (_target ${_aliasName})
3354 endif()
3355 # check if target needs to be cotired for build type
3356 # when using configuration types, the test is performed at build time
3357 cotire_init_cotire_target_properties(${_target})
3358 if (NOT CMAKE_CONFIGURATION_TYPES)
3359 if (CMAKE_BUILD_TYPE)
3360 list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
3361 else()
3362 list (FIND _option_CONFIGURATIONS "None" _index)
3363 endif()
3364 if (_index EQUAL -1)
3365 if (COTIRE_DEBUG)
3366 message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
3367 endif()
3368 return()
3369 endif()
3370 endif()
3371 # when not using configuration types, immediately create cotire intermediate dir
3372 if (NOT CMAKE_CONFIGURATION_TYPES)
3373 cotire_get_intermediate_dir(_baseDir)
3374 file (MAKE_DIRECTORY "${_baseDir}")
3375 endif()
3376 # choose languages that apply to the target
3377 cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES})
3378 if (NOT _targetLanguages)
3379 return()
3380 endif()
3381 set (_cmds "")
3382 foreach (_language ${_targetLanguages})
3383 cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd)
3384 if (_cmd)
3385 list (APPEND _cmds ${_cmd})
3386 endif()
3387 endforeach()
3388 get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
3389 if (_targetAddSCU)
3390 cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3391 endif()
3392 get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
3393 if (_targetUsePCH)
3394 cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds})
3395 cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
3396 if (_targetAddSCU)
3397 cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target})
3398 endif()
3399 endif()
3400 get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
3401 if (_targetAddCleanTarget)
3402 cotire_setup_clean_target(${_target})
3403 endif()
3404 endfunction(cotire_target)
3405
3406 function (cotire_map_libraries _strategy _mappedLibrariesVar)
3407 set (_mappedLibraries "")
3408 foreach (_library ${ARGN})
3409 if (_library MATCHES "^\\$<LINK_ONLY:(.+)>$")
3410 set (_libraryName "${CMAKE_MATCH_1}")
3411 set (_linkOnly TRUE)
3412 set (_objectLibrary FALSE)
3413 elseif (_library MATCHES "^\\$<TARGET_OBJECTS:(.+)>$")
3414 set (_libraryName "${CMAKE_MATCH_1}")
3415 set (_linkOnly FALSE)
3416 set (_objectLibrary TRUE)
3417 else()
3418 set (_libraryName "${_library}")
3419 set (_linkOnly FALSE)
3420 set (_objectLibrary FALSE)
3421 endif()
3422 if ("${_strategy}" MATCHES "COPY_UNITY")
3423 cotire_is_target_supported(${_libraryName} _isSupported)
3424 if (_isSupported)
3425 # use target's corresponding unity target, if available
3426 get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME)
3427 if (TARGET "${_libraryUnityTargetName}")
3428 if (_linkOnly)
3429 list (APPEND _mappedLibraries "$<LINK_ONLY:${_libraryUnityTargetName}>")
3430 elseif (_objectLibrary)
3431 list (APPEND _mappedLibraries "$<TARGET_OBJECTS:${_libraryUnityTargetName}>")
3432 else()
3433 list (APPEND _mappedLibraries "${_libraryUnityTargetName}")
3434 endif()
3435 else()
3436 list (APPEND _mappedLibraries "${_library}")
3437 endif()
3438 else()
3439 list (APPEND _mappedLibraries "${_library}")
3440 endif()
3441 else()
3442 list (APPEND _mappedLibraries "${_library}")
3443 endif()
3444 endforeach()
3445 list (REMOVE_DUPLICATES _mappedLibraries)
3446 set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE)
3447 endfunction()
3448
3449 function (cotire_target_link_libraries _target)
3450 cotire_is_target_supported(${_target} _isSupported)
3451 if (NOT _isSupported)
3452 return()
3453 endif()
3454 get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
3455 if (TARGET "${_unityTargetName}")
3456 get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT)
3457 if (COTIRE_DEBUG)
3458 message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}")
3459 endif()
3460 if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$")
3461 get_target_property(_linkLibraries ${_target} LINK_LIBRARIES)
3462 if (_linkLibraries)
3463 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries})
3464 set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}")
3465 if (COTIRE_DEBUG)
3466 message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}")
3467 endif()
3468 endif()
3469 get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES)
3470 if (_interfaceLinkLibraries)
3471 cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries})
3472 set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}")
3473 if (COTIRE_DEBUG)
3474 message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}")
3475 endif()
3476 endif()
3477 get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES)
3478 if (_manualDependencies)
3479 cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies})
3480 if (_unityManualDependencies)
3481 add_dependencies("${_unityTargetName}" ${_unityManualDependencies})
3482 endif()
3483 endif()
3484 endif()
3485 endif()
3486 endfunction(cotire_target_link_libraries)
3487
3488 function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
3489 if (_targetName)
3490 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
3491 else()
3492 file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
3493 endif()
3494 # filter files in intermediate directory
3495 set (_filesToRemove "")
3496 foreach (_file ${_cotireFiles})
3497 get_filename_component(_dir "${_file}" DIRECTORY)
3498 get_filename_component(_dirName "${_dir}" NAME)
3499 if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
3500 list (APPEND _filesToRemove "${_file}")
3501 endif()
3502 endforeach()
3503 if (_filesToRemove)
3504 if (COTIRE_VERBOSE)
3505 message (STATUS "cleaning up ${_filesToRemove}")
3506 endif()
3507 file (REMOVE ${_filesToRemove})
3508 endif()
3509 endfunction()
3510
3511 function (cotire_init_target _targetName)
3512 if (COTIRE_TARGETS_FOLDER)
3513 set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
3514 endif()
3515 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE)
3516 if (MSVC_IDE)
3517 set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
3518 endif()
3519 endfunction()
3520
3521 function (cotire_add_to_pch_all_target _pchTargetName)
3522 set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
3523 if (NOT TARGET "${_targetName}")
3524 add_custom_target("${_targetName}"
3525 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3526 VERBATIM)
3527 cotire_init_target("${_targetName}")
3528 endif()
3529 cotire_setup_clean_all_target()
3530 add_dependencies(${_targetName} ${_pchTargetName})
3531 endfunction()
3532
3533 function (cotire_add_to_unity_all_target _unityTargetName)
3534 set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
3535 if (NOT TARGET "${_targetName}")
3536 add_custom_target("${_targetName}"
3537 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3538 VERBATIM)
3539 cotire_init_target("${_targetName}")
3540 endif()
3541 cotire_setup_clean_all_target()
3542 add_dependencies(${_targetName} ${_unityTargetName})
3543 endfunction()
3544
3545 function (cotire_setup_clean_all_target)
3546 set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
3547 if (NOT TARGET "${_targetName}")
3548 cotire_set_cmd_to_prologue(_cmds)
3549 list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
3550 add_custom_target(${_targetName}
3551 COMMAND ${_cmds}
3552 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
3553 COMMENT "Cleaning up all cotire generated files"
3554 VERBATIM)
3555 cotire_init_target("${_targetName}")
3556 endif()
3557 endfunction()
3558
3559 function (cotire)
3560 set(_options "")
3561 set(_oneValueArgs "")
3562 set(_multiValueArgs LANGUAGES CONFIGURATIONS)
3563 cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
3564 set (_targets ${_option_UNPARSED_ARGUMENTS})
3565 foreach (_target ${_targets})
3566 if (TARGET ${_target})
3567 cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS})
3568 else()
3569 message (WARNING "cotire: ${_target} is not a target.")
3570 endif()
3571 endforeach()
3572 foreach (_target ${_targets})
3573 if (TARGET ${_target})
3574 cotire_target_link_libraries(${_target})
3575 endif()
3576 endforeach()
3577 endfunction()
3578
3579 if (CMAKE_SCRIPT_MODE_FILE)
3580
3581 # cotire is being run in script mode
3582 # locate -P on command args
3583 set (COTIRE_ARGC -1)
3584 foreach (_index RANGE ${CMAKE_ARGC})
3585 if (COTIRE_ARGC GREATER -1)
3586 set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
3587 math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
3588 elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
3589 set (COTIRE_ARGC 0)
3590 endif()
3591 endforeach()
3592
3593 # include target script if available
3594 if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
3595 # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
3596 include("${COTIRE_ARGV2}")
3597 endif()
3598
3599 if (COTIRE_DEBUG)
3600 message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
3601 endif()
3602
3603 if (NOT COTIRE_BUILD_TYPE)
3604 set (COTIRE_BUILD_TYPE "None")
3605 endif()
3606 string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
3607 set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
3608 set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}})
3609 set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
3610 set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
3611 # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
3612 list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
3613 if (_index GREATER -1)
3614 set (_sources ${COTIRE_TARGET_SOURCES})
3615 set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
3616 else()
3617 if (COTIRE_DEBUG)
3618 message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
3619 endif()
3620 set (_sources "")
3621 set (_sourcesDefinitions "")
3622 endif()
3623 set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
3624 set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
3625 set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
3626 set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
3627
3628 if ("${COTIRE_ARGV1}" STREQUAL "unity")
3629
3630 if (XCODE)
3631 # executing pre-build action under Xcode, check dependency on target script
3632 set (_dependsOption DEPENDS "${COTIRE_ARGV2}")
3633 else()
3634 # executing custom command, no need to re-check for dependencies
3635 set (_dependsOption "")
3636 endif()
3637
3638 cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
3639
3640 cotire_generate_unity_source(
3641 "${COTIRE_ARGV3}" ${_sources}
3642 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3643 SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
3644 PRE_UNDEFS ${_targetPreUndefs}
3645 POST_UNDEFS ${_targetPostUndefs}
3646 SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
3647 SOURCES_POST_UNDEFS ${_sourcesPostUndefs}
3648 ${_dependsOption})
3649
3650 elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
3651
3652 if (XCODE)
3653 # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies
3654 set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS})
3655 else()
3656 # executing custom command, no need to re-check for dependencies
3657 set (_dependsOption "")
3658 endif()
3659
3660 set (_files "")
3661 foreach (_index RANGE 4 ${COTIRE_ARGC})
3662 if (COTIRE_ARGV${_index})
3663 list (APPEND _files "${COTIRE_ARGV${_index}}")
3664 endif()
3665 endforeach()
3666
3667 cotire_generate_prefix_header(
3668 "${COTIRE_ARGV3}" ${_files}
3669 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3670 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3671 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3672 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3673 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3674 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3675 IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
3676 INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
3677 IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
3678 INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH}
3679 INCLUDE_DIRECTORIES ${_includeDirs}
3680 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3681 COMPILE_DEFINITIONS ${_compileDefinitions}
3682 COMPILE_FLAGS ${_compileFlags}
3683 ${_dependsOption})
3684
3685 elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
3686
3687 set (_files "")
3688 foreach (_index RANGE 5 ${COTIRE_ARGC})
3689 if (COTIRE_ARGV${_index})
3690 list (APPEND _files "${COTIRE_ARGV${_index}}")
3691 endif()
3692 endforeach()
3693
3694 cotire_precompile_prefix_header(
3695 "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
3696 COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}"
3697 COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
3698 COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
3699 COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
3700 COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
3701 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3702 INCLUDE_DIRECTORIES ${_includeDirs}
3703 SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs}
3704 COMPILE_DEFINITIONS ${_compileDefinitions}
3705 COMPILE_FLAGS ${_compileFlags})
3706
3707 elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
3708
3709 if (COTIRE_TARGET_LANGUAGE)
3710 set (_combinedFile "${COTIRE_ARGV3}")
3711 set (_startIndex 4)
3712 else()
3713 set (_combinedFile "${COTIRE_ARGV2}")
3714 set (_startIndex 3)
3715 endif()
3716 set (_files "")
3717 foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
3718 if (COTIRE_ARGV${_index})
3719 list (APPEND _files "${COTIRE_ARGV${_index}}")
3720 endif()
3721 endforeach()
3722
3723 if (XCODE)
3724 # executing pre-build action under Xcode, check dependency on files to be combined
3725 set (_dependsOption DEPENDS ${_files})
3726 else()
3727 # executing custom command, no need to re-check for dependencies
3728 set (_dependsOption "")
3729 endif()
3730
3731 if (COTIRE_TARGET_LANGUAGE)
3732 cotire_generate_unity_source(
3733 "${_combinedFile}" ${_files}
3734 LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
3735 ${_dependsOption})
3736 else()
3737 cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption})
3738 endif()
3739
3740 elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
3741
3742 cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
3743
3744 else()
3745 message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".")
3746 endif()
3747
3748 else()
3749
3750 # cotire is being run in include mode
3751 # set up all variable and property definitions
3752
3753 if (NOT DEFINED COTIRE_DEBUG_INIT)
3754 if (DEFINED COTIRE_DEBUG)
3755 set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
3756 else()
3757 set (COTIRE_DEBUG_INIT FALSE)
3758 endif()
3759 endif()
3760 option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
3761
3762 if (NOT DEFINED COTIRE_VERBOSE_INIT)
3763 if (DEFINED COTIRE_VERBOSE)
3764 set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
3765 else()
3766 set (COTIRE_VERBOSE_INIT FALSE)
3767 endif()
3768 endif()
3769 option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
3770
3771 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
3772 "Ignore headers with the listed file extensions from the generated prefix header.")
3773
3774 set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
3775 "Ignore headers from these directories when generating the prefix header.")
3776
3777 set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
3778 "Ignore sources with the listed file extensions from the generated unity source.")
3779
3780 set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING
3781 "Minimum number of sources in target required to enable use of precompiled header.")
3782
3783 if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
3784 if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
3785 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
3786 elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
3787 # enable parallelization for generators that run multiple jobs by default
3788 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
3789 else()
3790 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
3791 endif()
3792 endif()
3793 set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
3794 "Maximum number of source files to include in a single unity source file.")
3795
3796 if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
3797 set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
3798 endif()
3799 if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
3800 set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
3801 endif()
3802 if (NOT COTIRE_INTDIR)
3803 set (COTIRE_INTDIR "cotire")
3804 endif()
3805 if (NOT COTIRE_PCH_ALL_TARGET_NAME)
3806 set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
3807 endif()
3808 if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
3809 set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
3810 endif()
3811 if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
3812 set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
3813 endif()
3814 if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
3815 set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
3816 endif()
3817 if (NOT COTIRE_PCH_TARGET_SUFFIX)
3818 set (COTIRE_PCH_TARGET_SUFFIX "_pch")
3819 endif()
3820 if (MSVC)
3821 # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code
3822 # use a bigger default factor of 170 percent (128 MB)
3823 if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR)
3824 set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170")
3825 endif()
3826 endif()
3827 if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
3828 set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
3829 endif()
3830 if (NOT DEFINED COTIRE_TARGETS_FOLDER)
3831 set (COTIRE_TARGETS_FOLDER "cotire")
3832 endif()
3833 if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
3834 if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
3835 # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
3836 set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
3837 else()
3838 set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
3839 endif()
3840 endif()
3841
3842 # define cotire cache variables
3843
3844 define_property(
3845 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
3846 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3847 FULL_DOCS
3848 "The variable can be set to a semicolon separated list of include directories."
3849 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
3850 "If not defined, defaults to empty list."
3851 )
3852
3853 define_property(
3854 CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
3855 BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
3856 FULL_DOCS
3857 "The variable can be set to a semicolon separated list of file extensions."
3858 "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
3859 "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
3860 "If not defined, defaults to inc;inl;ipp."
3861 )
3862
3863 define_property(
3864 CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
3865 BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
3866 FULL_DOCS
3867 "The variable can be set to a semicolon separated list of file extensions."
3868 "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
3869 "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
3870 "If not defined, defaults to m;mm."
3871 )
3872
3873 define_property(
3874 CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
3875 BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
3876 FULL_DOCS
3877 "The variable can be set to an integer > 0."
3878 "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
3879 "If not defined, defaults to 2."
3880 )
3881
3882 define_property(
3883 CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
3884 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3885 FULL_DOCS
3886 "This may be set to an integer >= 0."
3887 "If 0, cotire will only create a single unity source file."
3888 "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
3889 "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
3890 "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
3891 "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3892 "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
3893 )
3894
3895 # define cotire directory properties
3896
3897 define_property(
3898 DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
3899 BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
3900 FULL_DOCS
3901 "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
3902 )
3903
3904 define_property(
3905 DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
3906 BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
3907 FULL_DOCS
3908 "See target property COTIRE_ADD_UNITY_BUILD."
3909 )
3910
3911 define_property(
3912 DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
3913 BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
3914 FULL_DOCS
3915 "See target property COTIRE_ADD_CLEAN."
3916 )
3917
3918 define_property(
3919 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
3920 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
3921 FULL_DOCS
3922 "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
3923 )
3924
3925 define_property(
3926 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
3927 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
3928 FULL_DOCS
3929 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
3930 )
3931
3932 define_property(
3933 DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH"
3934 BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header."
3935 FULL_DOCS
3936 "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH."
3937 )
3938
3939 define_property(
3940 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
3941 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
3942 FULL_DOCS
3943 "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
3944 )
3945
3946 define_property(
3947 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
3948 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
3949 FULL_DOCS
3950 "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
3951 )
3952
3953 define_property(
3954 DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
3955 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
3956 FULL_DOCS
3957 "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
3958 )
3959
3960 define_property(
3961 DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT"
3962 BRIEF_DOCS "Define strategy for setting up the unity target's link libraries."
3963 FULL_DOCS
3964 "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT."
3965 )
3966
3967 # define cotire target properties
3968
3969 define_property(
3970 TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
3971 BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
3972 FULL_DOCS
3973 "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
3974 "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
3975 "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
3976 "The target name will be set to this target's name with the suffix _pch appended."
3977 "Inherited from directory."
3978 "Defaults to TRUE."
3979 )
3980
3981 define_property(
3982 TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
3983 BRIEF_DOCS "Add a new target that performs a unity build for this target."
3984 FULL_DOCS
3985 "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources."
3986 "Most of the relevant target properties will be copied from this target to the new unity build target."
3987 "Target dependencies and linked libraries have to be manually set up for the new unity build target."
3988 "The unity target name will be set to this target's name with the suffix _unity appended."
3989 "Inherited from directory."
3990 "Defaults to TRUE."
3991 )
3992
3993 define_property(
3994 TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
3995 BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
3996 FULL_DOCS
3997 "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
3998 "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
3999 "Inherited from directory."
4000 "Defaults to FALSE."
4001 )
4002
4003 define_property(
4004 TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
4005 BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
4006 FULL_DOCS
4007 "The property can be set to a list of directories."
4008 "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
4009 "Inherited from directory."
4010 "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
4011 )
4012
4013 define_property(
4014 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
4015 BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
4016 FULL_DOCS
4017 "The property can be set to a list of directories."
4018 "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
4019 "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
4020 "the option which yields the closer relative path match wins."
4021 "Inherited from directory."
4022 "If not set, this property is initialized to the empty list."
4023 )
4024
4025 define_property(
4026 TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED
4027 BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header."
4028 FULL_DOCS
4029 "The property can be set to a list of directories."
4030 "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header."
4031 "Header files are sorted according to the order of the directories in the property."
4032 "If not set, this property is initialized to the empty list."
4033 )
4034
4035 define_property(
4036 TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
4037 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
4038 FULL_DOCS
4039 "This may be set to a semicolon-separated list of preprocessor symbols."
4040 "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
4041 "Inherited from directory."
4042 "Defaults to empty string."
4043 )
4044
4045 define_property(
4046 TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
4047 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
4048 FULL_DOCS
4049 "This may be set to a semicolon-separated list of preprocessor symbols."
4050 "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
4051 "Inherited from directory."
4052 "Defaults to empty string."
4053 )
4054
4055 define_property(
4056 TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
4057 BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
4058 FULL_DOCS
4059 "This may be set to an integer > 0."
4060 "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
4061 "If not set, cotire will only create a single unity source file."
4062 "Inherited from directory."
4063 "Defaults to empty."
4064 )
4065
4066 define_property(
4067 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
4068 BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
4069 FULL_DOCS
4070 "If set, cotire will only add the given file(s) to the generated unity source file."
4071 "If not set, cotire will add all the target source files to the generated unity source file."
4072 "The property can be set to a user provided unity source file."
4073 "Defaults to empty."
4074 )
4075
4076 define_property(
4077 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
4078 BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
4079 FULL_DOCS
4080 "If set, cotire will add the given header file(s) to the generated prefix header file."
4081 "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
4082 "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
4083 "Defaults to empty."
4084 )
4085
4086 define_property(
4087 TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED
4088 BRIEF_DOCS "Define strategy for setting up unity target's link libraries."
4089 FULL_DOCS
4090 "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually."
4091 "If this property is set to COPY, the unity target's link libraries will be copied from this target."
4092 "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets."
4093 "Inherited from directory."
4094 "Defaults to empty."
4095 )
4096
4097 define_property(
4098 TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
4099 BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
4100 FULL_DOCS
4101 "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
4102 "Defaults to empty string."
4103 )
4104
4105 define_property(
4106 TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
4107 BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
4108 FULL_DOCS
4109 "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
4110 "Defaults to empty string."
4111 )
4112
4113 define_property(
4114 TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
4115 BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
4116 FULL_DOCS
4117 "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
4118 "Defaults to empty string."
4119 )
4120
4121 define_property(
4122 TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
4123 BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
4124 FULL_DOCS
4125 "This property can be set to the desired name of the unity target that will be created by cotire."
4126 "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
4127 "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
4128 "Defaults to empty string."
4129 )
4130
4131 # define cotire source properties
4132
4133 define_property(
4134 SOURCE PROPERTY "COTIRE_EXCLUDED"
4135 BRIEF_DOCS "Do not modify source file's build command."
4136 FULL_DOCS
4137 "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
4138 "The source file will also be excluded from the generated unity source file."
4139 "Source files that have their COMPILE_FLAGS property set will be excluded by default."
4140 "Defaults to FALSE."
4141 )
4142
4143 define_property(
4144 SOURCE PROPERTY "COTIRE_DEPENDENCY"
4145 BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
4146 FULL_DOCS
4147 "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
4148 "If the file is modified, cotire will re-generate the prefix header source upon build."
4149 "Defaults to FALSE."
4150 )
4151
4152 define_property(
4153 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
4154 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
4155 FULL_DOCS
4156 "This may be set to a semicolon-separated list of preprocessor symbols."
4157 "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
4158 "Defaults to empty string."
4159 )
4160
4161 define_property(
4162 SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
4163 BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
4164 FULL_DOCS
4165 "This may be set to a semicolon-separated list of preprocessor symbols."
4166 "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
4167 "Defaults to empty string."
4168 )
4169
4170 define_property(
4171 SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
4172 BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
4173 FULL_DOCS
4174 "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
4175 "The new unity source file will include this source file as the first one."
4176 "This property essentially works as a separator for unity source files."
4177 "Defaults to FALSE."
4178 )
4179
4180 define_property(
4181 SOURCE PROPERTY "COTIRE_TARGET"
4182 BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
4183 FULL_DOCS
4184 "cotire sets this property to the name of target, that the source file's build command has been altered for."
4185 "Defaults to empty string."
4186 )
4187
4188 message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")
4189
4190 endif()

mercurial