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