diff options
Diffstat (limited to 'Source')
25 files changed, 363 insertions, 39 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fe92716..b6f7c85 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -571,6 +571,8 @@ set(SRCS cmFindProgramCommand.h cmForEachCommand.cxx cmForEachCommand.h + cmBlockCommand.cxx + cmBlockCommand.h cmFunctionBlocker.cxx cmFunctionBlocker.h cmFunctionCommand.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 97286cc..d52bbbf 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 24) -set(CMake_VERSION_PATCH 20220822) +set(CMake_VERSION_PATCH 20220826) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmBlockCommand.cxx b/Source/cmBlockCommand.cxx new file mode 100644 index 0000000..c358aa2 --- /dev/null +++ b/Source/cmBlockCommand.cxx @@ -0,0 +1,200 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBlockCommand.h" + +#include <cstdint> // IWYU pragma: keep +#include <utility> + +#include <cm/memory> +#include <cm/optional> +#include <cm/string_view> +#include <cmext/enum_set> +#include <cmext/string_view> + +#include "cmArgumentParser.h" +#include "cmArgumentParserTypes.h" +#include "cmExecutionStatus.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" +#include "cmMakefile.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +namespace { +enum class ScopeType : std::uint8_t +{ + VARIABLES, + POLICIES +}; +using ScopeSet = cm::enum_set<ScopeType>; + +class BlockScopePushPop +{ +public: + BlockScopePushPop(cmMakefile* m, const ScopeSet& scopes); + ~BlockScopePushPop() = default; + + BlockScopePushPop(const BlockScopePushPop&) = delete; + BlockScopePushPop& operator=(const BlockScopePushPop&) = delete; + +private: + std::unique_ptr<cmMakefile::PolicyPushPop> PolicyScope; + std::unique_ptr<cmMakefile::VariablePushPop> VariableScope; +}; + +BlockScopePushPop::BlockScopePushPop(cmMakefile* mf, const ScopeSet& scopes) +{ + if (scopes.contains(ScopeType::POLICIES)) { + this->PolicyScope = cm::make_unique<cmMakefile::PolicyPushPop>(mf); + } + if (scopes.contains(ScopeType::VARIABLES)) { + this->VariableScope = cm::make_unique<cmMakefile::VariablePushPop>(mf); + } +} + +class cmBlockFunctionBlocker : public cmFunctionBlocker +{ +public: + cmBlockFunctionBlocker(cmMakefile* mf, const ScopeSet& scopes, + std::vector<std::string> variableNames); + ~cmBlockFunctionBlocker() override; + + cm::string_view StartCommandName() const override { return "block"_s; } + cm::string_view EndCommandName() const override { return "endblock"_s; } + + bool EndCommandSupportsArguments() const override { return false; } + + bool ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) override; + +private: + cmMakefile* Makefile; + BlockScopePushPop BlockScope; + std::vector<std::string> VariableNames; +}; + +cmBlockFunctionBlocker::cmBlockFunctionBlocker( + cmMakefile* const mf, const ScopeSet& scopes, + std::vector<std::string> variableNames) + : Makefile{ mf } + , BlockScope{ mf, scopes } + , VariableNames{ std::move(variableNames) } +{ +} + +cmBlockFunctionBlocker::~cmBlockFunctionBlocker() +{ + for (auto const& varName : this->VariableNames) { + if (this->Makefile->IsNormalDefinitionSet(varName)) { + this->Makefile->RaiseScope(varName, + this->Makefile->GetDefinition(varName)); + } else { + // unset variable in parent scope + this->Makefile->RaiseScope(varName, nullptr); + } + } +} + +bool cmBlockFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile&) const +{ + // no arguments expected for endblock() + // but this method should not be called because EndCommandHasArguments() + // returns false. + return lff.Arguments().empty(); +} + +bool cmBlockFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) +{ + auto& mf = inStatus.GetMakefile(); + + // Invoke all the functions that were collected in the block. + for (cmListFileFunction const& fn : functions) { + cmExecutionStatus status(mf); + mf.ExecuteCommand(fn, status); + if (status.GetReturnInvoked()) { + inStatus.SetReturnInvoked(); + return true; + } + if (status.GetBreakInvoked()) { + inStatus.SetBreakInvoked(); + return true; + } + if (status.GetContinueInvoked()) { + inStatus.SetContinueInvoked(); + return true; + } + if (cmSystemTools::GetFatalErrorOccurred()) { + return true; + } + } + return true; +} + +} // anonymous namespace + +bool cmBlockCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + struct Arguments : public ArgumentParser::ParseResult + { + cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> ScopeFor; + ArgumentParser::MaybeEmpty<std::vector<std::string>> Propagate; + }; + static auto const parser = cmArgumentParser<Arguments>{} + .Bind("SCOPE_FOR"_s, &Arguments::ScopeFor) + .Bind("PROPAGATE"_s, &Arguments::Propagate); + std::vector<std::string> unrecognizedArguments; + auto parsedArgs = parser.Parse(args, &unrecognizedArguments); + + if (!unrecognizedArguments.empty()) { + status.SetError(cmStrCat("called with unsupported argument \"", + unrecognizedArguments[0], '"')); + cmSystemTools::SetFatalErrorOccurred(); + return false; + } + + if (parsedArgs.MaybeReportError(status.GetMakefile())) { + cmSystemTools::SetFatalErrorOccurred(); + return true; + } + + ScopeSet scopes; + + if (parsedArgs.ScopeFor) { + for (auto const& scope : *parsedArgs.ScopeFor) { + if (scope == "VARIABLES"_s) { + scopes.insert(ScopeType::VARIABLES); + continue; + } + if (scope == "POLICIES"_s) { + scopes.insert(ScopeType::POLICIES); + continue; + } + status.SetError(cmStrCat("SCOPE_FOR unsupported scope \"", scope, '"')); + cmSystemTools::SetFatalErrorOccurred(); + return false; + } + } else { + scopes = { ScopeType::VARIABLES, ScopeType::POLICIES }; + } + if (!scopes.contains(ScopeType::VARIABLES) && + !parsedArgs.Propagate.empty()) { + status.SetError( + "PROPAGATE cannot be specified without a new scope for VARIABLES"); + cmSystemTools::SetFatalErrorOccurred(); + return false; + } + + // create a function blocker + auto fb = cm::make_unique<cmBlockFunctionBlocker>( + &status.GetMakefile(), scopes, parsedArgs.Propagate); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); + + return true; +} diff --git a/Source/cmBlockCommand.h b/Source/cmBlockCommand.h new file mode 100644 index 0000000..5fd8f42 --- /dev/null +++ b/Source/cmBlockCommand.h @@ -0,0 +1,14 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> +#include <vector> + +class cmExecutionStatus; + +/// Starts block() ... endblock() block +bool cmBlockCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx index 76561c3..68e658c 100644 --- a/Source/cmCMakeLanguageCommand.cxx +++ b/Source/cmCMakeLanguageCommand.cxx @@ -36,13 +36,14 @@ bool FatalError(cmExecutionStatus& status, std::string const& error) return false; } -std::array<cm::static_string_view, 12> InvalidCommands{ +std::array<cm::static_string_view, 14> InvalidCommands{ { // clang-format off "function"_s, "endfunction"_s, "macro"_s, "endmacro"_s, "if"_s, "elseif"_s, "else"_s, "endif"_s, "while"_s, "endwhile"_s, - "foreach"_s, "endforeach"_s + "foreach"_s, "endforeach"_s, + "block"_s, "endblock"_s } // clang-format on }; diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 5e616b3..3bc4f0e 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -14,6 +14,7 @@ #include "cmAddLibraryCommand.h" #include "cmAddSubDirectoryCommand.h" #include "cmAddTestCommand.h" +#include "cmBlockCommand.h" #include "cmBreakCommand.h" #include "cmBuildCommand.h" #include "cmCMakeLanguageCommand.h" @@ -126,6 +127,7 @@ void GetScriptingCommands(cmState* state) state->AddFlowControlCommand("macro", cmMacroCommand); state->AddFlowControlCommand("return", cmReturnCommand); state->AddFlowControlCommand("while", cmWhileCommand); + state->AddFlowControlCommand("block", cmBlockCommand); state->AddBuiltinCommand("cmake_language", cmCMakeLanguageCommand); state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired); @@ -198,6 +200,10 @@ void GetScriptingCommands(cmState* state) "An ENDWHILE command was found outside of a proper " "WHILE ENDWHILE structure. Or its arguments did not " "match the opening WHILE command."); + state->AddUnexpectedFlowControlCommand( + "endblock", + "An ENDBLOCK command was found outside of a proper " + "BLOCK ENDBLOCK structure."); #if !defined(CMAKE_BOOTSTRAP) state->AddBuiltinCommand("cmake_host_system_information", diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx index 40e692d..523482a 100644 --- a/Source/cmFunctionBlocker.cxx +++ b/Source/cmFunctionBlocker.cxx @@ -24,10 +24,11 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, auto self = mf.RemoveFunctionBlocker(); assert(self.get() == this); - if (!this->ArgumentsMatch(lff, mf)) { - cmListFileContext const& lfc = this->GetStartingContext(); - cmListFileContext closingContext = - cmListFileContext::FromListFileFunction(lff, lfc.FilePath); + cmListFileContext const& lfc = this->GetStartingContext(); + cmListFileContext closingContext = + cmListFileContext::FromListFileFunction(lff, lfc.FilePath); + if (this->EndCommandSupportsArguments() && + !this->ArgumentsMatch(lff, mf)) { std::ostringstream e; /* clang-format off */ e << "A logical block opening on the line\n" @@ -37,6 +38,15 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, << "with mis-matching arguments."; /* clang-format on */ mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + } else if (!this->EndCommandSupportsArguments() && + !lff.Arguments().empty()) { + std::ostringstream e; + /* clang-format off */ + e << "A logical block closing on the line\n" + " " << closingContext << "\n" + "has unexpected arguments."; + /* clang-format on */ + mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); } return this->Replay(std::move(this->Functions), status); diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index 38abeba..3e096f2 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -38,6 +38,8 @@ private: virtual cm::string_view StartCommandName() const = 0; virtual cm::string_view EndCommandName() const = 0; + virtual bool EndCommandSupportsArguments() const { return true; } + virtual bool ArgumentsMatch(cmListFileFunction const& lff, cmMakefile& mf) const = 0; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 7cd7915..54c900f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1715,7 +1715,7 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget, } bool found = false; for (auto const& sg : headTarget->Makefile->GetSourceGroups()) { - if (sg.MatchesFiles(path)) { + if (sg.MatchChildrenFiles(path)) { found = true; break; } diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 91157cb..6270c82 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -347,6 +347,7 @@ enum class NestingStateEnum Foreach, Function, Macro, + Block }; struct NestingState @@ -434,6 +435,16 @@ cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.pop_back(); + } else if (name == "block") { + stack.push_back({ + NestingStateEnum::Block, + cmListFileContext::FromListFileFunction(func, this->FileName), + }); + } else if (name == "endblock") { + if (!TopIs(stack, NestingStateEnum::Block)) { + return cmListFileContext::FromListFileFunction(func, this->FileName); + } + stack.pop_back(); } } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 64f8996..b44d2a0 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -15,6 +15,7 @@ #include <vector> #include <cm/memory> +#include <cm/optional> #include <cm/string_view> #include <cmext/algorithm> #include <cmext/string_view> @@ -2686,7 +2687,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) cmStrCat(linkerProperty, configUpper), cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)), - true); + cm::nullopt, true); } else if (reuseTarget->GetType() == cmStateEnums::OBJECT_LIBRARY) { // FIXME: This can propagate more than one level, unlike diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 208d907..b228e2b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4543,6 +4543,19 @@ bool cmMakefile::SetPolicyVersion(std::string const& version_min, cmPolicies::WarnCompat::On); } +cmMakefile::VariablePushPop::VariablePushPop(cmMakefile* m) + : Makefile(m) +{ + this->Makefile->StateSnapshot = + this->Makefile->GetState()->CreateVariableScopeSnapshot( + this->Makefile->StateSnapshot); +} + +cmMakefile::VariablePushPop::~VariablePushPop() +{ + this->Makefile->PopSnapshot(); +} + bool cmMakefile::HasCMP0054AlreadyBeenReported( cmListFileContext const& context) const { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index df40c82..10432a8 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -376,6 +376,20 @@ public: }; friend class PolicyPushPop; + /** Helper class to push and pop variables scopes automatically. */ + class VariablePushPop + { + public: + VariablePushPop(cmMakefile* m); + ~VariablePushPop(); + + VariablePushPop(VariablePushPop const&) = delete; + VariablePushPop& operator=(VariablePushPop const&) = delete; + + private: + cmMakefile* Makefile; + }; + /** * Determine if the given context, name pair has already been reported * in context of CMP0054. @@ -862,6 +876,10 @@ public: void PushScope(); void PopScope(); void RaiseScope(const std::string& var, const char* value); + void RaiseScope(const std::string& var, cmValue value) + { + this->RaiseScope(var, value.GetCStr()); + } // push and pop loop scopes void PushLoopBlockBarrier(); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 40f3ab5..6c500b0 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1847,8 +1847,7 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName) { - this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName, - false); + this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName); } void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString, diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index db10cd4..521cf63 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -9,6 +9,7 @@ #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmInstalledFile.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" @@ -561,7 +562,8 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile, { // Set or append the property. if (appendMode) { - target->AppendProperty(propertyName, propertyValue, appendAsString); + target->AppendProperty(propertyName, propertyValue, + makefile.GetBacktrace(), appendAsString); } else { if (remove) { target->SetProperty(propertyName, nullptr); diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 155068cb..6019de1 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -124,6 +124,21 @@ cmSourceGroup* cmSourceGroup::MatchChildrenFiles(const std::string& name) return nullptr; } +const cmSourceGroup* cmSourceGroup::MatchChildrenFiles( + const std::string& name) const +{ + if (this->MatchesFiles(name)) { + return this; + } + for (const cmSourceGroup& group : this->Internal->GroupChildren) { + const cmSourceGroup* result = group.MatchChildrenFiles(name); + if (result) { + return result; + } + } + return nullptr; +} + cmSourceGroup* cmSourceGroup::MatchChildrenRegex(const std::string& name) { for (cmSourceGroup& group : this->Internal->GroupChildren) { diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 295240d..9ce71c7 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h @@ -80,6 +80,12 @@ public: cmSourceGroup* MatchChildrenFiles(const std::string& name); /** + * Check if the given name matches this group's explicit file list + * in children. + */ + const cmSourceGroup* MatchChildrenFiles(const std::string& name) const; + + /** * Check if the given name matches this group's regex in children. */ cmSourceGroup* MatchChildrenRegex(const std::string& name); diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx index 785f356..be15288 100644 --- a/Source/cmStandardLevelResolver.cxx +++ b/Source/cmStandardLevelResolver.cxx @@ -18,6 +18,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" @@ -416,7 +417,8 @@ bool cmStandardLevelResolver::AddRequiredTargetFeature( cmTarget* target, const std::string& feature, std::string* error) const { if (cmGeneratorExpression::Find(feature) != std::string::npos) { - target->AppendProperty("COMPILE_FEATURES", feature); + target->AppendProperty("COMPILE_FEATURES", feature, + this->Makefile->GetBacktrace()); return true; } @@ -426,7 +428,8 @@ bool cmStandardLevelResolver::AddRequiredTargetFeature( return false; } - target->AppendProperty("COMPILE_FEATURES", feature); + target->AppendProperty("COMPILE_FEATURES", feature, + this->Makefile->GetBacktrace()); // FIXME: Add a policy to avoid updating the <LANG>_STANDARD target // property due to COMPILE_FEATURES. The language standard selection diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index eafea05..050206a 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -295,6 +295,12 @@ public: cm::string_view fileSetType) const; cmValue GetFileSetPaths(cmTarget const* self, std::string const& fileSetName, cm::string_view fileSetType) const; + + cmListFileBacktrace GetBacktrace( + cm::optional<cmListFileBacktrace> const& bt) const + { + return bt ? *bt : this->Makefile->GetBacktrace(); + } }; cmTargetInternals::cmTargetInternals() @@ -1243,7 +1249,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, ? targetNameGenex(lib) : lib; this->AppendProperty("LINK_LIBRARIES", - this->GetDebugGeneratorExpressions(libName, llt)); + this->GetDebugGeneratorExpressions(libName, llt), + mf.GetBacktrace()); } if (cmGeneratorExpression::Find(lib) != std::string::npos || @@ -1684,7 +1691,9 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value) } void cmTarget::AppendProperty(const std::string& prop, - const std::string& value, bool asString) + const std::string& value, + cm::optional<cmListFileBacktrace> const& bt, + bool asString) { if (prop == "NAME") { this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, @@ -1715,32 +1724,32 @@ void cmTarget::AppendProperty(const std::string& prop, } if (prop == "INCLUDE_DIRECTORIES") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt); } } else if (prop == "COMPILE_OPTIONS") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->CompileOptionsEntries.emplace_back(value, lfbt); } } else if (prop == "COMPILE_FEATURES") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->CompileFeaturesEntries.emplace_back(value, lfbt); } } else if (prop == "COMPILE_DEFINITIONS") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt); } } else if (prop == "LINK_OPTIONS") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->LinkOptionsEntries.emplace_back(value, lfbt); } } else if (prop == "LINK_DIRECTORIES") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt); } } else if (prop == "PRECOMPILE_HEADERS") { @@ -1753,32 +1762,32 @@ void cmTarget::AppendProperty(const std::string& prop, return; } if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt); } } else if (prop == "LINK_LIBRARIES") { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); } } else if (prop == propINTERFACE_LINK_LIBRARIES) { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); } } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt); } } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value, lfbt); } } else if (prop == "SOURCES") { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); this->impl->SourceEntries.emplace_back(value, lfbt); } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) { this->impl->Makefile->IssueMessage( diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3d0a06b..1550f5b 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -185,8 +185,10 @@ public: { this->SetProperty(prop, cmValue(value)); } - void AppendProperty(const std::string& prop, const std::string& value, - bool asString = false); + void AppendProperty( + const std::string& prop, const std::string& value, + cm::optional<cmListFileBacktrace> const& bt = cm::nullopt, + bool asString = false); //! Might return a nullptr if the property is not set or invalid cmValue GetProperty(const std::string& prop) const; //! Always returns a valid pointer diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index b56b245..268bfac 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetCompileDefinitionsCommand.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" @@ -28,7 +29,8 @@ private: const std::vector<std::string>& content, bool /*prepend*/, bool /*system*/) override { - tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content)); + tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content), + this->Makefile->GetBacktrace()); return true; // Successfully handled. } diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index b4b4319..cb83873 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -88,7 +88,8 @@ void TargetIncludeDirectoriesImpl::HandleInterfaceContent( system); if (system) { std::string joined = this->Join(content); - tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined); + tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined, + this->Makefile->GetBacktrace()); } } diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index ba901d0..fb03b62 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -625,7 +625,7 @@ bool TLL::HandleLibrary(ProcessingState currentProcessingState, void TLL::AppendProperty(std::string const& prop, std::string const& value) { this->AffectsProperty(prop); - this->Target->AppendProperty(prop, value); + this->Target->AppendProperty(prop, value, this->Makefile.GetBacktrace()); } void TLL::AffectsProperty(std::string const& prop) @@ -636,14 +636,16 @@ void TLL::AffectsProperty(std::string const& prop) // Add a wrapper to the expression to tell LookupLinkItem to look up // names in the caller's directory. if (this->Props.insert(prop).second) { - this->Target->AppendProperty(prop, this->DirectoryId); + this->Target->AppendProperty(prop, this->DirectoryId, + this->Makefile.GetBacktrace()); } } TLL::~TLL() { for (std::string const& prop : this->Props) { - this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP); + this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP, + this->Makefile.GetBacktrace()); } } diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx index a5066cc..4dd158d 100644 --- a/Source/cmTargetPrecompileHeadersCommand.cxx +++ b/Source/cmTargetPrecompileHeadersCommand.cxx @@ -5,6 +5,7 @@ #include <utility> #include "cmGeneratorExpression.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" @@ -48,7 +49,8 @@ private: { std::string const& base = this->Makefile->GetCurrentSourceDirectory(); tgt->AppendProperty("PRECOMPILE_HEADERS", - this->Join(ConvertToAbsoluteContent(content, base))); + this->Join(ConvertToAbsoluteContent(content, base)), + this->Makefile->GetBacktrace()); return true; } diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index e2b0213..53e25b5 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -79,7 +79,8 @@ private: { tgt->AppendProperty("SOURCES", this->Join(this->ConvertToAbsoluteContent( - tgt, content, IsInterface::No, CheckCMP0076::Yes))); + tgt, content, IsInterface::No, CheckCMP0076::Yes)), + this->Makefile->GetBacktrace()); return true; // Successfully handled. } @@ -324,11 +325,13 @@ bool TargetSourcesImpl::HandleOneFileSet( cmStrCat("$<BUILD_INTERFACE:", dir, ">"); if (cmFileSetVisibilityIsForSelf(visibility)) { this->Target->AppendProperty("INCLUDE_DIRECTORIES", - interfaceDirectoriesGenex); + interfaceDirectoriesGenex, + this->Makefile->GetBacktrace()); } if (cmFileSetVisibilityIsForInterface(visibility)) { this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", - interfaceDirectoriesGenex); + interfaceDirectoriesGenex, + this->Makefile->GetBacktrace()); } } } |