Skip to content

Commit

Permalink
[projmgr] Rework context and layers parsing order
Browse files Browse the repository at this point in the history
  • Loading branch information
brondani authored Jul 26, 2023
1 parent cc0078c commit a56a8cc
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 39 deletions.
3 changes: 2 additions & 1 deletion tools/projmgr/include/ProjMgrWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>& results, const ContextItem& context);
void UpdateMisc(std::vector<MiscItem>& vec, const std::string& compiler);
Expand Down Expand Up @@ -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
88 changes: 50 additions & 38 deletions tools/projmgr/src/ProjMgrWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -91,15 +91,15 @@ 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;
}
}
}
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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -3319,6 +3323,14 @@ bool ProjMgrWorker::ParseContextSelection(const vector<string>& 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;
}

Expand Down
7 changes: 7 additions & 0 deletions tools/projmgr/test/data/TestSolution/contexts.cproject.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
project:
device: RteTest_ARMCM0
compiler: AC6

components:
- component: CORE

layers:
- layer: $LayerVar$
type: LayerType
24 changes: 24 additions & 0 deletions tools/projmgr/test/src/ProjMgrUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> 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;
Expand Down
2 changes: 2 additions & 0 deletions tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class ProjMgrWorkerUnitTests : public ProjMgrWorker, public ::testing::Test {

void ProjMgrWorkerUnitTests::SetCsolutionPacks(CsolutionItem* csolution, std::vector<std::string> packs, std::string targetType) {
ContextItem context;
static CprojectItem cproject;
context.cproject = &cproject;
for (auto& pack : packs) {
csolution->packs.push_back(PackItem{pack, {}});
}
Expand Down

0 comments on commit a56a8cc

Please sign in to comment.