mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-13 01:29:02 -05:00
Merge topic 'makefiles-compiler-deps-optims'
2c71d051faMakefiles Generators: use compiler for dependencies generationafd0f6785dRefactoring: Abstract Makefile line continuation formatb6068ce407Refactoring: enhance include file filtering3401403f69Refactoring: Introduce place-holder for dependency target.a97c41bf8bRefactoring: Makefiles Generators: Add support for various depends scanners Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Brad King <brad.king@kitware.com> Merge-request: !5528
This commit is contained in:
@@ -387,6 +387,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_DEFAULT_BUILD_TYPE
|
||||
/variable/CMAKE_DEFAULT_CONFIGS
|
||||
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
|
||||
/variable/CMAKE_DEPENDS_USE_COMPILER
|
||||
/variable/CMAKE_ENABLE_EXPORTS
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
makefiles-dependencies-use-compiler
|
||||
-----------------------------------
|
||||
|
||||
* The :ref:`Makefile Generators` gained the capability, for a selection of
|
||||
compilers, to use the compiler itself to generate implicit dependencies.
|
||||
@@ -0,0 +1,9 @@
|
||||
CMAKE_DEPENDS_USE_COMPILER
|
||||
--------------------------
|
||||
|
||||
.. versionadded:: 3.20
|
||||
|
||||
For the :ref:`Makefile Generators`, source dependencies are now, for a
|
||||
selection of compilers, generated by the compiler itself. By defining this
|
||||
variable with value ``FALSE``, you can restore the legacy behavior (i.e. using
|
||||
``CMake`` for dependencies discovery).
|
||||
@@ -152,7 +152,10 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
|
||||
set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
|
||||
endif()
|
||||
|
||||
if(CMAKE_GENERATOR MATCHES "^Ninja" AND MSVC_${lang}_ARCHITECTURE_ID)
|
||||
if((CMAKE_GENERATOR MATCHES "^Ninja"
|
||||
OR ((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"))
|
||||
AND MSVC_${lang}_ARCHITECTURE_ID)
|
||||
foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
|
||||
CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}")
|
||||
endforeach()
|
||||
|
||||
@@ -33,7 +33,7 @@ macro(__compiler_armcc lang)
|
||||
set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> --list <TARGET_BASE>.map")
|
||||
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--depend=<DEPFILE> --depend_single_line --no_depend_system_headers")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--depend=<DEP_FILE> --depend_single_line --no_depend_system_headers")
|
||||
|
||||
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
|
||||
endmacro()
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
include(Compiler/Clang)
|
||||
__compiler_clang(C)
|
||||
|
||||
|
||||
if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
|
||||
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||
|
||||
@@ -2,6 +2,14 @@ include(Compiler/Clang)
|
||||
__compiler_clang(CXX)
|
||||
|
||||
if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
include(Compiler/Clang-OBJC)
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles"
|
||||
AND CMAKE_DEPFILE_FLAGS_OBJC)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_OBJC_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 4.0)
|
||||
set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||
set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
include(Compiler/Clang-OBJCXX)
|
||||
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles"
|
||||
AND CMAKE_DEPFILE_FLAGS_OBJCXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||
|
||||
if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.0)
|
||||
|
||||
@@ -8,6 +8,19 @@ endif()
|
||||
|
||||
if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||
set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
|
||||
|
||||
@@ -2,7 +2,13 @@ include(Compiler/Clang)
|
||||
__compiler_clang(CUDA)
|
||||
|
||||
# Set explicitly, because __compiler_clang() doesn't set this if we're simulating MSVC.
|
||||
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CUDA_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CUDA_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
# C++03 isn't supported for CXX, but is for CUDA, so we need to set these manually.
|
||||
# Do this before __compiler_clang_cxx_standards() since that adds the feature.
|
||||
|
||||
@@ -3,6 +3,14 @@ __compiler_clang(CXX)
|
||||
__compiler_clang_cxx_standards(CXX)
|
||||
|
||||
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||
endif()
|
||||
|
||||
@@ -13,4 +21,9 @@ endif()
|
||||
|
||||
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||
set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
include(Compiler/Clang)
|
||||
__compiler_clang(OBJC)
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_OBJC)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_OBJC_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 3.4)
|
||||
set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||
set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
include(Compiler/Clang)
|
||||
__compiler_clang(OBJCXX)
|
||||
__compiler_clang_cxx_standards(OBJCXX)
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_OBJCXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
@@ -6,7 +6,7 @@ set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm)
|
||||
__compiler_gnu(ASM)
|
||||
|
||||
if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH STREQUAL "GNU assembler")
|
||||
set(CMAKE_DEPFILE_FLAGS_ASM${ASM_DIALECT} "--MD <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_ASM${ASM_DIALECT} "--MD <DEP_FILE>")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
|
||||
"<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||
set(CMAKE_ASM_DEFINE_FLAG "--defsym ")
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
include(Compiler/GNU)
|
||||
__compiler_gnu(C)
|
||||
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
|
||||
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
include(Compiler/GNU)
|
||||
__compiler_gnu(CXX)
|
||||
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if (WIN32)
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
|
||||
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
|
||||
|
||||
@@ -1,2 +1,11 @@
|
||||
include(Compiler/GNU)
|
||||
__compiler_gnu(OBJC)
|
||||
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_OBJC)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_OBJC_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
include(Compiler/GNU)
|
||||
__compiler_gnu(OBJCXX)
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_OBJCXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.2)
|
||||
set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||
endif()
|
||||
|
||||
@@ -48,7 +48,7 @@ macro(__compiler_gnu lang)
|
||||
# distcc does not transform -o to -MT when invoking the preprocessor
|
||||
# internally, as it ought to. Work around this bug by setting -MT here
|
||||
# even though it isn't strictly necessary.
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
endif()
|
||||
|
||||
# Initial configuration flags.
|
||||
|
||||
@@ -49,7 +49,7 @@ macro(__compiler_iar_ilink lang)
|
||||
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
|
||||
|
||||
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEP_FILE>")
|
||||
|
||||
string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
|
||||
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -r")
|
||||
@@ -85,7 +85,7 @@ macro(__compiler_iar_xlink lang)
|
||||
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
|
||||
|
||||
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEP_FILE>")
|
||||
|
||||
string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
|
||||
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -r")
|
||||
|
||||
@@ -5,7 +5,13 @@ string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -DNDEBUG")
|
||||
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -DNDEBUG")
|
||||
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG")
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_C "-MD -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_C "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
|
||||
|
||||
@@ -5,7 +5,13 @@ string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -DNDEBUG")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -DNDEBUG")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG")
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
|
||||
|
||||
@@ -3,7 +3,13 @@ include(Compiler/CMakeCommonCompilerMacros)
|
||||
# Not aware of any verbose flag for ISPC
|
||||
#set(CMAKE_ISPC_VERBOSE_FLAG )
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_ISPC "-M -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_ISPC "-M -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_ISPC_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_ISPC_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
string(APPEND CMAKE_ISPC_FLAGS_INIT " ")
|
||||
string(APPEND CMAKE_ISPC_FLAGS_DEBUG_INIT "-O0 -g")
|
||||
|
||||
@@ -28,7 +28,15 @@ if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89)
|
||||
# The -MD flag was only added to nvcc in 10.2 so
|
||||
# before that we had to invoke the compiler twice
|
||||
# to get header dependency information
|
||||
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
endif()
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
if (NOT CMAKE_DEPFILE_FLAGS_CUDA)
|
||||
set(CMAKE_CUDA_DEPENDS_EXTRA_COMMANDS "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -M <SOURCE> -MT <OBJECT> -o <DEP_FILE>")
|
||||
endif()
|
||||
set(CMAKE_CUDA_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CUDA_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
|
||||
@@ -14,7 +14,7 @@ macro(__compiler_qcc lang)
|
||||
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "-Wc,-isysroot,")
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-Wp,-MD,<DEPFILE> -Wp,-MT,<OBJECT> -Wp,-MF,<DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-Wp,-MD,<DEP_FILE> -Wp,-MT,<DEP_TARGET> -Wp,-MF,<DEP_FILE>")
|
||||
|
||||
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
|
||||
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
|
||||
|
||||
@@ -22,7 +22,7 @@ string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -xO2 -xspace -DNDEBUG")
|
||||
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -xO3 -DNDEBUG")
|
||||
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG")
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_C "-xMD -xMF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_C "-xMD -xMF <DEP_FILE>")
|
||||
|
||||
# Initialize C link type selection flags. These flags are used when
|
||||
# building a shared library, shared module, or executable that links
|
||||
|
||||
@@ -22,7 +22,7 @@ string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -xO2 -xspace -DNDEBUG")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -xO3 -DNDEBUG")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG")
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_CXX "-xMD -xMF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_CXX "-xMD -xMF <DEP_FILE>")
|
||||
|
||||
# Initialize C link type selection flags. These flags are used when
|
||||
# building a shared library, shared module, or executable that links
|
||||
|
||||
@@ -18,7 +18,7 @@ macro(__compiler_ti lang)
|
||||
set(CMAKE_${lang}_RESPONSE_FILE_FLAG "--cmd_file=")
|
||||
|
||||
set(CMAKE_INCLUDE_FLAG_${lang} "--include_path=")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--preproc_with_compile --preproc_dependency=<DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "--preproc_with_compile --preproc_dependency=<DEP_FILE>")
|
||||
|
||||
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> --preproc_only ${__COMPILER_TI_SOURCE_FLAG_${lang}}=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
|
||||
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> --compile_only --skip_assembler ${__COMPILER_TI_SOURCE_FLAG_${lang}}=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
|
||||
|
||||
@@ -30,5 +30,5 @@ macro(__compiler_xl lang)
|
||||
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
|
||||
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
|
||||
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-MF <DEPFILE> -qmakedep=gcc")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-MF <DEP_FILE> -qmakedep=gcc")
|
||||
endmacro()
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
include(Platform/Windows-Clang)
|
||||
__windows_compiler_clang(C)
|
||||
|
||||
if("x${MAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
include(Platform/Windows-Clang)
|
||||
set(_COMPILE_CXX_MSVC " -TP")
|
||||
__windows_compiler_clang(CXX)
|
||||
|
||||
if("x${MAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
elseif("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -27,7 +27,7 @@ macro(__windows_compiler_clang_gnu lang)
|
||||
set(CMAKE_SHARED_MODULE_SUFFIX ".dll")
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
|
||||
if(NOT "${lang}" STREQUAL "ASM")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <OBJECT> -MF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||
endif()
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
|
||||
@@ -111,7 +111,7 @@ macro(__enable_llvm_rc_preprocessing clang_option_prefix)
|
||||
set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER)
|
||||
endif()
|
||||
if(DEFINED CMAKE_RC_PREPROCESSOR)
|
||||
set(CMAKE_DEPFILE_FLAGS_RC "${clang_option_prefix}-MD ${clang_option_prefix}-MF ${clang_option_prefix}<DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_RC "${clang_option_prefix}-MD ${clang_option_prefix}-MF ${clang_option_prefix}<DEP_FILE>")
|
||||
# The <FLAGS> are passed to the preprocess and the resource compiler to pick
|
||||
# up the eventual -D / -C options passed through the CMAKE_RC_FLAGS.
|
||||
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> <FLAGS> /fo <OBJECT> <OBJECT>.pp")
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
include(Platform/Windows-Intel)
|
||||
__windows_compiler_intel(C)
|
||||
set(CMAKE_NINJA_DEPTYPE_C intel) # special value handled by CMake
|
||||
set(CMAKE_DEPFILE_FLAGS_C "-QMMD -QMT <OBJECT> -QMF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_C "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
@@ -2,4 +2,11 @@ include(Platform/Windows-Intel)
|
||||
set(_COMPILE_CXX " /TP")
|
||||
__windows_compiler_intel(CXX)
|
||||
set(CMAKE_NINJA_DEPTYPE_CXX intel) # special value handled by CMake
|
||||
set(CMAKE_DEPFILE_FLAGS_CXX "-QMMD -QMT <OBJECT> -QMF <DEPFILE>")
|
||||
set(CMAKE_DEPFILE_FLAGS_CXX "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake")
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
@@ -3,3 +3,10 @@ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0)
|
||||
set(_FS_C " /FS")
|
||||
endif()
|
||||
__windows_compiler_msvc(C)
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_C)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
@@ -4,3 +4,10 @@ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
|
||||
set(_FS_CXX " /FS")
|
||||
endif()
|
||||
__windows_compiler_msvc(CXX)
|
||||
|
||||
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
|
||||
AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
|
||||
AND CMAKE_DEPFILE_FLAGS_CXX)
|
||||
# dependencies are computed by the compiler itself
|
||||
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
@@ -437,6 +437,13 @@ macro(__windows_compiler_msvc lang)
|
||||
set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON)
|
||||
set(CMAKE_NINJA_DEPTYPE_${lang} msvc)
|
||||
__windows_compiler_msvc_enable_rc("${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}")
|
||||
|
||||
# define generic information about compiler dependencies
|
||||
# activation is done on per language platform configuration basis
|
||||
if (MSVC_VERSION GREATER 1300)
|
||||
set(CMAKE_DEPFILE_FLAGS_${lang} "/showIncludes")
|
||||
set(CMAKE_${lang}_DEPFILE_FORMAT msvc)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(__windows_compiler_msvc_enable_rc flags)
|
||||
|
||||
@@ -227,6 +227,8 @@ set(SRCS
|
||||
cmDependsJava.h
|
||||
cmDependsJavaParserHelper.cxx
|
||||
cmDependsJavaParserHelper.h
|
||||
cmDependsCompiler.cxx
|
||||
cmDependsCompiler.h
|
||||
cmDocumentation.cxx
|
||||
cmDocumentationFormatter.cxx
|
||||
cmDocumentationSection.cxx
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
|
||||
#include "cmDependsCompiler.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/string_view>
|
||||
#include <cm/vector>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmFileTime.h"
|
||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
namespace {
|
||||
std::string& ReplaceAll(std::string& data, const std::string& toSearch,
|
||||
const std::string& replaceStr)
|
||||
{
|
||||
// Get the first occurrence
|
||||
auto pos = data.find(toSearch);
|
||||
// Repeat until the end is reached
|
||||
while (pos != std::string::npos) {
|
||||
// Replace this occurrence of Sub String
|
||||
data.replace(pos, toSearch.size(), replaceStr);
|
||||
// Get the next occurrence from the current position
|
||||
pos = data.find(toSearch, pos + replaceStr.size());
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string& NormalizePath(std::string& item)
|
||||
{
|
||||
ReplaceAll(item, "$$", "$");
|
||||
ReplaceAll(item, "\\ ", " ");
|
||||
ReplaceAll(item, "\\#", "#");
|
||||
ReplaceAll(item, "\\", "/");
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void ParseLine(const std::string& line, std::vector<std::string>& depends)
|
||||
{
|
||||
auto start = line.find_first_not_of(' ');
|
||||
if (start == std::string::npos || line[start] == '#') {
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = start;
|
||||
while ((index = line.find(' ', index)) != std::string::npos) {
|
||||
if (line[index - 1] == '\\') {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto item = line.substr(start, index - start);
|
||||
if (item.back() != ':') {
|
||||
// check that ':' is not present after some spaces
|
||||
auto index2 = line.find_first_not_of(' ', index + 1);
|
||||
if (index2 == std::string::npos || line[index2] != ':') {
|
||||
// this is a dependency, add it
|
||||
depends.emplace_back(std::move(NormalizePath(item)));
|
||||
} else {
|
||||
index = index2;
|
||||
}
|
||||
}
|
||||
|
||||
start = line.find_first_not_of(' ', index + 1);
|
||||
index = start;
|
||||
}
|
||||
if (start != std::string::npos) {
|
||||
auto item = line.substr(start);
|
||||
if (line.back() != ':') {
|
||||
// this is a dependency, add it
|
||||
depends.emplace_back(std::move(NormalizePath(item)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cmDependsCompiler::CheckDependencies(
|
||||
const std::string& internalDepFile, const std::vector<std::string>& depFiles,
|
||||
cmDepends::DependencyMap& dependencies,
|
||||
const std::function<bool(const std::string&)>& isValidPath)
|
||||
{
|
||||
bool status = true;
|
||||
bool forceReadDeps = true;
|
||||
|
||||
cmFileTime internalDepFileTime;
|
||||
// read cached dependencies stored in internal file
|
||||
if (cmSystemTools::FileExists(internalDepFile)) {
|
||||
internalDepFileTime.Load(internalDepFile);
|
||||
forceReadDeps = false;
|
||||
|
||||
// read current dependencies
|
||||
cmsys::ifstream fin(internalDepFile.c_str());
|
||||
if (fin) {
|
||||
std::string line;
|
||||
std::string depender;
|
||||
std::vector<std::string>* currentDependencies = nullptr;
|
||||
while (std::getline(fin, line)) {
|
||||
if (line.empty() || line.front() == '#') {
|
||||
continue;
|
||||
}
|
||||
// Drop carriage return character at the end
|
||||
if (line.back() == '\r') {
|
||||
line.pop_back();
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Check if this a depender line
|
||||
if (line.front() != ' ') {
|
||||
depender = std::move(line);
|
||||
currentDependencies = &dependencies[depender];
|
||||
continue;
|
||||
}
|
||||
// This is a dependee line
|
||||
if (currentDependencies != nullptr) {
|
||||
currentDependencies->emplace_back(line.substr(1));
|
||||
}
|
||||
}
|
||||
fin.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Now, update dependencies map with all new compiler generated
|
||||
// dependencies files
|
||||
cmFileTime depFileTime;
|
||||
for (auto dep = depFiles.begin(); dep != depFiles.end(); dep++) {
|
||||
const auto& source = *dep++;
|
||||
const auto& target = *dep++;
|
||||
const auto& format = *dep++;
|
||||
const auto& depFile = *dep;
|
||||
|
||||
if (!cmSystemTools::FileExists(depFile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!forceReadDeps) {
|
||||
depFileTime.Load(depFile);
|
||||
}
|
||||
if (forceReadDeps || depFileTime.Newer(internalDepFileTime)) {
|
||||
status = false;
|
||||
if (this->Verbose) {
|
||||
cmSystemTools::Stdout(cmStrCat("Dependencies file \"", depFile,
|
||||
"\" is newer than depends file \"",
|
||||
internalDepFile, "\".\n"));
|
||||
}
|
||||
cmsys::ifstream fin(depFile.c_str());
|
||||
if (!fin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> depends;
|
||||
std::string line;
|
||||
if (format == "msvc"_s) {
|
||||
if (!isValidPath) {
|
||||
// insert source as first dependency
|
||||
depends.push_back(source);
|
||||
}
|
||||
while (cmSystemTools::GetLineFromStream(fin, line)) {
|
||||
depends.emplace_back(std::move(line));
|
||||
}
|
||||
} else {
|
||||
while (cmSystemTools::GetLineFromStream(fin, line)) {
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (line.back() == '\\') {
|
||||
line.pop_back();
|
||||
}
|
||||
ParseLine(line, depends);
|
||||
}
|
||||
|
||||
// depending of the effective format of the dependencies file generated
|
||||
// by the compiler, the target can be wrongly identified as a
|
||||
// dependency so remove it from the list
|
||||
if (depends.front() == target) {
|
||||
depends.erase(depends.begin());
|
||||
}
|
||||
|
||||
if (isValidPath) {
|
||||
// remove first dependency because it must not be filtered out
|
||||
depends.erase(depends.begin());
|
||||
}
|
||||
}
|
||||
|
||||
if (isValidPath) {
|
||||
cm::erase_if(depends, isValidPath);
|
||||
// insert source as first dependency
|
||||
depends.insert(depends.begin(), source);
|
||||
}
|
||||
|
||||
dependencies[target] = std::move(depends);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void cmDependsCompiler::WriteDependencies(
|
||||
const cmDepends::DependencyMap& dependencies, std::ostream& makeDepends,
|
||||
std::ostream& internalDepends)
|
||||
{
|
||||
// dependencies file consumed by make tool
|
||||
const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>(
|
||||
this->LocalGenerator->GetGlobalGenerator())
|
||||
->LineContinueDirective;
|
||||
const auto& binDir = this->LocalGenerator->GetBinaryDirectory();
|
||||
cmDepends::DependencyMap makeDependencies(dependencies);
|
||||
std::unordered_set<cm::string_view> phonyTargets;
|
||||
|
||||
// external dependencies file
|
||||
for (auto& node : makeDependencies) {
|
||||
auto& deps = node.second;
|
||||
std::transform(
|
||||
deps.cbegin(), deps.cend(), deps.begin(),
|
||||
[this, &binDir](const std::string& dep) {
|
||||
return LocalGenerator->ConvertToMakefilePath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
|
||||
});
|
||||
|
||||
makeDepends << this->LocalGenerator->ConvertToMakefilePath(node.first)
|
||||
<< ": " << deps.front();
|
||||
// first dependency is the source, remove it because should not be declared
|
||||
// as phony target
|
||||
deps.erase(deps.begin());
|
||||
for (const auto& dep : deps) {
|
||||
makeDepends << ' ' << lineContinue << " " << dep;
|
||||
phonyTargets.emplace(dep.data(), dep.length());
|
||||
}
|
||||
makeDepends << std::endl << std::endl;
|
||||
}
|
||||
|
||||
// add phony targets
|
||||
for (const auto& target : phonyTargets) {
|
||||
makeDepends << std::endl << target << ':' << std::endl;
|
||||
}
|
||||
|
||||
// internal dependencies file
|
||||
for (const auto& node : dependencies) {
|
||||
internalDepends << node.first << std::endl;
|
||||
for (const auto& dep : node.second) {
|
||||
internalDepends << ' ' << dep << std::endl;
|
||||
}
|
||||
internalDepends << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void cmDependsCompiler::ClearDependencies(
|
||||
const std::vector<std::string>& depFiles)
|
||||
{
|
||||
for (auto dep = depFiles.begin(); dep != depFiles.end(); dep++) {
|
||||
dep += 3;
|
||||
cmSystemTools::RemoveFile(*dep);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmDepends.h"
|
||||
|
||||
class cmLocalUnixMakefileGenerator3;
|
||||
|
||||
/** \class cmDepends
|
||||
* \brief Dependencies files manager.
|
||||
*
|
||||
* This class is responsible for maintaining a compiler_depends.make file in
|
||||
* the build tree corresponding to an object file.
|
||||
*/
|
||||
class cmDependsCompiler
|
||||
{
|
||||
public:
|
||||
cmDependsCompiler() = default;
|
||||
~cmDependsCompiler() = default;
|
||||
|
||||
/** should this be verbose in its output */
|
||||
void SetVerbose(bool verb) { this->Verbose = verb; }
|
||||
|
||||
/** Set the local generator for the directory in which we are
|
||||
scanning dependencies. This is not a full local generator; it
|
||||
has been setup to do relative path conversions for the current
|
||||
directory. */
|
||||
void SetLocalGenerator(cmLocalUnixMakefileGenerator3* lg)
|
||||
{
|
||||
this->LocalGenerator = lg;
|
||||
}
|
||||
|
||||
/** Read dependencies for the target file. Return true if
|
||||
dependencies didn't changed and false if not.
|
||||
Up-to-date Dependencies will be stored in deps. */
|
||||
bool CheckDependencies(
|
||||
const std::string& internalDepFile,
|
||||
const std::vector<std::string>& depFiles,
|
||||
cmDepends::DependencyMap& dependencies,
|
||||
const std::function<bool(const std::string&)>& isValidPath);
|
||||
|
||||
/** Write dependencies for the target file. */
|
||||
void WriteDependencies(const cmDepends::DependencyMap& dependencies,
|
||||
std::ostream& makeDepends,
|
||||
std::ostream& internalDepends);
|
||||
|
||||
/** Clear dependencies for the target so they will be regenerated. */
|
||||
void ClearDependencies(const std::vector<std::string>& depFiles);
|
||||
|
||||
private:
|
||||
bool Verbose = false;
|
||||
cmLocalUnixMakefileGenerator3* LocalGenerator = nullptr;
|
||||
};
|
||||
@@ -44,6 +44,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
|
||||
#endif
|
||||
|
||||
this->IncludeDirective = "include";
|
||||
this->LineContinueDirective = "\\\n";
|
||||
this->DefineWindowsNULL = false;
|
||||
this->PassMakeflags = false;
|
||||
this->UnixCD = true;
|
||||
|
||||
@@ -127,6 +127,12 @@ public:
|
||||
void WriteConvenienceRules(std::ostream& ruleFileStream,
|
||||
std::set<std::string>& emitted);
|
||||
|
||||
// Make tool supports dependency files generated by compiler
|
||||
bool SupportsCompilerDependencies()
|
||||
{
|
||||
return this->ToolSupportsCompilerDependencies;
|
||||
}
|
||||
|
||||
/** Get the command to use for a target that has no rule. This is
|
||||
used for multiple output dependencies and for cmake_force. */
|
||||
std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
|
||||
@@ -170,6 +176,7 @@ public:
|
||||
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
|
||||
|
||||
std::string IncludeDirective;
|
||||
std::string LineContinueDirective;
|
||||
bool DefineWindowsNULL;
|
||||
bool PassMakeflags;
|
||||
bool UnixCD;
|
||||
@@ -218,6 +225,10 @@ protected:
|
||||
|
||||
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
|
||||
|
||||
// Specify if the make tool is able to consume dependency files
|
||||
// generated by the compiler
|
||||
bool ToolSupportsCompilerDependencies = true;
|
||||
|
||||
// Some make programs (Borland) do not keep a rule if there are no
|
||||
// dependencies or commands. This is a problem for creating rules
|
||||
// that might not do anything but might have other dependencies
|
||||
|
||||
@@ -25,6 +25,7 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm)
|
||||
#endif
|
||||
cm->GetState()->SetWatcomWMake(true);
|
||||
this->IncludeDirective = "!include";
|
||||
this->LineContinueDirective = "&\n";
|
||||
this->DefineWindowsNULL = true;
|
||||
this->UnixCD = false;
|
||||
this->MakeSilentFlag = "-h";
|
||||
@@ -37,7 +38,6 @@ void cmGlobalWatcomWMakeGenerator::EnableLanguage(
|
||||
mf->AddDefinition("WATCOM", "1");
|
||||
mf->AddDefinition("CMAKE_QUOTE_INCLUDE_PATHS", "1");
|
||||
mf->AddDefinition("CMAKE_MANGLE_OBJECT_FILE_NAMES", "1");
|
||||
mf->AddDefinition("CMAKE_MAKE_LINE_CONTINUE", "&");
|
||||
mf->AddDefinition("CMAKE_MAKE_SYMBOLIC_RULE", ".SYMBOLIC");
|
||||
mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl386");
|
||||
mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl386");
|
||||
|
||||
@@ -43,6 +43,13 @@ enum class cmSourceOutputKind
|
||||
OutputOrByproduct
|
||||
};
|
||||
|
||||
/** What scanner to use for dependencies lookup. */
|
||||
enum class cmDependencyScannerKind
|
||||
{
|
||||
CMake,
|
||||
Compiler
|
||||
};
|
||||
|
||||
/** Target and source file which have a specific output. */
|
||||
struct cmSourcesWithOutput
|
||||
{
|
||||
|
||||
@@ -5,18 +5,22 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/memory>
|
||||
#include <cm/string_view>
|
||||
#include <cm/vector>
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
#include "cmsys/Terminal.h"
|
||||
|
||||
#include "cmCMakePath.h"
|
||||
#include "cmCustomCommand.h" // IWYU pragma: keep
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmDependsCompiler.h"
|
||||
#include "cmFileTimeCache.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
@@ -50,8 +54,9 @@
|
||||
# include "cmDependsJava.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
// Helper function used below.
|
||||
static std::string cmSplitExtension(std::string const& in, std::string& base)
|
||||
std::string cmSplitExtension(std::string const& in, std::string& base)
|
||||
{
|
||||
std::string ext;
|
||||
std::string::size_type dot_pos = in.rfind('.');
|
||||
@@ -65,6 +70,43 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
|
||||
return ext;
|
||||
}
|
||||
|
||||
// Helper predicate for removing absolute paths that don't point to the
|
||||
// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
|
||||
// is set ON, to only consider in-project dependencies during the build.
|
||||
class NotInProjectDir
|
||||
{
|
||||
public:
|
||||
// Constructor with the source and binary directory's path
|
||||
NotInProjectDir(cm::string_view sourceDir, cm::string_view binaryDir)
|
||||
: SourceDir(sourceDir)
|
||||
, BinaryDir(binaryDir)
|
||||
{
|
||||
}
|
||||
|
||||
// Operator evaluating the predicate
|
||||
bool operator()(const std::string& p) const
|
||||
{
|
||||
auto path = cmCMakePath(p).Normal();
|
||||
|
||||
// Keep all relative paths:
|
||||
if (path.IsRelative()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's an absolute path, check if it starts with the source
|
||||
// directory:
|
||||
return !(cmCMakePath(SourceDir).IsPrefix(path) ||
|
||||
cmCMakePath(BinaryDir).IsPrefix(path));
|
||||
}
|
||||
|
||||
private:
|
||||
// The path to the source directory
|
||||
cm::string_view SourceDir;
|
||||
// The path to the binary directory
|
||||
cm::string_view BinaryDir;
|
||||
};
|
||||
}
|
||||
|
||||
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
|
||||
cmGlobalGenerator* gg, cmMakefile* mf)
|
||||
: cmLocalCommonGenerator(gg, mf, mf->GetCurrentBinaryDirectory())
|
||||
@@ -552,8 +594,10 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
|
||||
}
|
||||
}
|
||||
|
||||
// Write the list of commands.
|
||||
os << cmWrap("\t", commands, "", "\n") << "\n";
|
||||
if (!commands.empty()) {
|
||||
// Write the list of commands.
|
||||
os << cmWrap("\t", commands, "", "\n") << "\n";
|
||||
}
|
||||
if (symbolic && !this->IsWatcomWMake()) {
|
||||
os << ".PHONY : " << tgt << "\n";
|
||||
}
|
||||
@@ -1298,91 +1342,153 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
|
||||
cmSystemTools::Error("Target DependInfo.cmake file not found");
|
||||
}
|
||||
|
||||
bool status = true;
|
||||
|
||||
// Check if any multiple output pairs have a missing file.
|
||||
this->CheckMultipleOutputs(verbose);
|
||||
|
||||
std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);
|
||||
std::string const internalDependFile = targetDir + "/depend.internal";
|
||||
std::string const dependFile = targetDir + "/depend.make";
|
||||
if (!this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
|
||||
// dependencies are managed by CMake itself
|
||||
|
||||
// If the target DependInfo.cmake file has changed since the last
|
||||
// time dependencies were scanned then force rescanning. This may
|
||||
// happen when a new source file is added and CMake regenerates the
|
||||
// project but no other sources were touched.
|
||||
bool needRescanDependInfo = false;
|
||||
cmFileTimeCache* ftc =
|
||||
this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
|
||||
{
|
||||
int result;
|
||||
if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
|
||||
if (verbose) {
|
||||
cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
|
||||
"\" is newer than depender \"",
|
||||
internalDependFile, "\".\n"));
|
||||
std::string const internalDependFile = targetDir + "/depend.internal";
|
||||
std::string const dependFile = targetDir + "/depend.make";
|
||||
|
||||
// If the target DependInfo.cmake file has changed since the last
|
||||
// time dependencies were scanned then force rescanning. This may
|
||||
// happen when a new source file is added and CMake regenerates the
|
||||
// project but no other sources were touched.
|
||||
bool needRescanDependInfo = false;
|
||||
cmFileTimeCache* ftc =
|
||||
this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
|
||||
{
|
||||
int result;
|
||||
if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
|
||||
if (verbose) {
|
||||
cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
|
||||
"\" is newer than depender \"",
|
||||
internalDependFile, "\".\n"));
|
||||
}
|
||||
needRescanDependInfo = true;
|
||||
}
|
||||
needRescanDependInfo = true;
|
||||
}
|
||||
|
||||
// If the directory information is newer than depend.internal, include
|
||||
// dirs may have changed. In this case discard all old dependencies.
|
||||
bool needRescanDirInfo = false;
|
||||
{
|
||||
std::string dirInfoFile =
|
||||
cmStrCat(this->GetCurrentBinaryDirectory(),
|
||||
"/CMakeFiles/CMakeDirectoryInformation.cmake");
|
||||
int result;
|
||||
if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
|
||||
result < 0) {
|
||||
if (verbose) {
|
||||
cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
|
||||
"\" is newer than depender \"",
|
||||
internalDependFile, "\".\n"));
|
||||
}
|
||||
needRescanDirInfo = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the implicit dependencies to see if they are up to date.
|
||||
// The build.make file may have explicit dependencies for the object
|
||||
// files but these will not affect the scanning process so they need
|
||||
// not be considered.
|
||||
cmDepends::DependencyMap validDependencies;
|
||||
bool needRescanDependencies = false;
|
||||
if (!needRescanDirInfo) {
|
||||
cmDependsC checker;
|
||||
checker.SetVerbose(verbose);
|
||||
checker.SetFileTimeCache(ftc);
|
||||
// cmDependsC::Check() fills the vector validDependencies() with the
|
||||
// dependencies for those files where they are still valid, i.e.
|
||||
// neither the files themselves nor any files they depend on have
|
||||
// changed. We don't do that if the CMakeDirectoryInformation.cmake
|
||||
// file has changed, because then potentially all dependencies have
|
||||
// changed. This information is given later on to cmDependsC, which
|
||||
// then only rescans the files where it did not get valid dependencies
|
||||
// via this dependency vector. This means that in the normal case, when
|
||||
// only few or one file have been edited, then also only this one file
|
||||
// is actually scanned again, instead of all files for this target.
|
||||
needRescanDependencies =
|
||||
!checker.Check(dependFile, internalDependFile, validDependencies);
|
||||
}
|
||||
|
||||
if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
|
||||
// The dependencies must be regenerated.
|
||||
std::string targetName = cmSystemTools::GetFilenameName(targetDir);
|
||||
targetName = targetName.substr(0, targetName.length() - 4);
|
||||
std::string message =
|
||||
cmStrCat("Scanning dependencies of target ", targetName);
|
||||
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
|
||||
cmsysTerminal_Color_ForegroundBold,
|
||||
message.c_str(), true, color);
|
||||
|
||||
status = this->ScanDependencies(targetDir, dependFile,
|
||||
internalDependFile, validDependencies);
|
||||
}
|
||||
}
|
||||
|
||||
// If the directory information is newer than depend.internal, include dirs
|
||||
// may have changed. In this case discard all old dependencies.
|
||||
bool needRescanDirInfo = false;
|
||||
{
|
||||
std::string dirInfoFile =
|
||||
cmStrCat(this->GetCurrentBinaryDirectory(),
|
||||
"/CMakeFiles/CMakeDirectoryInformation.cmake");
|
||||
int result;
|
||||
if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
|
||||
result < 0) {
|
||||
if (verbose) {
|
||||
cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
|
||||
"\" is newer than depender \"",
|
||||
internalDependFile, "\".\n"));
|
||||
auto depends =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
|
||||
if (!depends.empty()) {
|
||||
// dependencies are managed by compiler
|
||||
auto depFiles = cmExpandedList(depends);
|
||||
std::string const internalDepFile =
|
||||
targetDir + "/compiler_depend.internal";
|
||||
std::string const depFile = targetDir + "/compiler_depend.make";
|
||||
cmDepends::DependencyMap dependencies;
|
||||
cmDependsCompiler depsManager;
|
||||
bool projectOnly = cmIsOn(
|
||||
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_IN_PROJECT_ONLY"));
|
||||
|
||||
depsManager.SetVerbose(verbose);
|
||||
depsManager.SetLocalGenerator(this);
|
||||
|
||||
if (!depsManager.CheckDependencies(
|
||||
internalDepFile, depFiles, dependencies,
|
||||
projectOnly ? NotInProjectDir(this->GetSourceDirectory(),
|
||||
this->GetBinaryDirectory())
|
||||
: std::function<bool(const std::string&)>())) {
|
||||
// regenerate dependencies files
|
||||
std::string targetName =
|
||||
cmCMakePath(targetDir).GetFileName().RemoveExtension().GenericString();
|
||||
auto message = cmStrCat(
|
||||
"Consolidate compiler generated dependencies of target ", targetName);
|
||||
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
|
||||
cmsysTerminal_Color_ForegroundBold,
|
||||
message.c_str(), true, color);
|
||||
|
||||
// Open the make depends file. This should be copy-if-different
|
||||
// because the make tool may try to reload it needlessly otherwise.
|
||||
cmGeneratedFileStream ruleFileStream(
|
||||
depFile, false, this->GlobalGenerator->GetMakefileEncoding());
|
||||
ruleFileStream.SetCopyIfDifferent(true);
|
||||
if (!ruleFileStream) {
|
||||
return false;
|
||||
}
|
||||
needRescanDirInfo = true;
|
||||
|
||||
// Open the cmake dependency tracking file. This should not be
|
||||
// copy-if-different because dependencies are re-scanned when it is
|
||||
// older than the DependInfo.cmake.
|
||||
cmGeneratedFileStream internalRuleFileStream(
|
||||
internalDepFile, false, this->GlobalGenerator->GetMakefileEncoding());
|
||||
if (!internalRuleFileStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->WriteDisclaimer(ruleFileStream);
|
||||
this->WriteDisclaimer(internalRuleFileStream);
|
||||
|
||||
depsManager.WriteDependencies(dependencies, ruleFileStream,
|
||||
internalRuleFileStream);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the implicit dependencies to see if they are up to date.
|
||||
// The build.make file may have explicit dependencies for the object
|
||||
// files but these will not affect the scanning process so they need
|
||||
// not be considered.
|
||||
cmDepends::DependencyMap validDependencies;
|
||||
bool needRescanDependencies = false;
|
||||
if (!needRescanDirInfo) {
|
||||
cmDependsC checker;
|
||||
checker.SetVerbose(verbose);
|
||||
checker.SetFileTimeCache(ftc);
|
||||
// cmDependsC::Check() fills the vector validDependencies() with the
|
||||
// dependencies for those files where they are still valid, i.e. neither
|
||||
// the files themselves nor any files they depend on have changed.
|
||||
// We don't do that if the CMakeDirectoryInformation.cmake file has
|
||||
// changed, because then potentially all dependencies have changed.
|
||||
// This information is given later on to cmDependsC, which then only
|
||||
// rescans the files where it did not get valid dependencies via this
|
||||
// dependency vector. This means that in the normal case, when only
|
||||
// few or one file have been edited, then also only this one file is
|
||||
// actually scanned again, instead of all files for this target.
|
||||
needRescanDependencies =
|
||||
!checker.Check(dependFile, internalDependFile, validDependencies);
|
||||
}
|
||||
|
||||
if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
|
||||
// The dependencies must be regenerated.
|
||||
std::string targetName = cmSystemTools::GetFilenameName(targetDir);
|
||||
targetName = targetName.substr(0, targetName.length() - 4);
|
||||
std::string message =
|
||||
cmStrCat("Scanning dependencies of target ", targetName);
|
||||
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
|
||||
cmsysTerminal_Color_ForegroundBold,
|
||||
message.c_str(), true, color);
|
||||
|
||||
return this->ScanDependencies(targetDir, dependFile, internalDependFile,
|
||||
validDependencies);
|
||||
}
|
||||
|
||||
// The dependencies are already up-to-date.
|
||||
return true;
|
||||
return status;
|
||||
}
|
||||
|
||||
bool cmLocalUnixMakefileGenerator3::ScanDependencies(
|
||||
@@ -1721,178 +1827,193 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
|
||||
cmDepends clearer;
|
||||
clearer.SetVerbose(verbose);
|
||||
for (std::string const& file : files) {
|
||||
std::string dir = cmSystemTools::GetFilenamePath(file);
|
||||
auto snapshot = mf->GetState()->CreateBaseSnapshot();
|
||||
cmMakefile lmf(mf->GetGlobalGenerator(), snapshot);
|
||||
lmf.ReadListFile(file);
|
||||
|
||||
// Clear the implicit dependency makefile.
|
||||
std::string dependFile = dir + "/depend.make";
|
||||
clearer.Clear(dependFile);
|
||||
if (!lmf.GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
|
||||
std::string dir = cmSystemTools::GetFilenamePath(file);
|
||||
|
||||
// Remove the internal dependency check file to force
|
||||
// regeneration.
|
||||
std::string internalDependFile = dir + "/depend.internal";
|
||||
cmSystemTools::RemoveFile(internalDependFile);
|
||||
}
|
||||
}
|
||||
// Clear the implicit dependency makefile.
|
||||
std::string dependFile = dir + "/depend.make";
|
||||
clearer.Clear(dependFile);
|
||||
|
||||
namespace {
|
||||
// Helper predicate for removing absolute paths that don't point to the
|
||||
// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
|
||||
// is set ON, to only consider in-project dependencies during the build.
|
||||
class NotInProjectDir
|
||||
{
|
||||
public:
|
||||
// Constructor with the source and binary directory's path
|
||||
NotInProjectDir(std::string sourceDir, std::string binaryDir)
|
||||
: SourceDir(std::move(sourceDir))
|
||||
, BinaryDir(std::move(binaryDir))
|
||||
{
|
||||
}
|
||||
|
||||
// Operator evaluating the predicate
|
||||
bool operator()(const std::string& path) const
|
||||
{
|
||||
// Keep all relative paths:
|
||||
if (!cmSystemTools::FileIsFullPath(path)) {
|
||||
return false;
|
||||
// Remove the internal dependency check file to force
|
||||
// regeneration.
|
||||
std::string internalDependFile = dir + "/depend.internal";
|
||||
cmSystemTools::RemoveFile(internalDependFile);
|
||||
}
|
||||
// If it's an absolute path, check if it starts with the source
|
||||
// directory:
|
||||
return (
|
||||
!(IsInDirectory(SourceDir, path) || IsInDirectory(BinaryDir, path)));
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper function used by the predicate
|
||||
static bool IsInDirectory(const std::string& baseDir,
|
||||
const std::string& testDir)
|
||||
{
|
||||
// First check if the test directory "starts with" the base directory:
|
||||
if (!cmHasPrefix(testDir, baseDir)) {
|
||||
return false;
|
||||
auto depsFiles = lmf.GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
|
||||
if (!depsFiles.empty()) {
|
||||
auto dir = cmCMakePath(file).GetParentPath();
|
||||
// Clear the implicit dependency makefile.
|
||||
auto depFile = cmCMakePath(dir).Append("compiler_depend.make");
|
||||
clearer.Clear(depFile.GenericString());
|
||||
|
||||
// Remove the internal dependency check file
|
||||
auto internalDepFile =
|
||||
cmCMakePath(dir).Append("compiler_depend.internal");
|
||||
cmSystemTools::RemoveFile(internalDepFile.GenericString());
|
||||
|
||||
// Touch timestamp file to force dependencies regeneration
|
||||
auto DepTimestamp = cmCMakePath(dir).Append("compiler_depend.ts");
|
||||
cmSystemTools::Touch(DepTimestamp.GenericString(), true);
|
||||
|
||||
// clear the dependencies files generated by the compiler
|
||||
std::vector<std::string> dependencies = cmExpandedList(depsFiles);
|
||||
cmDependsCompiler depsManager;
|
||||
depsManager.SetVerbose(verbose);
|
||||
depsManager.ClearDependencies(dependencies);
|
||||
}
|
||||
// If it does, then check that it's either the same string, or that the
|
||||
// next character is a slash:
|
||||
return ((testDir.size() == baseDir.size()) ||
|
||||
(testDir[baseDir.size()] == '/'));
|
||||
}
|
||||
|
||||
// The path to the source directory
|
||||
std::string SourceDir;
|
||||
// The path to the binary directory
|
||||
std::string BinaryDir;
|
||||
};
|
||||
}
|
||||
|
||||
void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
|
||||
std::ostream& cmakefileStream, cmGeneratorTarget* target)
|
||||
{
|
||||
ImplicitDependLanguageMap const& implicitLangs =
|
||||
this->GetImplicitDepends(target);
|
||||
// To enable dependencies filtering
|
||||
cmakefileStream << "\n"
|
||||
<< "# Consider dependencies only in project.\n"
|
||||
<< "set(CMAKE_DEPENDS_IN_PROJECT_ONLY "
|
||||
<< (cmIsOn(this->Makefile->GetSafeDefinition(
|
||||
"CMAKE_DEPENDS_IN_PROJECT_ONLY"))
|
||||
? "ON"
|
||||
: "OFF")
|
||||
<< ")\n\n";
|
||||
|
||||
auto const& implicitLangs =
|
||||
this->GetImplicitDepends(target, cmDependencyScannerKind::CMake);
|
||||
|
||||
// list the languages
|
||||
cmakefileStream
|
||||
<< "# The set of languages for which implicit dependencies are needed:\n";
|
||||
cmakefileStream << "# The set of languages for which implicit "
|
||||
"dependencies are needed:\n";
|
||||
cmakefileStream << "set(CMAKE_DEPENDS_LANGUAGES\n";
|
||||
for (auto const& implicitLang : implicitLangs) {
|
||||
cmakefileStream << " \"" << implicitLang.first << "\"\n";
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
|
||||
// now list the files for each language
|
||||
cmakefileStream
|
||||
<< "# The set of files for implicit dependencies of each language:\n";
|
||||
for (auto const& implicitLang : implicitLangs) {
|
||||
cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << implicitLang.first
|
||||
<< "\n";
|
||||
ImplicitDependFileMap const& implicitPairs = implicitLang.second;
|
||||
if (!implicitLangs.empty()) {
|
||||
// now list the files for each language
|
||||
cmakefileStream
|
||||
<< "# The set of files for implicit dependencies of each language:\n";
|
||||
for (auto const& implicitLang : implicitLangs) {
|
||||
const auto& lang = implicitLang.first;
|
||||
|
||||
// for each file pair
|
||||
for (auto const& implicitPair : implicitPairs) {
|
||||
for (auto const& di : implicitPair.second) {
|
||||
cmakefileStream << " \"" << di << "\" ";
|
||||
cmakefileStream << "\"" << implicitPair.first << "\"\n";
|
||||
cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << lang << "\n";
|
||||
auto const& implicitPairs = implicitLang.second;
|
||||
|
||||
// for each file pair
|
||||
for (auto const& implicitPair : implicitPairs) {
|
||||
for (auto const& di : implicitPair.second) {
|
||||
cmakefileStream << " \"" << di << "\" ";
|
||||
cmakefileStream << "\"" << implicitPair.first << "\"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
cmakefileStream << " )\n";
|
||||
|
||||
// Tell the dependency scanner what compiler is used.
|
||||
std::string cidVar =
|
||||
cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
|
||||
cmProp cid = this->Makefile->GetDefinition(cidVar);
|
||||
if (cmNonempty(cid)) {
|
||||
cmakefileStream << "set(CMAKE_" << implicitLang.first
|
||||
<< "_COMPILER_ID \"" << *cid << "\")\n";
|
||||
}
|
||||
// Tell the dependency scanner what compiler is used.
|
||||
std::string cidVar = cmStrCat("CMAKE_", lang, "_COMPILER_ID");
|
||||
cmProp cid = this->Makefile->GetDefinition(cidVar);
|
||||
if (cmNonempty(cid)) {
|
||||
cmakefileStream << "set(CMAKE_" << lang << "_COMPILER_ID \"" << *cid
|
||||
<< "\")\n";
|
||||
}
|
||||
|
||||
if (implicitLang.first == "Fortran") {
|
||||
std::string smodSep =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
|
||||
std::string smodExt =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
|
||||
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
|
||||
<< "\")\n";
|
||||
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
|
||||
<< "\")\n";
|
||||
}
|
||||
if (lang == "Fortran") {
|
||||
std::string smodSep =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
|
||||
std::string smodExt =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
|
||||
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
|
||||
<< "\")\n";
|
||||
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
|
||||
<< "\")\n";
|
||||
}
|
||||
|
||||
// Build a list of preprocessor definitions for the target.
|
||||
std::set<std::string> defines;
|
||||
this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
|
||||
defines);
|
||||
if (!defines.empty()) {
|
||||
/* clang-format off */
|
||||
// Build a list of preprocessor definitions for the target.
|
||||
std::set<std::string> defines;
|
||||
this->GetTargetDefines(target, this->GetConfigName(), lang, defines);
|
||||
if (!defines.empty()) {
|
||||
/* clang-format off */
|
||||
cmakefileStream
|
||||
<< "\n"
|
||||
<< "# Preprocessor definitions for this target.\n"
|
||||
<< "set(CMAKE_TARGET_DEFINITIONS_" << implicitLang.first << "\n";
|
||||
/* clang-format on */
|
||||
for (std::string const& define : defines) {
|
||||
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(define)
|
||||
<< "\n";
|
||||
<< "set(CMAKE_TARGET_DEFINITIONS_" << lang << "\n";
|
||||
/* clang-format on */
|
||||
for (std::string const& define : defines) {
|
||||
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(define)
|
||||
<< "\n";
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
}
|
||||
|
||||
// Target-specific include directories:
|
||||
cmakefileStream << "\n"
|
||||
<< "# The include file search paths:\n";
|
||||
cmakefileStream << "set(CMAKE_" << lang << "_TARGET_INCLUDE_PATH\n";
|
||||
std::vector<std::string> includes;
|
||||
|
||||
this->GetIncludeDirectories(includes, target, lang,
|
||||
this->GetConfigName());
|
||||
std::string const& binaryDir = this->GetState()->GetBinaryDirectory();
|
||||
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
|
||||
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
|
||||
cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
|
||||
}
|
||||
for (std::string const& include : includes) {
|
||||
cmakefileStream << " \""
|
||||
<< this->MaybeConvertToRelativePath(binaryDir, include)
|
||||
<< "\"\n";
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
}
|
||||
|
||||
// Target-specific include directories:
|
||||
cmakefileStream << "\n"
|
||||
<< "# The include file search paths:\n";
|
||||
cmakefileStream << "set(CMAKE_" << implicitLang.first
|
||||
<< "_TARGET_INCLUDE_PATH\n";
|
||||
std::vector<std::string> includes;
|
||||
|
||||
this->GetIncludeDirectories(includes, target, implicitLang.first,
|
||||
this->GetConfigName());
|
||||
std::string binaryDir = this->GetState()->GetBinaryDirectory();
|
||||
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
|
||||
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
|
||||
cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
|
||||
// Store include transform rule properties. Write the directory
|
||||
// rules first because they may be overridden by later target rules.
|
||||
std::vector<std::string> transformRules;
|
||||
if (cmProp xform =
|
||||
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
||||
cmExpandList(*xform, transformRules);
|
||||
}
|
||||
for (std::string const& include : includes) {
|
||||
cmakefileStream << " \""
|
||||
<< this->MaybeConvertToRelativePath(binaryDir, include)
|
||||
<< "\"\n";
|
||||
if (cmProp xform =
|
||||
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
||||
cmExpandList(*xform, transformRules);
|
||||
}
|
||||
if (!transformRules.empty()) {
|
||||
cmakefileStream << "\nset(CMAKE_INCLUDE_TRANSFORMS\n";
|
||||
for (std::string const& tr : transformRules) {
|
||||
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(tr)
|
||||
<< "\n";
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
}
|
||||
|
||||
// Store include transform rule properties. Write the directory
|
||||
// rules first because they may be overridden by later target rules.
|
||||
std::vector<std::string> transformRules;
|
||||
if (cmProp xform =
|
||||
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
||||
cmExpandList(*xform, transformRules);
|
||||
}
|
||||
if (cmProp xform =
|
||||
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
||||
cmExpandList(*xform, transformRules);
|
||||
}
|
||||
if (!transformRules.empty()) {
|
||||
cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
|
||||
for (std::string const& tr : transformRules) {
|
||||
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(tr) << "\n";
|
||||
auto const& compilerLangs =
|
||||
this->GetImplicitDepends(target, cmDependencyScannerKind::Compiler);
|
||||
|
||||
// list the dependency files managed by the compiler
|
||||
cmakefileStream << "\n# The set of dependency files which are needed:\n";
|
||||
cmakefileStream << "set(CMAKE_DEPENDS_DEPENDENCY_FILES\n";
|
||||
for (auto const& compilerLang : compilerLangs) {
|
||||
auto depFormat = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
|
||||
auto const& compilerPairs = compilerLang.second;
|
||||
for (auto const& compilerPair : compilerPairs) {
|
||||
for (auto const& src : compilerPair.second) {
|
||||
cmakefileStream << " \"" << src << "\" \""
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< "\" \"" << depFormat << "\" \""
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< ".d\"\n";
|
||||
}
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
}
|
||||
cmakefileStream << " )\n";
|
||||
}
|
||||
|
||||
void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
|
||||
@@ -2049,16 +2170,18 @@ std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory(
|
||||
}
|
||||
|
||||
cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
|
||||
cmLocalUnixMakefileGenerator3::GetImplicitDepends(const cmGeneratorTarget* tgt)
|
||||
cmLocalUnixMakefileGenerator3::GetImplicitDepends(
|
||||
const cmGeneratorTarget* tgt, cmDependencyScannerKind scanner)
|
||||
{
|
||||
return this->ImplicitDepends[tgt->GetName()];
|
||||
return this->ImplicitDepends[tgt->GetName()][scanner];
|
||||
}
|
||||
|
||||
void cmLocalUnixMakefileGenerator3::AddImplicitDepends(
|
||||
const cmGeneratorTarget* tgt, const std::string& lang,
|
||||
const std::string& obj, const std::string& src)
|
||||
const std::string& obj, const std::string& src,
|
||||
cmDependencyScannerKind scanner)
|
||||
{
|
||||
this->ImplicitDepends[tgt->GetName()][lang][obj].push_back(src);
|
||||
this->ImplicitDepends[tgt->GetName()][scanner][lang][obj].push_back(src);
|
||||
}
|
||||
|
||||
void cmLocalUnixMakefileGenerator3::CreateCDCommand(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "cmDepends.h"
|
||||
#include "cmLocalCommonGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
|
||||
class cmCustomCommand;
|
||||
class cmCustomCommandGenerator;
|
||||
@@ -152,23 +153,21 @@ public:
|
||||
|
||||
// File pairs for implicit dependency scanning. The key of the map
|
||||
// is the depender and the value is the explicit dependee.
|
||||
struct ImplicitDependFileMap : public cmDepends::DependencyMap
|
||||
{
|
||||
};
|
||||
struct ImplicitDependLanguageMap
|
||||
: public std::map<std::string, ImplicitDependFileMap>
|
||||
{
|
||||
};
|
||||
struct ImplicitDependTargetMap
|
||||
: public std::map<std::string, ImplicitDependLanguageMap>
|
||||
{
|
||||
};
|
||||
using ImplicitDependFileMap = cmDepends::DependencyMap;
|
||||
using ImplicitDependLanguageMap =
|
||||
std::map<std::string, ImplicitDependFileMap>;
|
||||
using ImplicitDependScannerMap =
|
||||
std::map<cmDependencyScannerKind, ImplicitDependLanguageMap>;
|
||||
using ImplicitDependTargetMap =
|
||||
std::map<std::string, ImplicitDependScannerMap>;
|
||||
ImplicitDependLanguageMap const& GetImplicitDepends(
|
||||
cmGeneratorTarget const* tgt);
|
||||
cmGeneratorTarget const* tgt,
|
||||
cmDependencyScannerKind scanner = cmDependencyScannerKind::CMake);
|
||||
|
||||
void AddImplicitDepends(cmGeneratorTarget const* tgt,
|
||||
const std::string& lang, const std::string& obj,
|
||||
const std::string& src);
|
||||
void AddImplicitDepends(
|
||||
cmGeneratorTarget const* tgt, const std::string& lang,
|
||||
const std::string& obj, const std::string& src,
|
||||
cmDependencyScannerKind scanner = cmDependencyScannerKind::CMake);
|
||||
|
||||
// write the target rules for the local Makefile into the stream
|
||||
void WriteLocalAllRules(std::ostream& ruleFileStream);
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
#include <utility>
|
||||
|
||||
#include <cm/memory>
|
||||
#include <cm/string_view>
|
||||
#include <cmext/algorithm>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmCustomCommand.h"
|
||||
@@ -23,6 +25,7 @@
|
||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||
#include "cmLinkLineComputer.h" // IWYU pragma: keep
|
||||
#include "cmLocalCommonGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMakefileExecutableTargetGenerator.h"
|
||||
@@ -325,7 +328,45 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
|
||||
<< cmSystemTools::ConvertToOutputPath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(), dependFileNameFull))
|
||||
<< "\n\n";
|
||||
<< "\n";
|
||||
|
||||
std::string depsUseCompiler = "CMAKE_DEPENDS_USE_COMPILER";
|
||||
if (!this->Makefile->IsDefinitionSet(depsUseCompiler) ||
|
||||
this->Makefile->IsOn(depsUseCompiler)) {
|
||||
std::string compilerDependFile =
|
||||
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
|
||||
*this->BuildFileStream
|
||||
<< "# Include any dependencies generated by the "
|
||||
"compiler for this target.\n"
|
||||
<< this->GlobalGenerator->IncludeDirective << " " << root
|
||||
<< cmSystemTools::ConvertToOutputPath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(), compilerDependFile))
|
||||
<< "\n\n";
|
||||
|
||||
if (!cmSystemTools::FileExists(compilerDependFile)) {
|
||||
// Write an empty dependency file.
|
||||
cmGeneratedFileStream depFileStream(
|
||||
compilerDependFile, false,
|
||||
this->GlobalGenerator->GetMakefileEncoding());
|
||||
depFileStream << "# Empty compiler generated dependencies file for "
|
||||
<< this->GeneratorTarget->GetName() << ".\n"
|
||||
<< "# This may be replaced when dependencies are built.\n";
|
||||
}
|
||||
|
||||
std::string compilerDependTimestamp =
|
||||
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
|
||||
if (!cmSystemTools::FileExists(compilerDependTimestamp)) {
|
||||
// Write a dependency timestamp file.
|
||||
cmGeneratedFileStream depFileStream(
|
||||
compilerDependTimestamp, false,
|
||||
this->GlobalGenerator->GetMakefileEncoding());
|
||||
depFileStream << "# CMAKE generated file: DO NOT EDIT!\n"
|
||||
<< "# Timestamp file for compiler generated dependencies "
|
||||
"management for "
|
||||
<< this->GeneratorTarget->GetName() << ".\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->NoRuleMessages) {
|
||||
// Include the progress variables for the target.
|
||||
@@ -472,6 +513,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
return;
|
||||
}
|
||||
|
||||
// Use compiler to generate dependencies, if supported.
|
||||
bool compilerGenerateDeps =
|
||||
this->GlobalGenerator->SupportsCompilerDependencies() &&
|
||||
cmIsOn(this->Makefile->GetDefinition(
|
||||
cmStrCat("CMAKE_", lang, "_DEPENDS_USE_COMPILER")));
|
||||
auto scanner = compilerGenerateDeps ? cmDependencyScannerKind::Compiler
|
||||
: cmDependencyScannerKind::CMake;
|
||||
|
||||
// Get the full path name of the object file.
|
||||
std::string const& objectName =
|
||||
this->GeneratorTarget->GetObjectName(&source);
|
||||
@@ -511,7 +560,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
std::string srcFullPath =
|
||||
cmSystemTools::CollapseFullPath(source.GetFullPath());
|
||||
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
||||
objFullPath, srcFullPath);
|
||||
objFullPath, srcFullPath, scanner);
|
||||
|
||||
this->LocalGenerator->AppendRuleDepend(depends,
|
||||
this->FlagFileNameFull.c_str());
|
||||
@@ -553,8 +602,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
depends.push_back(
|
||||
this->GeneratorTarget->GetPchFile(config, lang, arch));
|
||||
}
|
||||
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
||||
objFullPath, pchHeader);
|
||||
this->LocalGenerator->AddImplicitDepends(
|
||||
this->GeneratorTarget, lang, objFullPath, pchHeader, scanner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,7 +737,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
source.GetFullPath(), cmOutputConverter::SHELL);
|
||||
|
||||
// Construct the build message.
|
||||
std::vector<std::string> no_commands;
|
||||
std::vector<std::string> no_depends;
|
||||
std::vector<std::string> commands;
|
||||
|
||||
// add in a progress call if needed
|
||||
@@ -782,6 +831,26 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
"$(" + lang + "_INCLUDES)");
|
||||
vars.Includes = includesString.c_str();
|
||||
|
||||
std::string dependencyTarget;
|
||||
std::string shellDependencyFile;
|
||||
std::string dependencyTimestamp;
|
||||
if (compilerGenerateDeps) {
|
||||
dependencyTarget = this->LocalGenerator->EscapeForShell(
|
||||
this->LocalGenerator->ConvertToMakefilePath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(), relativeObj)));
|
||||
vars.DependencyTarget = dependencyTarget.c_str();
|
||||
|
||||
auto depFile = cmStrCat(obj, ".d");
|
||||
shellDependencyFile = this->LocalGenerator->ConvertToOutputFormat(
|
||||
depFile, cmOutputConverter::SHELL);
|
||||
vars.DependencyFile = shellDependencyFile.c_str();
|
||||
|
||||
dependencyTimestamp = this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(),
|
||||
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"));
|
||||
}
|
||||
|
||||
// At the moment, it is assumed that C, C++, Fortran, and CUDA have both
|
||||
// assembly and preprocessor capabilities. The same is true for the
|
||||
// ability to export compile commands
|
||||
@@ -953,6 +1022,53 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
}
|
||||
}
|
||||
|
||||
std::string flagsWithDeps(flags);
|
||||
|
||||
if (compilerGenerateDeps) {
|
||||
// Injects dependency computation
|
||||
auto depFlags = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_DEPFILE_FLAGS_", lang));
|
||||
|
||||
if (!depFlags.empty()) {
|
||||
// Add dependency flags
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
|
||||
depFlags, vars);
|
||||
flagsWithDeps.append(1, ' ');
|
||||
flagsWithDeps.append(depFlags);
|
||||
}
|
||||
vars.Flags = flagsWithDeps.c_str();
|
||||
|
||||
const auto& extraCommands = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
|
||||
if (!extraCommands.empty()) {
|
||||
auto commandList = cmExpandedList(extraCommands);
|
||||
compileCommands.insert(compileCommands.end(), commandList.cbegin(),
|
||||
commandList.cend());
|
||||
}
|
||||
|
||||
const auto& depFormat = this->Makefile->GetRequiredDefinition(
|
||||
cmStrCat("CMAKE_", lang, "_DEPFILE_FORMAT"));
|
||||
|
||||
if (depFormat == "msvc"_s) {
|
||||
// compiler must be launched through a wrapper to pick-up dependencies
|
||||
std::string depFilter =
|
||||
"$(CMAKE_COMMAND) -E cmake_cl_compile_depends ";
|
||||
depFilter += cmStrCat("--dep-file=", shellDependencyFile);
|
||||
depFilter +=
|
||||
cmStrCat(" --working-dir=",
|
||||
this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(),
|
||||
cmOutputConverter::SHELL));
|
||||
const auto& prefix = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", lang, "_CL_SHOWINCLUDES_PREFIX"));
|
||||
depFilter += cmStrCat(" --filter-prefix=",
|
||||
this->LocalGenerator->ConvertToOutputFormat(
|
||||
prefix, cmOutputConverter::SHELL));
|
||||
depFilter += " -- ";
|
||||
compileCommands.front().insert(0, depFilter);
|
||||
}
|
||||
}
|
||||
|
||||
// Expand placeholders in the commands.
|
||||
for (std::string& compileCommand : compileCommands) {
|
||||
compileCommand = cmStrCat(launcher, compileCommand);
|
||||
@@ -978,8 +1094,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
cmExpandList(evaluated_outputs, outputs);
|
||||
}
|
||||
}
|
||||
if (!ispcHeaderRelative
|
||||
.empty()) { // can't move ispcHeader as vars is using it
|
||||
if (!ispcHeaderRelative.empty()) {
|
||||
// can't move ispcHeader as vars is using it
|
||||
outputs.emplace_back(ispcHeaderRelative);
|
||||
}
|
||||
|
||||
@@ -987,10 +1103,19 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
|
||||
}
|
||||
|
||||
if (compilerGenerateDeps) {
|
||||
depends.push_back(dependencyTimestamp);
|
||||
}
|
||||
|
||||
// Write the rule.
|
||||
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
|
||||
commands);
|
||||
|
||||
if (compilerGenerateDeps) {
|
||||
// set back flags without dependency generation
|
||||
vars.Flags = flags.c_str();
|
||||
}
|
||||
|
||||
bool do_preprocess_rules = lang_has_preprocessor &&
|
||||
this->LocalGenerator->GetCreatePreprocessedSourceRules();
|
||||
bool do_assembly_rules =
|
||||
@@ -1387,10 +1512,10 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
|
||||
|
||||
std::string registerFileCmd;
|
||||
|
||||
// The generated register file contains macros that when expanded register
|
||||
// the device routines. Because the routines are the same for all
|
||||
// architectures the register file will be the same too. Thus generate it
|
||||
// only on the first invocation to reduce overhead.
|
||||
// The generated register file contains macros that when expanded
|
||||
// register the device routines. Because the routines are the same for
|
||||
// all architectures the register file will be the same too. Thus
|
||||
// generate it only on the first invocation to reduce overhead.
|
||||
if (fatbinaryDepends.size() == 1) {
|
||||
std::string registerFileRel =
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
@@ -1425,7 +1550,8 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
|
||||
fatbinaryOutputRel, fatbinaryDepends,
|
||||
{ fatbinaryCommand }, false);
|
||||
|
||||
// Compile the stub that registers the kernels and contains the fatbinaries.
|
||||
// Compile the stub that registers the kernels and contains the
|
||||
// fatbinaries.
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
||||
vars.CMTargetType =
|
||||
@@ -1543,12 +1669,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
|
||||
<< this->GeneratorTarget->GetName() << "\n"
|
||||
<< variableName << " =";
|
||||
std::string object;
|
||||
std::string lineContinue;
|
||||
if (cmProp p = this->Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE")) {
|
||||
lineContinue = *p;
|
||||
} else {
|
||||
lineContinue = "\\";
|
||||
}
|
||||
const auto& lineContinue = this->GlobalGenerator->LineContinueDirective;
|
||||
|
||||
cmProp pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
@@ -1556,7 +1677,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
|
||||
if (cmSystemTools::StringEndsWith(obj, cmToCStr(pchExtension))) {
|
||||
continue;
|
||||
}
|
||||
*this->BuildFileStream << " " << lineContinue << "\n";
|
||||
*this->BuildFileStream << " " << lineContinue;
|
||||
*this->BuildFileStream
|
||||
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
|
||||
obj, useWatcomQuote);
|
||||
@@ -1579,7 +1700,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
|
||||
for (std::string const& obj : this->ExternalObjects) {
|
||||
object =
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, obj);
|
||||
*this->BuildFileStream << " " << lineContinue << "\n";
|
||||
*this->BuildFileStream << " " << lineContinue;
|
||||
*this->BuildFileStream
|
||||
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
|
||||
obj, useWatcomQuote);
|
||||
@@ -1843,9 +1964,9 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects(
|
||||
if (size_t const limit = cmSystemTools::CalculateCommandLineLengthLimit()) {
|
||||
// Compute the total length of our list of object files with room
|
||||
// for argument separation and quoting. This does not convert paths
|
||||
// relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so the
|
||||
// actual list will likely be much shorter than this. However, in the
|
||||
// worst case all objects will remain as absolute paths.
|
||||
// relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so
|
||||
// the actual list will likely be much shorter than this. However, in
|
||||
// the worst case all objects will remain as absolute paths.
|
||||
size_t length = 0;
|
||||
for (std::string const& obj : this->Objects) {
|
||||
length += obj.size() + 3;
|
||||
|
||||
@@ -548,6 +548,7 @@ cmNinjaRule GetScanRule(
|
||||
scanVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
|
||||
scanVars.PreprocessedSource = "$out";
|
||||
scanVars.DependencyFile = rule.DepFile.c_str();
|
||||
scanVars.DependencyTarget = "$out";
|
||||
|
||||
// Scanning needs the same preprocessor settings as direct compilation would.
|
||||
scanVars.Source = vars.Source;
|
||||
@@ -750,8 +751,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
const std::string flagsName = cmStrCat("CMAKE_DEPFILE_FLAGS_", lang);
|
||||
std::string depfileFlags = mf->GetSafeDefinition(flagsName);
|
||||
if (!depfileFlags.empty()) {
|
||||
cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
|
||||
cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
|
||||
cmSystemTools::ReplaceString(depfileFlags, "<DEP_FILE>", "$DEP_FILE");
|
||||
cmSystemTools::ReplaceString(depfileFlags, "<DEP_TARGET>", "$out");
|
||||
cmSystemTools::ReplaceString(
|
||||
depfileFlags, "<CMAKE_C_COMPILER>",
|
||||
cmToCStr(mf->GetDefinition("CMAKE_C_COMPILER")));
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "cmRulePlaceholderExpander.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#include "cmOutputConverter.h"
|
||||
@@ -20,11 +19,6 @@ cmRulePlaceholderExpander::cmRulePlaceholderExpander(
|
||||
{
|
||||
}
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables::RuleVariables()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
std::string cmRulePlaceholderExpander::ExpandRuleVariable(
|
||||
cmOutputConverter* outputConverter, std::string const& variable,
|
||||
const RuleVariables& replaceValues)
|
||||
@@ -141,6 +135,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
|
||||
return replaceValues.DependencyFile;
|
||||
}
|
||||
}
|
||||
if (replaceValues.DependencyTarget) {
|
||||
if (variable == "DEP_TARGET") {
|
||||
return replaceValues.DependencyTarget;
|
||||
}
|
||||
}
|
||||
if (replaceValues.Fatbinary) {
|
||||
if (variable == "FATBINARY") {
|
||||
return replaceValues.Fatbinary;
|
||||
|
||||
@@ -27,45 +27,45 @@ public:
|
||||
// ExpandRuleVariables
|
||||
struct RuleVariables
|
||||
{
|
||||
RuleVariables();
|
||||
const char* CMTargetName;
|
||||
const char* CMTargetType;
|
||||
const char* TargetPDB;
|
||||
const char* TargetCompilePDB;
|
||||
const char* TargetVersionMajor;
|
||||
const char* TargetVersionMinor;
|
||||
const char* Language;
|
||||
const char* AIXExports;
|
||||
const char* Objects;
|
||||
const char* Target;
|
||||
const char* LinkLibraries;
|
||||
const char* Source;
|
||||
const char* AssemblySource;
|
||||
const char* PreprocessedSource;
|
||||
const char* Output;
|
||||
const char* Object;
|
||||
const char* ObjectDir;
|
||||
const char* ObjectFileDir;
|
||||
const char* Flags;
|
||||
const char* ObjectsQuoted;
|
||||
const char* SONameFlag;
|
||||
const char* TargetSOName;
|
||||
const char* TargetInstallNameDir;
|
||||
const char* LinkFlags;
|
||||
const char* Manifests;
|
||||
const char* LanguageCompileFlags;
|
||||
const char* Defines;
|
||||
const char* Includes;
|
||||
const char* DependencyFile;
|
||||
const char* FilterPrefix;
|
||||
const char* SwiftLibraryName;
|
||||
const char* SwiftModule;
|
||||
const char* SwiftModuleName;
|
||||
const char* SwiftOutputFileMap;
|
||||
const char* SwiftSources;
|
||||
const char* ISPCHeader;
|
||||
const char* Fatbinary;
|
||||
const char* RegisterFile;
|
||||
const char* CMTargetName = nullptr;
|
||||
const char* CMTargetType = nullptr;
|
||||
const char* TargetPDB = nullptr;
|
||||
const char* TargetCompilePDB = nullptr;
|
||||
const char* TargetVersionMajor = nullptr;
|
||||
const char* TargetVersionMinor = nullptr;
|
||||
const char* Language = nullptr;
|
||||
const char* AIXExports = nullptr;
|
||||
const char* Objects = nullptr;
|
||||
const char* Target = nullptr;
|
||||
const char* LinkLibraries = nullptr;
|
||||
const char* Source = nullptr;
|
||||
const char* AssemblySource = nullptr;
|
||||
const char* PreprocessedSource = nullptr;
|
||||
const char* Output = nullptr;
|
||||
const char* Object = nullptr;
|
||||
const char* ObjectDir = nullptr;
|
||||
const char* ObjectFileDir = nullptr;
|
||||
const char* Flags = nullptr;
|
||||
const char* ObjectsQuoted = nullptr;
|
||||
const char* SONameFlag = nullptr;
|
||||
const char* TargetSOName = nullptr;
|
||||
const char* TargetInstallNameDir = nullptr;
|
||||
const char* LinkFlags = nullptr;
|
||||
const char* Manifests = nullptr;
|
||||
const char* LanguageCompileFlags = nullptr;
|
||||
const char* Defines = nullptr;
|
||||
const char* Includes = nullptr;
|
||||
const char* DependencyFile = nullptr;
|
||||
const char* DependencyTarget = nullptr;
|
||||
const char* FilterPrefix = nullptr;
|
||||
const char* SwiftLibraryName = nullptr;
|
||||
const char* SwiftModule = nullptr;
|
||||
const char* SwiftModuleName = nullptr;
|
||||
const char* SwiftOutputFileMap = nullptr;
|
||||
const char* SwiftSources = nullptr;
|
||||
const char* ISPCHeader = nullptr;
|
||||
const char* Fatbinary = nullptr;
|
||||
const char* RegisterFile = nullptr;
|
||||
};
|
||||
|
||||
// Expand rule variables in CMake of the type found in language rules
|
||||
|
||||
+155
-28
@@ -33,6 +33,13 @@
|
||||
# include "bindexplib.h"
|
||||
#endif
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
|
||||
# include <algorithm>
|
||||
|
||||
# include "cmCMakePath.h"
|
||||
# include "cmProcessTools.h"
|
||||
#endif
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include "cmVisualStudioWCEPlatformParser.h"
|
||||
#endif
|
||||
@@ -66,6 +73,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
|
||||
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
|
||||
std::vector<std::string>::const_iterator argEnd);
|
||||
|
||||
namespace {
|
||||
void CMakeCommandUsage(const char* program)
|
||||
{
|
||||
std::ostringstream errorStream;
|
||||
@@ -144,8 +152,7 @@ void CMakeCommandUsage(const char* program)
|
||||
cmSystemTools::Error(errorStream.str());
|
||||
}
|
||||
|
||||
static bool cmTarFilesFrom(std::string const& file,
|
||||
std::vector<std::string>& files)
|
||||
bool cmTarFilesFrom(std::string const& file, std::vector<std::string>& files)
|
||||
{
|
||||
if (cmSystemTools::FileIsDirectory(file)) {
|
||||
std::ostringstream e;
|
||||
@@ -180,7 +187,7 @@ static bool cmTarFilesFrom(std::string const& file,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cmCatFile(const std::string& fileToAppend)
|
||||
void cmCatFile(const std::string& fileToAppend)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_setmode(fileno(stdout), _O_BINARY);
|
||||
@@ -190,7 +197,7 @@ static void cmCatFile(const std::string& fileToAppend)
|
||||
std::cout << source.rdbuf();
|
||||
}
|
||||
|
||||
static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
|
||||
bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
|
||||
{
|
||||
if (cmSystemTools::FileIsSymlink(dir)) {
|
||||
if (!cmSystemTools::RemoveFile(dir)) {
|
||||
@@ -208,9 +215,123 @@ static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int HandleIWYU(const std::string& runCmd,
|
||||
const std::string& /* sourceFile */,
|
||||
const std::vector<std::string>& orig_cmd)
|
||||
#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
|
||||
class CLIncludeParser : public cmProcessTools::LineParser
|
||||
{
|
||||
public:
|
||||
CLIncludeParser(cm::string_view includePrefix, cmsys::ofstream& depFile,
|
||||
std::ostream& output)
|
||||
: IncludePrefix(includePrefix)
|
||||
, DepFile(depFile)
|
||||
, Output(output)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
bool ProcessLine() override
|
||||
{
|
||||
if (cmHasPrefix(this->Line, this->IncludePrefix)) {
|
||||
this->DepFile << cmCMakePath(
|
||||
cmTrimWhitespace(this->Line.c_str() +
|
||||
this->IncludePrefix.size()))
|
||||
.GenericString()
|
||||
<< std::endl;
|
||||
} else {
|
||||
this->Output << this->Line << std::endl << std::flush;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cm::string_view IncludePrefix;
|
||||
cmsys::ofstream& DepFile;
|
||||
std::ostream& Output;
|
||||
};
|
||||
|
||||
class CLOutputLogger : public cmProcessTools::OutputLogger
|
||||
{
|
||||
public:
|
||||
CLOutputLogger(std::ostream& log)
|
||||
: cmProcessTools::OutputLogger(log)
|
||||
{
|
||||
}
|
||||
|
||||
bool ProcessLine() override
|
||||
{
|
||||
*this->Log << std::flush;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
int CLCompileAndDependencies(const std::vector<std::string>& args)
|
||||
{
|
||||
std::string depFile;
|
||||
std::string currentBinaryDir;
|
||||
std::string filterPrefix;
|
||||
std::vector<std::string> command;
|
||||
for (auto it = args.cbegin() + 2; it != args.cend(); it++) {
|
||||
if (cmHasLiteralPrefix(*it, "--dep-file=")) {
|
||||
depFile = it->substr(11);
|
||||
} else if (cmHasLiteralPrefix(*it, "--working-dir=")) {
|
||||
currentBinaryDir = it->substr(14);
|
||||
} else if (cmHasLiteralPrefix(*it, "--filter-prefix=")) {
|
||||
filterPrefix = it->substr(16);
|
||||
} else if (*it == "--") {
|
||||
command.insert(command.begin(), ++it, args.cend());
|
||||
break;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp(
|
||||
cmsysProcess_New(), cmsysProcess_Delete);
|
||||
std::vector<const char*> argv(command.size() + 1);
|
||||
std::transform(command.begin(), command.end(), argv.begin(),
|
||||
[](std::string const& s) { return s.c_str(); });
|
||||
argv.back() = nullptr;
|
||||
cmsysProcess_SetCommand(cp.get(), argv.data());
|
||||
cmsysProcess_SetWorkingDirectory(cp.get(), currentBinaryDir.c_str());
|
||||
|
||||
cmsys::ofstream fout(depFile.c_str());
|
||||
if (!fout) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
CLIncludeParser includeParser(filterPrefix, fout, std::cout);
|
||||
CLOutputLogger errLogger(std::cerr);
|
||||
|
||||
// Start the process.
|
||||
cmProcessTools::RunProcess(cp.get(), &includeParser, &errLogger);
|
||||
|
||||
int status = 0;
|
||||
// handle status of process
|
||||
switch (cmsysProcess_GetState(cp.get())) {
|
||||
case cmsysProcess_State_Exited:
|
||||
status = cmsysProcess_GetExitValue(cp.get());
|
||||
break;
|
||||
case cmsysProcess_State_Exception:
|
||||
status = 1;
|
||||
break;
|
||||
case cmsysProcess_State_Error:
|
||||
status = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
// remove the dependencies file because potentially invalid
|
||||
fout.close();
|
||||
cmSystemTools::RemoveFile(depFile);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
|
||||
const std::vector<std::string>& orig_cmd)
|
||||
{
|
||||
// Construct the iwyu command line by taking what was given
|
||||
// and adding all the arguments we give to the compiler.
|
||||
@@ -235,8 +356,8 @@ static int HandleIWYU(const std::string& runCmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
|
||||
const std::vector<std::string>& orig_cmd)
|
||||
int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
|
||||
const std::vector<std::string>& orig_cmd)
|
||||
{
|
||||
// Construct the clang-tidy command line by taking what was given
|
||||
// and adding our compiler command line. The clang-tidy tool will
|
||||
@@ -265,9 +386,8 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int HandleLWYU(const std::string& runCmd,
|
||||
const std::string& /* sourceFile */,
|
||||
const std::vector<std::string>&)
|
||||
int HandleLWYU(const std::string& runCmd, const std::string& /* sourceFile */,
|
||||
const std::vector<std::string>&)
|
||||
{
|
||||
// Construct the ldd -r -u (link what you use lwyu) command line
|
||||
// ldd -u -r lwuy target
|
||||
@@ -298,9 +418,8 @@ static int HandleLWYU(const std::string& runCmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HandleCppLint(const std::string& runCmd,
|
||||
const std::string& sourceFile,
|
||||
const std::vector<std::string>&)
|
||||
int HandleCppLint(const std::string& runCmd, const std::string& sourceFile,
|
||||
const std::vector<std::string>&)
|
||||
{
|
||||
// Construct the cpplint command line.
|
||||
std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
|
||||
@@ -326,9 +445,8 @@ static int HandleCppLint(const std::string& runCmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HandleCppCheck(const std::string& runCmd,
|
||||
const std::string& sourceFile,
|
||||
const std::vector<std::string>& orig_cmd)
|
||||
int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile,
|
||||
const std::vector<std::string>& orig_cmd)
|
||||
{
|
||||
// Construct the cpplint command line.
|
||||
std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
|
||||
@@ -391,7 +509,7 @@ struct CoCompiler
|
||||
bool NoOriginalCommand;
|
||||
};
|
||||
|
||||
static const std::array<CoCompiler, 5> CoCompilers = {
|
||||
const std::array<CoCompiler, 5> CoCompilers = {
|
||||
{ // Table of options and handlers.
|
||||
{ "--cppcheck=", HandleCppCheck, false },
|
||||
{ "--cpplint=", HandleCppLint, false },
|
||||
@@ -405,6 +523,7 @@ struct CoCompileJob
|
||||
std::string Command;
|
||||
CoCompileHandler Handler;
|
||||
};
|
||||
}
|
||||
|
||||
// called when args[0] == "__run_co_compile"
|
||||
int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
|
||||
@@ -586,7 +705,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
||||
} else if (args[2] == "--ignore-eol") {
|
||||
filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
|
||||
} else {
|
||||
::CMakeCommandUsage(args[0].c_str());
|
||||
CMakeCommandUsage(args[0].c_str());
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -621,8 +740,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
}
|
||||
if (outValid) {
|
||||
// The def file already exists and all input files are older than the
|
||||
// existing def file.
|
||||
// The def file already exists and all input files are older than
|
||||
// the existing def file.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1162,6 +1281,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
|
||||
// Internal CMake compiler dependencies filtering
|
||||
if (args[1] == "cmake_cl_compile_depends") {
|
||||
return CLCompileAndDependencies(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Internal CMake link script support.
|
||||
if (args[1] == "cmake_link_script" && args.size() >= 3) {
|
||||
return cmcmd::ExecuteLinkScript(args);
|
||||
@@ -1412,7 +1538,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
}
|
||||
|
||||
::CMakeCommandUsage(args[0].c_str());
|
||||
CMakeCommandUsage(args[0].c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1779,8 +1905,8 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
|
||||
skipNextArg = false;
|
||||
continue;
|
||||
}
|
||||
// We use ++ as seperator between the preprocessing step definition and the
|
||||
// rc compilation step becase we need to prepend a -- to seperate the
|
||||
// We use ++ as seperator between the preprocessing step definition and
|
||||
// the rc compilation step becase we need to prepend a -- to seperate the
|
||||
// source file properly from other options when using clang-cl for
|
||||
// preprocessing.
|
||||
if (arg == "++") {
|
||||
@@ -1830,7 +1956,8 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
|
||||
return 1;
|
||||
}
|
||||
// Since we might have skipped the last argument to llvm-rc
|
||||
// we need to make sure the llvm-rc source file is present in the commandline
|
||||
// we need to make sure the llvm-rc source file is present in the
|
||||
// commandline
|
||||
if (resource_compile.back() != intermediate_file) {
|
||||
resource_compile.push_back(intermediate_file);
|
||||
}
|
||||
@@ -2123,8 +2250,8 @@ int cmVSLink::LinkIncremental()
|
||||
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
|
||||
|
||||
// 1. Compiler compiles the application and generates the *.obj files.
|
||||
// 2. An empty manifest file is generated if this is a clean build and if
|
||||
// not the previous one is reused.
|
||||
// 2. An empty manifest file is generated if this is a clean build and
|
||||
// if not the previous one is reused.
|
||||
// 3. The resource compiler (rc.exe) compiles the *.manifest file to a
|
||||
// *.res file.
|
||||
// 4. Linker generates the binary (EXE or DLL) with the /incremental
|
||||
|
||||
@@ -102,6 +102,12 @@ target_link_libraries(zot zot_pch)
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
|
||||
target_precompile_headers(zot_pch PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/zot_pch.hxx)
|
||||
endif()
|
||||
if (CMAKE_CXX_DEPENDS_USE_COMPILER AND
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.4")
|
||||
# Mixing pre-compile headers and flags to generate dependencies (-M options family)
|
||||
# causes the compiler to crash
|
||||
set_property(TARGET zot_pch PROPERTY DISABLE_PRECOMPILE_HEADERS ON)
|
||||
endif()
|
||||
|
||||
# Test the #include line macro transformation rule support.
|
||||
set_property(
|
||||
|
||||
@@ -67,7 +67,11 @@ else()
|
||||
endif()
|
||||
|
||||
# Test escaping of special characters in include directory paths.
|
||||
set(special_chars "~@%&{}()!'")
|
||||
set(special_chars "~@&{}()!'")
|
||||
if(NOT CMAKE_GENERATOR MATCHES "(Unix|MinGW|MSYS) Makefiles")
|
||||
# when compiler is used for dependencies, special characters for make are not escaped
|
||||
string(APPEND special_chars "%")
|
||||
endif()
|
||||
if(NOT CMAKE_GENERATOR STREQUAL "Watcom WMake")
|
||||
# Watcom seems to have no way to encode these characters.
|
||||
string(APPEND special_chars "#=[]")
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
enable_language(C)
|
||||
|
||||
add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
|
||||
|
||||
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
|
||||
set(check_pairs
|
||||
\"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
|
||||
\"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.h\"
|
||||
)
|
||||
set(check_exes
|
||||
\"$<TARGET_FILE:main>\"
|
||||
)
|
||||
|
||||
if (check_step EQUAL 2)
|
||||
include(\"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Makefile.cmake\")
|
||||
if (NOT CMAKE_DEPEND_INFO_FILES)
|
||||
set(RunCMake_TEST_FAILED \"Variable CMAKE_DEPEND_INFO_FILES not found.\")
|
||||
else()
|
||||
include(\"${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_DEPEND_INFO_FILES}\")
|
||||
if (NOT CMAKE_DEPENDS_DEPENDENCY_FILES)
|
||||
set(RunCMake_TEST_FAILED \"Variable CMAKE_DEPENDS_DEPENDENCY_FILES not found.\")
|
||||
else()
|
||||
list(GET CMAKE_DEPENDS_DEPENDENCY_FILES 1 OBJECT_FILE)
|
||||
list(GET CMAKE_DEPENDS_DEPENDENCY_FILES 3 DEP_FILE)
|
||||
if (NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/\${DEP_FILE}\")
|
||||
set(RunCMake_TEST_FAILED \"File \${DEP_FILE} not found.\")
|
||||
else()
|
||||
set (TARGET_DEP_FILE \"${CMAKE_CURRENT_BINARY_DIR}/\${DEP_FILE}\")
|
||||
cmake_path(REPLACE_FILENAME TARGET_DEP_FILE \"compiler_depend.make\")
|
||||
file(READ \"\${TARGET_DEP_FILE}\" DEPENDS_CONTENT)
|
||||
if (WIN32)
|
||||
string (REPLACE \"\\\\\" \"/\" DEPENDS_CONTENT \"\${DEPENDS_CONTENT}\")
|
||||
string (TOLOWER \"\${DEPENDS_CONTENT}\" DEPENDS_CONTENT)
|
||||
string (TOLOWER \"\${OBJECT_FILE}\" OBJECT_FILE)
|
||||
else()
|
||||
string(REPLACE \"\\\\ \" \" \" DEPENDS_CONTENT \"\${DEPENDS_CONTENT}\")
|
||||
endif()
|
||||
if(NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c\"
|
||||
OR NOT DEPENDS_CONTENT MATCHES \"main.h\")
|
||||
set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated.\")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
")
|
||||
@@ -0,0 +1,9 @@
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h" [[
|
||||
#define COUNT 1
|
||||
]])
|
||||
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
|
||||
#include "main.h"
|
||||
|
||||
int main(void) { return COUNT; }
|
||||
]])
|
||||
@@ -0,0 +1,3 @@
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h" [[
|
||||
#define COUNT 2
|
||||
]])
|
||||
@@ -113,3 +113,13 @@ if(CMake_TEST_BuildDepends_GNU_AS)
|
||||
set(ENV{ASM} "${CMake_TEST_BuildDepends_GNU_AS}")
|
||||
run_BuildDepends(GNU-AS)
|
||||
endif()
|
||||
|
||||
if ((RunCMake_GENERATOR STREQUAL "Unix Makefiles"
|
||||
AND (CMAKE_C_COMPILER_ID STREQUAL "GNU"
|
||||
OR CMAKE_C_COMPILER_ID STREQUAL "Clang"
|
||||
OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"))
|
||||
OR (RunCMake_GENERATOR STREQUAL "NMake Makefiles"
|
||||
AND MSVC_VERSION GREATER 1300
|
||||
AND CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
|
||||
run_BuildDepends(CompilerDependencies)
|
||||
endif()
|
||||
|
||||
@@ -204,7 +204,10 @@ if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
|
||||
set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_RunCMake_test(BuildDepends
|
||||
-DMSVC_VERSION=${MSVC_VERSION}
|
||||
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
|
||||
-DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
|
||||
)
|
||||
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_TARGET_MESSAGES OFF)
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/TargetMessages-validation.cmake")
|
||||
@@ -1,5 +1 @@
|
||||
^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*
|
||||
)*Scanning dependencies of target CustomTarget(
|
||||
([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*)*$
|
||||
.*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_TARGET_MESSAGES ON)
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/TargetMessages-validation.cmake")
|
||||
@@ -1,8 +1 @@
|
||||
^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*
|
||||
)*Scanning dependencies of target CustomTarget(
|
||||
([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*)*
|
||||
Built target CustomTarget(
|
||||
([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*)*$
|
||||
.*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_TARGET_MESSAGES OFF)
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/TargetMessages-validation.cmake")
|
||||
@@ -1,5 +1 @@
|
||||
^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*
|
||||
)*Scanning dependencies of target CustomTarget(
|
||||
([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*)*$
|
||||
.*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_TARGET_MESSAGES ON)
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/TargetMessages-validation.cmake")
|
||||
@@ -1,8 +1 @@
|
||||
^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*
|
||||
)*Scanning dependencies of target CustomTarget(
|
||||
([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*)*
|
||||
Built target CustomTarget(
|
||||
([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
|
||||
]*)*$
|
||||
.*
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
if (CHECK_TARGET_MESSAGES)
|
||||
if (NOT actual_stdout MATCHES "Built target CustomTarget")
|
||||
set (RunCMake_TEST_FAILED "Not found expected 'Built target' message.")
|
||||
endif()
|
||||
else()
|
||||
if (actual_stdout MATCHES "Built target CustomTarget")
|
||||
set (RunCMake_TEST_FAILED "Found unexpected 'Built target' message.")
|
||||
endif()
|
||||
endif()
|
||||
@@ -1054,12 +1054,14 @@ else
|
||||
CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
|
||||
cmDepends \
|
||||
cmDependsC \
|
||||
cmDependsCompiler \
|
||||
cmGlobalUnixMakefileGenerator3 \
|
||||
cmLocalUnixMakefileGenerator3 \
|
||||
cmMakefileExecutableTargetGenerator \
|
||||
cmMakefileLibraryTargetGenerator \
|
||||
cmMakefileTargetGenerator \
|
||||
cmMakefileUtilityTargetGenerator \
|
||||
cmProcessTools \
|
||||
"
|
||||
|
||||
JSONCPP_CXX_SOURCES=
|
||||
|
||||
Reference in New Issue
Block a user