summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/target_precompile_headers.rst14
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst7
-rw-r--r--Modules/CMakePlatformId.h.in3
-rw-r--r--Modules/Compiler/IAR-C.cmake5
-rw-r--r--Modules/Compiler/IAR-CXX.cmake4
-rw-r--r--Modules/Compiler/IAR-DetermineCompiler.cmake2
-rw-r--r--Modules/Compiler/IAR-FindBinUtils.cmake3
-rw-r--r--Modules/FindPkgConfig.cmake6
-rw-r--r--Modules/Platform/Windows-MSVC.cmake13
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx25
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.h12
-rw-r--r--Source/CPack/cpack.cxx5
-rw-r--r--Source/cmAddCustomTargetCommand.cxx2
-rw-r--r--Source/cmCommonTargetGenerator.cxx1
-rw-r--r--Source/cmGeneratorTarget.cxx131
-rw-r--r--Source/cmGeneratorTarget.h3
-rw-r--r--Source/cmLocalGenerator.cxx113
-rw-r--r--Source/cmMakefile.cxx6
-rw-r--r--Source/cmSourceFile.cxx21
-rw-r--r--Source/cmSourceFile.h17
-rw-r--r--Source/cmTarget.cxx44
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx2
-rw-r--r--Source/cmTargetPropCommandBase.cxx13
-rw-r--r--Source/cmTargetPropCommandBase.h7
-rw-r--r--Tests/CustomCommandByproducts/CMakeLists.txt10
-rw-r--r--Tests/FindEnvModules/EnvModules.cmake16
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake49
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake20
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt2
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake18
-rw-r--r--Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/PrecompileHeaders/empty.c3
-rw-r--r--Tests/RunCMake/PrecompileHeaders/include/foo.h2
-rw-r--r--Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/add_custom_command/GeneratedProperty.cmake10
-rw-r--r--Tests/RunCMake/add_custom_command/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/add_custom_target/GeneratedProperty.cmake14
-rw-r--r--Tests/RunCMake/add_custom_target/RunCMakeTest.cmake1
40 files changed, 446 insertions, 167 deletions
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst
index 3e28265..7d36b11 100644
--- a/Help/command/target_precompile_headers.rst
+++ b/Help/command/target_precompile_headers.rst
@@ -9,9 +9,23 @@ Add a list of header files to precompile.
<INTERFACE|PUBLIC|PRIVATE> [header1...]
[<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
+ target_precompile_headers(<target> REUSE_FROM <other_target>)
+
Adds header files to :prop_tgt:`PRECOMPILE_HEADERS` or
:prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` target properties.
+The second signature will reuse an already precompiled header file artefact
+from another target. This is done by setting the
+:prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` to ``<other_target>`` value.
+The ``<other_target>`` will become a dependency of ``<target>``.
+
+.. note::
+
+ The second signature will require the same set of compiler options,
+ compiler flags, compiler definitions for both ``<target>``, and
+ ``<other_target>``. Compilers (e.g. GCC) will issue a warning if the
+ precompiled header file cannot be used (``-Winvalid-pch``).
+
Precompiling header files can speed up compilation by creating a partially
processed version of some header files, and then using that version during
compilations rather than repeatedly parsing the original headers.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 19afb7d..0928abe 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -298,6 +298,7 @@ Properties on Targets
/prop_tgt/PDB_OUTPUT_DIRECTORY
/prop_tgt/POSITION_INDEPENDENT_CODE
/prop_tgt/PRECOMPILE_HEADERS
+ /prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM
/prop_tgt/PREFIX
/prop_tgt/PRIVATE_HEADER
/prop_tgt/PROJECT_LABEL
diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
new file mode 100644
index 0000000..d740303
--- /dev/null
+++ b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
@@ -0,0 +1,7 @@
+PRECOMPILE_HEADERS_REUSE_FROM
+-----------------------------
+
+Target from which to reuse the precomipled headers build artifact.
+
+See the second signature of :command:`target_precompile_headers` command
+for more detailed information.
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
index 542a6fe..95465ce 100644
--- a/Modules/CMakePlatformId.h.in
+++ b/Modules/CMakePlatformId.h.in
@@ -174,6 +174,9 @@
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
+# elif defined(__ICCV850__)
+# define ARCHITECTURE_ID "V850"
+
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake
index e03ce3f..9ad1ba0 100644
--- a/Modules/Compiler/IAR-C.cmake
+++ b/Modules/Compiler/IAR-C.cmake
@@ -60,6 +60,11 @@ elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
__compiler_check_default_language_standard(C 1.10 90 5.10 99)
set(CMAKE_C_OUTPUT_EXTENSION ".r43")
+elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850")
+ __compiler_iar_xlink(C)
+ __compiler_check_default_language_standard(C 1.10 90 4.10 99)
+ set(CMAKE_C_OUTPUT_EXTENSION ".r85")
+
else()
message(FATAL_ERROR "CMAKE_C_COMPILER_ARCHITECTURE_ID not detected. This should be automatic.")
endif()
diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake
index e8f1142..549d242 100644
--- a/Modules/Compiler/IAR-CXX.cmake
+++ b/Modules/Compiler/IAR-CXX.cmake
@@ -68,6 +68,10 @@ elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
__compiler_check_default_language_standard(CXX 5.10 98)
set(CMAKE_CXX_OUTPUT_EXTENSION ".r43")
+elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850")
+ __compiler_iar_xlink(CXX)
+ __compiler_check_default_language_standard(CXX 1.10 98)
+ set(CMAKE_C_OUTPUT_EXTENSION ".r85")
else()
message(FATAL_ERROR "CMAKE_CXX_COMPILER_ARCHITECTURE_ID not detected. This should be automatic." )
endif()
diff --git a/Modules/Compiler/IAR-DetermineCompiler.cmake b/Modules/Compiler/IAR-DetermineCompiler.cmake
index 57ca1c9..7e17778 100644
--- a/Modules/Compiler/IAR-DetermineCompiler.cmake
+++ b/Modules/Compiler/IAR-DetermineCompiler.cmake
@@ -31,7 +31,7 @@ set(_compiler_id_version_compute "
# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(((__VER__) / 1000) % 1000)
# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@((__VER__) % 1000)
# define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__IAR_SYSTEMS_ICC__)
-# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__))
+# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__))
# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@((__VER__) / 100)
# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@((__VER__) - (((__VER__) / 100)*100))
# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__SUBVERSION__)
diff --git a/Modules/Compiler/IAR-FindBinUtils.cmake b/Modules/Compiler/IAR-FindBinUtils.cmake
index b7d4664..6258cf3 100644
--- a/Modules/Compiler/IAR-FindBinUtils.cmake
+++ b/Modules/Compiler/IAR-FindBinUtils.cmake
@@ -45,7 +45,8 @@ set(CMAKE_IAR_LINKER \"${CMAKE_IAR_LINKER}\")
")
elseif("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR" OR
- "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430" OR
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850")
# Find the "xlink" linker and "xar" archiver:
find_program(CMAKE_IAR_LINKER xlink HINTS ${__iar_hints}
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 4c9af91..5162a44 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -214,7 +214,11 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path)
NAMES ${_pkg_search}
${_find_opts})
mark_as_advanced(pkgcfg_lib_${_prefix}_${_pkg_search})
- list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}")
+ if(pkgcfg_lib_${_prefix}_${_pkg_search})
+ list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}")
+ else()
+ list(APPEND _libs ${_pkg_search})
+ endif()
endforeach()
set(${_prefix}_LINK_LIBRARIES "${_libs}" PARENT_SCOPE)
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 6ddcaa3..34f5d03 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -333,10 +333,17 @@ macro(__windows_compiler_msvc lang)
set(CMAKE_LINK_PCH ON)
if(MSVC_VERSION GREATER_EQUAL 1910)
# VS 2017 or greater
- set(CMAKE_PCH_PROLOGUE "#pragma system_header")
+ if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang")
+ set(CMAKE_PCH_PROLOGUE "#pragma system_header")
+ else()
+ set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
+ endif()
+ endif()
+ if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang")
+ set(CMAKE_PCH_COPY_COMPILE_PDB ON)
endif()
- set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /FI<PCH_HEADER>)
- set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /FI<PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /Fp<PCH_FILE> /FI<PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /Fp<PCH_FILE> /FI<PCH_HEADER>)
if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 2aef888..1e0721f 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 15)
-set(CMake_VERSION_PATCH 20190916)
+set(CMake_VERSION_PATCH 20190918)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index a564eb1..79e344b 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -6,7 +6,6 @@
#include <utility>
#include "IFW/cmCPackIFWGenerator.h"
-#include "cmAlgorithms.h"
#ifdef HAVE_FREEBSD_PKG
# include "cmCPackFreeBSDGenerator.h"
#endif
@@ -138,33 +137,21 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
#endif
}
-cmCPackGeneratorFactory::~cmCPackGeneratorFactory()
-{
- cmDeleteAll(this->Generators);
-}
-
-cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator(
+std::unique_ptr<cmCPackGenerator> cmCPackGeneratorFactory::NewGenerator(
const std::string& name)
{
- cmCPackGenerator* gen = this->NewGeneratorInternal(name);
+ auto it = this->GeneratorCreators.find(name);
+ if (it == this->GeneratorCreators.end()) {
+ return nullptr;
+ }
+ std::unique_ptr<cmCPackGenerator> gen(it->second());
if (!gen) {
return nullptr;
}
- this->Generators.push_back(gen);
gen->SetLogger(this->Logger);
return gen;
}
-cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal(
- const std::string& name)
-{
- auto it = this->GeneratorCreators.find(name);
- if (it == this->GeneratorCreators.end()) {
- return nullptr;
- }
- return (it->second)();
-}
-
void cmCPackGeneratorFactory::RegisterGenerator(
const std::string& name, const char* generatorDescription,
CreateGeneratorCall* createGenerator)
diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h
index da2eb8d..62b7484 100644
--- a/Source/CPack/cmCPackGeneratorFactory.h
+++ b/Source/CPack/cmCPackGeneratorFactory.h
@@ -6,8 +6,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <string>
-#include <vector>
class cmCPackGenerator;
class cmCPackLog;
@@ -20,14 +20,9 @@ class cmCPackGeneratorFactory
{
public:
cmCPackGeneratorFactory();
- ~cmCPackGeneratorFactory();
-
- cmCPackGeneratorFactory(const cmCPackGeneratorFactory&) = delete;
- cmCPackGeneratorFactory& operator=(const cmCPackGeneratorFactory&) = delete;
//! Get the generator
- cmCPackGenerator* NewGenerator(const std::string& name);
- void DeleteGenerator(cmCPackGenerator* gen);
+ std::unique_ptr<cmCPackGenerator> NewGenerator(const std::string& name);
using CreateGeneratorCall = cmCPackGenerator*();
@@ -44,9 +39,6 @@ public:
}
private:
- cmCPackGenerator* NewGeneratorInternal(const std::string& name);
- std::vector<cmCPackGenerator*> Generators;
-
using t_GeneratorCreatorsMap = std::map<std::string, CreateGeneratorCall*>;
t_GeneratorCreatorsMap GeneratorCreators;
DescriptionsMap GeneratorDescriptions;
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index ab44a42..ce41d40 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -25,6 +25,7 @@
#include <cstddef>
#include <iostream>
#include <map>
+#include <memory>
#include <sstream>
#include <string>
#include <utility>
@@ -237,7 +238,6 @@ int main(int argc, char const* const* argv)
cmCPackGeneratorFactory generators;
generators.SetLogger(&log);
- cmCPackGenerator* cpackGenerator = nullptr;
cmDocumentation doc;
doc.addCPackStandardDocSections();
@@ -360,7 +360,8 @@ int main(int argc, char const* const* argv)
parsed = 0;
}
if (parsed) {
- cpackGenerator = generators.NewGenerator(gen);
+ std::unique_ptr<cmCPackGenerator> cpackGenerator =
+ generators.NewGenerator(gen);
if (cpackGenerator) {
cpackGenerator->SetTrace(trace);
cpackGenerator->SetTraceExpand(traceExpand);
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index caea510..ec5c1a7 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -127,7 +127,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
}
filename += copy;
cmSystemTools::ConvertToUnixSlashes(filename);
- byproducts.push_back(filename);
+ byproducts.push_back(cmSystemTools::CollapseFullPath(filename));
} break;
case doing_depends: {
std::string dep = copy;
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 33286ad..19a096b 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -171,6 +171,7 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
return compilePdbPath;
}
+
compilePdbPath =
this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
if (compilePdbPath.empty()) {
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2ca5706..3a321c5 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -35,6 +35,7 @@
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
+#include "cmSourceFileLocationKind.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -3371,57 +3372,67 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
}
std::string& filename = inserted.first->second;
+ const cmGeneratorTarget* generatorTarget = this;
+ const char* pchReuseFrom =
+ generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ if (pchReuseFrom) {
+ generatorTarget =
+ this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ }
+
if (this->GetGlobalGenerator()->IsMultiConfig()) {
- filename =
- cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), "/");
+ filename = cmStrCat(
+ generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(), "/");
} else {
// For GCC we need to have the header file .h[xx]
// next to the .h[xx].gch file
- filename = this->ObjectDirectory;
+ filename = generatorTarget->ObjectDirectory;
}
- filename = cmStrCat(filename, "CMakeFiles/", this->GetName(),
+ filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(),
".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx"));
const std::string filename_tmp = cmStrCat(filename, ".tmp");
- {
+ if (!pchReuseFrom) {
auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE");
- cmGeneratedFileStream file(
- filename_tmp, false,
- this->GetGlobalGenerator()->GetMakefileEncoding());
- file << "/* generated by CMake */\n\n";
- if (pchPrologue) {
- file << pchPrologue << "\n";
- }
- if (this->GetGlobalGenerator()->IsXcode()) {
- file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n";
- }
- if (language == "CXX") {
- file << "#ifdef __cplusplus\n";
- }
- for (auto const& header_bt : headers) {
- if (header_bt.Value.empty()) {
- continue;
+ {
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ this->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+ if (pchPrologue) {
+ file << pchPrologue << "\n";
}
- if (header_bt.Value[0] == '<' || header_bt.Value[0] == '"') {
- file << "#include " << header_bt.Value << "\n";
- } else {
- file << "#include \"" << header_bt.Value << "\"\n";
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n";
+ }
+ if (language == "CXX") {
+ file << "#ifdef __cplusplus\n";
+ }
+ for (auto const& header_bt : headers) {
+ if (header_bt.Value.empty()) {
+ continue;
+ }
+ if (header_bt.Value[0] == '<' || header_bt.Value[0] == '\"') {
+ file << "#include " << header_bt.Value << "\n";
+ } else {
+ file << "#include \"" << header_bt.Value << "\"\n";
+ }
+ }
+ if (language == "CXX") {
+ file << "#endif // __cplusplus\n";
+ }
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n";
+ }
+ if (pchEpilogue) {
+ file << pchEpilogue << "\n";
}
}
- if (language == "CXX") {
- file << "#endif // __cplusplus\n";
- }
- if (this->GetGlobalGenerator()->IsXcode()) {
- file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n";
- }
- if (pchEpilogue) {
- file << pchEpilogue << "\n";
- }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
- cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
return inserted.first->second;
}
@@ -3440,8 +3451,18 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
return std::string();
}
std::string& filename = inserted.first->second;
- filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
- "/CMakeFiles/", this->GetName(), ".dir/cmake_pch");
+
+ const cmGeneratorTarget* generatorTarget = this;
+ const char* pchReuseFrom =
+ generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ if (pchReuseFrom) {
+ generatorTarget =
+ this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ }
+
+ filename =
+ cmStrCat(generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch");
// For GCC the source extension will be tranformed into .h[xx].gch
if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
@@ -3449,12 +3470,40 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
} else {
filename += ((language == "C") ? ".c" : ".cxx");
}
+
const std::string filename_tmp = cmStrCat(filename, ".tmp");
- {
- cmGeneratedFileStream file(filename_tmp);
- file << "/* generated by CMake */\n";
+ if (!pchReuseFrom) {
+ {
+ cmGeneratedFileStream file(filename_tmp);
+ file << "/* generated by CMake */\n";
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
- cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ }
+ return inserted.first->second;
+}
+
+std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
+ const std::string& language)
+{
+ if (language != "C" && language != "CXX") {
+ return std::string();
+ }
+ const auto inserted =
+ this->PchObjectFiles.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ const std::string pchSource = this->GetPchSource(config, language);
+ if (pchSource.empty()) {
+ return std::string();
+ }
+ std::string& filename = inserted.first->second;
+
+ this->AddSource(pchSource, true);
+
+ auto pchSf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
+
+ filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf));
}
return inserted.first->second;
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 4207d65..6c36c4b 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -462,6 +462,8 @@ public:
const std::string& language) const;
std::string GetPchSource(const std::string& config,
const std::string& language) const;
+ std::string GetPchFileObject(const std::string& config,
+ const std::string& language);
bool IsSystemIncludeDirectory(const std::string& dir,
const std::string& config,
@@ -880,6 +882,7 @@ private:
mutable std::set<std::string> LinkImplicitNullProperties;
mutable std::map<std::string, std::string> PchHeaders;
mutable std::map<std::string, std::string> PchSources;
+ mutable std::map<std::string, std::string> PchObjectFiles;
void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 5bbb83c..afcd69f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -4,7 +4,9 @@
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
+#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -2255,23 +2257,124 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target,
return;
}
+ const char* pchReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+
auto pch_sf = this->Makefile->GetOrCreateSource(
pchSource, false, cmSourceFileLocationKind::Known);
std::string pchFile = pchHeader;
if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!pchReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
+
// Exclude the pch files from linking
if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
- cmSystemTools::ReplaceString(pchFile, (lang == "C" ? ".h" : ".hxx"),
- pchExtension);
- pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+
+ auto replaceExtension = [](const std::string& str,
+ const std::string& ext) -> std::string {
+ auto dot_pos = str.rfind('.');
+ std::string result;
+ if (dot_pos != std::string::npos) {
+ result = str.substr(0, dot_pos);
+ }
+ result += ext;
+ return result;
+ };
+
+ if (!pchReuseFrom) {
+ std::string pchSourceObj = target->GetPchFileObject(config, lang);
+
+ pchFile = replaceExtension(pchSourceObj, pchExtension);
+ pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+ } else {
+ auto reuseTarget =
+ this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+
+ if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig()
+ ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
+ : "";
+
+ const std::string target_compile_pdb_dir =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", target->GetName(), ".dir/");
+
+ const std::string copy_script =
+ cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+ cmGeneratedFileStream file(copy_script);
+
+ file << "# CMake generated file\n";
+ for (auto extension : { ".pdb", ".idb" }) {
+ const std::string from_file = cmStrCat(
+ reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom,
+ extension);
+
+ const std::string to_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/${PDB_PREFIX}");
+
+ file << "if (EXISTS \"" << from_file << "\")\n";
+ file << " file(COPY \"" << from_file << "\""
+ << " DESTINATION \"" << to_dir << "\")\n";
+ file << "endif()\n";
+ }
+
+ cmCustomCommandLines commandLines;
+ cmCustomCommandLine currentLine;
+ currentLine.push_back(cmSystemTools::GetCMakeCommand());
+ currentLine.push_back(cmStrCat("-DPDB_PREFIX=", pdb_prefix));
+ currentLine.push_back("-P");
+ currentLine.push_back(copy_script);
+ commandLines.push_back(std::move(currentLine));
+
+ const std::string no_main_dependency;
+ const std::vector<std::string> no_deps;
+ const char* no_message = "";
+ const char* no_current_dir = nullptr;
+ std::vector<std::string> no_byproducts;
+
+ std::vector<std::string> outputs;
+ outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
+ pchReuseFrom, ".pdb"));
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ this->Makefile->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmTarget::PRE_BUILD, no_message, no_current_dir);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule = this->Makefile->AddCustomCommandToOutput(
+ outputs, no_byproducts, no_deps, no_main_dependency,
+ no_implicit_depends, commandLines, no_message, no_current_dir);
+
+ if (copy_rule) {
+ target->AddSource(copy_rule->ResolveFullPath());
+ }
+ }
+
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir.c_str());
+ }
+
+ std::string pchSourceObj = reuseTarget->GetPchFileObject(config, lang);
+
+ // Link to the pch object file
+ target->Target->SetProperty(
+ "LINK_FLAGS",
+ this->ConvertToOutputFormat(pchSourceObj, SHELL).c_str());
+
+ pchFile = replaceExtension(pchSourceObj, pchExtension);
+ }
} else {
pchFile += pchExtension;
pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
}
- target->AddSource(pchSource, true);
-
for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) {
cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader);
cmSystemTools::ReplaceString(str, "<PCH_FILE>", pchFile);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 2c7e5e9..c593939 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -15,6 +15,8 @@
#include <sstream>
#include <utility>
+#include "cm_memory.hxx"
+
#include "cmAlgorithms.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
@@ -1026,7 +1028,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
depends2.push_back(main_dependency);
}
- cmCustomCommand* cc = new cmCustomCommand(
+ std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
this, outputs, byproducts, depends2, commandLines, comment, workingDir);
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
@@ -1035,7 +1037,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
cc->SetCommandExpandLists(command_expand_lists);
cc->SetDepfile(depfile);
cc->SetJobPool(job_pool);
- file->SetCustomCommand(cc);
+ file->SetCustomCommand(std::move(cc));
this->UpdateOutputToSourceMap(outputs, file, false);
this->UpdateOutputToSourceMap(byproducts, file, true);
}
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 4deb94a..3344217 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -5,7 +5,6 @@
#include <array>
#include <utility>
-#include "cmCustomCommand.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -21,11 +20,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name,
{
}
-cmSourceFile::~cmSourceFile()
-{
- this->SetCustomCommand(nullptr);
-}
-
std::string const& cmSourceFile::GetExtension() const
{
return this->Extension;
@@ -320,19 +314,12 @@ bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
return cmIsOn(this->GetProperty(prop));
}
-cmCustomCommand* cmSourceFile::GetCustomCommand()
-{
- return this->CustomCommand;
-}
-
-cmCustomCommand const* cmSourceFile::GetCustomCommand() const
+cmCustomCommand* cmSourceFile::GetCustomCommand() const
{
- return this->CustomCommand;
+ return this->CustomCommand.get();
}
-void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
+void cmSourceFile::SetCustomCommand(std::unique_ptr<cmCustomCommand> cc)
{
- cmCustomCommand* old = this->CustomCommand;
- this->CustomCommand = cc;
- delete old;
+ this->CustomCommand = std::move(cc);
}
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 774cb28..dd36d45 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -5,14 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
#include "cmSourceFileLocation.h"
#include "cmSourceFileLocationKind.h"
+#include <memory>
#include <string>
#include <vector>
-class cmCustomCommand;
class cmMakefile;
/** \class cmSourceFile
@@ -32,17 +33,11 @@ public:
cmMakefile* mf, const std::string& name,
cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
- ~cmSourceFile();
-
- cmSourceFile(const cmSourceFile&) = delete;
- cmSourceFile& operator=(const cmSourceFile&) = delete;
-
/**
- * Get the list of the custom commands for this source file
+ * Get the custom command for this source file
*/
- cmCustomCommand* GetCustomCommand();
- cmCustomCommand const* GetCustomCommand() const;
- void SetCustomCommand(cmCustomCommand* cc);
+ cmCustomCommand* GetCustomCommand() const;
+ void SetCustomCommand(std::unique_ptr<cmCustomCommand> cc);
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
@@ -114,7 +109,7 @@ public:
private:
cmSourceFileLocation Location;
cmPropertyMap Properties;
- cmCustomCommand* CustomCommand = nullptr;
+ std::unique_ptr<cmCustomCommand> CustomCommand;
std::string Extension;
std::string Language;
std::string FullPath;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6637e32..e65fb25 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1085,6 +1085,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
MAKE_STATIC_PROP(COMPILE_FEATURES);
MAKE_STATIC_PROP(COMPILE_OPTIONS);
MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
+ MAKE_STATIC_PROP(PRECOMPILE_HEADERS_REUSE_FROM);
MAKE_STATIC_PROP(CUDA_PTX_COMPILATION);
MAKE_STATIC_PROP(EXPORT_NAME);
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
@@ -1231,6 +1232,41 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
<< impl->Name << "\")\n";
impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
+ } else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) {
+ if (this->GetProperty("PRECOMPILE_HEADERS")) {
+ std::ostringstream e;
+ e << "PRECOMPILE_HEADERS property is already set on target (\""
+ << impl->Name << "\")\n";
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return;
+ }
+ auto reusedTarget =
+ impl->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
+ value);
+ if (!reusedTarget) {
+ const std::string e(
+ "PRECOMPILE_HEADERS_REUSE_FROM set with non existing target");
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+ return;
+ }
+
+ std::string reusedFrom = reusedTarget->GetSafeProperty(prop);
+ if (reusedFrom.empty()) {
+ reusedFrom = value;
+ }
+
+ impl->Properties.SetProperty(prop, reusedFrom.c_str());
+
+ reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom.c_str());
+ reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ cmStrCat(reusedFrom, ".dir/").c_str());
+
+ for (auto p : { "COMPILE_PDB_NAME", "PRECOMPILE_HEADERS",
+ "INTERFACE_PRECOMPILE_HEADERS" }) {
+ this->SetProperty(p, reusedTarget->GetProperty(p));
+ }
+
+ this->AddUtility(reusedFrom, impl->Makefile);
} else {
impl->Properties.SetProperty(prop, value);
}
@@ -1308,6 +1344,14 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "PRECOMPILE_HEADERS") {
+ if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
+ std::ostringstream e;
+ e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target "
+ "(\""
+ << impl->Name << "\")\n";
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return;
+ }
if (value && *value) {
impl->PrecompileHeadersEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index 30cf1be..97f1bea 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -10,7 +10,7 @@
bool cmTargetPrecompileHeadersCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- return this->HandleArguments(args, "PRECOMPILE_HEADERS");
+ return this->HandleArguments(args, "PRECOMPILE_HEADERS", PROCESS_REUSE_FROM);
}
void cmTargetPrecompileHeadersCommand::HandleMissingTarget(
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 3aa845c..4bc3125 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -65,6 +65,19 @@ bool cmTargetPropCommandBase::HandleArguments(
++argIndex;
}
+ if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") {
+ if (args.size() != 3) {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ ++argIndex;
+
+ this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM",
+ args[argIndex].c_str());
+
+ ++argIndex;
+ }
+
this->Property = prop;
while (argIndex < args.size()) {
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 943285d..b244417 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -17,9 +17,10 @@ class cmTargetPropCommandBase : public cmCommand
public:
enum ArgumentFlags
{
- NO_FLAGS = 0,
- PROCESS_BEFORE = 1,
- PROCESS_SYSTEM = 2
+ NO_FLAGS = 0x0,
+ PROCESS_BEFORE = 0x1,
+ PROCESS_SYSTEM = 0x2,
+ PROCESS_REUSE_FROM = 0x3
};
bool HandleArguments(std::vector<std::string> const& args,
diff --git a/Tests/CustomCommandByproducts/CMakeLists.txt b/Tests/CustomCommandByproducts/CMakeLists.txt
index bfa69ce..08c897c 100644
--- a/Tests/CustomCommandByproducts/CMakeLists.txt
+++ b/Tests/CustomCommandByproducts/CMakeLists.txt
@@ -14,20 +14,20 @@ add_custom_command(
# Generate a byproduct in a rule that runs in a dependency of the consumer.
add_custom_command(
- OUTPUT timestamp2.txt
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/timestamp2.txt
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in byproduct2.c
- BYPRODUCTS byproduct2.c
+ BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/byproduct2.c
COMMAND ${CMAKE_COMMAND} -E touch timestamp2.txt
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in
)
-add_custom_target(Producer2 DEPENDS timestamp2.txt)
+add_custom_target(Producer2 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/timestamp2.txt)
# Generate a byproduct in a custom target.
add_custom_target(Producer3_4
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/byproduct3.c.in byproduct3.c
- BYPRODUCTS byproduct3.c
+ BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/byproduct3.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct3.c.in
)
@@ -36,7 +36,7 @@ add_custom_command(
TARGET Producer3_4 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/byproduct4.c.in byproduct4.c
- BYPRODUCTS byproduct4.c
+ BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/byproduct4.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct4.c.in
)
diff --git a/Tests/FindEnvModules/EnvModules.cmake b/Tests/FindEnvModules/EnvModules.cmake
index 0c81bf2..21b0042 100644
--- a/Tests/FindEnvModules/EnvModules.cmake
+++ b/Tests/FindEnvModules/EnvModules.cmake
@@ -18,18 +18,16 @@ if(avail_mods)
message("module list")
env_module_list(loaded_mods)
+ set(mod0_found FALSE)
foreach(mod IN LISTS loaded_mods)
message(" ${mod}")
+ if(NOT mod0_found AND mod MATCHES "^${mod0}")
+ set(mod0_found ${mod})
+ endif()
endforeach()
- list(LENGTH loaded_mods num_loaded_mods)
- message("Number of modules loaded: ${num_loaded_mods}")
- if(NOT num_loaded_mods EQUAL 1)
- message(FATAL_ERROR "Exactly 1 module should be loaded. Found ${num_loaded_mods}")
- endif()
-
- list(GET loaded_mods 0 mod0_actual)
- if(NOT (mod0_actual MATCHES "^${mod0}"))
- message(FATAL_ERROR "Loaded module does not match ${mod0}. Actual: ${mod0_actual}")
+ if(NOT mod0_found)
+ message(FATAL_ERROR "Requested module ${mod0} not found in loaded modules")
endif()
+ message("module ${mod0} found loaded as ${mod0_found}")
endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
index e82b05f..62bb5de 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
@@ -39,7 +39,7 @@ foreach(i 1 2)
"Name: CMakeInternalFakePackage${i}
Description: Dummy package (${i}) for FindPkgConfig IMPORTED_TARGET test
Version: 1.2.3
-Libs: -l${pname}
+Libs: -l${pname} -l${pname}-doesnotexist
")
endforeach()
@@ -47,27 +47,6 @@ endforeach()
# the import target find_library() calls handle the NO...PATH options correctly
set(ENV{PKG_CONFIG_PATH} ${fakePkgDir}/lib/pkgconfig)
-# Confirm correct behavior of NO_CMAKE_PATH, ensuring we only find the library
-# for the imported target if we have both set CMAKE_PREFIX_PATH and have not
-# given the NO_CMAKE_PATH option
-unset(CMAKE_PREFIX_PATH)
-unset(ENV{CMAKE_PREFIX_PATH})
-pkg_check_modules(FakePackage1 QUIET IMPORTED_TARGET cmakeinternalfakepackage1)
-if (TARGET PkgConfig::FakePackage1)
- message(FATAL_ERROR "Have import target for fake package 1 with no path prefix")
-endif()
-
-set(CMAKE_PREFIX_PATH ${fakePkgDir})
-pkg_check_modules(FakePackage1 QUIET IMPORTED_TARGET NO_CMAKE_PATH cmakeinternalfakepackage1)
-if (TARGET PkgConfig::FakePackage1)
- message(FATAL_ERROR "Have import target for fake package 1 with ignored cmake path")
-endif()
-
-pkg_check_modules(FakePackage1 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage1)
-if (NOT TARGET PkgConfig::FakePackage1)
- message(FATAL_ERROR "No import target for fake package 1 with prefix path")
-endif()
-
# find targets in subdir and check their visibility
add_subdirectory(target_subdir)
if (TARGET PkgConfig::FakePackage1_dir)
@@ -82,31 +61,35 @@ endif()
# combination
unset(CMAKE_PREFIX_PATH)
unset(ENV{CMAKE_PREFIX_PATH})
-pkg_check_modules(FakePackage2 QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
-if (TARGET PkgConfig::FakePackage2)
- message(FATAL_ERROR "Have import target for fake package 2 with no path prefix")
-endif()
-
set(ENV{CMAKE_PREFIX_PATH} ${fakePkgDir})
-pkg_check_modules(FakePackage2 QUIET IMPORTED_TARGET NO_CMAKE_ENVIRONMENT_PATH cmakeinternalfakepackage2)
-if (TARGET PkgConfig::FakePackage2)
- message(FATAL_ERROR "Have import target for fake package 2 with ignored cmake path")
-endif()
pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
if (NOT TARGET PkgConfig::FakePackage2)
message(FATAL_ERROR "No import target for fake package 2 with prefix path")
endif()
+# check that 2 library entries exist
+list(LENGTH FakePackage2_LINK_LIBRARIES fp2_nlibs)
+if (NOT fp2_nlibs EQUAL 2)
+ message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has ${fp2_nlibs} entries but should have exactly 2")
+endif()
+
# check that the full library path is also returned
-if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
+list(GET FakePackage2_LINK_LIBRARIES 0 fp2_lib0)
+if (NOT fp2_lib0 STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
+ message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}")
+endif()
+
+# check that the library that couldn't be found still shows up
+list(GET FakePackage2_LINK_LIBRARIES 1 fp2_lib1)
+if (NOT fp2_lib1 STREQUAL "cmakeinternalfakepackage2-doesnotexist")
message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}")
endif()
# the information in *_LINK_LIBRARIES is not cached, so ensure is also is present on second run
unset(FakePackage2_LINK_LIBRARIES)
pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
-if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
+if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a;cmakeinternalfakepackage2-doesnotexist")
message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on second run: ${FakePackage2_LINK_LIBRARIES}")
endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake
new file mode 100644
index 0000000..4502456
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.15)
+project(PchReuseFrom C)
+
+add_library(empty empty.c)
+target_precompile_headers(empty PUBLIC
+ <stdio.h>
+ <string.h>
+)
+target_include_directories(empty PUBLIC include)
+
+add_library(foo foo.c)
+target_include_directories(foo PUBLIC include)
+target_precompile_headers(foo REUSE_FROM empty)
+
+add_executable(foobar foobar.c)
+target_link_libraries(foobar foo )
+set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo)
+
+enable_testing()
+add_test(NAME foobar COMMAND foobar)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt
new file mode 100644
index 0000000..8cdcfd9
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt
@@ -0,0 +1,2 @@
+^(|Warning #670: precompiled header file [^
+]* was not generated in this directory)$
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake
new file mode 100644
index 0000000..fff74dc
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.15)
+project(PchReuseFromSubdir C)
+
+add_library(empty empty.c)
+target_precompile_headers(empty PUBLIC
+ <stdio.h>
+ <string.h>
+)
+target_include_directories(empty PUBLIC include)
+
+add_library(foo foo.c)
+target_include_directories(foo PUBLIC include)
+target_precompile_headers(foo REUSE_FROM empty)
+
+subdirs(subdir)
+
+enable_testing()
+add_test(NAME foobar COMMAND foobar)
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
index fffcc47..bd3b1b8 100644
--- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -16,3 +16,5 @@ run_cmake(DisabledPch)
run_test(PchInterface)
run_cmake(PchPrologueEpilogue)
run_test(SkipPrecompileHeaders)
+run_test(PchReuseFrom)
+run_test(PchReuseFromSubdir)
diff --git a/Tests/RunCMake/PrecompileHeaders/empty.c b/Tests/RunCMake/PrecompileHeaders/empty.c
new file mode 100644
index 0000000..30ae1c4
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/empty.c
@@ -0,0 +1,3 @@
+void nothing()
+{
+}
diff --git a/Tests/RunCMake/PrecompileHeaders/include/foo.h b/Tests/RunCMake/PrecompileHeaders/include/foo.h
index 4a49474..fc0ae14 100644
--- a/Tests/RunCMake/PrecompileHeaders/include/foo.h
+++ b/Tests/RunCMake/PrecompileHeaders/include/foo.h
@@ -1,6 +1,6 @@
#ifndef foo_h
#define foo_h
-extern int foo();
+int foo(void);
#endif
diff --git a/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt b/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt
new file mode 100644
index 0000000..fa926c4
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_executable(foobar ../foobar.c)
+target_link_libraries(foobar foo )
+set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo)
diff --git a/Tests/RunCMake/add_custom_command/GeneratedProperty.cmake b/Tests/RunCMake/add_custom_command/GeneratedProperty.cmake
new file mode 100644
index 0000000..628134b
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/GeneratedProperty.cmake
@@ -0,0 +1,10 @@
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/a"
+ BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/b"
+ COMMAND c
+ )
+get_source_file_property(GENERATED_A "${CMAKE_CURRENT_BINARY_DIR}/a" GENERATED)
+get_source_file_property(GENERATED_B "${CMAKE_CURRENT_BINARY_DIR}/b" GENERATED)
+if(NOT GENERATED_A OR NOT GENERATED_B)
+ message(FATAL_ERROR "failed")
+endif()
diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
index 0387dbb..20097b7 100644
--- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
@@ -3,6 +3,7 @@ include(RunCMake)
run_cmake(AppendNoOutput)
run_cmake(AppendNotOutput)
run_cmake(BadArgument)
+run_cmake(GeneratedProperty)
run_cmake(NoArguments)
run_cmake(NoOutputOrTarget)
run_cmake(OutputAndTarget)
diff --git a/Tests/RunCMake/add_custom_target/GeneratedProperty.cmake b/Tests/RunCMake/add_custom_target/GeneratedProperty.cmake
new file mode 100644
index 0000000..d034534
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/GeneratedProperty.cmake
@@ -0,0 +1,14 @@
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/a"
+ COMMAND b
+ )
+add_custom_target(CollapseFullPath
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/a"
+ BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/c"
+ COMMAND d
+ )
+get_source_file_property(GENERATED_A "${CMAKE_CURRENT_BINARY_DIR}/a" GENERATED)
+get_source_file_property(GENERATED_C "${CMAKE_CURRENT_BINARY_DIR}/c" GENERATED)
+if(NOT GENERATED_A OR NOT GENERATED_C)
+ message(FATAL_ERROR "failed")
+endif()
diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
index 2caed03..d80ca19 100644
--- a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
include(RunCMake)
run_cmake(CommandExpandsEmpty)
+run_cmake(GeneratedProperty)
run_cmake(NoArguments)
run_cmake(BadTargetName)
run_cmake(ByproductsNoCommand)