From b6412e3e38ba22bf816445f19394e7c8027c186f Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 7 May 2019 23:11:52 -0700 Subject: Ninja: add placeholders to support Swift build Add the placeholders needed to support compiling Swift code. --- Source/cmNinjaNormalTargetGenerator.cxx | 85 ++++++++++++++++++++++++++++++++- Source/cmRulePlaceholderExpander.cxx | 25 ++++++++++ Source/cmRulePlaceholderExpander.h | 5 ++ Source/cmTarget.cxx | 1 + 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 770d80c..146ef79 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -282,6 +282,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) vars.Language = this->TargetLinkLanguage.c_str(); + if (this->TargetLinkLanguage == "Swift") { + vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME"; + vars.SwiftModule = "$SWIFT_MODULE"; + vars.SwiftModuleName = "$SWIFT_MODULE_NAME"; + vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP"; + vars.SwiftSources = "$SWIFT_SOURCES"; + } + std::string responseFlag; if (!useResponseFile) { vars.Objects = "$in"; @@ -799,8 +807,83 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaDeps outputs; outputs.push_back(targetOutputReal); + if (this->TargetLinkLanguage == "Swift") { + vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string { + cmGeneratorTarget::Names targetNames = + this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName()); + return targetNames.Base; + }(); + + vars["SWIFT_MODULE"] = [this]() -> std::string { + cmGeneratorTarget::Names targetNames = + this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName()); + + std::string directory = + this->GetLocalGenerator()->GetCurrentBinaryDirectory(); + if (const char* prop = this->GetGeneratorTarget()->GetProperty( + "Swift_MODULE_DIRECTORY")) { + directory = prop; + } + + std::string name = targetNames.Base + ".swiftmodule"; + if (const char* prop = + this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) { + name = prop; + } + + return this->GetLocalGenerator()->ConvertToOutputFormat( + this->ConvertToNinjaPath(directory + "/" + name), + cmOutputConverter::SHELL); + }(); + + vars["SWIFT_MODULE_NAME"] = [this]() -> std::string { + if (const char* name = + this->GetGeneratorTarget()->GetProperty("Swift_MODULE_NAME")) { + return name; + } + return this->GetGeneratorTarget()->GetName(); + }(); + + vars["SWIFT_OUTPUT_FILE_MAP"] = + this->GetLocalGenerator()->ConvertToOutputFormat( + this->ConvertToNinjaPath(gt.GetSupportDirectory() + + "/output-file-map.json"), + cmOutputConverter::SHELL); + + vars["SWIFT_SOURCES"] = [this]() -> std::string { + std::vector sources; + std::stringstream oss; + + this->GetGeneratorTarget()->GetObjectSources(sources, + this->GetConfigName()); + cmLocalGenerator const* LocalGen = this->GetLocalGenerator(); + for (const auto& source : sources) { + oss << " " + << LocalGen->ConvertToOutputFormat( + this->ConvertToNinjaPath(this->GetSourceFilePath(source)), + cmOutputConverter::SHELL); + } + return oss.str(); + }(); + } + // Compute specific libraries to link with. - cmNinjaDeps explicitDeps = this->GetObjects(); + cmNinjaDeps explicitDeps; + if (this->TargetLinkLanguage == "Swift") { + std::vector sources; + this->GetGeneratorTarget()->GetObjectSources(sources, + this->GetConfigName()); + for (const auto& source : sources) { + outputs.push_back( + this->ConvertToNinjaPath(this->GetObjectFilePath(source))); + explicitDeps.push_back( + this->ConvertToNinjaPath(this->GetSourceFilePath(source))); + } + + outputs.push_back(vars["SWIFT_MODULE"]); + } else { + explicitDeps = this->GetObjects(); + } cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); if (!this->DeviceLinkObject.empty()) { diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index 8751a11..33389ca 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -91,6 +91,31 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( if (replaceValues.Includes && variable == "INCLUDES") { return replaceValues.Includes; } + if (replaceValues.SwiftLibraryName) { + if (variable == "SWIFT_LIBRARY_NAME") { + return replaceValues.SwiftLibraryName; + } + } + if (replaceValues.SwiftModule) { + if (variable == "SWIFT_MODULE") { + return replaceValues.SwiftModule; + } + } + if (replaceValues.SwiftModuleName) { + if (variable == "SWIFT_MODULE_NAME") { + return replaceValues.SwiftModuleName; + } + } + if (replaceValues.SwiftOutputFileMap) { + if (variable == "SWIFT_OUTPUT_FILE_MAP") { + return replaceValues.SwiftOutputFileMap; + } + } + if (replaceValues.SwiftSources) { + if (variable == "SWIFT_SOURCES") { + return replaceValues.SwiftSources; + } + } if (replaceValues.TargetPDB) { if (variable == "TARGET_PDB") { return replaceValues.TargetPDB; diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h index 4a03dc8..8f36196 100644 --- a/Source/cmRulePlaceholderExpander.h +++ b/Source/cmRulePlaceholderExpander.h @@ -58,6 +58,11 @@ public: const char* Includes; const char* DependencyFile; const char* FilterPrefix; + const char* SwiftLibraryName; + const char* SwiftModule; + const char* SwiftModuleName; + const char* SwiftOutputFileMap; + const char* SwiftSources; }; // Expand rule variables in CMake of the type found in language rules diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d6d463b..2de8950 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -335,6 +335,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, InitProperty("LINK_SEARCH_START_STATIC", nullptr); InitProperty("LINK_SEARCH_END_STATIC", nullptr); InitProperty("FOLDER", nullptr); + InitProperty("Swift_MODULE_DIRECTORY", nullptr); InitProperty("VS_JUST_MY_CODE_DEBUGGING", nullptr); #ifdef __APPLE__ if (this->GetGlobalGenerator()->IsXcode()) { -- cgit v0.12