diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 9a58dd494..568351c15 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -614,7 +614,7 @@ class ProjMgrWorker { bool ProcessLinkerOptions(ContextItem& context); bool ProcessLinkerOptions(ContextItem& context, const LinkerItem& linker, const std::string& ref); bool ProcessProcessorOptions(ContextItem& context); - bool AddContext(ProjMgrParser& parser, ContextDesc& descriptor, const TypePair& type, const std::string& cprojectFile, ContextItem& parentContext); + bool AddContext(ContextDesc& descriptor, const TypePair& type, ContextItem& parentContext); bool ValidateContext(ContextItem& context); bool FormatValidationResults(std::set& results, const ContextItem& context); void UpdateMisc(std::vector& vec, const std::string& compiler); @@ -669,6 +669,7 @@ class ProjMgrWorker { void UpdatePartialReferencedContext(ContextItem& context, std::string& contextName); void ExpandAccessSequence(const ContextItem& context, const ContextItem& refContext, const std::string& sequence, std::string& item, bool withHeadingDot); bool GetGeneratorDir(const RteGenerator* generator, ContextItem& context, const std::string& layer, std::string& genDir); + bool ParseContextLayers(ContextItem& context); }; #endif // PROJMGRWORKER_H diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 7d55c248e..ee4270010 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -75,13 +75,13 @@ bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor, // No build/target-types if (context.csolution->buildTypes.empty() && context.csolution->targetTypes.empty()) { - return AddContext(parser, descriptor, { "" }, cprojectFile, context); + return AddContext(descriptor, { "" }, context); } // No build-types if (context.csolution->buildTypes.empty()) { for (const auto& targetTypeItem : context.csolution->targetTypes) { - if (!AddContext(parser, descriptor, {"", targetTypeItem.first}, cprojectFile, context)) { + if (!AddContext(descriptor, {"", targetTypeItem.first}, context)) { return false; } } @@ -91,7 +91,7 @@ bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor, // Add contexts for project x build-type x target-type combinations for (const auto& buildTypeItem : context.csolution->buildTypes) { for (const auto& targetTypeItem : context.csolution->targetTypes) { - if (!AddContext(parser, descriptor, {buildTypeItem.first, targetTypeItem.first}, cprojectFile, context)) { + if (!AddContext(descriptor, {buildTypeItem.first, targetTypeItem.first}, context)) { return false; } } @@ -99,7 +99,7 @@ bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor, return true; } -bool ProjMgrWorker::AddContext(ProjMgrParser& parser, ContextDesc& descriptor, const TypePair& type, const string& cprojectFile, ContextItem& parentContext) { +bool ProjMgrWorker::AddContext(ContextDesc& descriptor, const TypePair& type, ContextItem& parentContext) { if (CheckType(descriptor.type, {type})) { ContextItem context = parentContext; context.type.build = type.build; @@ -138,46 +138,50 @@ bool ProjMgrWorker::AddContext(ProjMgrParser& parser, ContextDesc& descriptor, c context.variables[ProjMgrUtils::AS_BUILD_TYPE] = context.type.build; context.variables[ProjMgrUtils::AS_TARGET_TYPE] = context.type.target; - // user defined variables - auto userVariablesList = { - context.csolution->target.build.variables, - context.csolution->buildTypes[type.build].variables, - context.csolution->targetTypes[type.target].build.variables, - }; - for (const auto& var : userVariablesList) { - for (const auto& [key, value] : var) { - if ((context.variables.find(key) != context.variables.end()) && (context.variables.at(key) != value)) { - ProjMgrLogger::Warn("variable '" + key + "' redefined from '" + context.variables.at(key) + "' to '" + value + "'"); - } - context.variables[key] = value; - } - } + ProjMgrUtils::PushBackUniquely(m_ymlOrderedContexts, context.name); + m_contexts[context.name] = context; + } + return true; +} - // parse clayers - for (const auto& clayer : context.cproject->clayers) { - if (clayer.layer.empty()) { - continue; +bool ProjMgrWorker::ParseContextLayers(ContextItem& context) { + // user defined variables + auto userVariablesList = { + context.csolution->target.build.variables, + context.csolution->buildTypes[context.type.build].variables, + context.csolution->targetTypes[context.type.target].build.variables, + }; + for (const auto& var : userVariablesList) { + for (const auto& [key, value] : var) { + if ((context.variables.find(key) != context.variables.end()) && (context.variables.at(key) != value)) { + ProjMgrLogger::Warn("variable '" + key + "' redefined from '" + context.variables.at(key) + "' to '" + value + "'"); } - if (CheckContextFilters(clayer.typeFilter, context)) { - string const& clayerRef = ExpandString(clayer.layer, context.variables); - string const& clayerFile = fs::canonical(fs::path(cprojectFile).parent_path().append(clayerRef), ec).generic_string(); - if (clayerFile.empty()) { - if (regex_match(clayer.layer, regex(".*\\$.*\\$.*"))) { - ProjMgrLogger::Warn(clayer.layer, "variable was not defined for context '" + context.name +"'"); - } else { - ProjMgrLogger::Error(clayer.layer, "clayer file was not found"); - return false; - } + context.variables[key] = value; + } + } + // parse clayers + for (const auto& clayer : context.cproject->clayers) { + if (clayer.layer.empty()) { + continue; + } + if (CheckContextFilters(clayer.typeFilter, context)) { + error_code ec; + string const& clayerRef = ExpandString(clayer.layer, context.variables); + string const& clayerFile = fs::canonical(fs::path(context.cproject->directory).append(clayerRef), ec).generic_string(); + if (clayerFile.empty()) { + if (regex_match(clayer.layer, regex(".*\\$.*\\$.*"))) { + ProjMgrLogger::Warn(clayer.layer, "variable was not defined for context '" + context.name +"'"); } else { - if (!parser.ParseClayer(clayerFile, m_checkSchema)) { - return false; - } - context.clayers[clayerFile] = &parser.GetClayers().at(clayerFile); + ProjMgrLogger::Error(clayer.layer, "clayer file was not found"); + return false; + } + } else { + if (!m_parser->ParseClayer(clayerFile, m_checkSchema)) { + return false; } + context.clayers[clayerFile] = &m_parser->GetClayers().at(clayerFile); } } - ProjMgrUtils::PushBackUniquely(m_ymlOrderedContexts, context.name); - m_contexts[context.name] = context; } return true; } @@ -3319,6 +3323,14 @@ bool ProjMgrWorker::ParseContextSelection(const vector& contextSelection cout << " " + context << endl; } } + + if (!((m_selectedContexts.size() == 1) && (m_selectedContexts.front() == RteUtils::EMPTY_STRING))) { + for (const auto& context : m_selectedContexts) { + if (!ParseContextLayers(m_contexts[context])) { + return false; + } + } + } return true; } diff --git a/tools/projmgr/test/data/TestSolution/contexts.cproject.yml b/tools/projmgr/test/data/TestSolution/contexts.cproject.yml index f21e87543..14ac43d0a 100644 --- a/tools/projmgr/test/data/TestSolution/contexts.cproject.yml +++ b/tools/projmgr/test/data/TestSolution/contexts.cproject.yml @@ -1,3 +1,10 @@ project: + device: RteTest_ARMCM0 + compiler: AC6 + components: - component: CORE + + layers: + - layer: $LayerVar$ + type: LayerType diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 137c29fcc..59f34e47f 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -2951,6 +2951,30 @@ TEST_F(ProjMgrUnitTests, RunCheckForContext) { } } +TEST_F(ProjMgrUnitTests, RunCheckContextProcessing) { + char* argv[7]; + StdStreamRedirect streamRedirect; + const string& csolution = testinput_folder + "/TestSolution/contexts.csolution.yml"; + argv[1] = (char*)"convert"; + argv[2] = (char*)csolution.c_str(); + argv[3] = (char*)"-c"; + argv[4] = (char*)"contexts.B1+T1"; + argv[5] = (char*)"-o"; + argv[6] = (char*)testoutput_folder.c_str(); + EXPECT_EQ(0, RunProjMgr(7, argv, 0)); + + // Check warning for processed context + const string expected = "$LayerVar$ - warning csolution: variable was not defined for context 'contexts.B1+T1'"; + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find(expected) != string::npos); + + // Contexts not being processed don't trigger warnings + const vector absenceExpectedList = { "'contexts.B1+T2'", "'contexts.B2+T1'", "'contexts.B2+T2'" }; + for (const auto& absenceExpected : absenceExpectedList) { + EXPECT_TRUE(errStr.find(absenceExpected) == string::npos); + } +} + TEST_F(ProjMgrUnitTests, RunProjMgrOutputFiles) { char* argv[5]; StdStreamRedirect streamRedirect; diff --git a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp index f46d3d76d..9178d6bda 100644 --- a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp @@ -25,6 +25,8 @@ class ProjMgrWorkerUnitTests : public ProjMgrWorker, public ::testing::Test { void ProjMgrWorkerUnitTests::SetCsolutionPacks(CsolutionItem* csolution, std::vector packs, std::string targetType) { ContextItem context; + static CprojectItem cproject; + context.cproject = &cproject; for (auto& pack : packs) { csolution->packs.push_back(PackItem{pack, {}}); }