diff options
author | Raul Tambre <raul@tambre.ee> | 2020-08-15 18:53:15 (GMT) |
---|---|---|
committer | Raul Tambre <raul@tambre.ee> | 2020-08-20 14:41:52 (GMT) |
commit | 27a912193bfe77e400784b152b1cd67003915c37 (patch) | |
tree | 5919a51c400894c9891720f44b842d347a892b31 | |
parent | 2a8f363a54c77bf1f110deabf1933e71a93ef3f4 (diff) | |
download | CMake-27a912193bfe77e400784b152b1cd67003915c37.zip CMake-27a912193bfe77e400784b152b1cd67003915c37.tar.gz CMake-27a912193bfe77e400784b152b1cd67003915c37.tar.bz2 |
file(GENERATE): Add TARGET argument
Adds TARGET argument to file(GENERATE) to make resolving generator expressions
requiring a target possible.
Implements #21101, fixes #21074.
-rw-r--r-- | Help/command/file.rst | 6 | ||||
-rw-r--r-- | Help/release/dev/file-generate-target.rst | 5 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 35 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionEvaluationFile.cxx | 21 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionEvaluationFile.h | 5 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 6 | ||||
-rw-r--r-- | Source/cmMakefile.h | 2 | ||||
-rw-r--r-- | Tests/RunCMake/File_Generate/RunCMakeTest.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/File_Generate/Target.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/File_Generate/sub1/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Tests/RunCMake/File_Generate/sub2/CMakeLists.txt | 7 |
11 files changed, 79 insertions, 24 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst index 2cf938b..953172b 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -449,7 +449,7 @@ modified. file(GENERATE OUTPUT output-file <INPUT input-file|CONTENT content> - [CONDITION expression]) + [CONDITION expression] [TARGET target]) Generate an output file for each build configuration supported by the current :manual:`CMake Generator <cmake-generators(7)>`. Evaluate @@ -479,6 +479,10 @@ from the input content to produce the output content. The options are: with respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`. See policy :policy:`CMP0070`. +``TARGET <target>`` + Specify target which to use when evaluating generator expressions. Enables + use of generator expressions requiring a target. + Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific ``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``. Generated files are modified and their timestamp updated on subsequent cmake diff --git a/Help/release/dev/file-generate-target.rst b/Help/release/dev/file-generate-target.rst new file mode 100644 index 0000000..09fb460 --- /dev/null +++ b/Help/release/dev/file-generate-target.rst @@ -0,0 +1,5 @@ +file-generate-target +-------------------- + +* The :command:`file(GENERATE)` command gained a new ``TARGET`` keyword to + support resolving target-dependent generator expressions. diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 8d20d35..550ad6e 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2240,6 +2240,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, } void AddEvaluationFile(const std::string& inputName, + const std::string& targetName, const std::string& outputExpr, const std::string& condition, bool inputIsContent, cmExecutionStatus& status) @@ -2255,7 +2256,8 @@ void AddEvaluationFile(const std::string& inputName, conditionGe.Parse(condition); status.GetMakefile().AddEvaluationFile( - inputName, std::move(outputCge), std::move(conditionCge), inputIsContent); + inputName, targetName, std::move(outputCge), std::move(conditionCge), + inputIsContent); } bool HandleGenerateCommand(std::vector<std::string> const& args, @@ -2269,23 +2271,36 @@ bool HandleGenerateCommand(std::vector<std::string> const& args, status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } + std::string condition; - if (args.size() > 5) { - if (args[5] != "CONDITION") { + std::string target; + + for (std::size_t i = 5; i < args.size();) { + const std::string& arg = args[i++]; + + if (args.size() - i == 0) { status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } - if (args.size() != 7) { - status.SetError("Incorrect arguments to GENERATE subcommand."); + + const std::string& value = args[i++]; + + if (value.empty()) { + status.SetError( + arg + " of sub-command GENERATE must not be empty if specified."); return false; } - condition = args[6]; - if (condition.empty()) { - status.SetError("CONDITION of sub-command GENERATE must not be empty if " - "specified."); + + if (arg == "CONDITION") { + condition = value; + } else if (arg == "TARGET") { + target = value; + } else { + status.SetError("Unknown argument to GENERATE subcommand."); return false; } } + std::string output = args[2]; const bool inputIsContent = args[3] != "INPUT"; if (inputIsContent && args[3] != "CONTENT") { @@ -2294,7 +2309,7 @@ bool HandleGenerateCommand(std::vector<std::string> const& args, } std::string input = args[4]; - AddEvaluationFile(input, output, condition, inputIsContent, status); + AddEvaluationFile(input, target, output, condition, inputIsContent, status); return true; } diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 6647e62..9e5023d 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -19,11 +19,12 @@ #include "cmSystemTools.h" cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( - std::string input, + std::string input, std::string target, std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr, std::unique_ptr<cmCompiledGeneratorExpression> condition, bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070) : Input(std::move(input)) + , Target(std::move(target)) , OutputFileExpr(std::move(outputFileExpr)) , Condition(std::move(condition)) , InputIsContent(inputIsContent) @@ -37,9 +38,10 @@ void cmGeneratorExpressionEvaluationFile::Generate( std::map<std::string, std::string>& outputFiles, mode_t perm) { std::string rawCondition = this->Condition->GetInput(); + cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(Target); if (!rawCondition.empty()) { std::string condResult = - this->Condition->Evaluate(lg, config, nullptr, nullptr, nullptr, lang); + this->Condition->Evaluate(lg, config, target, nullptr, nullptr, lang); if (condResult == "0") { return; } @@ -54,9 +56,10 @@ void cmGeneratorExpressionEvaluationFile::Generate( } } - const std::string outputFileName = this->GetOutputFileName(lg, config, lang); + const std::string outputFileName = + this->GetOutputFileName(lg, target, config, lang); const std::string& outputContent = - inputExpression->Evaluate(lg, config, nullptr, nullptr, nullptr, lang); + inputExpression->Evaluate(lg, config, target, nullptr, nullptr, lang); auto it = outputFiles.find(outputFileName); @@ -91,10 +94,11 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile( { std::vector<std::string> enabledLanguages; cmGlobalGenerator* gg = lg->GetGlobalGenerator(); + cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(Target); gg->GetEnabledLanguages(enabledLanguages); for (std::string const& le : enabledLanguages) { - std::string const name = this->GetOutputFileName(lg, config, le); + std::string const name = this->GetOutputFileName(lg, target, config, le); cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource( name, false, cmSourceFileLocationKind::Known); // Tell TraceDependencies that the file is not expected to exist @@ -176,10 +180,11 @@ std::string cmGeneratorExpressionEvaluationFile::GetInputFileName( } std::string cmGeneratorExpressionEvaluationFile::GetOutputFileName( - cmLocalGenerator* lg, const std::string& config, const std::string& lang) + cmLocalGenerator* lg, cmGeneratorTarget* target, const std::string& config, + const std::string& lang) { - std::string outputFileName = this->OutputFileExpr->Evaluate( - lg, config, nullptr, nullptr, nullptr, lang); + std::string outputFileName = + this->OutputFileExpr->Evaluate(lg, config, target, nullptr, nullptr, lang); if (cmSystemTools::FileIsFullPath(outputFileName)) { outputFileName = cmSystemTools::CollapseFullPath(outputFileName); diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index a258a2d..caa8064 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -15,13 +15,14 @@ #include "cmGeneratorExpression.h" #include "cmPolicies.h" +class cmGeneratorTarget; class cmLocalGenerator; class cmGeneratorExpressionEvaluationFile { public: cmGeneratorExpressionEvaluationFile( - std::string input, + std::string input, std::string target, std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr, std::unique_ptr<cmCompiledGeneratorExpression> condition, bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070); @@ -40,6 +41,7 @@ private: std::string GetInputFileName(cmLocalGenerator* lg); std::string GetOutputFileName(cmLocalGenerator* lg, + cmGeneratorTarget* target, const std::string& config, const std::string& lang); enum PathRole @@ -52,6 +54,7 @@ private: private: const std::string Input; + const std::string Target; const std::unique_ptr<cmCompiledGeneratorExpression> OutputFileExpr; const std::unique_ptr<cmCompiledGeneratorExpression> Condition; std::vector<std::string> Files; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 5cfe5f1..d9d4ae8 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -801,15 +801,15 @@ void cmMakefile::EnforceDirectoryLevelRules() const } void cmMakefile::AddEvaluationFile( - const std::string& inputFile, + const std::string& inputFile, const std::string& targetName, std::unique_ptr<cmCompiledGeneratorExpression> outputName, std::unique_ptr<cmCompiledGeneratorExpression> condition, bool inputIsContent) { this->EvaluationFiles.push_back( cm::make_unique<cmGeneratorExpressionEvaluationFile>( - inputFile, std::move(outputName), std::move(condition), inputIsContent, - this->GetPolicyStatus(cmPolicies::CMP0070))); + inputFile, targetName, std::move(outputName), std::move(condition), + inputIsContent, this->GetPolicyStatus(cmPolicies::CMP0070))); } const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>& diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 80d80d3..69894b1 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -949,7 +949,7 @@ public: void EnforceDirectoryLevelRules() const; void AddEvaluationFile( - const std::string& inputFile, + const std::string& inputFile, const std::string& targetName, std::unique_ptr<cmCompiledGeneratorExpression> outputName, std::unique_ptr<cmCompiledGeneratorExpression> condition, bool inputIsContent); diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake index 770fc6e..48fb71c 100644 --- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -33,6 +33,13 @@ foreach(l CXX C) endif() endforeach() +run_cmake(Target) +file(READ "${RunCMake_BINARY_DIR}/Target-build/sub1/output.txt" sub_1) +file(READ "${RunCMake_BINARY_DIR}/Target-build/sub2/output.txt" sub_2) +if(NOT sub_1 MATCHES "first" OR NOT sub_2 MATCHES "second") + message(SEND_ERROR "Wrong target used by TARGET argument! ${sub_1} ${sub_2}") +endif() + set(timeformat "%Y%j%H%M%S") file(REMOVE "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt") diff --git a/Tests/RunCMake/File_Generate/Target.cmake b/Tests/RunCMake/File_Generate/Target.cmake new file mode 100644 index 0000000..16e8457 --- /dev/null +++ b/Tests/RunCMake/File_Generate/Target.cmake @@ -0,0 +1,2 @@ +add_subdirectory(sub1) +add_subdirectory(sub2) diff --git a/Tests/RunCMake/File_Generate/sub1/CMakeLists.txt b/Tests/RunCMake/File_Generate/sub1/CMakeLists.txt new file mode 100644 index 0000000..34c51a4 --- /dev/null +++ b/Tests/RunCMake/File_Generate/sub1/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(library IMPORTED STATIC) +set_property(TARGET library PROPERTY COMPILE_DEFINITIONS "first") + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + CONTENT "$<TARGET_PROPERTY:COMPILE_DEFINITIONS>" + TARGET library +) diff --git a/Tests/RunCMake/File_Generate/sub2/CMakeLists.txt b/Tests/RunCMake/File_Generate/sub2/CMakeLists.txt new file mode 100644 index 0000000..09b81ac --- /dev/null +++ b/Tests/RunCMake/File_Generate/sub2/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(library IMPORTED STATIC) +set_property(TARGET library PROPERTY COMPILE_DEFINITIONS "second") + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + CONTENT "$<TARGET_PROPERTY:COMPILE_DEFINITIONS>" + TARGET library +) |