From 2b1cc175ee913477c3f1dc6978dd63b2fdaff7e2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 15 Dec 2020 06:50:33 -0500 Subject: Help: Clarify version adding add_custom_{command,target} OUTPUT genex support Update the documentation added by commit c257c25419 (add_custom_{command,target}: Add genex support to OUTPUT and BYPRODUCTS, 2020-10-19) to use sphinx markup instead of prose to specify the version in which the feature was added. --- Help/command/add_custom_command.rst | 68 ++++++++++++++++++++----------------- Help/command/add_custom_target.rst | 5 +-- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index 4464ad6..0b7e796 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -79,8 +79,9 @@ The options are: The :ref:`Makefile Generators` will remove ``BYPRODUCTS`` and other :prop_sf:`GENERATED` files during ``make clean``. - Since CMake 3.20, arguments to ``BYPRODUCTS`` may use - :manual:`generator expressions `. + .. versionadded:: 3.20 + Arguments to ``BYPRODUCTS`` may use + :manual:`generator expressions `. ``COMMAND`` Specify the command-line(s) to execute at build time. @@ -229,8 +230,9 @@ The options are: as a file on disk it should be marked with the :prop_sf:`SYMBOLIC` source file property. - Since CMake 3.20, arguments to ``OUTPUT`` may use - :manual:`generator expressions `. + .. versionadded:: 3.20 + Arguments to ``OUTPUT`` may use + :manual:`generator expressions `. ``USES_TERMINAL`` .. versionadded:: 3.2 @@ -291,23 +293,24 @@ adds a custom command to run ``someTool`` to generate ``out.c`` and then compile the generated source as part of a library. The generation rule will re-run whenever ``in.txt`` changes. -Since CMake 3.20, one may use generator expressions to specify -per-configuration outputs. For example, the code: +.. versionadded:: 3.20 + One may use generator expressions to specify per-configuration outputs. + For example, the code: -.. code-block:: cmake + .. code-block:: cmake - add_custom_command( - OUTPUT "out-$.c" - COMMAND someTool -i ${CMAKE_CURRENT_SOURCE_DIR}/in.txt - -o "out-$.c" - -c "$" - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/in.txt - VERBATIM) - add_library(myLib "out-$.c") + add_custom_command( + OUTPUT "out-$.c" + COMMAND someTool -i ${CMAKE_CURRENT_SOURCE_DIR}/in.txt + -o "out-$.c" + -c "$" + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/in.txt + VERBATIM) + add_library(myLib "out-$.c") -adds a custom command to run ``someTool`` to generate ``out-.c``, -where ```` is the build configuration, and then compile the generated -source as part of a library. + adds a custom command to run ``someTool`` to generate ``out-.c``, + where ```` is the build configuration, and then compile the generated + source as part of a library. Build Events ^^^^^^^^^^^^ @@ -377,20 +380,21 @@ For example, the code: will run ``someHasher`` to produce a ``.hash`` file next to the executable after linking. -Since CMake 3.20, one may use generator expressions to specify -per-configuration byproducts. For example, the code: +.. versionadded:: 3.20 + One may use generator expressions to specify per-configuration byproducts. + For example, the code: -.. code-block:: cmake + .. code-block:: cmake - add_library(myPlugin MODULE myPlugin.c) - add_custom_command( - TARGET myPlugin POST_BUILD - COMMAND someHasher -i "$" - --as-code "myPlugin-hash-$.c" - BYPRODUCTS "myPlugin-hash-$.c" - VERBATIM) - add_executable(myExe myExe.c "myPlugin-hash-$.c") + add_library(myPlugin MODULE myPlugin.c) + add_custom_command( + TARGET myPlugin POST_BUILD + COMMAND someHasher -i "$" + --as-code "myPlugin-hash-$.c" + BYPRODUCTS "myPlugin-hash-$.c" + VERBATIM) + add_executable(myExe myExe.c "myPlugin-hash-$.c") -will run ``someHasher`` after linking ``myPlugin``, e.g. to produce a ``.c`` -file containing code to check the hash of ``myPlugin`` that the ``myExe`` -executable can use to verify it before loading. + will run ``someHasher`` after linking ``myPlugin``, e.g. to produce a ``.c`` + file containing code to check the hash of ``myPlugin`` that the ``myExe`` + executable can use to verify it before loading. diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst index 85e1e16..2beb519 100644 --- a/Help/command/add_custom_target.rst +++ b/Help/command/add_custom_target.rst @@ -54,8 +54,9 @@ The options are: The :ref:`Makefile Generators` will remove ``BYPRODUCTS`` and other :prop_sf:`GENERATED` files during ``make clean``. - Since CMake 3.20, arguments to ``BYPRODUCTS`` may use - :manual:`generator expressions `. + .. versionadded:: 3.20 + Arguments to ``BYPRODUCTS`` may use + :manual:`generator expressions `. ``COMMAND`` Specify the command-line(s) to execute at build time. -- cgit v0.12 From d29da8ed3eb757d10643039aa738bad0727c1b6a Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 30 Oct 2020 11:17:24 -0400 Subject: cmMakefile: Simplify custom target 'force' output name generation Remove unnecessary check of policy CMP0049. The policy can never trigger on our internally-generated name because it has no variable references. The rename in commit 0ed5ce4cd8 (cmTarget: Rename AddSource method for backward compatibility., 2014-03-17, v3.1.0-rc1~688^2~17) made it look like this code path depended on CMP0049. Then commit 0e1faa28cb (cmMakefile: Separate custom command setup from actual creation, 2019-09-14, v3.16.0-rc1~85^2) and commit ea1bed34b2 (cmMakefile: Extract utilities used for creation of custom commands, 2019-09-21, v3.16.0-rc1~52^2~1) built additional infrastructure to thread that dependence through the call stack. Remove it all. --- Source/cmCustomCommandTypes.h | 7 ------- Source/cmLocalGenerator.cxx | 8 +++----- Source/cmLocalGenerator.h | 2 +- Source/cmMakefile.cxx | 27 ++++++++++----------------- Source/cmMakefile.h | 4 ++-- 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/Source/cmCustomCommandTypes.h b/Source/cmCustomCommandTypes.h index 5c900ce..324da9e 100644 --- a/Source/cmCustomCommandTypes.h +++ b/Source/cmCustomCommandTypes.h @@ -27,10 +27,3 @@ enum class cmObjectLibraryCommands Reject, Accept }; - -/** Utility target output source file name. */ -struct cmUtilityOutput -{ - std::string Name; - std::string NameCMP0049; -}; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9f9d725..acc4c77 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4115,7 +4115,7 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg, void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, cmCommandOrigin origin, cmTarget* target, - const cmUtilityOutput& force, const char* workingDir, + std::string const& force, const char* workingDir, const std::vector& byproducts, const std::vector& depends, const cmCustomCommandLines& commandLines, @@ -4131,7 +4131,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, std::string no_main_dependency; cmImplicitDependsList no_implicit_depends; cmSourceFile* rule = AddCustomCommand( - lg, lfbt, origin, { force.Name }, byproducts, depends, no_main_dependency, + lg, lfbt, origin, { force }, byproducts, depends, no_main_dependency, no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"", job_pool, stdPipesUTF8); @@ -4139,9 +4139,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, lg.AddTargetByproducts(target, byproducts, lfbt, origin); } - if (!force.NameCMP0049.empty()) { - target->AddSource(force.NameCMP0049); - } + target->AddSource(force); } std::vector ComputeISPCObjectSuffixes(cmGeneratorTarget* target) diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 581badb..0c7ea45 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -684,7 +684,7 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg, void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, cmCommandOrigin origin, cmTarget* target, - const cmUtilityOutput& force, const char* workingDir, + std::string const& force, const char* workingDir, const std::vector& byproducts, const std::vector& depends, const cmCustomCommandLines& commandLines, diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 4e93785..6743a89 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1257,25 +1257,18 @@ void cmMakefile::AppendCustomCommandToOutput( } } -cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target) +std::string cmMakefile::GetUtilityOutput(cmTarget* target) { std::string force = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", target->GetName()); - std::string forceCMP0049 = target->GetSourceCMP0049(force); - { - cmSourceFile* sf = nullptr; - if (!forceCMP0049.empty()) { - sf = this->GetOrCreateSource(forceCMP0049, false, - cmSourceFileLocationKind::Known); - } - // The output is not actually created so mark it symbolic. - if (sf) { - sf->SetProperty("SYMBOLIC", "1"); - } else { - cmSystemTools::Error("Could not get source file entry for " + force); - } + // The output is not actually created so mark it symbolic. + if (cmSourceFile* sf = this->GetOrCreateSource( + force, false, cmSourceFileLocationKind::Known)) { + sf->SetProperty("SYMBOLIC", "1"); + } else { + cmSystemTools::Error("Could not get source file entry for " + force); } - return { std::move(force), std::move(forceCMP0049) }; + return force; } cmTarget* cmMakefile::AddUtilityCommand( @@ -1295,8 +1288,8 @@ cmTarget* cmMakefile::AddUtilityCommand( } // Get the output name of the utility target and mark it generated. - cmUtilityOutput force = this->GetUtilityOutput(target); - this->GetOrCreateGeneratedSource(force.Name); + std::string force = this->GetUtilityOutput(target); + this->GetOrCreateGeneratedSource(force); // Always create the byproduct sources and mark them generated. this->CreateGeneratedOutputs(byproducts); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index a864074..cab3e17 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -243,9 +243,9 @@ public: bool excludeFromAll = false); /** - * Return the utility target output source file name and the CMP0049 name. + * Return the utility target output source file name. */ - cmUtilityOutput GetUtilityOutput(cmTarget* target); + std::string GetUtilityOutput(cmTarget* target); /** * Dispatch adding a utility to the build. A utility target is a command -- cgit v0.12 From 7b64b0cd5a4046bf8743c3e2d3c57cb470bfa95f Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 22 Oct 2020 13:57:54 -0400 Subject: cmLocalGenerator: Refactor custom command generator construction Add support for constructing and using multiple generators for one custom command. cmGeneratorTarget contains a code path that needs this behavior when used with Ninja but not other generators, so use virtual dispatch through cmLocalGenerator. --- Source/cmGeneratorTarget.cxx | 15 ++-- Source/cmLocalGenerator.cxx | 9 +++ Source/cmLocalGenerator.h | 4 + Source/cmLocalNinjaGenerator.cxx | 167 +++++++++++++++++++++------------------ Source/cmLocalNinjaGenerator.h | 3 + 5 files changed, 113 insertions(+), 85 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b444edd..5293f52 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3079,15 +3079,16 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc) std::set depends; for (std::string const& config : this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) { - cmCustomCommandGenerator ccg(cc, config, this->LocalGenerator); + for (cmCustomCommandGenerator const& ccg : + this->LocalGenerator->MakeCustomCommandGenerators(cc, config)) { + // Collect target-level dependencies referenced in command lines. + for (auto const& util : ccg.GetUtilities()) { + this->GeneratorTarget->Target->AddUtility(util); + } - // Collect target-level dependencies referenced in command lines. - for (auto const& util : ccg.GetUtilities()) { - this->GeneratorTarget->Target->AddUtility(util); + // Collect file-level dependencies referenced in DEPENDS. + depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end()); } - - // Collect file-level dependencies referenced in DEPENDS. - depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end()); } // Queue file-level dependencies. diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index acc4c77..dc4a3fc 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4232,6 +4232,15 @@ cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput( return nullptr; } +std::vector +cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc, + std::string const& config) +{ + std::vector ccgs; + ccgs.emplace_back(cc, config, this); + return ccgs; +} + std::vector cmLocalGenerator::ExpandCustomCommandOutputPaths( cmCompiledGeneratorExpression const& cge, std::string const& config) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0c7ea45..db239c0 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -24,6 +24,7 @@ class cmCompiledGeneratorExpression; class cmComputeLinkInformation; +class cmCustomCommand; class cmCustomCommandGenerator; class cmCustomCommandLines; class cmGeneratorTarget; @@ -363,6 +364,9 @@ public: bool command_expand_lists = false, const std::string& job_pool = "", bool stdPipesUTF8 = false); + virtual std::vector MakeCustomCommandGenerators( + cmCustomCommand const& cc, std::string const& config); + std::vector ExpandCustomCommandOutputPaths( cmCompiledGeneratorExpression const& cge, std::string const& config); std::vector ExpandCustomCommandOutputGenex( diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index d90a37b..a36c479 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -575,97 +575,108 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( return; } - bool transformDepfile = false; - auto cmp0116 = this->GetPolicyStatus(cmPolicies::CMP0116); - switch (cmp0116) { - case cmPolicies::OLD: - case cmPolicies::WARN: - break; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - transformDepfile = true; - break; - } + for (cmCustomCommandGenerator const& ccg : + this->MakeCustomCommandGenerators(*cc, config)) { - cmCustomCommandGenerator ccg(*cc, config, this, transformDepfile); + const std::vector& outputs = ccg.GetOutputs(); + const std::vector& byproducts = ccg.GetByproducts(); - const std::vector& outputs = ccg.GetOutputs(); - const std::vector& byproducts = ccg.GetByproducts(); - - bool symbolic = false; - for (std::string const& output : outputs) { - if (cmSourceFile* sf = this->Makefile->GetSource(output)) { - if (sf->GetPropertyAsBool("SYMBOLIC")) { - symbolic = true; - break; + bool symbolic = false; + for (std::string const& output : outputs) { + if (cmSourceFile* sf = this->Makefile->GetSource(output)) { + if (sf->GetPropertyAsBool("SYMBOLIC")) { + symbolic = true; + break; + } } } - } - cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size()); - std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(), - gg->MapToNinjaPath()); - std::transform(byproducts.begin(), byproducts.end(), - ninjaOutputs.begin() + outputs.size(), gg->MapToNinjaPath()); + cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size()); + std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(), + gg->MapToNinjaPath()); + std::transform(byproducts.begin(), byproducts.end(), + ninjaOutputs.begin() + outputs.size(), + gg->MapToNinjaPath()); - for (std::string const& ninjaOutput : ninjaOutputs) { - gg->SeenCustomCommandOutput(ninjaOutput); - } + for (std::string const& ninjaOutput : ninjaOutputs) { + gg->SeenCustomCommandOutput(ninjaOutput); + } - cmNinjaDeps ninjaDeps; - this->AppendCustomCommandDeps(ccg, ninjaDeps, config); + cmNinjaDeps ninjaDeps; + this->AppendCustomCommandDeps(ccg, ninjaDeps, config); - std::vector cmdLines; - this->AppendCustomCommandLines(ccg, cmdLines); + std::vector cmdLines; + this->AppendCustomCommandLines(ccg, cmdLines); - if (cmdLines.empty()) { - cmNinjaBuild build("phony"); - build.Comment = "Phony custom command for " + ninjaOutputs[0]; - build.Outputs = std::move(ninjaOutputs); - build.ExplicitDeps = std::move(ninjaDeps); - build.OrderOnlyDeps = orderOnlyDeps; - gg->WriteBuild(this->GetImplFileStream(config), build); - } else { - std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]); - // Hash full path to make unique. - customStep += '-'; - cmCryptoHash hash(cmCryptoHash::AlgoSHA256); - customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7); - - std::string depfile = cc->GetDepfile(); - if (!depfile.empty()) { - switch (cmp0116) { - case cmPolicies::WARN: - if (this->GetCurrentBinaryDirectory() != - this->GetBinaryDirectory() || - this->Makefile->PolicyOptionalWarningEnabled( - "CMAKE_POLICY_WARNING_CMP0116")) { - this->GetCMakeInstance()->IssueMessage( - MessageType::AUTHOR_WARNING, - cmPolicies::GetPolicyWarning(cmPolicies::CMP0116), - cc->GetBacktrace()); - } - CM_FALLTHROUGH; - case cmPolicies::OLD: - break; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - cmSystemTools::MakeDirectory( - cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d")); - depfile = ccg.GetInternalDepfile(); - break; + if (cmdLines.empty()) { + cmNinjaBuild build("phony"); + build.Comment = "Phony custom command for " + ninjaOutputs[0]; + build.Outputs = std::move(ninjaOutputs); + build.ExplicitDeps = std::move(ninjaDeps); + build.OrderOnlyDeps = orderOnlyDeps; + gg->WriteBuild(this->GetImplFileStream(config), build); + } else { + std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]); + // Hash full path to make unique. + customStep += '-'; + cmCryptoHash hash(cmCryptoHash::AlgoSHA256); + customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7); + + std::string depfile = cc->GetDepfile(); + if (!depfile.empty()) { + switch (this->GetPolicyStatus(cmPolicies::CMP0116)) { + case cmPolicies::WARN: + if (this->GetCurrentBinaryDirectory() != + this->GetBinaryDirectory() || + this->Makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0116")) { + this->GetCMakeInstance()->IssueMessage( + MessageType::AUTHOR_WARNING, + cmPolicies::GetPolicyWarning(cmPolicies::CMP0116), + cc->GetBacktrace()); + } + CM_FALLTHROUGH; + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + cmSystemTools::MakeDirectory( + cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d")); + depfile = ccg.GetInternalDepfile(); + break; + } } + + gg->WriteCustomCommandBuild( + this->BuildCommandLine(cmdLines, customStep), + this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], + depfile, cc->GetJobPool(), cc->GetUsesTerminal(), + /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config, + ninjaDeps, orderOnlyDeps); } + } +} - gg->WriteCustomCommandBuild( - this->BuildCommandLine(cmdLines, customStep), - this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], - depfile, cc->GetJobPool(), cc->GetUsesTerminal(), - /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config, - ninjaDeps, orderOnlyDeps); +std::vector +cmLocalNinjaGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc, + std::string const& config) +{ + bool transformDepfile = false; + switch (this->GetPolicyStatus(cmPolicies::CMP0116)) { + case cmPolicies::OLD: + case cmPolicies::WARN: + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + transformDepfile = true; + break; } + + std::vector ccgs; + ccgs.emplace_back(cc, config, this, transformDepfile); + return ccgs; } void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc, diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index e81402c..760aea0 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -70,6 +70,9 @@ public: const std::string& fileConfig, cmNinjaTargetDepends depends); + std::vector MakeCustomCommandGenerators( + cmCustomCommand const& cc, std::string const& config) override; + void AddCustomCommandTarget(cmCustomCommand const* cc, cmGeneratorTarget* target); void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg, -- cgit v0.12 From 15467f12f796205f97721f43ae7d9ee7cdc47466 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 30 Oct 2020 11:48:43 -0400 Subject: cmLocalGenerator: Adopt custom target 'force' output name generation --- Source/cmLocalGenerator.cxx | 28 ++++++++++++++++++++++------ Source/cmLocalGenerator.h | 4 +++- Source/cmMakefile.cxx | 22 ++-------------------- Source/cmMakefile.h | 5 ----- 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index dc4a3fc..cd18670 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1129,9 +1129,8 @@ cmTarget* cmLocalGenerator::AddUtilityCommand( detail::AddUtilityCommand( *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target, - this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends, - commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists, - job_pool, stdPipesUTF8); + workingDir, byproducts, depends, commandLines, escapeOldStyle, comment, + uses_terminal, command_expand_lists, job_pool, stdPipesUTF8); return target; } @@ -4115,7 +4114,7 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg, void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, cmCommandOrigin origin, cmTarget* target, - std::string const& force, const char* workingDir, + const char* workingDir, const std::vector& byproducts, const std::vector& depends, const cmCustomCommandLines& commandLines, @@ -4128,10 +4127,13 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, comment = ""; } + // Create the generated symbolic output name of the utility target. + std::string output = lg.CreateUtilityOutput(target->GetName()); + std::string no_main_dependency; cmImplicitDependsList no_implicit_depends; cmSourceFile* rule = AddCustomCommand( - lg, lfbt, origin, { force }, byproducts, depends, no_main_dependency, + lg, lfbt, origin, { output }, byproducts, depends, no_main_dependency, no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"", job_pool, stdPipesUTF8); @@ -4139,7 +4141,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, lg.AddTargetByproducts(target, byproducts, lfbt, origin); } - target->AddSource(force); + target->AddSource(output); } std::vector ComputeISPCObjectSuffixes(cmGeneratorTarget* target) @@ -4232,6 +4234,20 @@ cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput( return nullptr; } +std::string cmLocalGenerator::CreateUtilityOutput( + std::string const& targetName) +{ + std::string force = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", targetName); + // The output is not actually created so mark it symbolic. + if (cmSourceFile* sf = this->Makefile->GetOrCreateGeneratedSource(force)) { + sf->SetProperty("SYMBOLIC", "1"); + } else { + cmSystemTools::Error("Could not get source file entry for " + force); + } + return force; +} + std::vector cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc, std::string const& config) diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index db239c0..d9c2c1e 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -364,6 +364,8 @@ public: bool command_expand_lists = false, const std::string& job_pool = "", bool stdPipesUTF8 = false); + std::string CreateUtilityOutput(std::string const& targetName); + virtual std::vector MakeCustomCommandGenerators( cmCustomCommand const& cc, std::string const& config); @@ -688,7 +690,7 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg, void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, cmCommandOrigin origin, cmTarget* target, - std::string const& force, const char* workingDir, + const char* workingDir, const std::vector& byproducts, const std::vector& depends, const cmCustomCommandLines& commandLines, diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 6743a89..028688d 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1257,20 +1257,6 @@ void cmMakefile::AppendCustomCommandToOutput( } } -std::string cmMakefile::GetUtilityOutput(cmTarget* target) -{ - std::string force = cmStrCat(this->GetCurrentBinaryDirectory(), - "/CMakeFiles/", target->GetName()); - // The output is not actually created so mark it symbolic. - if (cmSourceFile* sf = this->GetOrCreateSource( - force, false, cmSourceFileLocationKind::Known)) { - sf->SetProperty("SYMBOLIC", "1"); - } else { - cmSystemTools::Error("Could not get source file entry for " + force); - } - return force; -} - cmTarget* cmMakefile::AddUtilityCommand( const std::string& utilityName, bool excludeFromAll, const char* workingDir, const std::vector& byproducts, @@ -1287,10 +1273,6 @@ cmTarget* cmMakefile::AddUtilityCommand( return target; } - // Get the output name of the utility target and mark it generated. - std::string force = this->GetUtilityOutput(target); - this->GetOrCreateGeneratedSource(force); - // Always create the byproduct sources and mark them generated. this->CreateGeneratedOutputs(byproducts); @@ -1303,8 +1285,8 @@ cmTarget* cmMakefile::AddUtilityCommand( [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) { BacktraceGuard guard(this->Backtrace, lfbt); detail::AddUtilityCommand(lg, lfbt, cmCommandOrigin::Project, target, - force, GetCStrOrNull(workingStr), byproducts, - depends, commandLines, escapeOldStyle, + GetCStrOrNull(workingStr), byproducts, depends, + commandLines, escapeOldStyle, GetCStrOrNull(commentStr), uses_terminal, command_expand_lists, job_pool, stdPipesUTF8); }); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index cab3e17..f18f70c 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -243,11 +243,6 @@ public: bool excludeFromAll = false); /** - * Return the utility target output source file name. - */ - std::string GetUtilityOutput(cmTarget* target); - - /** * Dispatch adding a utility to the build. A utility target is a command * that is run every time the target is built. */ -- cgit v0.12 From dcf9f4d2f71d7c608ce24b690d30d465df51dc71 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Wed, 9 Dec 2020 16:39:15 -0500 Subject: Ninja Multi-Config: Add support for cross-config custom commands Co-Author: Brad King --- Help/command/add_custom_command.rst | 9 + Help/command/add_custom_target.rst | 9 + Help/generator/Ninja Multi-Config.rst | 44 +++++ Help/manual/cmake-generator-expressions.7.rst | 18 ++ Help/release/dev/custom-command-output-genex.rst | 5 + Source/cmCustomCommandGenerator.cxx | 132 +++++++++++--- Source/cmCustomCommandGenerator.h | 11 +- Source/cmGeneratorTarget.cxx | 2 +- Source/cmGlobalNinjaGenerator.cxx | 97 +++++++++-- Source/cmGlobalNinjaGenerator.h | 45 ++++- Source/cmLocalGenerator.cxx | 6 +- Source/cmLocalGenerator.h | 4 +- Source/cmLocalNinjaGenerator.cxx | 194 ++++++++++++++++----- Source/cmLocalNinjaGenerator.h | 11 +- Source/cmNinjaUtilityTargetGenerator.cxx | 53 ++++-- Source/cmNinjaUtilityTargetGenerator.h | 4 + .../codemodel-v2-data/targets/custom_tgt.json | 8 +- 17 files changed, 547 insertions(+), 105 deletions(-) diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index 0b7e796..567af16 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -398,3 +398,12 @@ after linking. will run ``someHasher`` after linking ``myPlugin``, e.g. to produce a ``.c`` file containing code to check the hash of ``myPlugin`` that the ``myExe`` executable can use to verify it before loading. + +Ninja Multi-Config +^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.20 + + ``add_custom_command`` supports the :generator:`Ninja Multi-Config` + generator's cross-config capabilities. See the generator documentation + for more information. diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst index 2beb519..9c4d60d 100644 --- a/Help/command/add_custom_target.rst +++ b/Help/command/add_custom_target.rst @@ -168,3 +168,12 @@ The options are: .. versionadded:: 3.13 Arguments to ``WORKING_DIRECTORY`` may use :manual:`generator expressions `. + +Ninja Multi-Config +^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.20 + + ``add_custom_target`` supports the :generator:`Ninja Multi-Config` + generator's cross-config capabilities. See the generator documentation + for more information. diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst index 112db74..d1df42b 100644 --- a/Help/generator/Ninja Multi-Config.rst +++ b/Help/generator/Ninja Multi-Config.rst @@ -86,3 +86,47 @@ used to generate ``generated.c``, which would be used to build the ``Debug`` configuration of ``generated``. This is useful for running a release-optimized version of a generator utility while still building the debug version of the targets built with the generated code. + +Custom Commands +^^^^^^^^^^^^^^^ + +.. versionadded:: 3.20 + +The ``Ninja Multi-Config`` generator adds extra capabilities to +:command:`add_custom_command` and :command:`add_custom_target` through its +cross-config mode. The ``COMMAND``, ``DEPENDS``, and ``WORKING_DIRECTORY`` +arguments can be evaluated in the context of either the "command config" (the +"native" configuration of the ``build-.ninja`` file in use) or the +"output config" (the configuration used to evaluate the ``OUTPUT`` and +``BYPRODUCTS``). + +If either ``OUTPUT`` or ``BYPRODUCTS`` names a path that is common to +more than one configuration (e.g. it does not use any generator expressions), +all arguments are evaluated in the command config by default. +If all ``OUTPUT`` and ``BYPRODUCTS`` paths are unique to each configuration +(e.g. by using the ``$`` generator expression), the first argument of +``COMMAND`` is still evaluated in the command config by default, while all +subsequent arguments, as well as the arguments to ``DEPENDS`` and +``WORKING_DIRECTORY``, are evaluated in the output config. These defaults can +be overridden with the ``$`` and ``$`` +generator-expressions. Note that if a target is specified by its name in +``DEPENDS``, or as the first argument of ``COMMAND``, it is always evaluated +in the command config, even if it is wrapped in ``$`` +(because its plain name is not a generator expression). + +As an example, consider the following: + +.. code-block:: cmake + + add_custom_command( + OUTPUT "$.txt" + COMMAND generator "$.txt" "$>" "$>" + DEPENDS tgt1 "$" "$>" "$>" + ) + +Assume that ``generator``, ``tgt1``, ``tgt2``, ``tgt3``, and ``tgt4`` are all +executable targets, and assume that ``$.txt`` is built in the ``Debug`` +output config using the ``Release`` command config. The ``Release`` build of +the ``generator`` target is called with ``Debug.txt Debug Release`` as +arguments. The command depends on the ``Release`` builds of ``tgt1`` and +``tgt4``, and the ``Debug`` builds of ``tgt2`` and ``tgt3``. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 482b14e..c949ce1 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -816,6 +816,24 @@ Output-Related Expressions ``;`` on Windows). Be sure to enclose the argument containing this genex in double quotes in CMake source code so that ``;`` does not split arguments. +``$`` + .. versionadded:: 3.20 + + Only valid in :command:`add_custom_command` and :command:`add_custom_target` + as the outer-most generator expression in an argument. + With the :generator:`Ninja Multi-Config` generator, generator expressions + in ``...`` are evaluated using the custom command's "output config". + With other generators, the content of ``...`` is evaluated normally. + +``$`` + .. versionadded:: 3.20 + + Only valid in :command:`add_custom_command` and :command:`add_custom_target` + as the outer-most generator expression in an argument. + With the :generator:`Ninja Multi-Config` generator, generator expressions + in ``...`` are evaluated using the custom command's "command config". + With other generators, the content of ``...`` is evaluated normally. + Debugging ========= diff --git a/Help/release/dev/custom-command-output-genex.rst b/Help/release/dev/custom-command-output-genex.rst index 215349f..471713a 100644 --- a/Help/release/dev/custom-command-output-genex.rst +++ b/Help/release/dev/custom-command-output-genex.rst @@ -4,3 +4,8 @@ custom-command-output-genex * :command:`add_custom_command` and :command:`add_custom_target` now support :manual:`generator expressions ` in their ``OUTPUT`` and ``BYPRODUCTS`` options. + + Their ``COMMAND``, ``WORKING_DIRECTORY``, and ``DEPENDS`` options gained + support for new generator expressions ``$`` and + ``$`` that control cross-config handling when using + the :generator:`Ninja Multi-Config` generator. diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 64cd88e..c67497a 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -7,7 +7,9 @@ #include #include +#include #include +#include #include "cmCryptoHash.h" #include "cmCustomCommand.h" @@ -24,15 +26,95 @@ #include "cmTransformDepfile.h" namespace { +std::string EvaluateSplitConfigGenex( + cm::string_view input, cmGeneratorExpression const& ge, cmLocalGenerator* lg, + bool useOutputConfig, std::string const& outputConfig, + std::string const& commandConfig, + std::set>>* utils = nullptr) +{ + std::string result; + + while (!input.empty()) { + // Copy non-genex content directly to the result. + std::string::size_type pos = input.find("$<"); + result += input.substr(0, pos); + if (pos == std::string::npos) { + break; + } + input = input.substr(pos); + + // Find the balanced end of this regex. + size_t nestingLevel = 1; + for (pos = 2; pos < input.size(); ++pos) { + cm::string_view cur = input.substr(pos); + if (cmHasLiteralPrefix(cur, "$<")) { + ++nestingLevel; + ++pos; + continue; + } + if (cmHasLiteralPrefix(cur, ">")) { + --nestingLevel; + if (nestingLevel == 0) { + ++pos; + break; + } + } + } + + // Split this genex from following input. + cm::string_view genex = input.substr(0, pos); + input = input.substr(pos); + + // Convert an outer COMMAND_CONFIG or OUTPUT_CONFIG to the matching config. + std::string const* config = + useOutputConfig ? &outputConfig : &commandConfig; + if (nestingLevel == 0) { + static cm::string_view const COMMAND_CONFIG = "$ cge = + ge.Parse(std::string(genex)); + result += cge->Evaluate(lg, *config); + + // Record targets referenced by the genex. + if (utils) { + // FIXME: What is the proper condition for a cross-dependency? + bool const cross = !useOutputConfig; + for (cmGeneratorTarget* gt : cge->GetTargets()) { + utils->emplace(BT>( + { gt->GetName(), cross }, cge->GetBacktrace())); + } + } + } + + return result; +} + std::vector EvaluateDepends(std::vector const& paths, cmGeneratorExpression const& ge, cmLocalGenerator* lg, - std::string const& config) + std::string const& outputConfig, + std::string const& commandConfig) { std::vector depends; for (std::string const& p : paths) { - std::unique_ptr cge = ge.Parse(p); - std::string const& ep = cge->Evaluate(lg, config); + std::string const& ep = + EvaluateSplitConfigGenex(p, ge, lg, /*useOutputConfig=*/true, + /*outputConfig=*/outputConfig, + /*commandConfig=*/commandConfig); cm::append(depends, cmExpandedList(ep)); } for (std::string& p : depends) { @@ -59,12 +141,12 @@ std::vector EvaluateOutputs(std::vector const& paths, } } -cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, - std::string config, - cmLocalGenerator* lg, - bool transformDepfile) +cmCustomCommandGenerator::cmCustomCommandGenerator( + cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg, + bool transformDepfile, cm::optional crossConfig) : CC(&cc) - , Config(std::move(config)) + , OutputConfig(crossConfig ? *crossConfig : config) + , CommandConfig(std::move(config)) , LG(lg) , OldStyle(cc.GetEscapeOldStyle()) , MakeVars(cc.GetEscapeAllowMakeVars()) @@ -75,18 +157,20 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines(); for (cmCustomCommandLine const& cmdline : cmdlines) { cmCustomCommandLine argv; + // For the command itself, we default to the COMMAND_CONFIG. + bool useOutputConfig = false; for (std::string const& clarg : cmdline) { - std::unique_ptr cge = ge.Parse(clarg); - std::string parsed_arg = cge->Evaluate(this->LG, this->Config); - for (cmGeneratorTarget* gt : cge->GetTargets()) { - this->Utilities.emplace(BT>( - { gt->GetName(), true }, cge->GetBacktrace())); - } + std::string parsed_arg = EvaluateSplitConfigGenex( + clarg, ge, this->LG, useOutputConfig, this->OutputConfig, + this->CommandConfig, &this->Utilities); if (this->CC->GetCommandExpandLists()) { cm::append(argv, cmExpandedList(parsed_arg)); } else { argv.push_back(std::move(parsed_arg)); } + + // For remaining arguments, we default to the OUTPUT_CONFIG. + useOutputConfig = true; } if (!argv.empty()) { @@ -94,8 +178,10 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, // collect the target to add a target-level dependency on it. cmGeneratorTarget* gt = this->LG->FindGeneratorTargetToUse(argv.front()); if (gt && gt->GetType() == cmStateEnums::EXECUTABLE) { + // FIXME: What is the proper condition for a cross-dependency? + bool const cross = true; this->Utilities.emplace(BT>( - { gt->GetName(), true }, cc.GetBacktrace())); + { gt->GetName(), cross }, cc.GetBacktrace())); } } else { // Later code assumes at least one entry exists, but expanding @@ -137,16 +223,18 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, this->CommandLines.push_back(std::move(argv)); } - this->Outputs = EvaluateOutputs(cc.GetOutputs(), ge, this->LG, this->Config); + this->Outputs = + EvaluateOutputs(cc.GetOutputs(), ge, this->LG, this->OutputConfig); this->Byproducts = - EvaluateOutputs(cc.GetByproducts(), ge, this->LG, this->Config); - this->Depends = EvaluateDepends(cc.GetDepends(), ge, this->LG, this->Config); + EvaluateOutputs(cc.GetByproducts(), ge, this->LG, this->OutputConfig); + this->Depends = EvaluateDepends(cc.GetDepends(), ge, this->LG, + this->OutputConfig, this->CommandConfig); const std::string& workingdirectory = this->CC->GetWorkingDirectory(); if (!workingdirectory.empty()) { - std::unique_ptr cge = - ge.Parse(workingdirectory); - this->WorkingDirectory = cge->Evaluate(this->LG, this->Config); + this->WorkingDirectory = + EvaluateSplitConfigGenex(workingdirectory, ge, this->LG, true, + this->OutputConfig, this->CommandConfig); // Convert working directory to a full path. if (!this->WorkingDirectory.empty()) { std::string const& build_dir = this->LG->GetCurrentBinaryDirectory(); @@ -203,7 +291,7 @@ const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const (target->IsImported() || target->GetProperty("CROSSCOMPILING_EMULATOR") || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) { - return target->GetLocation(this->Config).c_str(); + return target->GetLocation(this->CommandConfig).c_str(); } return nullptr; } diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index dac3596..4be5b3f 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -9,6 +9,8 @@ #include #include +#include + #include "cmCustomCommandLines.h" #include "cmListFileCache.h" @@ -18,7 +20,8 @@ class cmLocalGenerator; class cmCustomCommandGenerator { cmCustomCommand const* CC; - std::string Config; + std::string OutputConfig; + std::string CommandConfig; cmLocalGenerator* LG; bool OldStyle; bool MakeVars; @@ -36,7 +39,8 @@ class cmCustomCommandGenerator public: cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, - cmLocalGenerator* lg, bool transformDepfile = true); + cmLocalGenerator* lg, bool transformDepfile = true, + cm::optional crossConfig = {}); cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete; cmCustomCommandGenerator(cmCustomCommandGenerator&&) = default; cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) = @@ -55,4 +59,7 @@ public: bool HasOnlyEmptyCommandLines() const; std::string GetFullDepfile() const; std::string GetInternalDepfile() const; + + const std::string& GetOutputConfig() const { return this->OutputConfig; } + const std::string& GetCommandConfig() const { return this->CommandConfig; } }; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 5293f52..dfeb029 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3064,7 +3064,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) } else { // The original name of the dependency was not a full path. It // must name a target, so add the target-level dependency. - this->GeneratorTarget->Target->AddUtility(util, false); + this->GeneratorTarget->Target->AddUtility(util, true); return true; } } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 4147ba8..b6ecc83 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -56,6 +56,52 @@ std::string const cmGlobalNinjaGenerator::SHELL_NOOP = "cd ."; std::string const cmGlobalNinjaGenerator::SHELL_NOOP = ":"; #endif +bool operator==( + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs, + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs) +{ + return lhs.Target == rhs.Target && lhs.Config == rhs.Config && + lhs.GenexOutput == rhs.GenexOutput; +} + +bool operator!=( + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs, + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs) +{ + return !(lhs == rhs); +} + +bool operator<( + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs, + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs) +{ + return lhs.Target < rhs.Target || + (lhs.Target == rhs.Target && + (lhs.Config < rhs.Config || + (lhs.Config == rhs.Config && lhs.GenexOutput < rhs.GenexOutput))); +} + +bool operator>( + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs, + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs) +{ + return rhs < lhs; +} + +bool operator<=( + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs, + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs) +{ + return !(lhs > rhs); +} + +bool operator>=( + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs, + const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs) +{ + return rhs <= lhs; +} + void cmGlobalNinjaGenerator::Indent(std::ostream& os, int count) { for (int i = 0; i < count; ++i) { @@ -1206,23 +1252,30 @@ void cmGlobalNinjaGenerator::AppendTargetDepends( void cmGlobalNinjaGenerator::AppendTargetDependsClosure( cmGeneratorTarget const* target, cmNinjaDeps& outputs, - const std::string& config) + const std::string& config, const std::string& fileConfig, bool genexOutput) { cmNinjaOuts outs; - this->AppendTargetDependsClosure(target, outs, config, true); + this->AppendTargetDependsClosure(target, outs, config, fileConfig, + genexOutput, true); cm::append(outputs, outs); } void cmGlobalNinjaGenerator::AppendTargetDependsClosure( cmGeneratorTarget const* target, cmNinjaOuts& outputs, - const std::string& config, bool omit_self) + const std::string& config, const std::string& fileConfig, bool genexOutput, + bool omit_self) { // try to locate the target in the cache - auto find = this->Configs[config].TargetDependsClosures.lower_bound(target); + ByConfig::TargetDependsClosureKey key{ + target, + config, + genexOutput, + }; + auto find = this->Configs[fileConfig].TargetDependsClosures.lower_bound(key); - if (find == this->Configs[config].TargetDependsClosures.end() || - find->first != target) { + if (find == this->Configs[fileConfig].TargetDependsClosures.end() || + find->first != key) { // We now calculate the closure outputs by inspecting the dependent // targets recursively. // For that we have to distinguish between a local result set that is only @@ -1232,18 +1285,27 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure( cmNinjaOuts this_outs; // this will be the new cache entry for (auto const& dep_target : this->GetTargetDirectDepends(target)) { - if (!dep_target->IsInBuildSystem() || - (target->GetType() != cmStateEnums::UTILITY && - dep_target->GetType() != cmStateEnums::UTILITY && - this->EnableCrossConfigBuild() && !dep_target.IsCross())) { + if (!dep_target->IsInBuildSystem()) { + continue; + } + + if (!this->IsSingleConfigUtility(target) && + !this->IsSingleConfigUtility(dep_target) && + this->EnableCrossConfigBuild() && !dep_target.IsCross() && + !genexOutput) { continue; } - // Collect the dependent targets for _this_ target - this->AppendTargetDependsClosure(dep_target, this_outs, config, false); + if (dep_target.IsCross()) { + this->AppendTargetDependsClosure(dep_target, this_outs, fileConfig, + fileConfig, genexOutput, false); + } else { + this->AppendTargetDependsClosure(dep_target, this_outs, config, + fileConfig, genexOutput, false); + } } - find = this->Configs[config].TargetDependsClosures.emplace_hint( - find, target, std::move(this_outs)); + find = this->Configs[fileConfig].TargetDependsClosures.emplace_hint( + find, key, std::move(this_outs)); } // now fill the outputs of the final result from the newly generated cache @@ -2490,6 +2552,13 @@ std::set cmGlobalNinjaGenerator::GetCrossConfigs( return result; } +bool cmGlobalNinjaGenerator::IsSingleConfigUtility( + cmGeneratorTarget const* target) const +{ + return target->GetType() == cmStateEnums::UTILITY && + !this->PerConfigUtilityTargets.count(target->GetName()); +} + const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE = "CMakeFiles/common.ninja"; const char* cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION = ".ninja"; diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 8df0372..b30a64a 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -330,10 +330,14 @@ public: cmNinjaTargetDepends depends); void AppendTargetDependsClosure(cmGeneratorTarget const* target, cmNinjaDeps& outputs, - const std::string& config); + const std::string& config, + const std::string& fileConfig, + bool genexOutput); void AppendTargetDependsClosure(cmGeneratorTarget const* target, cmNinjaOuts& outputs, - const std::string& config, bool omit_self); + const std::string& config, + const std::string& fileConfig, + bool genexOutput, bool omit_self); void AppendDirectoryForConfig(const std::string& prefix, const std::string& config, @@ -430,6 +434,18 @@ public: return this->DefaultConfigs; } + const std::set& GetPerConfigUtilityTargets() const + { + return this->PerConfigUtilityTargets; + } + + void AddPerConfigUtilityTarget(const std::string& name) + { + this->PerConfigUtilityTargets.insert(name); + } + + bool IsSingleConfigUtility(cmGeneratorTarget const* target) const; + protected: void Generate() override; @@ -523,6 +539,9 @@ private: /// The mapping from source file to assumed dependencies. std::map> AssumedSourceDependencies; + /// Utility targets which have per-config outputs + std::set PerConfigUtilityTargets; + struct TargetAlias { cmGeneratorTarget* GeneratorTarget; @@ -563,7 +582,14 @@ private: /// The set of custom commands we have seen. std::set CustomCommands; - std::map TargetDependsClosures; + struct TargetDependsClosureKey + { + cmGeneratorTarget const* Target; + std::string Config; + bool GenexOutput; + }; + + std::map TargetDependsClosures; TargetAliasMap TargetAliases; @@ -572,6 +598,19 @@ private: std::map Configs; cmNinjaDeps ByproductsForCleanTarget; + + friend bool operator==(const ByConfig::TargetDependsClosureKey& lhs, + const ByConfig::TargetDependsClosureKey& rhs); + friend bool operator!=(const ByConfig::TargetDependsClosureKey& lhs, + const ByConfig::TargetDependsClosureKey& rhs); + friend bool operator<(const ByConfig::TargetDependsClosureKey& lhs, + const ByConfig::TargetDependsClosureKey& rhs); + friend bool operator>(const ByConfig::TargetDependsClosureKey& lhs, + const ByConfig::TargetDependsClosureKey& rhs); + friend bool operator<=(const ByConfig::TargetDependsClosureKey& lhs, + const ByConfig::TargetDependsClosureKey& rhs); + friend bool operator>=(const ByConfig::TargetDependsClosureKey& lhs, + const ByConfig::TargetDependsClosureKey& rhs); }; class cmGlobalNinjaMultiGenerator : public cmGlobalNinjaGenerator diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index cd18670..274c0db 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4128,7 +4128,8 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, } // Create the generated symbolic output name of the utility target. - std::string output = lg.CreateUtilityOutput(target->GetName()); + std::string output = + lg.CreateUtilityOutput(target->GetName(), byproducts, lfbt); std::string no_main_dependency; cmImplicitDependsList no_implicit_depends; @@ -4235,7 +4236,8 @@ cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput( } std::string cmLocalGenerator::CreateUtilityOutput( - std::string const& targetName) + std::string const& targetName, std::vector const&, + cmListFileBacktrace const&) { std::string force = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", targetName); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index d9c2c1e..91dd8ae 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -364,7 +364,9 @@ public: bool command_expand_lists = false, const std::string& job_pool = "", bool stdPipesUTF8 = false); - std::string CreateUtilityOutput(std::string const& targetName); + virtual std::string CreateUtilityOutput( + std::string const& targetName, std::vector const& byproducts, + cmListFileBacktrace const& bt); virtual std::vector MakeCustomCommandGenerators( cmCustomCommand const& cc, std::string const& config); diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index a36c479..b035f70 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -10,6 +10,8 @@ #include #include +#include + #include "cmsys/FStream.hxx" #include "cmCryptoHash.h" @@ -567,16 +569,45 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines( } void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( - cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps, - const std::string& config) + cmCustomCommand const* cc, const std::set& targets, + const std::string& fileConfig) { cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator(); - if (gg->SeenCustomCommand(cc, config)) { + if (gg->SeenCustomCommand(cc, fileConfig)) { return; } - for (cmCustomCommandGenerator const& ccg : - this->MakeCustomCommandGenerators(*cc, config)) { + auto ccgs = this->MakeCustomCommandGenerators(*cc, fileConfig); + for (cmCustomCommandGenerator const& ccg : ccgs) { + cmNinjaDeps orderOnlyDeps; + + // A custom command may appear on multiple targets. However, some build + // systems exist where the target dependencies on some of the targets are + // overspecified, leading to a dependency cycle. If we assume all target + // dependencies are a superset of the true target dependencies for this + // custom command, we can take the set intersection of all target + // dependencies to obtain a correct dependency list. + // + // FIXME: This won't work in certain obscure scenarios involving indirect + // dependencies. + auto j = targets.begin(); + assert(j != targets.end()); + this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure( + *j, orderOnlyDeps, ccg.GetOutputConfig(), fileConfig, ccgs.size() > 1); + std::sort(orderOnlyDeps.begin(), orderOnlyDeps.end()); + ++j; + + for (; j != targets.end(); ++j) { + std::vector jDeps; + std::vector depsIntersection; + this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure( + *j, jDeps, ccg.GetOutputConfig(), fileConfig, ccgs.size() > 1); + std::sort(jDeps.begin(), jDeps.end()); + std::set_intersection(orderOnlyDeps.begin(), orderOnlyDeps.end(), + jDeps.begin(), jDeps.end(), + std::back_inserter(depsIntersection)); + orderOnlyDeps = depsIntersection; + } const std::vector& outputs = ccg.GetOutputs(); const std::vector& byproducts = ccg.GetByproducts(); @@ -603,7 +634,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } cmNinjaDeps ninjaDeps; - this->AppendCustomCommandDeps(ccg, ninjaDeps, config); + this->AppendCustomCommandDeps(ccg, ninjaDeps, fileConfig); std::vector cmdLines; this->AppendCustomCommandLines(ccg, cmdLines); @@ -614,7 +645,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( build.Outputs = std::move(ninjaOutputs); build.ExplicitDeps = std::move(ninjaDeps); build.OrderOnlyDeps = orderOnlyDeps; - gg->WriteBuild(this->GetImplFileStream(config), build); + gg->WriteBuild(this->GetImplFileStream(fileConfig), build); } else { std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]); // Hash full path to make unique. @@ -652,16 +683,92 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( this->BuildCommandLine(cmdLines, customStep), this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], depfile, cc->GetJobPool(), cc->GetUsesTerminal(), - /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config, + /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, fileConfig, ninjaDeps, orderOnlyDeps); } } } +namespace { +bool HasUniqueByproducts(cmLocalGenerator& lg, + std::vector const& byproducts, + cmListFileBacktrace const& bt) +{ + std::vector configs = + lg.GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); + cmGeneratorExpression ge(bt); + for (std::string const& p : byproducts) { + if (cmGeneratorExpression::Find(p) == std::string::npos) { + return false; + } + std::set seen; + std::unique_ptr cge = ge.Parse(p); + for (std::string const& config : configs) { + for (std::string const& b : + lg.ExpandCustomCommandOutputPaths(*cge, config)) { + if (!seen.insert(b).second) { + return false; + } + } + } + } + return true; +} + +bool HasUniqueOutputs(std::vector const& ccgs) +{ + std::set allOutputs; + std::set allByproducts; + for (cmCustomCommandGenerator const& ccg : ccgs) { + for (std::string const& output : ccg.GetOutputs()) { + if (!allOutputs.insert(output).second) { + return false; + } + } + for (std::string const& byproduct : ccg.GetByproducts()) { + if (!allByproducts.insert(byproduct).second) { + return false; + } + } + } + return true; +} +} + +std::string cmLocalNinjaGenerator::CreateUtilityOutput( + std::string const& targetName, std::vector const& byproducts, + cmListFileBacktrace const& bt) +{ + // In Ninja Multi-Config, we can only produce cross-config utility + // commands if all byproducts are per-config. + if (!this->GetGlobalGenerator()->IsMultiConfig() || + !HasUniqueByproducts(*this, byproducts, bt)) { + return this->cmLocalGenerator::CreateUtilityOutput(targetName, byproducts, + bt); + } + + std::string const base = cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/", targetName, '-'); + // The output is not actually created so mark it symbolic. + for (std::string const& config : + this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) { + std::string const force = cmStrCat(base, config); + if (cmSourceFile* sf = this->Makefile->GetOrCreateGeneratedSource(force)) { + sf->SetProperty("SYMBOLIC", "1"); + } else { + cmSystemTools::Error("Could not get source file entry for " + force); + } + } + this->GetGlobalNinjaGenerator()->AddPerConfigUtilityTarget(targetName); + return cmStrCat(base, "$"_s); +} + std::vector -cmLocalNinjaGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc, - std::string const& config) +cmLocalNinjaGenerator::MakeCustomCommandGenerators( + cmCustomCommand const& cc, std::string const& fileConfig) { + cmGlobalNinjaGenerator const* gg = this->GetGlobalNinjaGenerator(); + bool transformDepfile = false; switch (this->GetPolicyStatus(cmPolicies::CMP0116)) { case cmPolicies::OLD: @@ -674,8 +781,40 @@ cmLocalNinjaGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc, break; } + // Start with the build graph's configuration. std::vector ccgs; - ccgs.emplace_back(cc, config, this, transformDepfile); + ccgs.emplace_back(cc, fileConfig, this, transformDepfile); + + // Consider adding cross configurations. + if (!gg->EnableCrossConfigBuild()) { + return ccgs; + } + + // Outputs and byproducts must be expressed using generator expressions. + for (std::string const& output : cc.GetOutputs()) { + if (cmGeneratorExpression::Find(output) == std::string::npos) { + return ccgs; + } + } + for (std::string const& byproduct : cc.GetByproducts()) { + if (cmGeneratorExpression::Find(byproduct) == std::string::npos) { + return ccgs; + } + } + + // Tentatively add the other cross configurations. + for (std::string const& config : gg->GetCrossConfigs(fileConfig)) { + if (fileConfig != config) { + ccgs.emplace_back(cc, fileConfig, this, transformDepfile, config); + } + } + + // If outputs and byproducts are not unique to each configuration, + // drop the cross configurations. + if (!HasUniqueOutputs(ccgs)) { + ccgs.erase(ccgs.begin() + 1, ccgs.end()); + } + return ccgs; } @@ -692,42 +831,13 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc, } void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements( - const std::string& config) + const std::string& fileConfig) { for (cmCustomCommand const* customCommand : this->CustomCommands) { auto i = this->CustomCommandTargets.find(customCommand); assert(i != this->CustomCommandTargets.end()); - // A custom command may appear on multiple targets. However, some build - // systems exist where the target dependencies on some of the targets are - // overspecified, leading to a dependency cycle. If we assume all target - // dependencies are a superset of the true target dependencies for this - // custom command, we can take the set intersection of all target - // dependencies to obtain a correct dependency list. - // - // FIXME: This won't work in certain obscure scenarios involving indirect - // dependencies. - auto j = i->second.begin(); - assert(j != i->second.end()); - std::vector ccTargetDeps; - this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure( - *j, ccTargetDeps, config); - std::sort(ccTargetDeps.begin(), ccTargetDeps.end()); - ++j; - - for (; j != i->second.end(); ++j) { - std::vector jDeps; - std::vector depsIntersection; - this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps, - config); - std::sort(jDeps.begin(), jDeps.end()); - std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(), - jDeps.begin(), jDeps.end(), - std::back_inserter(depsIntersection)); - ccTargetDeps = depsIntersection; - } - - this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps, config); + this->WriteCustomCommandBuildStatement(i->first, i->second, fileConfig); } } diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 760aea0..87d5e53 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -10,6 +10,7 @@ #include #include +#include "cmListFileCache.h" #include "cmLocalCommonGenerator.h" #include "cmNinjaTypes.h" #include "cmOutputConverter.h" @@ -70,6 +71,10 @@ public: const std::string& fileConfig, cmNinjaTargetDepends depends); + std::string CreateUtilityOutput(std::string const& targetName, + std::vector const& byproducts, + cmListFileBacktrace const& bt) override; + std::vector MakeCustomCommandGenerators( cmCustomCommand const& cc, std::string const& config) override; @@ -102,9 +107,9 @@ private: void WriteProcessedMakefile(std::ostream& os); void WritePools(std::ostream& os); - void WriteCustomCommandBuildStatement(cmCustomCommand const* cc, - const cmNinjaDeps& orderOnlyDeps, - const std::string& config); + void WriteCustomCommandBuildStatement( + cmCustomCommand const* cc, const std::set& targets, + const std::string& config); void WriteCustomCommandBuildStatements(const std::string& config); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index ad1d5f1..0b62e16 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -34,13 +35,30 @@ cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default; void cmNinjaUtilityTargetGenerator::Generate(const std::string& config) { + for (auto const& fileConfig : this->GetConfigNames()) { + if (!this->GetGlobalGenerator() + ->GetCrossConfigs(fileConfig) + .count(config)) { + continue; + } + if (fileConfig != config && + this->GetGeneratorTarget()->GetType() == cmStateEnums::GLOBAL_TARGET) { + continue; + } + this->WriteUtilBuildStatements(config, fileConfig); + } +} + +void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( + std::string const& config, std::string const& fileConfig) +{ cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator(); cmLocalNinjaGenerator* lg = this->GetLocalGenerator(); cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); std::string configDir; if (genTarget->Target->IsPerConfig()) { - configDir = gg->ConfigDirectory(config); + configDir = gg->ConfigDirectory(fileConfig); } std::string utilCommandName = cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, "/", @@ -60,8 +78,8 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config) for (std::vector const* cmdList : cmdLists) { for (cmCustomCommand const& ci : *cmdList) { - cmCustomCommandGenerator ccg(ci, config, lg); - lg->AppendCustomCommandDeps(ccg, deps, config); + cmCustomCommandGenerator ccg(ci, fileConfig, lg); + lg->AppendCustomCommandDeps(ccg, deps, fileConfig); lg->AppendCustomCommandLines(ccg, commands); std::vector const& ccByproducts = ccg.GetByproducts(); std::transform(ccByproducts.begin(), ccByproducts.end(), @@ -103,13 +121,19 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config) std::copy(util_outputs.begin(), util_outputs.end(), std::back_inserter(gg->GetByproductsForCleanTarget())); } - lg->AppendTargetDepends(genTarget, deps, config, config, + // TODO: Does this need an output config? + // Does this need to go in impl-.ninja? + lg->AppendTargetDepends(genTarget, deps, config, fileConfig, DependOnTargetArtifact); if (commands.empty()) { phonyBuild.Comment = "Utility command for " + this->GetTargetName(); phonyBuild.ExplicitDeps = std::move(deps); - gg->WriteBuild(this->GetCommonFileStream(), phonyBuild); + if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { + gg->WriteBuild(this->GetImplFileStream(fileConfig), phonyBuild); + } else { + gg->WriteBuild(this->GetCommonFileStream(), phonyBuild); + } } else { std::string command = lg->BuildCommandLine(commands, "utility", this->GeneratorTarget); @@ -145,15 +169,22 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config) std::string ccConfig; if (genTarget->Target->IsPerConfig() && genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { - ccConfig = config; + ccConfig = fileConfig; + } + if (config == fileConfig || + gg->GetPerConfigUtilityTargets().count(genTarget->GetName())) { + gg->WriteCustomCommandBuild( + command, desc, "Utility command for " + this->GetTargetName(), + /*depfile*/ "", /*job_pool*/ "", uses_terminal, + /*restat*/ true, util_outputs, ccConfig, deps); } - gg->WriteCustomCommandBuild(command, desc, - "Utility command for " + this->GetTargetName(), - /*depfile*/ "", /*job_pool*/ "", uses_terminal, - /*restat*/ true, util_outputs, ccConfig, deps); phonyBuild.ExplicitDeps.push_back(utilCommandName); - gg->WriteBuild(this->GetCommonFileStream(), phonyBuild); + if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { + gg->WriteBuild(this->GetImplFileStream(fileConfig), phonyBuild); + } else { + gg->WriteBuild(this->GetCommonFileStream(), phonyBuild); + } } // Find ADDITIONAL_CLEAN_FILES diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h index 24b47f8..dbd3797 100644 --- a/Source/cmNinjaUtilityTargetGenerator.h +++ b/Source/cmNinjaUtilityTargetGenerator.h @@ -17,4 +17,8 @@ public: ~cmNinjaUtilityTargetGenerator() override; void Generate(const std::string& config) override; + +private: + void WriteUtilBuildStatements(std::string const& config, + std::string const& fileConfig); }; diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json index a7106fc..483ae79 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json @@ -7,7 +7,7 @@ "isGeneratorProvided": null, "sources": [ { - "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$", + "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt(-(Debug|Release|RelWithDebInfo|MinSizeRel))?$", "isGenerated": true, "sourceGroupName": "", "compileGroupLanguage": null, @@ -27,7 +27,7 @@ ] }, { - "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$", + "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt(-\\(CONFIG\\))?\\.rule$", "isGenerated": true, "sourceGroupName": "CMake Rules", "compileGroupLanguage": null, @@ -45,13 +45,13 @@ { "name": "", "sourcePaths": [ - "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$" + "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt(-(Debug|Release|RelWithDebInfo|MinSizeRel))?$" ] }, { "name": "CMake Rules", "sourcePaths": [ - "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$" + "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt(-\\(CONFIG\\))?\\.rule$" ] } ], -- cgit v0.12 From 1526ae3abac7c8e8ad61ba92e6a8219aaece7f7a Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 2 Nov 2020 14:19:27 -0500 Subject: Tests: Add cases for Ninja Multi-Config cross-config custom commands --- ...o_genex-debug-in-release-graph-ninja-stdout.txt | 4 + ...tGenex-depend_echo_genex-debug-ninja-stdout.txt | 4 + ...nex_cmd-debug-in-release-graph-ninja-stdout.txt | 4 + ...ex-depend_echo_genex_cmd-debug-ninja-stdout.txt | 4 + ...nex_out-debug-in-release-graph-ninja-stdout.txt | 4 + ...ex-depend_echo_genex_out-debug-ninja-stdout.txt | 4 + ...cho_raw-debug-in-release-graph-ninja-stdout.txt | 4 + ...putGenex-depend_echo_raw-debug-ninja-stdout.txt | 4 + ..._depend-debug-in-release-graph-ninja-stdout.txt | 4 + ...dOutputGenex-echo_depend-debug-ninja-stdout.txt | 4 + ...end_cmd-debug-in-release-graph-ninja-stdout.txt | 4 + ...putGenex-echo_depend_cmd-debug-ninja-stdout.txt | 4 + ...end_out-debug-in-release-graph-ninja-stdout.txt | 4 + ...putGenex-echo_depend_out-debug-ninja-stdout.txt | 4 + ...o_genex-debug-in-release-graph-ninja-stdout.txt | 4 + ...ndOutputGenex-echo_genex-debug-ninja-stdout.txt | 4 + ...nex_out-debug-in-release-graph-ninja-stdout.txt | 4 + ...tputGenex-echo_genex_out-debug-ninja-stdout.txt | 4 + ...product-debug-in-release-graph-ninja-result.txt | 1 + ...product-debug-in-release-graph-ninja-stderr.txt | 1 + ...-echo_no_cross_byproduct-debug-ninja-stdout.txt | 4 + ...duct_if-debug-in-release-graph-ninja-result.txt | 1 + ...duct_if-debug-in-release-graph-ninja-stderr.txt | 1 + ...ho_no_cross_byproduct_if-debug-ninja-stdout.txt | 4 + ..._output-debug-in-release-graph-ninja-result.txt | 1 + ..._output-debug-in-release-graph-ninja-stderr.txt | 1 + ...nex-echo_no_cross_output-debug-ninja-stdout.txt | 4 + ...tput_if-debug-in-release-graph-ninja-result.txt | 1 + ...tput_if-debug-in-release-graph-ninja-stderr.txt | 1 + ...-echo_no_cross_output_if-debug-ninja-stdout.txt | 4 + ...cho_raw-debug-in-release-graph-ninja-stdout.txt | 4 + ...mandOutputGenex-echo_raw-debug-ninja-stdout.txt | 4 + ..._depend-debug-in-release-graph-ninja-stdout.txt | 4 + ...Genex-echo_target_depend-debug-ninja-stdout.txt | 4 + ...end_cmd-debug-in-release-graph-ninja-stdout.txt | 4 + ...x-echo_target_depend_cmd-debug-ninja-stdout.txt | 4 + ...end_out-debug-in-release-graph-ninja-stdout.txt | 5 + ...x-echo_target_depend_out-debug-ninja-stdout.txt | 4 + ...t_genex-debug-in-release-graph-ninja-stdout.txt | 4 + ...tGenex-echo_target_genex-debug-ninja-stdout.txt | 4 + ...nex_out-debug-in-release-graph-ninja-stdout.txt | 4 + ...ex-echo_target_genex_out-debug-ninja-stdout.txt | 4 + ...get_raw-debug-in-release-graph-ninja-stdout.txt | 4 + ...putGenex-echo_target_raw-debug-ninja-stdout.txt | 4 + ...product-debug-in-release-graph-ninja-stdout.txt | 4 + ...arget_no_cross_byproduct-debug-ninja-stdout.txt | 4 + .../CustomCommandOutputGenex.cmake | 167 +++++++++++++++++++++ Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake | 96 ++++++++++++ Tests/RunCMake/NinjaMultiConfig/echo.c | 21 +++ .../add_custom_command/BadByproduct-stderr.txt | 20 +++ .../RunCMake/add_custom_command/BadByproduct.cmake | 2 + .../add_custom_command/BadCommand-result.txt | 1 + .../add_custom_command/BadCommand-stderr.txt | 21 +++ Tests/RunCMake/add_custom_command/BadCommand.cmake | 3 + .../add_custom_command/BadOutput-stderr.txt | 20 +++ Tests/RunCMake/add_custom_command/BadOutput.cmake | 2 + .../RunCMake/add_custom_command/RunCMakeTest.cmake | 1 + .../add_custom_target/BadByproduct-stderr.txt | 20 +++ .../RunCMake/add_custom_target/BadByproduct.cmake | 2 + .../add_custom_target/BadCommand-result.txt | 1 + .../add_custom_target/BadCommand-stderr.txt | 21 +++ Tests/RunCMake/add_custom_target/BadCommand.cmake | 4 + .../RunCMake/add_custom_target/RunCMakeTest.cmake | 1 + 63 files changed, 564 insertions(+) create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-result.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-stderr.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-result.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-stderr.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-result.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-stderr.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-result.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-stderr.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-in-release-graph-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-ninja-stdout.txt create mode 100644 Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake create mode 100644 Tests/RunCMake/NinjaMultiConfig/echo.c create mode 100644 Tests/RunCMake/add_custom_command/BadCommand-result.txt create mode 100644 Tests/RunCMake/add_custom_command/BadCommand-stderr.txt create mode 100644 Tests/RunCMake/add_custom_command/BadCommand.cmake create mode 100644 Tests/RunCMake/add_custom_target/BadCommand-result.txt create mode 100644 Tests/RunCMake/add_custom_target/BadCommand-stderr.txt create mode 100644 Tests/RunCMake/add_custom_target/BadCommand.cmake diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..cc2e49a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_genex_Debug\.txt +depend_echo_genex_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-ninja-stdout.txt new file mode 100644 index 0000000..cc2e49a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_genex_Debug\.txt +depend_echo_genex_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..214e747 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_genex_cmd_Debug\.txt +depend_echo_genex_cmd_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-ninja-stdout.txt new file mode 100644 index 0000000..842336d --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_cmd-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_genex_cmd_Debug\.txt +depend_echo_genex_cmd_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..eafe30b --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_genex_out_Debug\.txt +depend_echo_genex_out_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-ninja-stdout.txt new file mode 100644 index 0000000..eafe30b --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_genex_out-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_genex_out_Debug\.txt +depend_echo_genex_out_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..e7b74b9 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_raw_Debug\.txt +depend_echo_raw_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-ninja-stdout.txt new file mode 100644 index 0000000..2e01d6a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-depend_echo_raw-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating depend_echo_raw_Debug\.txt +depend_echo_raw_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..7455c25 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] Generating echo_depend_Debug\.txt +echo_depend_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-ninja-stdout.txt new file mode 100644 index 0000000..7455c25 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] Generating echo_depend_Debug\.txt +echo_depend_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..6d5620d --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Release\.txt +depend_Release\.txt +\[2/2\] Generating echo_depend_cmd_Debug\.txt +echo_depend_cmd_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-ninja-stdout.txt new file mode 100644 index 0000000..2f0f1f1 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_cmd-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] Generating echo_depend_cmd_Debug\.txt +echo_depend_cmd_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..39f5471 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] Generating echo_depend_out_Debug\.txt +echo_depend_out_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-ninja-stdout.txt new file mode 100644 index 0000000..39f5471 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_depend_out-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] Generating echo_depend_out_Debug\.txt +echo_depend_out_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..cc43cda --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] Generating echo_genex_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release[\/]echo(\.exe)?' 'Release' 'echo_genex_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-ninja-stdout.txt new file mode 100644 index 0000000..11985c6 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_genex_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_genex_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..68a8cd1 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_genex_out_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_genex_out_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-ninja-stdout.txt new file mode 100644 index 0000000..76b409d --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_genex_out-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_genex_out_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_genex_out_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-stderr.txt new file mode 100644 index 0000000..86f7995 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-in-release-graph-ninja-stderr.txt @@ -0,0 +1 @@ +ninja: error: 'echo_no_cross_byproduct_Debug\.txt', needed by 'CMakeFiles/echo_no_cross_byproduct-Debug', missing and no known rule to make it diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-ninja-stdout.txt new file mode 100644 index 0000000..1c74b71 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_no_cross_byproduct_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_no_cross_byproduct_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-stderr.txt new file mode 100644 index 0000000..e41cb17 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-in-release-graph-ninja-stderr.txt @@ -0,0 +1 @@ +ninja: error: 'echo_no_cross_byproduct_if_Debug\.txt', needed by 'CMakeFiles/echo_no_cross_byproduct_if-Debug', missing and no known rule to make it diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-ninja-stdout.txt new file mode 100644 index 0000000..294d48b --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_byproduct_if-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_no_cross_byproduct_if_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_no_cross_byproduct_if_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-stderr.txt new file mode 100644 index 0000000..2ea22fa --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-in-release-graph-ninja-stderr.txt @@ -0,0 +1 @@ +ninja: error: 'echo_no_cross_output_Debug\.txt', needed by 'CMakeFiles/echo_no_cross_output-Debug', missing and no known rule to make it diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-ninja-stdout.txt new file mode 100644 index 0000000..1f4cc41 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_no_cross_output\.txt, echo_no_cross_output_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_no_cross_output_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-stderr.txt new file mode 100644 index 0000000..fde66ea --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-in-release-graph-ninja-stderr.txt @@ -0,0 +1 @@ +ninja: error: 'echo_no_cross_output_if_Debug\.txt', needed by 'CMakeFiles/echo_no_cross_output_if-Debug', missing and no known rule to make it diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-ninja-stdout.txt new file mode 100644 index 0000000..dc31f3b --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_no_cross_output_if-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_no_cross_output_a\.txt, echo_no_cross_output_if_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_no_cross_output_if_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..01ebae3 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] Generating echo_raw_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release[\/]echo(\.exe)?' 'Debug' 'echo_raw_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-ninja-stdout.txt new file mode 100644 index 0000000..242c9b0 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_raw-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] Generating echo_raw_Debug\.txt +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_raw_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..e77ef1a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] echo_target_depend +echo_target_depend_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-ninja-stdout.txt new file mode 100644 index 0000000..e77ef1a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] echo_target_depend +echo_target_depend_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..8196fcb --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Release\.txt +depend_Release\.txt +\[2/2\] echo_target_depend_cmd +echo_target_depend_cmd_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-ninja-stdout.txt new file mode 100644 index 0000000..d45dcc2 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_cmd-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] echo_target_depend_cmd +echo_target_depend_cmd_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..45f2e57 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,5 @@ +^(Recompacting log\.\.\. +)?\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] echo_target_depend_out +echo_target_depend_out_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-ninja-stdout.txt new file mode 100644 index 0000000..d90a2f3 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_depend_out-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/2\] Generating depend_Debug\.txt +depend_Debug\.txt +\[2/2\] echo_target_depend_out +echo_target_depend_out_Debug\.txt$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..73b403f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] echo_target_genex +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release[\/]echo(\.exe)?' 'Release' 'echo_target_genex_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-ninja-stdout.txt new file mode 100644 index 0000000..c374ce8 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] echo_target_genex +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_target_genex_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..ad6d6e0 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] echo_target_genex_out +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_target_genex_out_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-ninja-stdout.txt new file mode 100644 index 0000000..e819fdf --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_genex_out-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] echo_target_genex_out +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_target_genex_out_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..34df645 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] echo_target_raw +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release[\/]echo(\.exe)?' 'Debug' 'echo_target_raw_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-ninja-stdout.txt new file mode 100644 index 0000000..3fa5488 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-echo_target_raw-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] echo_target_raw +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'echo_target_raw_Debug\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-in-release-graph-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-in-release-graph-ninja-stdout.txt new file mode 100644 index 0000000..f504d98 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-in-release-graph-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Release[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Release[\/]echo(\.exe)? +\[3/3\] target_no_cross_byproduct +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Release[\/]echo(\.exe)?' 'Release' 'target_no_cross_byproduct\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-ninja-stdout.txt new file mode 100644 index 0000000..6e933b2 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex-target_no_cross_byproduct-debug-ninja-stdout.txt @@ -0,0 +1,4 @@ +^\[1/3\] Building C object CMakeFiles[\/]echo.dir[\/]Debug[\/]echo\.c\.(o|obj) +\[2/3\] Linking C executable Debug[\/]echo(\.exe)? +\[3/3\] target_no_cross_byproduct +'[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug'\$ '[^']*[\/]Tests[\/]RunCMake[\/]NinjaMultiConfig[\/]CustomCommandOutputGenex-build[\/]Debug[\/]echo(\.exe)?' 'Debug' 'target_no_cross_byproduct\.txt'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake new file mode 100644 index 0000000..5d6f421 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake @@ -0,0 +1,167 @@ +enable_language(C) + +add_executable(echo echo.c) + +add_custom_command( + OUTPUT echo_raw_$.txt + COMMAND echo $ echo_raw_$.txt + WORKING_DIRECTORY $ + ) + +add_custom_command( + OUTPUT echo_genex_$,Debug,$,Release,$,MinSizeRel,RelWithDebInfo>>>.txt + COMMAND $ $> echo_genex_$>.txt + WORKING_DIRECTORY $> + ) + +add_custom_command( + OUTPUT echo_genex_out_$.txt + COMMAND $> $ echo_genex_out_$.txt + WORKING_DIRECTORY $> + ) + +add_custom_command( + OUTPUT depend_$.txt + COMMAND ${CMAKE_COMMAND} -E echo depend_$.txt + ) + +add_custom_command( + OUTPUT echo_depend_$.txt + COMMAND ${CMAKE_COMMAND} -E echo echo_depend_$.txt + DEPENDS depend_$.txt + ) + +add_custom_command( + OUTPUT echo_depend_out_$.txt + COMMAND ${CMAKE_COMMAND} -E echo echo_depend_out_$.txt + DEPENDS $.txt> + ) + +add_custom_command( + OUTPUT echo_depend_cmd_$.txt + COMMAND ${CMAKE_COMMAND} -E echo echo_depend_cmd_$.txt + DEPENDS $.txt> + ) + +add_custom_command( + OUTPUT depend_echo_raw_$.txt + COMMAND ${CMAKE_COMMAND} -E echo depend_echo_raw_$.txt + DEPENDS echo + ) + +add_custom_command( + OUTPUT depend_echo_genex_$.txt + COMMAND ${CMAKE_COMMAND} -E echo depend_echo_genex_$.txt + DEPENDS $ + ) + +add_custom_command( + OUTPUT depend_echo_genex_out_$.txt + COMMAND ${CMAKE_COMMAND} -E echo depend_echo_genex_out_$.txt + DEPENDS $> + ) + +add_custom_command( + OUTPUT depend_echo_genex_cmd_$.txt + COMMAND ${CMAKE_COMMAND} -E echo depend_echo_genex_cmd_$.txt + DEPENDS $> + ) + +# An OUTPUT that is not per-config prevents cross-config generation. +add_custom_command( + OUTPUT echo_no_cross_output.txt echo_no_cross_output_$.txt + COMMAND echo $ echo_no_cross_output_$.txt + WORKING_DIRECTORY $ + ) +add_custom_command( + OUTPUT echo_no_cross_output_$,a,b>.txt echo_no_cross_output_if_$.txt + COMMAND echo $ echo_no_cross_output_if_$.txt + WORKING_DIRECTORY $ + ) + +# BYPRODUCTS that are not per-config prevent cross-config generation. +add_custom_command( + OUTPUT echo_no_cross_byproduct_$.txt + BYPRODUCTS echo_no_cross_byproduct.txt + COMMAND echo $ echo_no_cross_byproduct_$.txt + WORKING_DIRECTORY $ + ) +add_custom_command( + OUTPUT echo_no_cross_byproduct_if_$.txt + BYPRODUCTS echo_no_cross_byproduct_$,a,b>.txt + COMMAND echo $ echo_no_cross_byproduct_if_$.txt + WORKING_DIRECTORY $ + ) + +foreach(case + echo_raw + echo_genex + echo_genex_out + echo_depend + echo_depend_out + echo_depend_cmd + depend + depend_echo_raw + depend_echo_genex + depend_echo_genex_out + depend_echo_genex_cmd + echo_no_cross_output + echo_no_cross_output_if + echo_no_cross_byproduct + echo_no_cross_byproduct_if + ) + set_property(SOURCE + ${CMAKE_CURRENT_BINARY_DIR}/${case}_Debug.txt + ${CMAKE_CURRENT_BINARY_DIR}/${case}_Release.txt + ${CMAKE_CURRENT_BINARY_DIR}/${case}_MinSizeRel.txt + ${CMAKE_CURRENT_BINARY_DIR}/${case}_RelWithDebInfo.txt + PROPERTY SYMBOLIC 1) + add_custom_target(${case} DEPENDS ${case}_$.txt) +endforeach() + +add_custom_target(echo_target_raw + BYPRODUCTS echo_target_raw_$.txt + COMMENT echo_target_raw + COMMAND echo $ echo_target_raw_$.txt + WORKING_DIRECTORY $ + ) + +add_custom_target(echo_target_genex + BYPRODUCTS echo_target_genex_$.txt + COMMENT echo_target_genex + COMMAND $ $> echo_target_genex_$>.txt + WORKING_DIRECTORY $> + ) + +add_custom_target(echo_target_genex_out + BYPRODUCTS echo_target_genex_out_$.txt + COMMENT echo_target_genex_out + COMMAND $> $ echo_target_genex_out_$.txt + WORKING_DIRECTORY $> + ) + +add_custom_target(echo_target_depend + COMMAND ${CMAKE_COMMAND} -E echo echo_target_depend_$.txt + DEPENDS depend_$.txt + COMMENT echo_target_depend + ) + +add_custom_target(echo_target_depend_out + COMMAND ${CMAKE_COMMAND} -E echo echo_target_depend_out_$.txt + DEPENDS $.txt> + COMMENT echo_target_depend_out + ) + +add_custom_target(echo_target_depend_cmd + COMMAND ${CMAKE_COMMAND} -E echo echo_target_depend_cmd_$.txt + DEPENDS $.txt> + COMMENT echo_target_depend_cmd + ) + +# BYPRODUCTS that are not per-config block cross-configs. +add_custom_target(target_no_cross_byproduct + BYPRODUCTS target_no_cross_byproduct.txt + COMMENT target_no_cross_byproduct + COMMAND echo $ target_no_cross_byproduct.txt + WORKING_DIRECTORY $ + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index 2411114..dc2db57 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -242,6 +242,102 @@ run_ninja(CustomCommandsAndTargets release-leaf-exe build-Release.ninja LeafExe) run_cmake_build(CustomCommandsAndTargets release-clean Release clean:all) run_ninja(CustomCommandsAndTargets release-leaf-byproduct build-Release.ninja main.c) +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandOutputGenex-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all") +run_cmake_configure(CustomCommandOutputGenex) +set(RunCMake_TEST_NO_CLEAN 1) +unset(RunCMake_TEST_OPTIONS) +# echo_raw +run_ninja(CustomCommandOutputGenex echo_raw-debug build-Debug.ninja echo_raw:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_raw-debug-in-release-graph build-Release.ninja echo_raw:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_genex +run_ninja(CustomCommandOutputGenex echo_genex-debug build-Debug.ninja echo_genex:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_genex-debug-in-release-graph build-Release.ninja echo_genex:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_genex_out +run_ninja(CustomCommandOutputGenex echo_genex_out-debug build-Debug.ninja echo_genex_out:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_genex_out-debug-in-release-graph build-Release.ninja echo_genex_out:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_depend* +run_ninja(CustomCommandOutputGenex echo_depend-debug build-Debug.ninja echo_depend:Debug) +run_ninja(CustomCommandOutputGenex echo_depend_out-debug build-Debug.ninja echo_depend_out_Debug.txt) +run_ninja(CustomCommandOutputGenex echo_depend_cmd-debug build-Debug.ninja echo_depend_cmd_Debug.txt) +run_ninja(CustomCommandOutputGenex echo_depend-debug-in-release-graph build-Release.ninja echo_depend:Debug) +run_ninja(CustomCommandOutputGenex echo_depend_out-debug-in-release-graph build-Release.ninja echo_depend_out_Debug.txt) +run_ninja(CustomCommandOutputGenex echo_depend_cmd-debug-in-release-graph build-Release.ninja echo_depend_cmd_Debug.txt) +# depend_echo_raw +run_ninja(CustomCommandOutputGenex depend_echo_raw-debug build-Debug.ninja depend_echo_raw:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex depend_echo_raw-debug-in-release-graph build-Release.ninja depend_echo_raw:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# depend_echo_genex +run_ninja(CustomCommandOutputGenex depend_echo_genex-debug build-Debug.ninja depend_echo_genex:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex depend_echo_genex-debug-in-release-graph build-Release.ninja depend_echo_genex:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# depend_echo_genex_out +run_ninja(CustomCommandOutputGenex depend_echo_genex_out-debug build-Debug.ninja depend_echo_genex_out:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex depend_echo_genex_out-debug-in-release-graph build-Release.ninja depend_echo_genex_out:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# depend_echo_genex_cmd +run_ninja(CustomCommandOutputGenex depend_echo_genex_cmd-debug build-Debug.ninja depend_echo_genex_cmd:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex depend_echo_genex_cmd-debug-in-release-graph build-Release.ninja depend_echo_genex_cmd:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# no_cross_output +run_ninja(CustomCommandOutputGenex echo_no_cross_output-debug build-Debug.ninja echo_no_cross_output:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_no_cross_output-debug-in-release-graph build-Release.ninja echo_no_cross_output:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# no_cross_output_if +run_ninja(CustomCommandOutputGenex echo_no_cross_output_if-debug build-Debug.ninja echo_no_cross_output_if:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_no_cross_output_if-debug-in-release-graph build-Release.ninja echo_no_cross_output_if:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# no_cross_byproduct +run_ninja(CustomCommandOutputGenex echo_no_cross_byproduct-debug build-Debug.ninja echo_no_cross_byproduct:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_no_cross_byproduct-debug-in-release-graph build-Release.ninja echo_no_cross_byproduct:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# no_cross_byproduct_if +run_ninja(CustomCommandOutputGenex echo_no_cross_byproduct_if-debug build-Debug.ninja echo_no_cross_byproduct_if:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_no_cross_byproduct_if-debug-in-release-graph build-Release.ninja echo_no_cross_byproduct_if:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_target_raw +run_ninja(CustomCommandOutputGenex echo_target_raw-debug build-Debug.ninja echo_target_raw:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_target_raw-debug-in-release-graph build-Release.ninja echo_target_raw:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_target_genex +run_ninja(CustomCommandOutputGenex echo_target_genex-debug build-Debug.ninja echo_target_genex:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_target_genex-debug-in-release-graph build-Release.ninja echo_target_genex:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_target_genex_out +run_ninja(CustomCommandOutputGenex echo_target_genex_out-debug build-Debug.ninja echo_target_genex_out:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex echo_target_genex_out-debug-in-release-graph build-Release.ninja echo_target_genex_out:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +# echo_target_depend* +run_ninja(CustomCommandOutputGenex echo_target_depend-debug build-Debug.ninja echo_target_depend:Debug) +run_ninja(CustomCommandOutputGenex echo_target_depend_out-debug build-Debug.ninja echo_target_depend_out:Debug) +run_ninja(CustomCommandOutputGenex echo_target_depend_cmd-debug build-Debug.ninja CMakeFiles/echo_target_depend_cmd-Debug) # undocumented +run_ninja(CustomCommandOutputGenex echo_target_depend-debug-in-release-graph build-Release.ninja echo_target_depend:Debug) +run_ninja(CustomCommandOutputGenex echo_target_depend_out-debug-in-release-graph build-Release.ninja echo_target_depend_out:Debug) +run_ninja(CustomCommandOutputGenex echo_target_depend_cmd-debug-in-release-graph build-Release.ninja CMakeFiles/echo_target_depend_cmd-Debug) # undocumented +# target_no_cross_* +run_ninja(CustomCommandOutputGenex target_no_cross_byproduct-debug build-Debug.ninja target_no_cross_byproduct:Debug) +run_ninja(CustomCommandOutputGenex clean-debug-graph build-Debug.ninja -t clean) +run_ninja(CustomCommandOutputGenex target_no_cross_byproduct-debug-in-release-graph build-Release.ninja target_no_cross_byproduct:Debug) +run_ninja(CustomCommandOutputGenex clean-release-graph build-Release.ninja -t clean) +unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_BINARY_DIR) run_cmake(CustomCommandDepfile) diff --git a/Tests/RunCMake/NinjaMultiConfig/echo.c b/Tests/RunCMake/NinjaMultiConfig/echo.c new file mode 100644 index 0000000..48a187f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/echo.c @@ -0,0 +1,21 @@ +#include +#if defined(_WIN32) +# include +# define getcwd _getcwd +#else +# include +#endif + +int main(int argc, char** argv) +{ + int i; + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd)) != NULL) { + printf("'%s'$", cwd); + } + for (i = 0; i < argc; ++i) { + printf(" '%s'", argv[i]); + } + printf("\n"); + return 0; +} diff --git a/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt b/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt index 6d51575..547fb1c 100644 --- a/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt +++ b/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt @@ -44,4 +44,24 @@ CMake Error at BadByproduct.cmake:7 \(add_custom_command\): Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) +)+( +CMake Error at BadByproduct.cmake:8 \(add_custom_command\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + +)+( +CMake Error at BadByproduct.cmake:9 \(add_custom_command\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + )+ diff --git a/Tests/RunCMake/add_custom_command/BadByproduct.cmake b/Tests/RunCMake/add_custom_command/BadByproduct.cmake index 7c786a4..cf00f5b 100644 --- a/Tests/RunCMake/add_custom_command/BadByproduct.cmake +++ b/Tests/RunCMake/add_custom_command/BadByproduct.cmake @@ -5,3 +5,5 @@ add_custom_command(OUTPUT c BYPRODUCTS "a>") add_custom_command(OUTPUT d BYPRODUCTS "$/#") add_custom_command(OUTPUT e BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/f) add_custom_command(OUTPUT f BYPRODUCTS "$") +add_custom_command(OUTPUT h BYPRODUCTS "$") +add_custom_command(OUTPUT i BYPRODUCTS "$") diff --git a/Tests/RunCMake/add_custom_command/BadCommand-result.txt b/Tests/RunCMake/add_custom_command/BadCommand-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/BadCommand-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/BadCommand-stderr.txt b/Tests/RunCMake/add_custom_command/BadCommand-stderr.txt new file mode 100644 index 0000000..470afd6 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/BadCommand-stderr.txt @@ -0,0 +1,21 @@ +(CMake Error at BadCommand.cmake:1 \(add_custom_command\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +)+(CMake Error at BadCommand.cmake:2 \(add_custom_command\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +)+ diff --git a/Tests/RunCMake/add_custom_command/BadCommand.cmake b/Tests/RunCMake/add_custom_command/BadCommand.cmake new file mode 100644 index 0000000..8c9c3f9 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/BadCommand.cmake @@ -0,0 +1,3 @@ +add_custom_command(OUTPUT "a" COMMAND "$<1:$>") +add_custom_command(OUTPUT "b" COMMAND "$<1:$>") +add_custom_target(drive DEPENDS "a" "b") diff --git a/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt b/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt index 506bec9..2e43568 100644 --- a/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt +++ b/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt @@ -44,4 +44,24 @@ CMake Error at BadOutput.cmake:7 \(add_custom_command\): Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) +)+( +CMake Error at BadOutput.cmake:8 \(add_custom_command\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + +)+( +CMake Error at BadOutput.cmake:9 \(add_custom_command\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + )+ diff --git a/Tests/RunCMake/add_custom_command/BadOutput.cmake b/Tests/RunCMake/add_custom_command/BadOutput.cmake index 77acb7f..f04bdd1 100644 --- a/Tests/RunCMake/add_custom_command/BadOutput.cmake +++ b/Tests/RunCMake/add_custom_command/BadOutput.cmake @@ -5,3 +5,5 @@ add_custom_command(OUTPUT "a>" COMMAND c) add_custom_command(OUTPUT "$/#" COMMAND d) add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/e COMMAND f) add_custom_command(OUTPUT "$" COMMAND g) +add_custom_command(OUTPUT "$" COMMAND h) +add_custom_command(OUTPUT "$" COMMAND i) diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake index aac085d..9c59b4b 100644 --- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake @@ -6,6 +6,7 @@ run_cmake(AppendNotOutput) run_cmake(BadArgument) run_cmake(BadByproduct) run_cmake(BadOutput) +run_cmake(BadCommand) run_cmake(GeneratedProperty) run_cmake(LiteralQuotes) run_cmake(NoArguments) diff --git a/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt b/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt index 4f0f005..da9af49 100644 --- a/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt +++ b/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt @@ -44,4 +44,24 @@ CMake Error at BadByproduct.cmake:7 \(add_custom_target\): Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) +)+( +CMake Error at BadByproduct.cmake:8 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + +)+( +CMake Error at BadByproduct.cmake:9 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + )+ diff --git a/Tests/RunCMake/add_custom_target/BadByproduct.cmake b/Tests/RunCMake/add_custom_target/BadByproduct.cmake index e97f9fd..c317b83 100644 --- a/Tests/RunCMake/add_custom_target/BadByproduct.cmake +++ b/Tests/RunCMake/add_custom_target/BadByproduct.cmake @@ -5,3 +5,5 @@ add_custom_target(e BYPRODUCTS "a>" COMMAND f) add_custom_target(g BYPRODUCTS "$/#" COMMAND h) add_custom_target(i BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/j COMMAND k) add_custom_target(l BYPRODUCTS "$" COMMAND m) +add_custom_target(n BYPRODUCTS "$" COMMAND o) +add_custom_target(p BYPRODUCTS "$" COMMAND q) diff --git a/Tests/RunCMake/add_custom_target/BadCommand-result.txt b/Tests/RunCMake/add_custom_target/BadCommand-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/BadCommand-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/BadCommand-stderr.txt b/Tests/RunCMake/add_custom_target/BadCommand-stderr.txt new file mode 100644 index 0000000..dfdf8f8 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/BadCommand-stderr.txt @@ -0,0 +1,21 @@ +(CMake Error at BadCommand.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +)+(CMake Error at BadCommand.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +)+ diff --git a/Tests/RunCMake/add_custom_target/BadCommand.cmake b/Tests/RunCMake/add_custom_target/BadCommand.cmake new file mode 100644 index 0000000..dadf038 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/BadCommand.cmake @@ -0,0 +1,4 @@ +add_custom_target(drive + COMMAND "$<1:$>" + COMMAND "$<1:$>" + ) diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake index f5d5dd2..22a9ed4 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(BadByproduct) +run_cmake(BadCommand) run_cmake(BadTargetName) run_cmake(ByproductsNoCommand) run_cmake(CommandExpandsEmpty) -- cgit v0.12