From 9480ee2deefb089e477f199f5fb65efe56e861c3 Mon Sep 17 00:00:00 2001 From: Sascha Kratky Date: Mon, 9 Jun 2014 17:59:16 +0200 Subject: [PATCH] cotire 1.6.2 --- CMake/cotire.cmake | 126 ++++++++++++++++++++++++++++++++------------- CMakeLists.txt | 2 +- HISTORY.md | 9 ++++ MANUAL.md | 3 ++ src/CMakeLists.txt | 6 --- 5 files changed, 104 insertions(+), 42 deletions(-) diff --git a/CMake/cotire.cmake b/CMake/cotire.cmake index ddfe4bf..fbe3995 100644 --- a/CMake/cotire.cmake +++ b/CMake/cotire.cmake @@ -45,7 +45,7 @@ if (NOT CMAKE_SCRIPT_MODE_FILE) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.6.1") +set (COTIRE_CMAKE_MODULE_VERSION "1.6.2") include(CMakeParseArguments) include(ProcessorCount) @@ -59,13 +59,15 @@ function (cotire_determine_compiler_version _language _versionPrefix) # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) - execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} + execute_process ( + COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10) string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}") else() # assume GCC like command line interface string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) - execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" + execute_process ( + COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" OUTPUT_VARIABLE ${_versionPrefix}_VERSION RESULT_VARIABLE _result OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10) @@ -366,6 +368,14 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ if (_targetOptions) set (_compileFlags "${_compileFlags} ${_targetOptions}") endif() + # interface compile options from linked library targets + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + foreach (_library ${_linkLibraries}) + get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + set (_compileFlags "${_compileFlags} ${_targetOptions}") + endif() + endforeach() endif() if (UNIX) separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") @@ -424,8 +434,18 @@ function (cotire_get_target_include_directories _config _language _targetSourceD get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) if (_targetDirs) list (APPEND _dirs ${_targetDirs}) - list (REMOVE_DUPLICATES _dirs) endif() + # interface include directories from linked library targets + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + foreach (_library ${_linkLibraries}) + get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + endforeach() + endif() + if (dirs) + list (REMOVE_DUPLICATES _dirs) endif() list (LENGTH _includeDirs _projectInsertIndex) foreach (_dir ${_dirs}) @@ -513,6 +533,14 @@ function (cotire_get_target_compile_definitions _config _language _directory _ta if (_definitions) list (APPEND _configDefinitions ${_definitions}) endif() + # interface compile definitions from linked library targets + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + foreach (_library ${_linkLibraries}) + get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + endforeach() # parse additional compile definitions from target compile flags # and don't look at directory compile definitions, which we already handled set (_targetFlags "") @@ -984,7 +1012,8 @@ function (cotire_scan_includes _includesVar) # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) endif() - execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + execute_process( + COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output) if (_result) message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") @@ -1143,6 +1172,8 @@ function (cotire_generate_prefix_header _prefixFile) if (_option_DEPENDS) cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) if (_prefixFileIsUpToDate) + set (_unparsedLinesFile "${_prefixFile}.log") + file (WRITE "${_unparsedLinesFile}" "") return() endif() endif() @@ -1300,18 +1331,19 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio endif() elseif (_compilerID MATCHES "GNU|Clang") # GCC / Clang options used - # -w disable all warnings # -x specify the source language # -c compile but do not link # -o place output in file + # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may + # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) set (_xLanguage_C "c-header") set (_xLanguage_CXX "c++-header") if (_flags) # append to list - list (APPEND _flags "-w" "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") else() # return as a flag string - set (_flags "-w -x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1408,6 +1440,7 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # GCC options used # -include process include file as the first line of the primary source file # -Winvalid-pch warns if precompiled header is found but cannot be used + # note: ccache requires the -include flag to be used in order to process precompiled header correctly if (_flags) # append to list list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") @@ -1420,24 +1453,13 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # -include process include file as the first line of the primary source file # -include-pch include precompiled header file # -Qunused-arguments don't emit warning for unused driver arguments - if (_pchFile AND NOT CMAKE_${_language}_COMPILER MATCHES "ccache") - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include-pch" "${_pchFile}") - else() - # return as a flag string - set (_flags "-Qunused-arguments -include-pch \"${_pchFile}\"") - endif() + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") else() - # no precompiled header, force inclusion of prefix header - # ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") - else() - # return as a flag string - set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") - endif() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1540,7 +1562,10 @@ function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) endif() - execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result) + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result) if (_result) message (FATAL_ERROR "Error ${_result} precompiling ${_prefixFile}.") endif() @@ -1618,6 +1643,8 @@ macro (cotire_setup_file_extension_variables) set (_unityFileExt_CXX ".cxx") set (_prefixFileExt_C ".h") set (_prefixFileExt_CXX ".hxx") + set (_prefixSourceFileExt_C ".c") + set (_prefixSourceFileExt_CXX ".cxx") endmacro() function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) @@ -1691,6 +1718,16 @@ function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixF set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) endfunction() +function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _prefixSourceFileExt_${_language}) + set (${_prefixSourceFileVar} "" PARENT_SCOPE) + return() + endif() + string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") + set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) +endfunction() + function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) cotire_setup_file_extension_variables() if (NOT _language) @@ -1888,17 +1925,24 @@ function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _ # for makefile based generator, we add a custom command to precompile the prefix header if (_targetScript) cotire_set_cmd_to_prologue(_cmds) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() list (GET _sourceFiles 0 _hostFile) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixSourceFile}" "${_pchFile}" "${_hostFile}") file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}") if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixSourceFile} IMPLICIT_DEPENDS ${_language} ${_prefixSourceFile}") endif() set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) - add_custom_command(OUTPUT "${_pchFile}" + add_custom_command( + OUTPUT "${_pchFile}" COMMAND ${_cmds} - DEPENDS "${_prefixFile}" - IMPLICIT_DEPENDS ${_language} "${_prefixFile}" + DEPENDS "${_prefixSourceFile}" + IMPLICIT_DEPENDS ${_language} "${_prefixSourceFile}" WORKING_DIRECTORY "${_targetSourceDir}" COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM) endif() @@ -1996,11 +2040,16 @@ function (cotire_setup_combine_command _language _sourceDir _targetScript _joine endif() set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") - get_filename_component(_joinedFileName "${_joinedFileRelPath}" NAME_WE) - if (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + get_filename_component(_joinedFileBaseName "${_joinedFileRelPath}" NAME_WE) + get_filename_component(_joinedFileExt "${_joinedFileRelPath}" EXT) + if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}") - elseif (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") - set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") + if (_joinedFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_joinedFileRelPath}") + else() + set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + endif() else() set (_comment "Generating ${_joinedFileRelPath}") endif() @@ -2138,6 +2187,9 @@ function (cotire_setup_multi_prefix_generation_command _language _target _target ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) endif() + # create a prefix source file from prefix header + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixSourceFile}" ${_cmdsVar} ${_prefixFile}) set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() @@ -2381,7 +2433,11 @@ function (cotire_process_target_language _language _configurations _targetSource # check for user provided prefix header files get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) if (_prefixHeaderFiles) + # create prefix header form user provided header files cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + # create a prefix source file from prefix header + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixFile}) else() cotire_setup_multi_prefix_generation_command( ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) diff --git a/CMakeLists.txt b/CMakeLists.txt index a522c9a..eeb1372 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # cotire example project -cmake_minimum_required(VERSION 2.8.5) +cmake_minimum_required(VERSION 2.8.6) project (CotireExample) diff --git a/HISTORY.md b/HISTORY.md index caed07f..fa5fe62 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,12 @@ +## 1.6.2 (2014-06-09) + +* don't use `-w` flag for pre-compiling the prefix header, because it has unwanted side effects. +* correctly handle linked targets' `INTERFACE_COMPILE_OPTIONS`, `INTERFACE_INCLUDE_DIRECTORIES` + and `INTERFACE_COMPILE_DEFINITIONS` properties upon pre-compiling and prefix header generation. +* For Clang and GCC, pre-compile prefix header through indirect inclusion via a prefix source file, + to make both compilers honor the `system_header` pragma in the prefix header correctly. +* fix ccache incompatibility. + ## 1.6.1 (2014-04-20) * fixed bug where precompiled headers did not work with Clang (thanks to nh2 for reporting). diff --git a/MANUAL.md b/MANUAL.md index 310057e..d309edf 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -198,6 +198,9 @@ machines. It is automatically recreated by the build system if it goes missing. The generated prefix header can be applied to a different target added in the same source directory (see below). +Optionally, cotire may also create a prefix source file that consists of a single include directive +for the prefix header. This file is needed for pre-compiling the prefix header with Clang or GCC. + ### the precompiled header The precompiled header is produced from the generated prefix header by using the proprietary diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 980541e..deb2b79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,12 +9,6 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set_target_properties(example PROPERTIES COMPILE_FLAGS "-Weverything") elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU") set_target_properties(example PROPERTIES COMPILE_FLAGS "-Wall -Wextra") -elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") - if (UNIX) - set_target_properties(example PROPERTIES COMPILE_FLAGS "-w5") - elseif (WIN32) - set_target_properties(example PROPERTIES COMPILE_FLAGS "/W5") - endif() endif() cotire(example)