diff options
Diffstat (limited to 'Source')
33 files changed, 421 insertions, 341 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 306f4c4..a48bf17 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 10) -set(CMake_VERSION_PATCH 20171025) +set(CMake_VERSION_PATCH 20171030) #set(CMake_VERSION_RC 1) diff --git a/Source/LexerParser/cmCommandArgumentLexer.cxx b/Source/LexerParser/cmCommandArgumentLexer.cxx index bf6bc2f..6b4fc85 100644 --- a/Source/LexerParser/cmCommandArgumentLexer.cxx +++ b/Source/LexerParser/cmCommandArgumentLexer.cxx @@ -674,6 +674,13 @@ Modify cmCommandArgumentLexer.cxx: /* Include the set of tokens from the parser. */ #include "cmCommandArgumentParserTokens.h" +static const char *DCURLYVariable = "${"; +static const char *RCURLYVariable = "}"; +static const char *ATVariable = "@"; +static const char *DOLLARVariable = "$"; +static const char *LCURLYVariable = "{"; +static const char *BSLASHVariable = "\\"; + /*--------------------------------------------------------------------------*/ #define INITIAL 0 @@ -1011,7 +1018,7 @@ YY_RULE_SETUP { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->DCURLYVariable; + yylvalp->str = DCURLYVariable; return cal_DCURLY; } YY_BREAK @@ -1020,7 +1027,7 @@ YY_RULE_SETUP { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->RCURLYVariable; + yylvalp->str = RCURLYVariable; return cal_RCURLY; } YY_BREAK @@ -1029,7 +1036,7 @@ YY_RULE_SETUP { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->ATVariable; + yylvalp->str = ATVariable; return cal_AT; } YY_BREAK @@ -1064,7 +1071,7 @@ case 10: YY_RULE_SETUP { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->DOLLARVariable; + yylvalp->str = DOLLARVariable; return cal_DOLLAR; } YY_BREAK @@ -1072,7 +1079,7 @@ case 11: YY_RULE_SETUP { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->LCURLYVariable; + yylvalp->str = LCURLYVariable; return cal_LCURLY; } YY_BREAK @@ -1080,7 +1087,7 @@ case 12: YY_RULE_SETUP { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->BSLASHVariable; + yylvalp->str = BSLASHVariable; return cal_BSLASH; } YY_BREAK @@ -1088,7 +1095,7 @@ case 13: YY_RULE_SETUP { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->BSLASHVariable; + yylvalp->str = BSLASHVariable; return cal_SYMBOL; } YY_BREAK diff --git a/Source/LexerParser/cmCommandArgumentLexer.in.l b/Source/LexerParser/cmCommandArgumentLexer.in.l index acf18f3..5927b9e 100644 --- a/Source/LexerParser/cmCommandArgumentLexer.in.l +++ b/Source/LexerParser/cmCommandArgumentLexer.in.l @@ -28,6 +28,13 @@ Modify cmCommandArgumentLexer.cxx: /* Include the set of tokens from the parser. */ #include "cmCommandArgumentParserTokens.h" +static const char *DCURLYVariable = "${"; +static const char *RCURLYVariable = "}"; +static const char *ATVariable = "@"; +static const char *DOLLARVariable = "$"; +static const char *LCURLYVariable = "{"; +static const char *BSLASHVariable = "\\"; + /*--------------------------------------------------------------------------*/ %} @@ -63,21 +70,21 @@ Modify cmCommandArgumentLexer.cxx: "${" { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->DCURLYVariable; + yylvalp->str = DCURLYVariable; return cal_DCURLY; } "}" { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->RCURLYVariable; + yylvalp->str = RCURLYVariable; return cal_RCURLY; } "@" { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->ATVariable; + yylvalp->str = ATVariable; return cal_AT; } @@ -103,25 +110,25 @@ Modify cmCommandArgumentLexer.cxx: "$" { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->DOLLARVariable; + yylvalp->str = DOLLARVariable; return cal_DOLLAR; } "{" { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->LCURLYVariable; + yylvalp->str = LCURLYVariable; return cal_LCURLY; } <ESCAPES>"\\" { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->BSLASHVariable; + yylvalp->str = BSLASHVariable; return cal_BSLASH; } <NOESCAPES>"\\" { //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - yylvalp->str = yyextra->BSLASHVariable; + yylvalp->str = BSLASHVariable; return cal_SYMBOL; } diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index 262e3a1..053e34c 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -140,8 +140,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, if (!aliasedTarget) { std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" does not already " - "exist."; + << aliasedName << "\" does not already exist."; this->SetError(e.str()); return false; } @@ -149,15 +148,15 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, if (type != cmStateEnums::EXECUTABLE) { std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" is not an " - "executable."; + << aliasedName << "\" is not an executable."; this->SetError(e.str()); return false; } - if (aliasedTarget->IsImported()) { + if (aliasedTarget->IsImported() && + !aliasedTarget->IsImportedGloballyVisible()) { std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" is IMPORTED."; + << aliasedName << "\" is imported but not globally visible."; this->SetError(e.str()); return false; } diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 31c2ecf..9129047 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -256,13 +256,6 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, this->SetError(e.str()); return false; } - if (aliasedTarget->IsImported()) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << libName << "\" because target \"" - << aliasedName << "\" is IMPORTED."; - this->SetError(e.str()); - return false; - } this->Makefile->AddAlias(libName, aliasedName); return true; } diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 69d0ed6..3380b78 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -43,22 +43,6 @@ inline bool cmHasLiteralSuffixImpl(const char* str1, const char* str2, } template <typename T, size_t N> -const T* cmArrayBegin(const T (&a)[N]) -{ - return a; -} -template <typename T, size_t N> -const T* cmArrayEnd(const T (&a)[N]) -{ - return a + N; -} -template <typename T, size_t N> -size_t cmArraySize(const T (&)[N]) -{ - return N; -} - -template <typename T, size_t N> bool cmHasLiteralPrefix(const T& str1, const char (&str2)[N]) { return cmHasLiteralPrefixImpl(str1, str2, N - 1); @@ -418,6 +402,67 @@ std::unique_ptr<T> make_unique(Args&&... args) #endif +#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L + +using std::size; + +#else + +// std::size backport from C++17. +template <class C> +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +#endif + auto + size(C const& c) -> decltype(c.size()) +{ + return c.size(); +} + +template <typename T, size_t N> +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +#endif + std::size_t + size(const T (&)[N]) throw() +{ + return N; +} + +#endif + +#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L + +using std::cbegin; +using std::cend; + +#else + +// std::c{begin,end} backport from C++14 +template <class C> +#if defined(_MSC_VER) && _MSC_VER < 1900 +auto cbegin(C const& c) +#else +constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c))) +#endif + -> decltype(std::begin(c)) +{ + return std::begin(c); +} + +template <class C> +#if defined(_MSC_VER) && _MSC_VER < 1900 +auto cend(C const& c) +#else +constexpr auto cend(C const& c) noexcept(noexcept(std::end(c))) +#endif + -> decltype(std::end(c)) +{ + return std::end(c); +} + +#endif + } // namespace cm #endif diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 6ae58d6..bf314bd 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -21,13 +21,6 @@ cmCommandArgumentParserHelper::cmCommandArgumentParserHelper() this->FileLine = -1; this->FileName = nullptr; this->RemoveEmpty = true; - this->EmptyVariable[0] = 0; - strcpy(this->DCURLYVariable, "${"); - strcpy(this->RCURLYVariable, "}"); - strcpy(this->ATVariable, "@"); - strcpy(this->DOLLARVariable, "$"); - strcpy(this->LCURLYVariable, "{"); - strcpy(this->BSLASHVariable, "\\"); this->NoEscapeMode = false; this->ReplaceAtSyntax = false; @@ -44,10 +37,10 @@ void cmCommandArgumentParserHelper::SetLineFile(long line, const char* file) this->FileName = file; } -char* cmCommandArgumentParserHelper::AddString(const std::string& str) +const char* cmCommandArgumentParserHelper::AddString(const std::string& str) { if (str.empty()) { - return this->EmptyVariable; + return ""; } char* stVal = new char[str.size() + 1]; strcpy(stVal, str.c_str()); @@ -55,14 +48,14 @@ char* cmCommandArgumentParserHelper::AddString(const std::string& str) return stVal; } -char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, - const char* var) +const char* cmCommandArgumentParserHelper::ExpandSpecialVariable( + const char* key, const char* var) { if (!key) { return this->ExpandVariable(var); } if (!var) { - return this->EmptyVariable; + return ""; } if (strcmp(key, "ENV") == 0) { std::string str; @@ -72,7 +65,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, } return this->AddString(str); } - return this->EmptyVariable; + return ""; } if (strcmp(key, "CACHE") == 0) { if (const char* c = @@ -82,7 +75,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, } return this->AddString(c); } - return this->EmptyVariable; + return ""; } std::ostringstream e; e << "Syntax $" << key << "{} is not supported. " @@ -91,7 +84,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, return nullptr; } -char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) +const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) { if (!var) { return nullptr; @@ -125,11 +118,11 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) return this->AddString(value ? value : ""); } -char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) +const char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) { if (this->ReplaceAtSyntax) { // try to expand the variable - char* ret = this->ExpandVariable(var); + const char* ret = this->ExpandVariable(var); // if the return was 0 and we want to replace empty strings // then return an empty string if (!ret && this->RemoveEmpty) { @@ -150,7 +143,8 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) return this->AddString(ref); } -char* cmCommandArgumentParserHelper::CombineUnions(char* in1, char* in2) +const char* cmCommandArgumentParserHelper::CombineUnions(const char* in1, + const char* in2) { if (!in1) { return in2; @@ -176,10 +170,11 @@ void cmCommandArgumentParserHelper::AllocateParserType( if (len == 0) { return; } - pt->str = new char[len + 1]; - strncpy(pt->str, str, len); - pt->str[len] = 0; - this->Variables.push_back(pt->str); + char* out = new char[len + 1]; + strncpy(out, str, len); + out[len] = 0; + pt->str = out; + this->Variables.push_back(out); } bool cmCommandArgumentParserHelper::HandleEscapeSymbol( diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index cb2a390..098c000 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -17,7 +17,7 @@ class cmCommandArgumentParserHelper public: struct ParserType { - char* str; + const char* str; }; cmCommandArgumentParserHelper(); @@ -35,11 +35,11 @@ public: void Error(const char* str); // For yacc - char* CombineUnions(char* in1, char* in2); + const char* CombineUnions(const char* in1, const char* in2); - char* ExpandSpecialVariable(const char* key, const char* var); - char* ExpandVariable(const char* var); - char* ExpandVariableForAt(const char* var); + const char* ExpandSpecialVariable(const char* key, const char* var); + const char* ExpandVariable(const char* var); + const char* ExpandVariableForAt(const char* var); void SetResult(const char* value); void SetMakefile(const cmMakefile* mf); @@ -53,13 +53,6 @@ public: void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; } const char* GetError() { return this->ErrorString.c_str(); } - char EmptyVariable[1]; - char DCURLYVariable[3]; - char RCURLYVariable[3]; - char ATVariable[3]; - char DOLLARVariable[3]; - char LCURLYVariable[3]; - char BSLASHVariable[3]; private: std::string::size_type InputBufferPos; @@ -69,7 +62,7 @@ private: void Print(const char* place, const char* str); void SafePrintMissing(const char* str, int line, int cnt); - char* AddString(const std::string& str); + const char* AddString(const std::string& str); void CleanupParser(); void SetError(std::string const& msg); diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index fea20ba..7fe0cbe 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1035,7 +1035,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode // No error. We just skip cyclic references. return std::string(); case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - for (size_t i = 1; i < cmArraySize(targetPropertyTransitiveWhitelist); + for (size_t i = 1; i < cm::size(targetPropertyTransitiveWhitelist); ++i) { if (targetPropertyTransitiveWhitelist[i] == propertyName) { // No error. We're not going to find anything new here. @@ -1443,7 +1443,7 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode context->HadContextSensitiveCondition = true; context->HadHeadSensitiveCondition = true; - for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i) { + for (size_t i = 1; i < cm::size(targetPolicyWhitelist); ++i) { const char* policy = targetPolicyWhitelist[i]; if (parameters.front() == policy) { cmLocalGenerator* lg = context->HeadTarget->GetLocalGenerator(); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index e0100ce..74a089f 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2588,8 +2588,8 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name) "RUN_TESTS", "package", "PACKAGE", "package_source", "ZERO_CHECK" }; - return std::find(cmArrayBegin(reservedTargets), cmArrayEnd(reservedTargets), - name) != cmArrayEnd(reservedTargets); + return std::find(cm::cbegin(reservedTargets), cm::cend(reservedTargets), + name) != cm::cend(reservedTargets); } void cmGlobalGenerator::SetExternalMakefileProjectGenerator( diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 1a088ea..12c0cfd 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -135,8 +135,8 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile) this->VariableMappings[compilerOptionSysroot] = this->Makefile->GetSafeDefinition(compilerOptionSysroot); - for (const char* const* replaceIter = cmArrayBegin(ruleReplaceVars); - replaceIter != cmArrayEnd(ruleReplaceVars); ++replaceIter) { + for (const char* const* replaceIter = cm::cbegin(ruleReplaceVars); + replaceIter != cm::cend(ruleReplaceVars); ++replaceIter) { std::string actualReplace = *replaceIter; if (actualReplace.find("${LANG}") != std::string::npos) { cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index b2641d2..fbafbf8 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -7,6 +7,7 @@ #include <algorithm> #include <assert.h> #include <ctype.h> +#include <iterator> #include <memory> // IWYU pragma: keep #include <sstream> #include <stdlib.h> @@ -4134,15 +4135,15 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target, assert(cmGeneratorExpression::Find(feature) == std::string::npos); bool isCFeature = - std::find_if(cmArrayBegin(C_FEATURES) + 1, cmArrayEnd(C_FEATURES), - cmStrCmp(feature)) != cmArrayEnd(C_FEATURES); + std::find_if(cm::cbegin(C_FEATURES) + 1, cm::cend(C_FEATURES), + cmStrCmp(feature)) != cm::cend(C_FEATURES); if (isCFeature) { lang = "C"; return true; } bool isCxxFeature = - std::find_if(cmArrayBegin(CXX_FEATURES) + 1, cmArrayEnd(CXX_FEATURES), - cmStrCmp(feature)) != cmArrayEnd(CXX_FEATURES); + std::find_if(cm::cbegin(CXX_FEATURES) + 1, cm::cend(CXX_FEATURES), + cmStrCmp(feature)) != cm::cend(CXX_FEATURES); if (isCxxFeature) { lang = "CXX"; return true; @@ -4231,8 +4232,8 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target, // Return true so the caller does not try to lookup the default standard. return true; } - if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), - cmStrCmp(defaultCStandard)) == cmArrayEnd(C_STANDARDS)) { + if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), + cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) { std::ostringstream e; e << "The CMAKE_C_STANDARD_DEFAULT variable contains an " "invalid value: \"" @@ -4252,8 +4253,8 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target, existingCStandard = defaultCStandard; } - if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), - cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) { + if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), + cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) { std::ostringstream e; e << "The C_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCStandard << "\"."; @@ -4262,23 +4263,23 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target, } const char* const* existingCIt = existingCStandard - ? std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), + ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(existingCStandard)) - : cmArrayEnd(C_STANDARDS); + : cm::cend(C_STANDARDS); if (needC11 && existingCStandard && - existingCIt < std::find_if(cmArrayBegin(C_STANDARDS), - cmArrayEnd(C_STANDARDS), cmStrCmp("11"))) { + existingCIt < std::find_if(cm::cbegin(C_STANDARDS), + cm::cend(C_STANDARDS), cmStrCmp("11"))) { return false; } if (needC99 && existingCStandard && - existingCIt < std::find_if(cmArrayBegin(C_STANDARDS), - cmArrayEnd(C_STANDARDS), cmStrCmp("99"))) { + existingCIt < std::find_if(cm::cbegin(C_STANDARDS), + cm::cend(C_STANDARDS), cmStrCmp("99"))) { return false; } if (needC90 && existingCStandard && - existingCIt < std::find_if(cmArrayBegin(C_STANDARDS), - cmArrayEnd(C_STANDARDS), cmStrCmp("90"))) { + existingCIt < std::find_if(cm::cbegin(C_STANDARDS), + cm::cend(C_STANDARDS), cmStrCmp("90"))) { return false; } return true; @@ -4290,16 +4291,16 @@ bool cmMakefile::IsLaterStandard(std::string const& lang, { if (lang == "C") { const char* const* rhsIt = std::find_if( - cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), cmStrCmp(rhs)); + cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs)); - return std::find_if(rhsIt, cmArrayEnd(C_STANDARDS), cmStrCmp(lhs)) != - cmArrayEnd(C_STANDARDS); + return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) != + cm::cend(C_STANDARDS); } const char* const* rhsIt = std::find_if( - cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), cmStrCmp(rhs)); + cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs)); - return std::find_if(rhsIt, cmArrayEnd(CXX_STANDARDS), cmStrCmp(lhs)) != - cmArrayEnd(CXX_STANDARDS); + return std::find_if(rhsIt, cm::cend(CXX_STANDARDS), cmStrCmp(lhs)) != + cm::cend(CXX_STANDARDS); } bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target, @@ -4315,9 +4316,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target, // Return true so the caller does not try to lookup the default standard. return true; } - if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), - cmStrCmp(defaultCxxStandard)) == - cmArrayEnd(CXX_STANDARDS)) { + if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), + cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) { std::ostringstream e; e << "The CMAKE_CXX_STANDARD_DEFAULT variable contains an " "invalid value: \"" @@ -4338,9 +4338,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target, existingCxxStandard = defaultCxxStandard; } - if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), - cmStrCmp(existingCxxStandard)) == - cmArrayEnd(CXX_STANDARDS)) { + if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), + cmStrCmp(existingCxxStandard)) == cm::cend(CXX_STANDARDS)) { std::ostringstream e; e << "The CXX_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCxxStandard << "\"."; @@ -4349,32 +4348,28 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target, } const char* const* existingCxxIt = existingCxxStandard - ? std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), + ? std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(existingCxxStandard)) - : cmArrayEnd(CXX_STANDARDS); + : cm::cend(CXX_STANDARDS); if (needCxx17 && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), - cmStrCmp("17"))) { + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("17"))) { return false; } if (needCxx14 && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), - cmStrCmp("14"))) { + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("14"))) { return false; } if (needCxx11 && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), - cmStrCmp("11"))) { + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("11"))) { return false; } if (needCxx98 && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), - cmStrCmp("98"))) { + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("98"))) { return false; } return true; @@ -4424,9 +4419,9 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target, const char* existingCxxStandard = target->GetProperty("CXX_STANDARD"); if (existingCxxStandard) { - if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), + if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(existingCxxStandard)) == - cmArrayEnd(CXX_STANDARDS)) { + cm::cend(CXX_STANDARDS)) { std::ostringstream e; e << "The CXX_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCxxStandard << "\"."; @@ -4440,9 +4435,9 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target, } } const char* const* existingCxxIt = existingCxxStandard - ? std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), + ? std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(existingCxxStandard)) - : cmArrayEnd(CXX_STANDARDS); + : cm::cend(CXX_STANDARDS); bool setCxx98 = needCxx98 && !existingCxxStandard; bool setCxx11 = needCxx11 && !existingCxxStandard; @@ -4450,23 +4445,22 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target, bool setCxx17 = needCxx17 && !existingCxxStandard; if (needCxx17 && existingCxxStandard && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), - cmStrCmp("17"))) { + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("17"))) { setCxx17 = true; } else if (needCxx14 && existingCxxStandard && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("14"))) { setCxx14 = true; } else if (needCxx11 && existingCxxStandard && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("11"))) { setCxx11 = true; } else if (needCxx98 && existingCxxStandard && - existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS), - cmArrayEnd(CXX_STANDARDS), + existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS), + cm::cend(CXX_STANDARDS), cmStrCmp("98"))) { setCxx98 = true; } @@ -4523,8 +4517,8 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target, const char* existingCStandard = target->GetProperty("C_STANDARD"); if (existingCStandard) { - if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), - cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) { + if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), + cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) { std::ostringstream e; e << "The C_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCStandard << "\"."; @@ -4538,26 +4532,26 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target, } } const char* const* existingCIt = existingCStandard - ? std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), + ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(existingCStandard)) - : cmArrayEnd(C_STANDARDS); + : cm::cend(C_STANDARDS); bool setC90 = needC90 && !existingCStandard; bool setC99 = needC99 && !existingCStandard; bool setC11 = needC11 && !existingCStandard; if (needC11 && existingCStandard && - existingCIt < std::find_if(cmArrayBegin(C_STANDARDS), - cmArrayEnd(C_STANDARDS), cmStrCmp("11"))) { + existingCIt < std::find_if(cm::cbegin(C_STANDARDS), + cm::cend(C_STANDARDS), cmStrCmp("11"))) { setC11 = true; } else if (needC99 && existingCStandard && - existingCIt < std::find_if(cmArrayBegin(C_STANDARDS), - cmArrayEnd(C_STANDARDS), + existingCIt < std::find_if(cm::cbegin(C_STANDARDS), + cm::cend(C_STANDARDS), cmStrCmp("99"))) { setC99 = true; } else if (needC90 && existingCStandard && - existingCIt < std::find_if(cmArrayBegin(C_STANDARDS), - cmArrayEnd(C_STANDARDS), + existingCIt < std::find_if(cm::cbegin(C_STANDARDS), + cm::cend(C_STANDARDS), cmStrCmp("90"))) { setC90 = true; } diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 354011a..6c33e2b 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -126,7 +126,7 @@ class cmMakefile; 3, 0, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0040, \ "The target in the TARGET signature of add_custom_command() must " \ - "exist.", \ + "exist and must be defined in the current directory.", \ 3, 0, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0041, \ "Error on relative include with generator expression.", 3, 0, 0, \ diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 5e89978..9dc77ac 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -9,6 +9,7 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include <iterator> #include <sstream> #include <stddef.h> @@ -301,8 +302,7 @@ std::string cmQtAutoGen::Quoted(std::string const& text) "\r", "\\r", "\t", "\\t", "\v", "\\v" }; std::string res = text; - for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep); - it += 2) { + for (const char* const* it = cm::cbegin(rep); it != cm::cend(rep); it += 2) { cmSystemTools::ReplaceString(res, *it, *(it + 1)); } res = '"' + res; diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index e7080cd..c7550e6 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -9,6 +9,7 @@ #include "cmFilePathChecksum.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmLinkItem.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -16,6 +17,7 @@ #include "cmSourceFile.h" #include "cmSourceGroup.h" #include "cmState.h" +#include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cm_sys_stat.h" @@ -24,6 +26,7 @@ #include <algorithm> #include <array> +#include <deque> #include <map> #include <set> #include <sstream> @@ -156,7 +159,7 @@ static void GetConfigs(cmMakefile* makefile, std::string& configDefault, { configDefault = makefile->GetConfigurations(configsList); if (configsList.empty()) { - configsList.push_back(""); + configsList.push_back(configDefault); } } @@ -299,6 +302,50 @@ static std::vector<std::string> AddGeneratedSource( return genFiles; } +/* @brief Tests if targetDepend is a STATIC_LIBRARY and if any of its + * recursive STATIC_LIBRARY dependencies depends on targetOrigin + * (STATIC_LIBRARY cycle). + */ +static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, + cmGeneratorTarget const* targetDepend, + std::string const& config) +{ + bool cycle = false; + if ((targetOrigin->GetType() == cmStateEnums::STATIC_LIBRARY) && + (targetDepend->GetType() == cmStateEnums::STATIC_LIBRARY)) { + std::set<cmGeneratorTarget const*> knownLibs; + std::deque<cmGeneratorTarget const*> testLibs; + + // Insert initial static_library dependency + knownLibs.insert(targetDepend); + testLibs.push_back(targetDepend); + + while (!testLibs.empty()) { + cmGeneratorTarget const* testTarget = testLibs.front(); + testLibs.pop_front(); + // Check if the test target is the origin target (cycle) + if (testTarget == targetOrigin) { + cycle = true; + break; + } + // Collect all static_library dependencies from the test target + cmLinkImplementationLibraries const* libs = + testTarget->GetLinkImplementationLibraries(config); + if (libs != nullptr) { + for (cmLinkItem const& item : libs->Libraries) { + cmGeneratorTarget const* depTarget = item.Target; + if ((depTarget != nullptr) && + (depTarget->GetType() == cmStateEnums::STATIC_LIBRARY) && + knownLibs.insert(depTarget).second) { + testLibs.push_back(depTarget); + } + } + } + } + } + return cycle; +} + struct cmQtAutoGenSetup { std::set<std::string> MocSkip; @@ -631,7 +678,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( GetConfigs(makefile, configDefault, configsList); std::set<std::string> autogenDependFiles; - std::set<std::string> autogenDependTargets; + std::set<cmTarget*> autogenDependTargets; std::vector<std::string> autogenProvides; // Remove build directories on cleanup @@ -953,7 +1000,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Allow target and file dependencies auto* depTarget = makefile->FindTargetToUse(depName); if (depTarget != nullptr) { - autogenDependTargets.insert(depTarget->GetName()); + autogenDependTargets.insert(depTarget); } else { autogenDependFiles.insert(depName); } @@ -980,8 +1027,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Create the autogen target/command if (usePRE_BUILD) { // Add additional autogen target dependencies to origin target - for (std::string const& depTarget : autogenDependTargets) { - target->Target->AddUtility(depTarget, makefile); + for (cmTarget* depTarget : autogenDependTargets) { + target->Target->AddUtility(depTarget->GetName(), makefile); } // Add the pre-build command directly to bypass the OBJECT_LIBRARY @@ -999,20 +1046,35 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( target->Target->AddPreBuildCommand(cc); } else { - // Add utility target dependencies to the autogen target dependencies - for (std::string const& depTarget : target->Target->GetUtilities()) { - autogenDependTargets.insert(depTarget); - } + // Convert file dependencies std::set to std::vector + std::vector<std::string> autogenDepends(autogenDependFiles.begin(), + autogenDependFiles.end()); + // Add link library target dependencies to the autogen target dependencies - for (const auto& item : target->Target->GetOriginalLinkLibraries()) { - if (makefile->FindTargetToUse(item.first) != nullptr) { - autogenDependTargets.insert(item.first); + for (std::string const& config : configsList) { + cmLinkImplementationLibraries const* libs = + target->GetLinkImplementationLibraries(config); + if (libs != nullptr) { + for (cmLinkItem const& item : libs->Libraries) { + cmGeneratorTarget const* libTarget = item.Target; + if ((libTarget != nullptr) && + !StaticLibraryCycle(target, libTarget, config)) { + std::string util; + if (configsList.size() > 1) { + util += "$<$<CONFIG:"; + util += config; + util += ">:"; + } + util += libTarget->GetName(); + if (configsList.size() > 1) { + util += ">"; + } + autogenDepends.push_back(util); + } + } } } - // Convert file dependencies std::set to std::vector - const std::vector<std::string> autogenDepends(autogenDependFiles.begin(), - autogenDependFiles.end()); // Create autogen target cmTarget* autogenTarget = makefile->AddUtilityCommand( autogenTargetName, true, workingDirectory.c_str(), @@ -1022,9 +1084,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( localGen->AddGeneratorTarget( new cmGeneratorTarget(autogenTarget, localGen)); + // Forward origin utilities to autogen target + for (std::string const& depName : target->Target->GetUtilities()) { + autogenTarget->AddUtility(depName, makefile); + } // Add additional autogen target dependencies to autogen target - for (std::string const& depTarget : autogenDependTargets) { - autogenTarget->AddUtility(depTarget, makefile); + for (cmTarget* depTarget : autogenDependTargets) { + autogenTarget->AddUtility(depTarget->GetName(), makefile); } // Set FOLDER property in autogen target diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index f13312f..a01d5d6 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1931,11 +1931,21 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) bool rccGenerated = false; std::string rccFileAbs; - if (this->MultiConfig == cmQtAutoGen::SINGLE) { - rccFileAbs = rccJob.RccFile; - } else { - rccFileAbs = - cmQtAutoGen::AppendFilenameSuffix(rccJob.RccFile, this->ConfigSuffix); + { + std::string suffix; + switch (this->MultiConfig) { + case cmQtAutoGen::SINGLE: + break; + case cmQtAutoGen::WRAP: + suffix = this->ConfigSuffix; + suffix += "_"; + suffix += this->FilePathChecksum.getPart(rccJob.RccFile, 4); + break; + case cmQtAutoGen::FULL: + suffix = this->ConfigSuffix; + break; + } + rccFileAbs = cmQtAutoGen::AppendFilenameSuffix(rccJob.RccFile, suffix); } std::string const rccFileRel = cmSystemTools::RelativePath( this->AutogenBuildDir.c_str(), rccFileAbs.c_str()); diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index d159d41..bd4121d 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -17,15 +17,6 @@ bool cmTargetCompileDefinitionsCommand::InitialPass( return this->HandleArguments(args, "COMPILE_DEFINITIONS"); } -void cmTargetCompileDefinitionsCommand::HandleImportedTarget( - const std::string& tgt) -{ - std::ostringstream e; - e << "Cannot specify compile definitions for imported target \"" << tgt - << "\"."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); -} - void cmTargetCompileDefinitionsCommand::HandleMissingTarget( const std::string& name) { @@ -56,5 +47,5 @@ bool cmTargetCompileDefinitionsCommand::HandleDirectContent( cmTarget* tgt, const std::vector<std::string>& content, bool, bool) { tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str()); - return true; + return true; // Successfully handled. } diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h index f910452..d41483a 100644 --- a/Source/cmTargetCompileDefinitionsCommand.h +++ b/Source/cmTargetCompileDefinitionsCommand.h @@ -30,7 +30,6 @@ public: cmExecutionStatus& status) override; private: - void HandleImportedTarget(const std::string& tgt) override; void HandleMissingTarget(const std::string& name) override; bool HandleDirectContent(cmTarget* tgt, diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx index 722bbe5..f58e404 100644 --- a/Source/cmTargetCompileFeaturesCommand.cxx +++ b/Source/cmTargetCompileFeaturesCommand.cxx @@ -17,15 +17,6 @@ bool cmTargetCompileFeaturesCommand::InitialPass( return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS); } -void cmTargetCompileFeaturesCommand::HandleImportedTarget( - const std::string& tgt) -{ - std::ostringstream e; - e << "Cannot specify compile features for imported target \"" << tgt - << "\"."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); -} - void cmTargetCompileFeaturesCommand::HandleMissingTarget( const std::string& name) { @@ -49,8 +40,8 @@ bool cmTargetCompileFeaturesCommand::HandleDirectContent( std::string error; if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) { this->SetError(error); - return false; + return false; // Not (successfully) handled. } } - return true; + return true; // Successfully handled. } diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h index 444d260..45240a5 100644 --- a/Source/cmTargetCompileFeaturesCommand.h +++ b/Source/cmTargetCompileFeaturesCommand.h @@ -22,7 +22,6 @@ class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase cmExecutionStatus& status) override; private: - void HandleImportedTarget(const std::string& tgt) override; void HandleMissingTarget(const std::string& name) override; bool HandleDirectContent(cmTarget* tgt, diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index 1b4056d..4df3630 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -18,21 +18,12 @@ bool cmTargetCompileOptionsCommand::InitialPass( return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE); } -void cmTargetCompileOptionsCommand::HandleImportedTarget( - const std::string& tgt) -{ - std::ostringstream e; - e << "Cannot specify compile options for imported target \"" << tgt << "\"."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); -} - void cmTargetCompileOptionsCommand::HandleMissingTarget( const std::string& name) { std::ostringstream e; e << "Cannot specify compile options for target \"" << name - << "\" " - "which is not built by this project."; + << "\" which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } @@ -47,5 +38,5 @@ bool cmTargetCompileOptionsCommand::HandleDirectContent( { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); tgt->InsertCompileOption(this->Join(content), lfbt); - return true; + return true; // Successfully handled. } diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h index 3fab238..6fb151a 100644 --- a/Source/cmTargetCompileOptionsCommand.h +++ b/Source/cmTargetCompileOptionsCommand.h @@ -30,7 +30,6 @@ public: cmExecutionStatus& status) override; private: - void HandleImportedTarget(const std::string& tgt) override; void HandleMissingTarget(const std::string& name) override; bool HandleDirectContent(cmTarget* tgt, diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index 4646c7e..dcec830 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -21,22 +21,12 @@ bool cmTargetIncludeDirectoriesCommand::InitialPass( ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM)); } -void cmTargetIncludeDirectoriesCommand::HandleImportedTarget( - const std::string& tgt) -{ - std::ostringstream e; - e << "Cannot specify include directories for imported target \"" << tgt - << "\"."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); -} - void cmTargetIncludeDirectoriesCommand::HandleMissingTarget( const std::string& name) { std::ostringstream e; e << "Cannot specify include directories for target \"" << name - << "\" " - "which is not built by this project."; + << "\" which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } @@ -79,7 +69,7 @@ bool cmTargetIncludeDirectoriesCommand::HandleDirectContent( } tgt->AddSystemIncludeDirectories(sdirs); } - return true; + return true; // Successfully handled. } void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent( diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h index 27a2f43..57bf8fc 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.h +++ b/Source/cmTargetIncludeDirectoriesCommand.h @@ -30,7 +30,6 @@ public: cmExecutionStatus& status) override; private: - void HandleImportedTarget(const std::string& tgt) override; void HandleMissingTarget(const std::string& name) override; bool HandleDirectContent(cmTarget* tgt, diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index dda0464..37bcb70 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -40,6 +40,16 @@ bool cmTargetLinkLibrariesCommand::InitialPass( this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( args[0]); if (!this->Target) { + const std::vector<cmTarget*>& importedTargets = + this->Makefile->GetOwnedImportedTargets(); + for (cmTarget* importedTarget : importedTargets) { + if (importedTarget->GetName() == args[0]) { + this->Target = importedTarget; + break; + } + } + } + if (!this->Target) { cmake::MessageType t = cmake::FATAL_ERROR; // fail by default std::ostringstream e; e << "Cannot specify link libraries for target \"" << args[0] << "\" " @@ -228,7 +238,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( } else { // Lookup old-style cache entry if type is unspecified. So if you // do a target_link_libraries(foo optimized bar) it will stay optimized - // and not use the lookup. As there maybe the case where someone has + // and not use the lookup. As there may be the case where someone has // specifed that a library is both debug and optimized. (this check is // only there for backwards compatibility when mixing projects built // with old versions of CMake and new) @@ -299,6 +309,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, "target_link_libraries"); return false; } + if (this->Target->IsImported() && + this->CurrentProcessingState != ProcessingKeywordLinkInterface) { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "IMPORTED library can only be used with the INTERFACE keyword of " + "target_link_libraries"); + return false; + } cmTarget::TLLSignature sig = (this->CurrentProcessingState == ProcessingPlainPrivateInterface || @@ -355,6 +373,16 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, cmTarget* t = this->Makefile->FindLocalNonAliasTarget(this->Target->GetName()); if (!t) { + const std::vector<cmTarget*>& importedTargets = + this->Makefile->GetOwnedImportedTargets(); + for (cmTarget* importedTarget : importedTargets) { + if (importedTarget->GetName() == this->Target->GetName()) { + t = importedTarget; + break; + } + } + } + if (!t) { std::ostringstream e; e << "Attempt to add link library \"" << lib << "\" to target \"" << this->Target->GetName() diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 45fe430..9a8fd96 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -17,11 +17,11 @@ bool cmTargetPropCommandBase::HandleArguments( return false; } - // Lookup the target for which libraries are specified. if (this->Makefile->IsAlias(args[0])) { this->SetError("can not be used on an ALIAS target."); return false; } + // Lookup the target for which property-values are specified. this->Target = this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( args[0]); @@ -84,16 +84,13 @@ bool cmTargetPropCommandBase::ProcessContentArgs( this->SetError("called with invalid arguments"); return false; } - - if (this->Target->IsImported()) { - this->HandleImportedTarget(args[0]); - return false; - } - if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY && scope != "INTERFACE") { - this->SetError("may only be set INTERFACE properties on INTERFACE " - "targets"); + this->SetError("may only set INTERFACE properties on INTERFACE targets"); + return false; + } + if (this->Target->IsImported() && scope != "INTERFACE") { + this->SetError("may only set INTERFACE properties on IMPORTED targets"); return false; } diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h index 46a2f6b..3c736fc 100644 --- a/Source/cmTargetPropCommandBase.h +++ b/Source/cmTargetPropCommandBase.h @@ -35,7 +35,6 @@ protected: bool prepend, bool system); private: - virtual void HandleImportedTarget(const std::string& tgt) = 0; virtual void HandleMissingTarget(const std::string& name) = 0; virtual bool HandleDirectContent(cmTarget* tgt, diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index 058659a..3dd3748 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -17,13 +17,6 @@ bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args, return this->HandleArguments(args, "SOURCES"); } -void cmTargetSourcesCommand::HandleImportedTarget(const std::string& tgt) -{ - std::ostringstream e; - e << "Cannot specify sources for imported target \"" << tgt << "\"."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); -} - void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name) { std::ostringstream e; @@ -43,5 +36,5 @@ bool cmTargetSourcesCommand::HandleDirectContent( cmTarget* tgt, const std::vector<std::string>& content, bool, bool) { tgt->AppendProperty("SOURCES", this->Join(content).c_str()); - return true; + return true; // Successfully handled. } diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h index 0639e98..ea8776a 100644 --- a/Source/cmTargetSourcesCommand.h +++ b/Source/cmTargetSourcesCommand.h @@ -30,7 +30,6 @@ public: cmExecutionStatus& status) override; private: - void HandleImportedTarget(const std::string& tgt) override; void HandleMissingTarget(const std::string& name) override; bool HandleDirectContent(cmTarget* tgt, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 1a1b1e2..0a303b0 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -15,6 +15,7 @@ #include "cmVisualStudioGeneratorOptions.h" #include "windows.h" +#include <iterator> #include <memory> // IWYU pragma: keep static std::string cmVS10EscapeXML(std::string arg) @@ -2368,14 +2369,14 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( // Choose a language whose flags to use for ClCompile. static const char* clLangs[] = { "CXX", "C", "Fortran", "CSharp" }; std::string langForClCompile; - if (std::find(cmArrayBegin(clLangs), cmArrayEnd(clLangs), linkLanguage) != - cmArrayEnd(clLangs)) { + if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) != + cm::cend(clLangs)) { langForClCompile = linkLanguage; } else { std::set<std::string> languages; this->GeneratorTarget->GetLanguages(languages, configName); - for (const char* const* l = cmArrayBegin(clLangs); - l != cmArrayEnd(clLangs); ++l) { + for (const char* const* l = cm::cbegin(clLangs); l != cm::cend(clLangs); + ++l) { if (languages.find(*l) != languages.end()) { langForClCompile = *l; break; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index cd714c6..fde77a7 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -110,6 +110,7 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <iostream> +#include <iterator> #include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> @@ -1472,12 +1473,12 @@ void cmake::CreateDefaultGlobalGenerator() if (vsSetupAPIHelper.IsVS2017Installed()) { found = "Visual Studio 15 2017"; } else { - for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators); - found.empty() && g != cmArrayEnd(vsGenerators); ++g) { - for (const char* const* v = cmArrayBegin(vsVariants); - found.empty() && v != cmArrayEnd(vsVariants); ++v) { - for (const char* const* e = cmArrayBegin(vsEntries); - found.empty() && e != cmArrayEnd(vsEntries); ++e) { + for (VSVersionedGenerator const* g = cm::cbegin(vsGenerators); + found.empty() && g != cm::cend(vsGenerators); ++g) { + for (const char* const* v = cm::cbegin(vsVariants); + found.empty() && v != cm::cend(vsVariants); ++v) { + for (const char* const* e = cm::cbegin(vsEntries); + found.empty() && e != cm::cend(vsEntries); ++e) { std::string const reg = vsregBase + *v + g->MSVersion + *e; std::string dir; if (cmSystemTools::ReadRegistryValue(reg, dir, @@ -1735,8 +1736,8 @@ bool cmake::LoadCache(const std::string& path, bool internal, bool result = this->State->LoadCache(path, internal, excludes, includes); static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION", "CMAKE_CACHE_MINOR_VERSION" }; - for (const char* const* nameIt = cmArrayBegin(entries); - nameIt != cmArrayEnd(entries); ++nameIt) { + for (const char* const* nameIt = cm::cbegin(entries); + nameIt != cm::cend(entries); ++nameIt) { this->UnwatchUnusedCli(*nameIt); } return result; @@ -1749,8 +1750,8 @@ bool cmake::SaveCache(const std::string& path) "CMAKE_CACHE_MINOR_VERSION", "CMAKE_CACHE_PATCH_VERSION", "CMAKE_CACHEFILE_DIR" }; - for (const char* const* nameIt = cmArrayBegin(entries); - nameIt != cmArrayEnd(entries); ++nameIt) { + for (const char* const* nameIt = cm::cbegin(entries); + nameIt != cm::cend(entries); ++nameIt) { this->UnwatchUnusedCli(*nameIt); } return result; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ed507fd..ef75b01 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -33,15 +33,14 @@ #include "cmsys/Process.h" #include "cmsys/Terminal.h" #include <algorithm> -#include <functional> #include <iostream> -#include <map> +#include <iterator> #include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <time.h> -#include <utility> class cmConnection; @@ -160,7 +159,8 @@ static bool cmTarFilesFrom(std::string const& file, return true; } -int cmcmd::HandleIWYU(const std::string& runCmd, const std::string&, +static int HandleIWYU(const std::string& runCmd, + const std::string& /* sourceFile */, const std::vector<std::string>& orig_cmd) { // Construct the iwyu command line by taking what was given @@ -187,7 +187,7 @@ int cmcmd::HandleIWYU(const std::string& runCmd, const std::string&, return 0; } -int cmcmd::HandleTidy(const std::string& runCmd, const std::string& sourceFile, +static int HandleTidy(const std::string& runCmd, const std::string& sourceFile, const std::vector<std::string>& orig_cmd) { // Construct the clang-tidy command line by taking what was given @@ -218,7 +218,8 @@ int cmcmd::HandleTidy(const std::string& runCmd, const std::string& sourceFile, return ret; } -int cmcmd::HandleLWYU(const std::string& runCmd, const std::string&, +static int HandleLWYU(const std::string& runCmd, + const std::string& /* sourceFile */, const std::vector<std::string>&) { // Construct the ldd -r -u (link what you use lwyu) command line @@ -250,7 +251,7 @@ int cmcmd::HandleLWYU(const std::string& runCmd, const std::string&, return 0; } -int cmcmd::HandleCppLint(const std::string& runCmd, +static int HandleCppLint(const std::string& runCmd, const std::string& sourceFile, const std::vector<std::string>&) { @@ -274,7 +275,7 @@ int cmcmd::HandleCppLint(const std::string& runCmd, return ret; } -int cmcmd::HandleCppCheck(const std::string& runCmd, +static int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile, const std::vector<std::string>& orig_cmd) { @@ -326,60 +327,70 @@ int cmcmd::HandleCppCheck(const std::string& runCmd, return 0; } +typedef int (*CoCompileHandler)(const std::string&, const std::string&, + const std::vector<std::string>&); + +struct CoCompiler +{ + const char* Option; + CoCompileHandler Handler; + bool NoOriginalCommand; +}; + +static CoCompiler CoCompilers[] = { // Table of options and handlers. + { "--cppcheck=", HandleCppCheck, false }, + { "--cpplint=", HandleCppLint, false }, + { "--iwyu=", HandleIWYU, false }, + { "--lwyu=", HandleLWYU, true }, + { "--tidy=", HandleTidy, false } +}; + +struct CoCompileJob +{ + std::string Command; + CoCompileHandler Handler; +}; + // called when args[0] == "__run_co_compile" int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args) { - // initialize a map from command option to handler function - std::map<std::string, - std::function<int(const std::string&, const std::string&, - const std::vector<std::string>&)>> - coCompileTypes; - auto a1 = std::placeholders::_1; - auto a2 = std::placeholders::_2; - auto a3 = std::placeholders::_3; - // create a map from option to handler function for option - // if the option does not call the original command then it will need - // to set runOriginalCmd to false later in this function - coCompileTypes["--iwyu="] = std::bind(&cmcmd::HandleIWYU, a1, a2, a3); - coCompileTypes["--tidy="] = std::bind(&cmcmd::HandleTidy, a1, a2, a3); - coCompileTypes["--lwyu="] = std::bind(&cmcmd::HandleLWYU, a1, a2, a3); - coCompileTypes["--cpplint="] = std::bind(&cmcmd::HandleCppLint, a1, a2, a3); - coCompileTypes["--cppcheck="] = - std::bind(&cmcmd::HandleCppCheck, a1, a2, a3); - // copy the command options to a vector of strings - std::vector<std::string> commandOptions; - commandOptions.reserve(coCompileTypes.size()); - for (const auto& i : coCompileTypes) { - commandOptions.push_back(i.first); - } - - std::string runCmd; // command to be run from --thing=command - std::string sourceFile; // store --source= - std::string commandFound; // the command that was in the args list + std::vector<CoCompileJob> jobs; + std::string sourceFile; // store --source= + + // Default is to run the original command found after -- if the option + // does not need to do that, it should be specified here, currently only + // lwyu does that. + bool runOriginalCmd = true; + std::vector<std::string> orig_cmd; bool doing_options = true; - for (std::string::size_type cc = 2; cc < args.size(); cc++) { - std::string const& arg = args[cc]; + for (std::string::size_type i = 2; i < args.size(); ++i) { + std::string const& arg = args[i]; // if the arg is -- then the rest of the args after // go into orig_cmd if (arg == "--") { doing_options = false; } else if (doing_options) { bool optionFound = false; - // check arg against all the commandOptions - for (auto const& command : commandOptions) { - if (arg.compare(0, command.size(), command) == 0) { + for (CoCompiler const* cc = cm::cbegin(CoCompilers); + cc != cm::cend(CoCompilers); ++cc) { + size_t optionLen = strlen(cc->Option); + if (arg.compare(0, optionLen, cc->Option) == 0) { optionFound = true; - runCmd = arg.substr(command.size()); - commandFound = command; + CoCompileJob job; + job.Command = arg.substr(optionLen); + job.Handler = cc->Handler; + jobs.push_back(std::move(job)); + if (cc->NoOriginalCommand) { + runOriginalCmd = false; + } } } - // check arg with --source= if (cmHasLiteralPrefix(arg, "--source=")) { sourceFile = arg.substr(9); optionFound = true; } - // if it was not a commandOptions or --source then error + // if it was not a co-compiler or --source then error if (!optionFound) { std::cerr << "__run_co_compile given unknown argument: " << arg << "\n"; @@ -389,39 +400,40 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args) orig_cmd.push_back(arg); } } - if (commandFound.empty()) { - std::cerr << "__run_co_compile missing command to run. Looking for one of " - "the following:\n"; - for (const auto& i : commandOptions) { - std::cerr << i << "\n"; + if (jobs.empty()) { + std::cerr << "__run_co_compile missing command to run. " + "Looking for one or more of the following:\n"; + for (CoCompiler const* cc = cm::cbegin(CoCompilers); + cc != cm::cend(CoCompilers); ++cc) { + std::cerr << cc->Option << "\n"; } return 1; } - // Default is to run the original command found after -- if the option - // does not need to do that, it should be specified here, currently only - // lwyu does that. - bool runOriginalCmd = true; - if (commandFound == "--lwyu=") { - runOriginalCmd = false; - } + if (runOriginalCmd && orig_cmd.empty()) { std::cerr << "__run_co_compile missing compile command after --\n"; return 1; } - // call the command handler here - int ret = coCompileTypes[commandFound](runCmd, sourceFile, orig_cmd); - // if the command returns non-zero then return and fail. - // for commands that do not want to break the build, they should return - // 0 no matter what. - if (ret != 0) { - return ret; + for (CoCompileJob const& job : jobs) { + // call the command handler here + int ret = job.Handler(job.Command, sourceFile, orig_cmd); + + // if the command returns non-zero then return and fail. + // for commands that do not want to break the build, they should return + // 0 no matter what. + if (ret != 0) { + return ret; + } } + // if there is no original command to run return now if (!runOriginalCmd) { - return ret; + return 0; } + // Now run the real compiler command and return its result value + int ret; if (!cmSystemTools::RunSingleCommand(orig_cmd, nullptr, nullptr, &ret, nullptr, cmSystemTools::OUTPUT_PASSTHROUGH)) { @@ -1013,8 +1025,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) } else if (cmHasLiteralPrefix(arg, "--format=")) { format = arg.substr(9); bool isKnown = - std::find(cmArrayBegin(knownFormats), cmArrayEnd(knownFormats), - format) != cmArrayEnd(knownFormats); + std::find(cm::cbegin(knownFormats), cm::cend(knownFormats), + format) != cm::cend(knownFormats); if (!isKnown) { cmSystemTools::Error("Unknown -E tar --format= argument: ", diff --git a/Source/cmcmd.h b/Source/cmcmd.h index 090ca08..d1e03d0 100644 --- a/Source/cmcmd.h +++ b/Source/cmcmd.h @@ -18,24 +18,6 @@ public: */ static int ExecuteCMakeCommand(std::vector<std::string>&); - // define co-compile command handlers they must be public - // because they are used in a std::function map - static int HandleIWYU(const std::string& runCmd, - const std::string& sourceFile, - const std::vector<std::string>& orig_cmd); - static int HandleTidy(const std::string& runCmd, - const std::string& sourceFile, - const std::vector<std::string>& orig_cmd); - static int HandleLWYU(const std::string& runCmd, - const std::string& sourceFile, - const std::vector<std::string>& orig_cmd); - static int HandleCppLint(const std::string& runCmd, - const std::string& sourceFile, - const std::vector<std::string>& orig_cmd); - static int HandleCppCheck(const std::string& runCmd, - const std::string& sourceFile, - const std::vector<std::string>& orig_cmd); - protected: static int HandleCoCompileCommands(std::vector<std::string>& args); static int HashSumFile(std::vector<std::string>& args, |