mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-12 17:19:05 -05:00
Makefiles Generators: use compiler for dependencies generation
Each source compilation generates a dependencies file. These dependencies files are consolidated in one file per target. This consolidation is done as part of command 'cmake -E cmake_depends` launched before evaluation of makefile dependency graph. The consolidation uses the same approach as `CMake` dependencies management. Fixes: #21321
This commit is contained in:
@@ -387,6 +387,7 @@ Variables that Control the Build
|
|||||||
/variable/CMAKE_DEFAULT_BUILD_TYPE
|
/variable/CMAKE_DEFAULT_BUILD_TYPE
|
||||||
/variable/CMAKE_DEFAULT_CONFIGS
|
/variable/CMAKE_DEFAULT_CONFIGS
|
||||||
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
|
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
|
||||||
|
/variable/CMAKE_DEPENDS_USE_COMPILER
|
||||||
/variable/CMAKE_ENABLE_EXPORTS
|
/variable/CMAKE_ENABLE_EXPORTS
|
||||||
/variable/CMAKE_EXE_LINKER_FLAGS
|
/variable/CMAKE_EXE_LINKER_FLAGS
|
||||||
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
|
/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")
|
set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
|
||||||
endif()
|
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}" "")
|
foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
|
||||||
CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}")
|
CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -1,6 +1,18 @@
|
|||||||
include(Compiler/Clang)
|
include(Compiler/Clang)
|
||||||
__compiler_clang(C)
|
__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)
|
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
|
||||||
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||||
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||||
|
|||||||
@@ -2,6 +2,14 @@ include(Compiler/Clang)
|
|||||||
__compiler_clang(CXX)
|
__compiler_clang(CXX)
|
||||||
|
|
||||||
if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
|
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")
|
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
include(Compiler/Clang-OBJC)
|
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)
|
if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 4.0)
|
||||||
set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
|
set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||||
set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
include(Compiler/Clang-OBJCXX)
|
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")
|
set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||||
|
|
||||||
if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.0)
|
if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.0)
|
||||||
|
|||||||
@@ -8,6 +8,19 @@ endif()
|
|||||||
|
|
||||||
if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||||
set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
|
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()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
|
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ __compiler_clang(CUDA)
|
|||||||
|
|
||||||
# Set explicitly, because __compiler_clang() doesn't set this if we're simulating MSVC.
|
# Set explicitly, because __compiler_clang() doesn't set this if we're simulating MSVC.
|
||||||
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
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.
|
# 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.
|
# Do this before __compiler_clang_cxx_standards() since that adds the feature.
|
||||||
|
|||||||
@@ -3,6 +3,14 @@ __compiler_clang(CXX)
|
|||||||
__compiler_clang_cxx_standards(CXX)
|
__compiler_clang_cxx_standards(CXX)
|
||||||
|
|
||||||
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
|
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")
|
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -13,4 +21,9 @@ endif()
|
|||||||
|
|
||||||
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||||
set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
|
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()
|
endif()
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
include(Compiler/Clang)
|
include(Compiler/Clang)
|
||||||
__compiler_clang(OBJC)
|
__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)
|
if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 3.4)
|
||||||
set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
|
set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||||
set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
include(Compiler/Clang)
|
include(Compiler/Clang)
|
||||||
__compiler_clang(OBJCXX)
|
__compiler_clang(OBJCXX)
|
||||||
__compiler_clang_cxx_standards(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()
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
include(Compiler/GNU)
|
include(Compiler/GNU)
|
||||||
__compiler_gnu(C)
|
__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)
|
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
|
||||||
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||||
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
include(Compiler/GNU)
|
include(Compiler/GNU)
|
||||||
__compiler_gnu(CXX)
|
__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 (WIN32)
|
||||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
|
||||||
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
|
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
|
||||||
|
|||||||
@@ -1,2 +1,11 @@
|
|||||||
include(Compiler/GNU)
|
include(Compiler/GNU)
|
||||||
__compiler_gnu(OBJC)
|
__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)
|
include(Compiler/GNU)
|
||||||
__compiler_gnu(OBJCXX)
|
__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)
|
if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.2)
|
||||||
set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -DNDEBUG")
|
|||||||
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG")
|
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG")
|
||||||
|
|
||||||
set(CMAKE_DEPFILE_FLAGS_C "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
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")
|
if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -DNDEBUG")
|
|||||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG")
|
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG")
|
||||||
|
|
||||||
set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
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")
|
if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ include(Compiler/CMakeCommonCompilerMacros)
|
|||||||
#set(CMAKE_ISPC_VERBOSE_FLAG )
|
#set(CMAKE_ISPC_VERBOSE_FLAG )
|
||||||
|
|
||||||
set(CMAKE_DEPFILE_FLAGS_ISPC "-M -MT <DEP_TARGET> -MF <DEP_FILE>")
|
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_INIT " ")
|
||||||
string(APPEND CMAKE_ISPC_FLAGS_DEBUG_INIT "-O0 -g")
|
string(APPEND CMAKE_ISPC_FLAGS_DEBUG_INIT "-O0 -g")
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89)
|
|||||||
# to get header dependency information
|
# to get header dependency information
|
||||||
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
|
||||||
endif()
|
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")
|
if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||||
set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE)
|
set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE)
|
||||||
|
|||||||
@@ -1,2 +1,18 @@
|
|||||||
include(Platform/Windows-Clang)
|
include(Platform/Windows-Clang)
|
||||||
__windows_compiler_clang(C)
|
__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)
|
include(Platform/Windows-Clang)
|
||||||
set(_COMPILE_CXX_MSVC " -TP")
|
set(_COMPILE_CXX_MSVC " -TP")
|
||||||
__windows_compiler_clang(CXX)
|
__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()
|
||||||
|
|||||||
@@ -2,3 +2,10 @@ include(Platform/Windows-Intel)
|
|||||||
__windows_compiler_intel(C)
|
__windows_compiler_intel(C)
|
||||||
set(CMAKE_NINJA_DEPTYPE_C intel) # special value handled by CMake
|
set(CMAKE_NINJA_DEPTYPE_C intel) # special value handled by CMake
|
||||||
set(CMAKE_DEPFILE_FLAGS_C "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
|
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()
|
||||||
|
|||||||
@@ -3,3 +3,10 @@ set(_COMPILE_CXX " /TP")
|
|||||||
__windows_compiler_intel(CXX)
|
__windows_compiler_intel(CXX)
|
||||||
set(CMAKE_NINJA_DEPTYPE_CXX intel) # special value handled by CMake
|
set(CMAKE_NINJA_DEPTYPE_CXX intel) # special value handled by CMake
|
||||||
set(CMAKE_DEPFILE_FLAGS_CXX "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
|
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")
|
set(_FS_C " /FS")
|
||||||
endif()
|
endif()
|
||||||
__windows_compiler_msvc(C)
|
__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")
|
set(_FS_CXX " /FS")
|
||||||
endif()
|
endif()
|
||||||
__windows_compiler_msvc(CXX)
|
__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_${lang}_LINKER_SUPPORTS_PDB ON)
|
||||||
set(CMAKE_NINJA_DEPTYPE_${lang} msvc)
|
set(CMAKE_NINJA_DEPTYPE_${lang} msvc)
|
||||||
__windows_compiler_msvc_enable_rc("${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}")
|
__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()
|
endmacro()
|
||||||
|
|
||||||
macro(__windows_compiler_msvc_enable_rc flags)
|
macro(__windows_compiler_msvc_enable_rc flags)
|
||||||
|
|||||||
@@ -224,6 +224,8 @@ set(SRCS
|
|||||||
cmDependsJava.h
|
cmDependsJava.h
|
||||||
cmDependsJavaParserHelper.cxx
|
cmDependsJavaParserHelper.cxx
|
||||||
cmDependsJavaParserHelper.h
|
cmDependsJavaParserHelper.h
|
||||||
|
cmDependsCompiler.cxx
|
||||||
|
cmDependsCompiler.h
|
||||||
cmDocumentation.cxx
|
cmDocumentation.cxx
|
||||||
cmDocumentationFormatter.cxx
|
cmDocumentationFormatter.cxx
|
||||||
cmDocumentationSection.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;
|
||||||
|
};
|
||||||
@@ -127,6 +127,12 @@ public:
|
|||||||
void WriteConvenienceRules(std::ostream& ruleFileStream,
|
void WriteConvenienceRules(std::ostream& ruleFileStream,
|
||||||
std::set<std::string>& emitted);
|
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
|
/** Get the command to use for a target that has no rule. This is
|
||||||
used for multiple output dependencies and for cmake_force. */
|
used for multiple output dependencies and for cmake_force. */
|
||||||
std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
|
std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
|
||||||
@@ -219,6 +225,10 @@ protected:
|
|||||||
|
|
||||||
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
|
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
|
// Some make programs (Borland) do not keep a rule if there are no
|
||||||
// dependencies or commands. This is a problem for creating rules
|
// dependencies or commands. This is a problem for creating rules
|
||||||
// that might not do anything but might have other dependencies
|
// that might not do anything but might have other dependencies
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <functional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
#include "cmCMakePath.h"
|
#include "cmCMakePath.h"
|
||||||
#include "cmCustomCommand.h" // IWYU pragma: keep
|
#include "cmCustomCommand.h" // IWYU pragma: keep
|
||||||
#include "cmCustomCommandGenerator.h"
|
#include "cmCustomCommandGenerator.h"
|
||||||
|
#include "cmDependsCompiler.h"
|
||||||
#include "cmFileTimeCache.h"
|
#include "cmFileTimeCache.h"
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
@@ -52,8 +54,9 @@
|
|||||||
# include "cmDependsJava.h"
|
# include "cmDependsJava.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
// Helper function used below.
|
// 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 ext;
|
||||||
std::string::size_type dot_pos = in.rfind('.');
|
std::string::size_type dot_pos = in.rfind('.');
|
||||||
@@ -67,6 +70,43 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
|
|||||||
return ext;
|
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(
|
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
|
||||||
cmGlobalGenerator* gg, cmMakefile* mf)
|
cmGlobalGenerator* gg, cmMakefile* mf)
|
||||||
: cmLocalCommonGenerator(gg, mf, mf->GetCurrentBinaryDirectory())
|
: cmLocalCommonGenerator(gg, mf, mf->GetCurrentBinaryDirectory())
|
||||||
@@ -554,8 +594,10 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the list of commands.
|
if (!commands.empty()) {
|
||||||
os << cmWrap("\t", commands, "", "\n") << "\n";
|
// Write the list of commands.
|
||||||
|
os << cmWrap("\t", commands, "", "\n") << "\n";
|
||||||
|
}
|
||||||
if (symbolic && !this->IsWatcomWMake()) {
|
if (symbolic && !this->IsWatcomWMake()) {
|
||||||
os << ".PHONY : " << tgt << "\n";
|
os << ".PHONY : " << tgt << "\n";
|
||||||
}
|
}
|
||||||
@@ -1300,91 +1342,153 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
|
|||||||
cmSystemTools::Error("Target DependInfo.cmake file not found");
|
cmSystemTools::Error("Target DependInfo.cmake file not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool status = true;
|
||||||
|
|
||||||
// Check if any multiple output pairs have a missing file.
|
// Check if any multiple output pairs have a missing file.
|
||||||
this->CheckMultipleOutputs(verbose);
|
this->CheckMultipleOutputs(verbose);
|
||||||
|
|
||||||
std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);
|
std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);
|
||||||
std::string const internalDependFile = targetDir + "/depend.internal";
|
if (!this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
|
||||||
std::string const dependFile = targetDir + "/depend.make";
|
// dependencies are managed by CMake itself
|
||||||
|
|
||||||
// If the target DependInfo.cmake file has changed since the last
|
std::string const internalDependFile = targetDir + "/depend.internal";
|
||||||
// time dependencies were scanned then force rescanning. This may
|
std::string const dependFile = targetDir + "/depend.make";
|
||||||
// happen when a new source file is added and CMake regenerates the
|
|
||||||
// project but no other sources were touched.
|
// If the target DependInfo.cmake file has changed since the last
|
||||||
bool needRescanDependInfo = false;
|
// time dependencies were scanned then force rescanning. This may
|
||||||
cmFileTimeCache* ftc =
|
// happen when a new source file is added and CMake regenerates the
|
||||||
this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
|
// project but no other sources were touched.
|
||||||
{
|
bool needRescanDependInfo = false;
|
||||||
int result;
|
cmFileTimeCache* ftc =
|
||||||
if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
|
this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
|
||||||
if (verbose) {
|
{
|
||||||
cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
|
int result;
|
||||||
"\" is newer than depender \"",
|
if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
|
||||||
internalDependFile, "\".\n"));
|
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
|
auto depends =
|
||||||
// may have changed. In this case discard all old dependencies.
|
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
|
||||||
bool needRescanDirInfo = false;
|
if (!depends.empty()) {
|
||||||
{
|
// dependencies are managed by compiler
|
||||||
std::string dirInfoFile =
|
auto depFiles = cmExpandedList(depends);
|
||||||
cmStrCat(this->GetCurrentBinaryDirectory(),
|
std::string const internalDepFile =
|
||||||
"/CMakeFiles/CMakeDirectoryInformation.cmake");
|
targetDir + "/compiler_depend.internal";
|
||||||
int result;
|
std::string const depFile = targetDir + "/compiler_depend.make";
|
||||||
if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
|
cmDepends::DependencyMap dependencies;
|
||||||
result < 0) {
|
cmDependsCompiler depsManager;
|
||||||
if (verbose) {
|
bool projectOnly = cmIsOn(
|
||||||
cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
|
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_IN_PROJECT_ONLY"));
|
||||||
"\" is newer than depender \"",
|
|
||||||
internalDependFile, "\".\n"));
|
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.
|
// The dependencies are already up-to-date.
|
||||||
return true;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmLocalUnixMakefileGenerator3::ScanDependencies(
|
bool cmLocalUnixMakefileGenerator3::ScanDependencies(
|
||||||
@@ -1723,166 +1827,193 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
|
|||||||
cmDepends clearer;
|
cmDepends clearer;
|
||||||
clearer.SetVerbose(verbose);
|
clearer.SetVerbose(verbose);
|
||||||
for (std::string const& file : files) {
|
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.
|
if (!lmf.GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
|
||||||
std::string dependFile = dir + "/depend.make";
|
std::string dir = cmSystemTools::GetFilenamePath(file);
|
||||||
clearer.Clear(dependFile);
|
|
||||||
|
|
||||||
// Remove the internal dependency check file to force
|
// Clear the implicit dependency makefile.
|
||||||
// regeneration.
|
std::string dependFile = dir + "/depend.make";
|
||||||
std::string internalDependFile = dir + "/depend.internal";
|
clearer.Clear(dependFile);
|
||||||
cmSystemTools::RemoveFile(internalDependFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
// Remove the internal dependency check file to force
|
||||||
// Helper predicate for removing absolute paths that don't point to the
|
// regeneration.
|
||||||
// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
|
std::string internalDependFile = dir + "/depend.internal";
|
||||||
// is set ON, to only consider in-project dependencies during the build.
|
cmSystemTools::RemoveFile(internalDependFile);
|
||||||
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:
|
auto depsFiles = lmf.GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
|
||||||
// The path to the source directory
|
if (!depsFiles.empty()) {
|
||||||
cm::string_view SourceDir;
|
auto dir = cmCMakePath(file).GetParentPath();
|
||||||
// The path to the binary directory
|
// Clear the implicit dependency makefile.
|
||||||
cm::string_view BinaryDir;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
|
void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
|
||||||
std::ostream& cmakefileStream, cmGeneratorTarget* target)
|
std::ostream& cmakefileStream, cmGeneratorTarget* target)
|
||||||
{
|
{
|
||||||
ImplicitDependLanguageMap const& implicitLangs =
|
// To enable dependencies filtering
|
||||||
this->GetImplicitDepends(target);
|
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
|
// list the languages
|
||||||
cmakefileStream
|
cmakefileStream << "# The set of languages for which implicit "
|
||||||
<< "# The set of languages for which implicit dependencies are needed:\n";
|
"dependencies are needed:\n";
|
||||||
cmakefileStream << "set(CMAKE_DEPENDS_LANGUAGES\n";
|
cmakefileStream << "set(CMAKE_DEPENDS_LANGUAGES\n";
|
||||||
for (auto const& implicitLang : implicitLangs) {
|
for (auto const& implicitLang : implicitLangs) {
|
||||||
cmakefileStream << " \"" << implicitLang.first << "\"\n";
|
cmakefileStream << " \"" << implicitLang.first << "\"\n";
|
||||||
}
|
}
|
||||||
cmakefileStream << " )\n";
|
cmakefileStream << " )\n";
|
||||||
|
|
||||||
// now list the files for each language
|
if (!implicitLangs.empty()) {
|
||||||
cmakefileStream
|
// now list the files for each language
|
||||||
<< "# The set of files for implicit dependencies of each language:\n";
|
cmakefileStream
|
||||||
for (auto const& implicitLang : implicitLangs) {
|
<< "# The set of files for implicit dependencies of each language:\n";
|
||||||
cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << implicitLang.first
|
for (auto const& implicitLang : implicitLangs) {
|
||||||
<< "\n";
|
const auto& lang = implicitLang.first;
|
||||||
ImplicitDependFileMap const& implicitPairs = implicitLang.second;
|
|
||||||
|
|
||||||
// for each file pair
|
cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << lang << "\n";
|
||||||
for (auto const& implicitPair : implicitPairs) {
|
auto const& implicitPairs = implicitLang.second;
|
||||||
for (auto const& di : implicitPair.second) {
|
|
||||||
cmakefileStream << " \"" << di << "\" ";
|
// for each file pair
|
||||||
cmakefileStream << "\"" << implicitPair.first << "\"\n";
|
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.
|
// Tell the dependency scanner what compiler is used.
|
||||||
std::string cidVar =
|
std::string cidVar = cmStrCat("CMAKE_", lang, "_COMPILER_ID");
|
||||||
cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
|
cmProp cid = this->Makefile->GetDefinition(cidVar);
|
||||||
cmProp cid = this->Makefile->GetDefinition(cidVar);
|
if (cmNonempty(cid)) {
|
||||||
if (cmNonempty(cid)) {
|
cmakefileStream << "set(CMAKE_" << lang << "_COMPILER_ID \"" << *cid
|
||||||
cmakefileStream << "set(CMAKE_" << implicitLang.first
|
<< "\")\n";
|
||||||
<< "_COMPILER_ID \"" << *cid << "\")\n";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (implicitLang.first == "Fortran") {
|
if (lang == "Fortran") {
|
||||||
std::string smodSep =
|
std::string smodSep =
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
|
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
|
||||||
std::string smodExt =
|
std::string smodExt =
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
|
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
|
||||||
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
|
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
|
||||||
<< "\")\n";
|
<< "\")\n";
|
||||||
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
|
cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
|
||||||
<< "\")\n";
|
<< "\")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a list of preprocessor definitions for the target.
|
// Build a list of preprocessor definitions for the target.
|
||||||
std::set<std::string> defines;
|
std::set<std::string> defines;
|
||||||
this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
|
this->GetTargetDefines(target, this->GetConfigName(), lang, defines);
|
||||||
defines);
|
if (!defines.empty()) {
|
||||||
if (!defines.empty()) {
|
/* clang-format off */
|
||||||
/* clang-format off */
|
|
||||||
cmakefileStream
|
cmakefileStream
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< "# Preprocessor definitions for this target.\n"
|
<< "# Preprocessor definitions for this target.\n"
|
||||||
<< "set(CMAKE_TARGET_DEFINITIONS_" << implicitLang.first << "\n";
|
<< "set(CMAKE_TARGET_DEFINITIONS_" << lang << "\n";
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
for (std::string const& define : defines) {
|
for (std::string const& define : defines) {
|
||||||
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(define)
|
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(define)
|
||||||
<< "\n";
|
<< "\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";
|
cmakefileStream << " )\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Target-specific include directories:
|
// Store include transform rule properties. Write the directory
|
||||||
cmakefileStream << "\n"
|
// rules first because they may be overridden by later target rules.
|
||||||
<< "# The include file search paths:\n";
|
std::vector<std::string> transformRules;
|
||||||
cmakefileStream << "set(CMAKE_" << implicitLang.first
|
if (cmProp xform =
|
||||||
<< "_TARGET_INCLUDE_PATH\n";
|
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
||||||
std::vector<std::string> includes;
|
cmExpandList(*xform, transformRules);
|
||||||
|
|
||||||
this->GetIncludeDirectories(includes, target, implicitLang.first,
|
|
||||||
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) {
|
if (cmProp xform =
|
||||||
cmakefileStream << " \""
|
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
||||||
<< this->MaybeConvertToRelativePath(binaryDir, include)
|
cmExpandList(*xform, transformRules);
|
||||||
<< "\"\n";
|
}
|
||||||
|
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
|
auto const& compilerLangs =
|
||||||
// rules first because they may be overridden by later target rules.
|
this->GetImplicitDepends(target, cmDependencyScannerKind::Compiler);
|
||||||
std::vector<std::string> transformRules;
|
|
||||||
if (cmProp xform =
|
// list the dependency files managed by the compiler
|
||||||
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
cmakefileStream << "\n# The set of dependency files which are needed:\n";
|
||||||
cmExpandList(*xform, transformRules);
|
cmakefileStream << "set(CMAKE_DEPENDS_DEPENDENCY_FILES\n";
|
||||||
}
|
for (auto const& compilerLang : compilerLangs) {
|
||||||
if (cmProp xform =
|
auto depFormat = this->Makefile->GetSafeDefinition(
|
||||||
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
|
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
|
||||||
cmExpandList(*xform, transformRules);
|
auto const& compilerPairs = compilerLang.second;
|
||||||
}
|
for (auto const& compilerPair : compilerPairs) {
|
||||||
if (!transformRules.empty()) {
|
for (auto const& src : compilerPair.second) {
|
||||||
cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
|
cmakefileStream << " \"" << src << "\" \""
|
||||||
for (std::string const& tr : transformRules) {
|
<< this->MaybeConvertToRelativePath(
|
||||||
cmakefileStream << " " << cmOutputConverter::EscapeForCMake(tr) << "\n";
|
this->GetBinaryDirectory(), compilerPair.first)
|
||||||
|
<< "\" \"" << depFormat << "\" \""
|
||||||
|
<< this->MaybeConvertToRelativePath(
|
||||||
|
this->GetBinaryDirectory(), compilerPair.first)
|
||||||
|
<< ".d\"\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmakefileStream << " )\n";
|
|
||||||
}
|
}
|
||||||
|
cmakefileStream << " )\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
|
void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <cm/memory>
|
#include <cm/memory>
|
||||||
|
#include <cm/string_view>
|
||||||
#include <cmext/algorithm>
|
#include <cmext/algorithm>
|
||||||
|
#include <cmext/string_view>
|
||||||
|
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
#include "cmCustomCommand.h"
|
#include "cmCustomCommand.h"
|
||||||
@@ -326,7 +328,45 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
|
|||||||
<< cmSystemTools::ConvertToOutputPath(
|
<< cmSystemTools::ConvertToOutputPath(
|
||||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||||
this->LocalGenerator->GetBinaryDirectory(), dependFileNameFull))
|
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) {
|
if (!this->NoRuleMessages) {
|
||||||
// Include the progress variables for the target.
|
// Include the progress variables for the target.
|
||||||
@@ -473,6 +513,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
return;
|
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.
|
// Get the full path name of the object file.
|
||||||
std::string const& objectName =
|
std::string const& objectName =
|
||||||
this->GeneratorTarget->GetObjectName(&source);
|
this->GeneratorTarget->GetObjectName(&source);
|
||||||
@@ -512,7 +560,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
std::string srcFullPath =
|
std::string srcFullPath =
|
||||||
cmSystemTools::CollapseFullPath(source.GetFullPath());
|
cmSystemTools::CollapseFullPath(source.GetFullPath());
|
||||||
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
||||||
objFullPath, srcFullPath);
|
objFullPath, srcFullPath, scanner);
|
||||||
|
|
||||||
this->LocalGenerator->AppendRuleDepend(depends,
|
this->LocalGenerator->AppendRuleDepend(depends,
|
||||||
this->FlagFileNameFull.c_str());
|
this->FlagFileNameFull.c_str());
|
||||||
@@ -554,8 +602,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
depends.push_back(
|
depends.push_back(
|
||||||
this->GeneratorTarget->GetPchFile(config, lang, arch));
|
this->GeneratorTarget->GetPchFile(config, lang, arch));
|
||||||
}
|
}
|
||||||
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
this->LocalGenerator->AddImplicitDepends(
|
||||||
objFullPath, pchHeader);
|
this->GeneratorTarget, lang, objFullPath, pchHeader, scanner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,7 +737,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
source.GetFullPath(), cmOutputConverter::SHELL);
|
source.GetFullPath(), cmOutputConverter::SHELL);
|
||||||
|
|
||||||
// Construct the build message.
|
// Construct the build message.
|
||||||
std::vector<std::string> no_commands;
|
std::vector<std::string> no_depends;
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
|
|
||||||
// add in a progress call if needed
|
// add in a progress call if needed
|
||||||
@@ -783,6 +831,26 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
"$(" + lang + "_INCLUDES)");
|
"$(" + lang + "_INCLUDES)");
|
||||||
vars.Includes = includesString.c_str();
|
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
|
// At the moment, it is assumed that C, C++, Fortran, and CUDA have both
|
||||||
// assembly and preprocessor capabilities. The same is true for the
|
// assembly and preprocessor capabilities. The same is true for the
|
||||||
// ability to export compile commands
|
// ability to export compile commands
|
||||||
@@ -954,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.
|
// Expand placeholders in the commands.
|
||||||
for (std::string& compileCommand : compileCommands) {
|
for (std::string& compileCommand : compileCommands) {
|
||||||
compileCommand = cmStrCat(launcher, compileCommand);
|
compileCommand = cmStrCat(launcher, compileCommand);
|
||||||
@@ -979,8 +1094,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
cmExpandList(evaluated_outputs, outputs);
|
cmExpandList(evaluated_outputs, outputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ispcHeaderRelative
|
if (!ispcHeaderRelative.empty()) {
|
||||||
.empty()) { // can't move ispcHeader as vars is using it
|
// can't move ispcHeader as vars is using it
|
||||||
outputs.emplace_back(ispcHeaderRelative);
|
outputs.emplace_back(ispcHeaderRelative);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,10 +1103,19 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
|
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compilerGenerateDeps) {
|
||||||
|
depends.push_back(dependencyTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
// Write the rule.
|
// Write the rule.
|
||||||
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
|
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
|
||||||
commands);
|
commands);
|
||||||
|
|
||||||
|
if (compilerGenerateDeps) {
|
||||||
|
// set back flags without dependency generation
|
||||||
|
vars.Flags = flags.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
bool do_preprocess_rules = lang_has_preprocessor &&
|
bool do_preprocess_rules = lang_has_preprocessor &&
|
||||||
this->LocalGenerator->GetCreatePreprocessedSourceRules();
|
this->LocalGenerator->GetCreatePreprocessedSourceRules();
|
||||||
bool do_assembly_rules =
|
bool do_assembly_rules =
|
||||||
@@ -1388,10 +1512,10 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
|
|||||||
|
|
||||||
std::string registerFileCmd;
|
std::string registerFileCmd;
|
||||||
|
|
||||||
// The generated register file contains macros that when expanded register
|
// The generated register file contains macros that when expanded
|
||||||
// the device routines. Because the routines are the same for all
|
// register the device routines. Because the routines are the same for
|
||||||
// architectures the register file will be the same too. Thus generate it
|
// all architectures the register file will be the same too. Thus
|
||||||
// only on the first invocation to reduce overhead.
|
// generate it only on the first invocation to reduce overhead.
|
||||||
if (fatbinaryDepends.size() == 1) {
|
if (fatbinaryDepends.size() == 1) {
|
||||||
std::string registerFileRel =
|
std::string registerFileRel =
|
||||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||||
@@ -1426,7 +1550,8 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
|
|||||||
fatbinaryOutputRel, fatbinaryDepends,
|
fatbinaryOutputRel, fatbinaryDepends,
|
||||||
{ fatbinaryCommand }, false);
|
{ 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;
|
cmRulePlaceholderExpander::RuleVariables vars;
|
||||||
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
||||||
vars.CMTargetType =
|
vars.CMTargetType =
|
||||||
@@ -1839,9 +1964,9 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects(
|
|||||||
if (size_t const limit = cmSystemTools::CalculateCommandLineLengthLimit()) {
|
if (size_t const limit = cmSystemTools::CalculateCommandLineLengthLimit()) {
|
||||||
// Compute the total length of our list of object files with room
|
// Compute the total length of our list of object files with room
|
||||||
// for argument separation and quoting. This does not convert paths
|
// for argument separation and quoting. This does not convert paths
|
||||||
// relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so the
|
// relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so
|
||||||
// actual list will likely be much shorter than this. However, in the
|
// the actual list will likely be much shorter than this. However, in
|
||||||
// worst case all objects will remain as absolute paths.
|
// the worst case all objects will remain as absolute paths.
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
for (std::string const& obj : this->Objects) {
|
for (std::string const& obj : this->Objects) {
|
||||||
length += obj.size() + 3;
|
length += obj.size() + 3;
|
||||||
|
|||||||
+155
-28
@@ -33,6 +33,13 @@
|
|||||||
# include "bindexplib.h"
|
# include "bindexplib.h"
|
||||||
#endif
|
#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__)
|
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
# include "cmVisualStudioWCEPlatformParser.h"
|
# include "cmVisualStudioWCEPlatformParser.h"
|
||||||
#endif
|
#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,
|
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
|
||||||
std::vector<std::string>::const_iterator argEnd);
|
std::vector<std::string>::const_iterator argEnd);
|
||||||
|
|
||||||
|
namespace {
|
||||||
void CMakeCommandUsage(const char* program)
|
void CMakeCommandUsage(const char* program)
|
||||||
{
|
{
|
||||||
std::ostringstream errorStream;
|
std::ostringstream errorStream;
|
||||||
@@ -144,8 +152,7 @@ void CMakeCommandUsage(const char* program)
|
|||||||
cmSystemTools::Error(errorStream.str());
|
cmSystemTools::Error(errorStream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cmTarFilesFrom(std::string const& file,
|
bool cmTarFilesFrom(std::string const& file, std::vector<std::string>& files)
|
||||||
std::vector<std::string>& files)
|
|
||||||
{
|
{
|
||||||
if (cmSystemTools::FileIsDirectory(file)) {
|
if (cmSystemTools::FileIsDirectory(file)) {
|
||||||
std::ostringstream e;
|
std::ostringstream e;
|
||||||
@@ -180,7 +187,7 @@ static bool cmTarFilesFrom(std::string const& file,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmCatFile(const std::string& fileToAppend)
|
void cmCatFile(const std::string& fileToAppend)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
_setmode(fileno(stdout), _O_BINARY);
|
_setmode(fileno(stdout), _O_BINARY);
|
||||||
@@ -190,7 +197,7 @@ static void cmCatFile(const std::string& fileToAppend)
|
|||||||
std::cout << source.rdbuf();
|
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::FileIsSymlink(dir)) {
|
||||||
if (!cmSystemTools::RemoveFile(dir)) {
|
if (!cmSystemTools::RemoveFile(dir)) {
|
||||||
@@ -208,9 +215,123 @@ static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HandleIWYU(const std::string& runCmd,
|
#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
|
||||||
const std::string& /* sourceFile */,
|
class CLIncludeParser : public cmProcessTools::LineParser
|
||||||
const std::vector<std::string>& orig_cmd)
|
{
|
||||||
|
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
|
// Construct the iwyu command line by taking what was given
|
||||||
// and adding all the arguments we give to the compiler.
|
// and adding all the arguments we give to the compiler.
|
||||||
@@ -235,8 +356,8 @@ static int HandleIWYU(const std::string& runCmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
|
int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
|
||||||
const std::vector<std::string>& orig_cmd)
|
const std::vector<std::string>& orig_cmd)
|
||||||
{
|
{
|
||||||
// Construct the clang-tidy command line by taking what was given
|
// Construct the clang-tidy command line by taking what was given
|
||||||
// and adding our compiler command line. The clang-tidy tool will
|
// 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HandleLWYU(const std::string& runCmd,
|
int HandleLWYU(const std::string& runCmd, const std::string& /* sourceFile */,
|
||||||
const std::string& /* sourceFile */,
|
const std::vector<std::string>&)
|
||||||
const std::vector<std::string>&)
|
|
||||||
{
|
{
|
||||||
// Construct the ldd -r -u (link what you use lwyu) command line
|
// Construct the ldd -r -u (link what you use lwyu) command line
|
||||||
// ldd -u -r lwuy target
|
// ldd -u -r lwuy target
|
||||||
@@ -298,9 +418,8 @@ static int HandleLWYU(const std::string& runCmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HandleCppLint(const std::string& runCmd,
|
int HandleCppLint(const std::string& runCmd, const std::string& sourceFile,
|
||||||
const std::string& sourceFile,
|
const std::vector<std::string>&)
|
||||||
const std::vector<std::string>&)
|
|
||||||
{
|
{
|
||||||
// Construct the cpplint command line.
|
// Construct the cpplint command line.
|
||||||
std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
|
std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
|
||||||
@@ -326,9 +445,8 @@ static int HandleCppLint(const std::string& runCmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HandleCppCheck(const std::string& runCmd,
|
int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile,
|
||||||
const std::string& sourceFile,
|
const std::vector<std::string>& orig_cmd)
|
||||||
const std::vector<std::string>& orig_cmd)
|
|
||||||
{
|
{
|
||||||
// Construct the cpplint command line.
|
// Construct the cpplint command line.
|
||||||
std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
|
std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
|
||||||
@@ -391,7 +509,7 @@ struct CoCompiler
|
|||||||
bool NoOriginalCommand;
|
bool NoOriginalCommand;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::array<CoCompiler, 5> CoCompilers = {
|
const std::array<CoCompiler, 5> CoCompilers = {
|
||||||
{ // Table of options and handlers.
|
{ // Table of options and handlers.
|
||||||
{ "--cppcheck=", HandleCppCheck, false },
|
{ "--cppcheck=", HandleCppCheck, false },
|
||||||
{ "--cpplint=", HandleCppLint, false },
|
{ "--cpplint=", HandleCppLint, false },
|
||||||
@@ -405,6 +523,7 @@ struct CoCompileJob
|
|||||||
std::string Command;
|
std::string Command;
|
||||||
CoCompileHandler Handler;
|
CoCompileHandler Handler;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// called when args[0] == "__run_co_compile"
|
// called when args[0] == "__run_co_compile"
|
||||||
int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
|
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") {
|
} else if (args[2] == "--ignore-eol") {
|
||||||
filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
|
filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
|
||||||
} else {
|
} else {
|
||||||
::CMakeCommandUsage(args[0].c_str());
|
CMakeCommandUsage(args[0].c_str());
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,8 +740,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outValid) {
|
if (outValid) {
|
||||||
// The def file already exists and all input files are older than the
|
// The def file already exists and all input files are older than
|
||||||
// existing def file.
|
// the existing def file.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1162,6 +1281,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
|||||||
return 1;
|
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.
|
// Internal CMake link script support.
|
||||||
if (args[1] == "cmake_link_script" && args.size() >= 3) {
|
if (args[1] == "cmake_link_script" && args.size() >= 3) {
|
||||||
return cmcmd::ExecuteLinkScript(args);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1779,8 +1905,8 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
|
|||||||
skipNextArg = false;
|
skipNextArg = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// We use ++ as seperator between the preprocessing step definition and the
|
// We use ++ as seperator between the preprocessing step definition and
|
||||||
// rc compilation step becase we need to prepend a -- to seperate the
|
// the rc compilation step becase we need to prepend a -- to seperate the
|
||||||
// source file properly from other options when using clang-cl for
|
// source file properly from other options when using clang-cl for
|
||||||
// preprocessing.
|
// preprocessing.
|
||||||
if (arg == "++") {
|
if (arg == "++") {
|
||||||
@@ -1830,7 +1956,8 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Since we might have skipped the last argument to llvm-rc
|
// 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) {
|
if (resource_compile.back() != intermediate_file) {
|
||||||
resource_compile.push_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
|
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
|
||||||
|
|
||||||
// 1. Compiler compiles the application and generates the *.obj files.
|
// 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
|
// 2. An empty manifest file is generated if this is a clean build and
|
||||||
// not the previous one is reused.
|
// if not the previous one is reused.
|
||||||
// 3. The resource compiler (rc.exe) compiles the *.manifest file to a
|
// 3. The resource compiler (rc.exe) compiles the *.manifest file to a
|
||||||
// *.res file.
|
// *.res file.
|
||||||
// 4. Linker generates the binary (EXE or DLL) with the /incremental
|
// 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 "[;$]")
|
if(NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
|
||||||
target_precompile_headers(zot_pch PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/zot_pch.hxx)
|
target_precompile_headers(zot_pch PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/zot_pch.hxx)
|
||||||
endif()
|
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.
|
# Test the #include line macro transformation rule support.
|
||||||
set_property(
|
set_property(
|
||||||
|
|||||||
@@ -67,7 +67,11 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Test escaping of special characters in include directory paths.
|
# 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")
|
if(NOT CMAKE_GENERATOR STREQUAL "Watcom WMake")
|
||||||
# Watcom seems to have no way to encode these characters.
|
# Watcom seems to have no way to encode these characters.
|
||||||
string(APPEND special_chars "#=[]")
|
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}")
|
set(ENV{ASM} "${CMake_TEST_BuildDepends_GNU_AS}")
|
||||||
run_BuildDepends(GNU-AS)
|
run_BuildDepends(GNU-AS)
|
||||||
endif()
|
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()
|
||||||
|
|||||||
@@ -203,7 +203,10 @@ if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
|
|||||||
set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}")
|
set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_RunCMake_test(BuildDepends
|
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}
|
-DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
|
||||||
)
|
)
|
||||||
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
|
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} \
|
CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
|
||||||
cmDepends \
|
cmDepends \
|
||||||
cmDependsC \
|
cmDependsC \
|
||||||
|
cmDependsCompiler \
|
||||||
cmGlobalUnixMakefileGenerator3 \
|
cmGlobalUnixMakefileGenerator3 \
|
||||||
cmLocalUnixMakefileGenerator3 \
|
cmLocalUnixMakefileGenerator3 \
|
||||||
cmMakefileExecutableTargetGenerator \
|
cmMakefileExecutableTargetGenerator \
|
||||||
cmMakefileLibraryTargetGenerator \
|
cmMakefileLibraryTargetGenerator \
|
||||||
cmMakefileTargetGenerator \
|
cmMakefileTargetGenerator \
|
||||||
cmMakefileUtilityTargetGenerator \
|
cmMakefileUtilityTargetGenerator \
|
||||||
|
cmProcessTools \
|
||||||
"
|
"
|
||||||
|
|
||||||
JSONCPP_CXX_SOURCES=
|
JSONCPP_CXX_SOURCES=
|
||||||
|
|||||||
Reference in New Issue
Block a user