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