|
|
@@ -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;
|
|
|
}
|