diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 8f0ddcac64..480fedd9d9 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -681,6 +681,50 @@ cmNinjaRule GetScanRule( return rule; } + +void SetupResponseFile(cmNinjaRule& rule, + cmRulePlaceholderExpander::RuleVariables& vars, + std::string& flags, std::string const& lang, + std::string const& responseFlag) +{ + rule.RspFile = "$RSP_FILE"; + rule.RspContent = + cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags); + flags = cmStrCat(responseFlag, rule.RspFile); + vars.Defines = ""; + vars.Includes = ""; + // Swift consumes all source files in a module at once, which reaches + // command line length limits pretty quickly. Inject source files into the + // response file in this case as well. + if (lang == "Swift") { + rule.RspContent = cmStrCat(rule.RspContent, ' ', vars.Source); + vars.Source = ""; + } +} + +cmList ExpandRuleCommands(std::string const& command, + cmRulePlaceholderExpander::RuleVariables const& vars, + cmMakefile const* mf, std::string const& lang, + std::string const& launcher, + cmLocalGenerator* localGenerator, + cmRulePlaceholderExpander* rulePlaceholderExpander) +{ + std::string const extraCommands = + mf->GetSafeDefinition(cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS")); + cmList commands(command); + if (!commands.empty()) { + commands.front().insert(0, "${CODE_CHECK}"); + commands.front().insert(0, "${LAUNCHER}"); + } + if (!extraCommands.empty()) { + commands.append(extraCommands); + } + for (std::string& cmd : commands) { + cmd = cmStrCat(launcher, cmd); + rulePlaceholderExpander->ExpandRuleVariables(localGenerator, cmd, vars); + } + return commands; +} } void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang, @@ -883,20 +927,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang, cmNinjaRule rule(this->LanguageCompilerRule(lang, config, withScanning)); // If using a response file, move defines, includes, and flags into it. if (!responseFlag.empty()) { - rule.RspFile = "$RSP_FILE"; - rule.RspContent = - cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags); - flags = cmStrCat(responseFlag, rule.RspFile); - vars.Defines = ""; - vars.Includes = ""; - - // Swift consumes all source files in a module at once, which reaches - // command line length limits pretty quickly. Inject source files into the - // response file in this case as well. - if (lang == "Swift") { - rule.RspContent = cmStrCat(rule.RspContent, ' ', vars.Source); - vars.Source = ""; - } + SetupResponseFile(rule, vars, flags, lang, responseFlag); } // Tell ninja dependency format so all deps can be loaded into a database @@ -987,29 +1018,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang, // Rule for compiling object file. std::string const cmdVar = this->GetCompileTemplateVar(lang); std::string const& compileCmd = mf->GetRequiredDefinition(cmdVar); - cmList compileCmds(compileCmd); - - if (!compileCmds.empty()) { - compileCmds.front().insert(0, "${CODE_CHECK}"); - compileCmds.front().insert(0, "${LAUNCHER}"); - } + cmList compileCmds = ExpandRuleCommands(compileCmd, vars, mf, lang, launcher, + this->GetLocalGenerator(), + rulePlaceholderExpander.get()); if (!compileCmds.empty()) { compileCmds.front().insert(0, cldeps); } - auto const& extraCommands = this->GetMakefile()->GetSafeDefinition( - cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS")); - if (!extraCommands.empty()) { - compileCmds.append(extraCommands); - } - - for (auto& i : compileCmds) { - i = cmStrCat(launcher, i); - rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i, - vars); - } - rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds, config, config); @@ -2102,19 +2118,6 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement( return true; }; - // Swift modules only make sense to emit from things that can be imported. - // Executables that don't export symbols can't be imported, so don't try to - // emit a swiftmodule for them. It will break. - if (isImportableTarget(target)) { - std::string const emitModuleFlag = "-emit-module"; - std::string const modulePathFlag = "-emit-module-path"; - this->LocalGenerator->AppendFlags( - vars["FLAGS"], - { emitModuleFlag, modulePathFlag, - this->LocalGenerator->ConvertToOutputFormat( - moduleFilepath, cmOutputConverter::SHELL) }); - objBuild.Outputs.push_back(moduleFilepath); - } this->LocalGenerator->AppendFlags(vars["FLAGS"], cmStrCat("-module-name ", moduleName)); @@ -2128,6 +2131,20 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement( this->LocalGenerator->AppendFlags(vars["FLAGS"], this->GetFlags(language, config)); + + // Swift modules only make sense to emit from things that can be imported. + // Executables that don't export symbols can't be imported, so don't try to + // emit a swiftmodule for them. It will break. + if (isImportableTarget(target)) { + std::string const emitModuleFlag = "-emit-module"; + std::string const modulePathFlag = "-emit-module-path"; + this->LocalGenerator->AppendFlags( + vars["FLAGS"], + { emitModuleFlag, modulePathFlag, + this->LocalGenerator->ConvertToOutputFormat( + moduleFilepath, cmOutputConverter::SHELL) }); + objBuild.Outputs.push_back(moduleFilepath); + } vars["DEFINES"] = this->GetDefines(language, config); vars["INCLUDES"] = this->GetIncludes(language, config); vars["CONFIG"] = config; diff --git a/Tests/RunCMake/Swift/CMP0195-NEW-build-stdout.txt b/Tests/RunCMake/Swift/CMP0195-NEW-build-stdout.txt index 1b1f4f10e4..57a8a52f6a 100644 --- a/Tests/RunCMake/Swift/CMP0195-NEW-build-stdout.txt +++ b/Tests/RunCMake/Swift/CMP0195-NEW-build-stdout.txt @@ -1,2 +1,3 @@ swiftc(\.exe)?"? [^ -]* -emit-module -emit-module-path El(/|\\)((Debug|Release)(/|\\))?El\.swiftmodule(/|\\)[-_a-z0-9]+\.swiftmodule -module-name El +]* -module-name El [^ +]* -emit-module -emit-module-path El(/|\\)((Debug|Release)(/|\\))?El\.swiftmodule(/|\\)[-_a-z0-9]+\.swiftmodule diff --git a/Tests/RunCMake/Swift/CMP0195-OLD-build-stdout.txt b/Tests/RunCMake/Swift/CMP0195-OLD-build-stdout.txt index ff096b8083..65cbf1fb5a 100644 --- a/Tests/RunCMake/Swift/CMP0195-OLD-build-stdout.txt +++ b/Tests/RunCMake/Swift/CMP0195-OLD-build-stdout.txt @@ -1,2 +1,3 @@ swiftc(\.exe)?"? [^ -]* -emit-module -emit-module-path El(/|\\)((Debug|Release)(/|\\))?El\.swiftmodule -module-name El +]* -module-name El [^ +]* -emit-module -emit-module-path El(/|\\)((Debug|Release)(/|\\))?El\.swiftmodule diff --git a/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-darwin.txt b/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-darwin.txt index 4d5c5d5bcc..2108a8feeb 100644 --- a/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-darwin.txt +++ b/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-darwin.txt @@ -1,12 +1,12 @@ .*swiftc(\.exe)?"? [^ ]* -parse-as-library -static[^ -]* -emit-module -emit-module-path (Debug/|Release/)?StaticLibrary\.swiftmodule[^ ]* -module-name StaticLibrary [^ +]* -emit-module -emit-module-path (Debug/|Release/)?StaticLibrary\.swiftmodule [^ ]* .*swiftc(\.exe)?"? [^ ]* -parse-as-library[^ -]* -emit-module -emit-module-path (debug|release)/modules/DynamicLibrary\.swiftmodule[^ ]* -module-name DynamicLibrary [^ +]* -emit-module -emit-module-path (debug|release)/modules/DynamicLibrary\.swiftmodule [^ ]* .*swiftc(\.exe)?"? [^ ]* -emit-library [^ @@ -14,7 +14,7 @@ ]* .*swiftc(\.exe)?"? [^ ]* -parse-as-library[^ -]* -emit-module -emit-module-path Modules/(Debug/|Release/)?DynamicLibrary2\.swiftmodule[^ -]* -module-name DynamicLibrary2[^ +]* -module-name DynamicLibrary2 [^ +]* -emit-module -emit-module-path Modules/(Debug/|Release/)?DynamicLibrary2\.swiftmodule [^ ]* .*swiftc(\.exe)?"? -j [0-9]+ -num-threads [0-9]+ -c -module-name Executable diff --git a/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-windows.txt b/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-windows.txt index 239164c2ef..1ad6315aa9 100644 --- a/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-windows.txt +++ b/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout-windows.txt @@ -1,12 +1,12 @@ .*swiftc(\.exe)?"? [^ ]* -parse-as-library -static[^ -]* -emit-module -emit-module-path (Debug\\|Release\\)?StaticLibrary\.swiftmodule[^ ]* -module-name StaticLibrary [^ +]* -emit-module -emit-module-path (Debug\\|Release\\)?StaticLibrary\.swiftmodule [^ ]* .*swiftc(\.exe)?"? [^ ]* -parse-as-library[^ -]* -emit-module -emit-module-path (debug|release)\\modules\\DynamicLibrary\.swiftmodule[^ ]* -module-name DynamicLibrary [^ +]* -emit-module -emit-module-path (debug|release)\\modules\\DynamicLibrary\.swiftmodule [^ ]* .*swiftc(\.exe)?"? [^ ]* -emit-library [^ @@ -14,7 +14,7 @@ ]* .*swiftc(\.exe)?"? [^ ]* -parse-as-library[^ -]* -emit-module -emit-module-path Modules\\(Debug\\|Release\\)?DynamicLibrary2\.swiftmodule[^ ]* -module-name DynamicLibrary2 [^ +]* -emit-module -emit-module-path Modules\\(Debug\\|Release\\)?DynamicLibrary2\.swiftmodule [^ ]* .*swiftc(\.exe)?"? -j [0-9]+ -num-threads [0-9]+ -c -module-name Executable diff --git a/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout.txt b/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout.txt index 7f2a34185c..f9f261b4c4 100644 --- a/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout.txt +++ b/Tests/RunCMake/Swift/SwiftLibraryModuleCommand-check-stdout.txt @@ -1,12 +1,12 @@ .*swiftc(\.exe)?"? [^ ]* -parse-as-library -static[^ -]* -emit-module -emit-module-path (Debug/|Release/)?StaticLibrary\.swiftmodule[^ ]* -module-name StaticLibrary [^ +]* -emit-module -emit-module-path (Debug/|Release/)?StaticLibrary\.swiftmodule [^ ]* .*swiftc(\.exe)?"? [^ ]* -parse-as-library[^ -]* -emit-module -emit-module-path (debug|release)/modules/DynamicLibrary\.swiftmodule[^ ]* -module-name DynamicLibrary [^ +]* -emit-module -emit-module-path (debug|release)/modules/DynamicLibrary\.swiftmodule [^ ]* .*swiftc(\.exe)?"? [^ ]* -emit-library [^ @@ -14,7 +14,7 @@ ]* .*swiftc(\.exe)?"? [^ ]* -parse-as-library[^ -]* -emit-module -emit-module-path Modules/(Debug/|Release/)?DynamicLibrary2\.swiftmodule[^ -]* -module-name DynamicLibrary2[^ +]* -module-name DynamicLibrary2 [^ +]* -emit-module -emit-module-path Modules/(Debug/|Release/)?DynamicLibrary2\.swiftmodule [^ ]* .*swiftc(\.exe)?"? -j [0-9]+ -num-threads [0-9]+ -c -module-name Executable