|
|
@@ -21,6 +21,7 @@
|
|
|
#include "cmCustomCommand.h"
|
|
|
#include "cmCustomCommandGenerator.h"
|
|
|
#include "cmCustomCommandLines.h"
|
|
|
+#include "cmGeneratedFileStream.h"
|
|
|
#include "cmGeneratorExpression.h"
|
|
|
#include "cmGeneratorExpressionContext.h"
|
|
|
#include "cmGeneratorExpressionDAGChecker.h"
|
|
|
@@ -3355,6 +3356,115 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
+std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
|
|
|
+ const std::string& language) const
|
|
|
+{
|
|
|
+ if (language != "C" && language != "CXX") {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+ if (this->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+ const auto inserted =
|
|
|
+ this->PchHeaders.insert(std::make_pair(language + config, ""));
|
|
|
+ if (inserted.second) {
|
|
|
+ const std::vector<BT<std::string>> headers =
|
|
|
+ this->GetPrecompileHeaders(config, language);
|
|
|
+ if (headers.empty()) {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+ std::string& filename = inserted.first->second;
|
|
|
+
|
|
|
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
|
|
+ filename =
|
|
|
+ cmStrCat(this->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 = cmStrCat(filename, "CMakeFiles/", this->GetName(),
|
|
|
+ ".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx"));
|
|
|
+
|
|
|
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
|
|
|
+ {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ 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";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
|
|
|
+ cmSystemTools::RemoveFile(filename_tmp);
|
|
|
+ }
|
|
|
+ return inserted.first->second;
|
|
|
+}
|
|
|
+
|
|
|
+std::string cmGeneratorTarget::GetPchSource(const std::string& config,
|
|
|
+ const std::string& language) const
|
|
|
+{
|
|
|
+ if (language != "C" && language != "CXX") {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+ const auto inserted =
|
|
|
+ this->PchSources.insert(std::make_pair(language + config, ""));
|
|
|
+ if (inserted.second) {
|
|
|
+ const std::string pchHeader = this->GetPchHeader(config, language);
|
|
|
+ if (pchHeader.empty()) {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+ std::string& filename = inserted.first->second;
|
|
|
+ filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
|
|
|
+ "/CMakeFiles/", this->GetName(), ".dir/cmake_pch");
|
|
|
+
|
|
|
+ // For GCC the source extension will be tranformed into .h[xx].gch
|
|
|
+ if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
|
|
|
+ filename += ((language == "C") ? ".h.c" : ".hxx.cxx");
|
|
|
+ } else {
|
|
|
+ filename += ((language == "C") ? ".c" : ".cxx");
|
|
|
+ }
|
|
|
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
|
|
|
+ {
|
|
|
+ cmGeneratedFileStream file(filename_tmp);
|
|
|
+ file << "/* generated by CMake */\n";
|
|
|
+ }
|
|
|
+ cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
|
|
|
+ cmSystemTools::RemoveFile(filename_tmp);
|
|
|
+ }
|
|
|
+ return inserted.first->second;
|
|
|
+}
|
|
|
+
|
|
|
void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
|
|
|
const std::string& config,
|
|
|
const std::string& language) const
|