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