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