From 79cc827120134a6f1fadcb01bae0af5339568193 Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Mon, 16 Mar 2026 19:31:08 +0100 Subject: [PATCH 1/4] Validate component Cbundle conflicts (ignore Cvendor) --- test/local_packs/S/SomeVendor.RteTest.pdsc | 54 +++++++++++ tools/projmgr/src/ProjMgrWorker.cpp | 23 +++++ .../TestProject1/testProject1.cproject.yml | 7 ++ .../TestProject2/testProject2.cproject.yml | 7 ++ .../TestProject3/testProject3.cproject.yml | 6 ++ .../TestProject4/testProject4.cproject.yml | 6 ++ .../multiBundleComponent.csolution.yml | 23 +++++ tools/projmgr/test/src/ProjMgrUnitTests.cpp | 90 ++++++++++++------- 8 files changed, 183 insertions(+), 33 deletions(-) create mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml create mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml create mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml create mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml create mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml diff --git a/test/local_packs/S/SomeVendor.RteTest.pdsc b/test/local_packs/S/SomeVendor.RteTest.pdsc index 904c1552d..48c911d02 100644 --- a/test/local_packs/S/SomeVendor.RteTest.pdsc +++ b/test/local_packs/S/SomeVendor.RteTest.pdsc @@ -21,6 +21,12 @@ + + + + + + @@ -30,6 +36,54 @@ + + + Test bundle one + https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#Component_Bundle + + Bundle One, component G0, version differs from bundle + + + + + + Bundle One, component G1, only in bundle 1 + + + + + + Bundle One, component G2 + + + + + + + + Test bundle two + https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#element_bundle + + Bundle Two, component G, version differs from bundle + + + + + + Bundle Two, component G2 + + + + + + + + Component G without bundle, but the same class and group as in bundle + + + + + diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 087c8c109..da6cc6ff2 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -1907,6 +1907,7 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { } map> processedComponents; + map>> processedBundles; for (auto& [item, layer] : context.componentRequirements) { if (item.component.empty()) { continue; @@ -1937,6 +1938,15 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { error = true; } + string bundleId = matchedComponent->GetCbundleName(); + string classId = matchedComponent->GetCclassName(); + if (bundleId.empty()) { bundleId = "noBundle"; } + processedBundles[classId][bundleId].push_back(item.component); + if (processedBundles[classId].size() > 1) { + // multiple bundle of the same component found + error = true; + } + // Set layer's rtePath attribute if (!layer.empty()) { error_code ec; @@ -2025,6 +2035,19 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { ProjMgrLogger::Get().Error(errMsg, context.name); } } + // check if same component bundles are specified multiple times (without considering Cvendor) + for (const auto& [_, bundleMap] : processedBundles) { + if (bundleMap.size() > 1) { + string errMsg = "components from multiple bundles are specified:"; + for (const auto& [bundleId, components] : bundleMap) { + errMsg += "\n bundle '" + bundleId + "':"; + for (const auto& comp : components) { + errMsg += "\n - " + comp; + } + } + ProjMgrLogger::Get().Error(errMsg, context.name); + } + } } // Add required components into RTE diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml new file mode 100644 index 000000000..2677f97f4 --- /dev/null +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml @@ -0,0 +1,7 @@ +project: + components: + - component: Startup + - component: RteTest:CORE + - component: ARM::RteTestBundle&BundleOne:G0 + - component: ARM::RteTestBundle&BundleOne:G1 + - component: SomeVendor::RteTestBundle&BundleOne:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml new file mode 100644 index 000000000..54f65a942 --- /dev/null +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml @@ -0,0 +1,7 @@ +project: + components: + - component: Startup + - component: CORE + - component: ARM::RteTestBundle&BundleOne:G0 + - component: ARM::RteTestBundle&BundleOne:G1 + - component: ARM::RteTestBundle&BundleTwo:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml new file mode 100644 index 000000000..fea3d9a6b --- /dev/null +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml @@ -0,0 +1,6 @@ +project: + components: + - component: Startup + - component: CORE + - component: ARM::RteTestBundle&BundleOne:G0 + - component: SomeVendor::RteTestBundle&BundleTwo:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml new file mode 100644 index 000000000..78f798121 --- /dev/null +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml @@ -0,0 +1,6 @@ +project: + components: + - component: Startup + - component: CORE + - component: ARM::RteTestBundle&BundleOne:G0 + - component: SomeVendor::RteTestBundle:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml new file mode 100644 index 000000000..c2b644469 --- /dev/null +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml @@ -0,0 +1,23 @@ +solution: + target-types: + - type: CM0 + device: RteTest_ARMCM0 + target-set: + - set: + images: + - project-context: testProject1.Debug + + build-types: + - type: Debug + compiler: AC6 + + packs: + - pack: ARM::RteTest + - pack: ARM::RteTest_DFP@0.2.0 + - pack: SomeVendor::RteTest@0.0.1 + + projects: + - project: ./TestProject1/testProject1.cproject.yml + - project: ./TestProject2/testProject2.cproject.yml + - project: ./TestProject3/testProject3.cproject.yml + - project: ./TestProject4/testProject4.cproject.yml diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index a1f709829..ea7587d32 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -6461,6 +6461,41 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_MultiVariantComponent) { errMsg.find("multiple variants of the same component are specified:\n - Device:Test variant\n - Device:Test variant&Variant name")); } +TEST_F(ProjMgrUnitTests, RunProjMgr_MultiBundleComponent) { + StdStreamRedirect streamRedirect; + char* argv[8]; + string csolutionFile = testinput_folder + "/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml"; + argv[1] = (char*)"convert"; + argv[2] = (char*)"--solution"; + argv[3] = (char*)csolutionFile.c_str(); + argv[4] = (char*)"-o"; + argv[5] = (char*)testoutput_folder.c_str(); + argv[6] = (char*)"--context"; + + // testProject1 - successed + argv[7] = (char*)"testProject1"; + EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); + auto errMsg = streamRedirect.GetErrorString(); + EXPECT_EQ(string::npos, errMsg.find("components from multiple bundles are specified:")); + + // testProject2, 3, 4 - failed + const char* failProjects[] = { "testProject2", "testProject3", "testProject4" }; + const char* expectedComponents[][2] = { + {"ARM::RteTestBundle&BundleOne:G0", "ARM::RteTestBundle&BundleTwo:G0"}, + {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle&BundleTwo:G0"}, + {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle:G0"} + }; + for (int i = 0; i < 3; i++) { + argv[7] = (char*)failProjects[i]; + EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); + errMsg = streamRedirect.GetErrorString(); + EXPECT_NE(string::npos, errMsg.find("components from multiple bundles are specified:")); + EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][0])); + EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][1])); + streamRedirect.ClearStringStreams(); + } +} + TEST_F(ProjMgrUnitTests, RunProjMgr_ListPacks_ContextSet) { char* argv[6]; StdStreamRedirect streamRedirect; @@ -7401,37 +7436,26 @@ TEST_F(ProjMgrUnitTests, TargetSetDependencies) { } TEST_F(ProjMgrUnitTests, DuplicateComponents) { - StdStreamRedirect streamRedirect; - - const string csolution = testinput_folder + "/TestSolution/DuplicateComponents/duplicateComponents.csolution.yml"; - - char* argv[9]; - argv[1] = (char*)"convert"; - argv[2] = (char*)"--solution"; - argv[3] = (char*)csolution.c_str(); - argv[4] = (char*)"-o"; - argv[5] = (char*)testoutput_folder.c_str(); - argv[6] = (char*)"--context"; - argv[7] = (char*)"duplicateComponents_cproject"; - argv[8] = (char*)"--no-check-schema"; - - EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); - auto errStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); - - argv[7] = (char*)"duplicateComponents_clayer"; - EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); - errStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); - - // Run with "--no-check-schema" - argv[7] = (char*)"duplicateComponents_cproject"; - EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); - errStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); - - argv[7] = (char*)"duplicateComponents_clayer"; - EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); - errStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); + StdStreamRedirect streamRedirect; + const string csolution = testinput_folder + "/TestSolution/DuplicateComponents/duplicateComponents.csolution.yml"; + char* argv[9]; + argv[1] = (char*)"convert"; + argv[2] = (char*)"--solution"; + argv[3] = (char*)csolution.c_str(); + argv[4] = (char*)"-o"; + argv[5] = (char*)testoutput_folder.c_str(); + argv[6] = (char*)"--context"; + argv[8] = (char*)"--no-check-schema"; + + const char* contexts[] = { "duplicateComponents_cproject", "duplicateComponents_clayer" }; + int argCounts[] = { 8, 9 }; // without/with --no-check-schema + for (int argCount : argCounts) { + for (const char* context : contexts) { + argv[7] = (char*)context; + EXPECT_EQ(1, RunProjMgr(argCount, argv, m_envp)); + auto errStr = streamRedirect.GetErrorString(); + EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); + streamRedirect.ClearStringStreams(); + } + } } From 477aab3f77b34320d3ae5d70b697fd55f349ce26 Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Tue, 17 Mar 2026 09:16:25 +0100 Subject: [PATCH 2/4] Modifiy RunProjMgr_MultiBundleComponent unit test --- tools/projmgr/src/ProjMgrWorker.cpp | 8 ++++---- .../TestProject1/testProject1.cproject.yml | 3 ++- .../TestProject2/testProject2.cproject.yml | 1 - .../TestProject4/testProject4.cproject.yml | 6 ------ .../multiBundleComponent.csolution.yml | 5 ----- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 10 +++++----- 6 files changed, 11 insertions(+), 22 deletions(-) delete mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index da6cc6ff2..535320e3a 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -1940,11 +1940,12 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { string bundleId = matchedComponent->GetCbundleName(); string classId = matchedComponent->GetCclassName(); - if (bundleId.empty()) { bundleId = "noBundle"; } - processedBundles[classId][bundleId].push_back(item.component); - if (processedBundles[classId].size() > 1) { + if (!bundleId.empty()) { + processedBundles[classId][bundleId].push_back(item.component); + if (processedBundles[classId].size() > 1) { // multiple bundle of the same component found error = true; + } } // Set layer's rtePath attribute @@ -2040,7 +2041,6 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { if (bundleMap.size() > 1) { string errMsg = "components from multiple bundles are specified:"; for (const auto& [bundleId, components] : bundleMap) { - errMsg += "\n bundle '" + bundleId + "':"; for (const auto& comp : components) { errMsg += "\n - " + comp; } diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml index 2677f97f4..6e1a5be49 100644 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject1/testProject1.cproject.yml @@ -2,6 +2,7 @@ project: components: - component: Startup - component: RteTest:CORE + - component: ARM::RteTestBundle:G0 - component: ARM::RteTestBundle&BundleOne:G0 - - component: ARM::RteTestBundle&BundleOne:G1 + - component: SomeVendor::RteTestBundle:G0 - component: SomeVendor::RteTestBundle&BundleOne:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml index 54f65a942..e5c7ef098 100644 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml @@ -3,5 +3,4 @@ project: - component: Startup - component: CORE - component: ARM::RteTestBundle&BundleOne:G0 - - component: ARM::RteTestBundle&BundleOne:G1 - component: ARM::RteTestBundle&BundleTwo:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml deleted file mode 100644 index 78f798121..000000000 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject4/testProject4.cproject.yml +++ /dev/null @@ -1,6 +0,0 @@ -project: - components: - - component: Startup - - component: CORE - - component: ARM::RteTestBundle&BundleOne:G0 - - component: SomeVendor::RteTestBundle:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml index c2b644469..3940c9554 100644 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml @@ -2,10 +2,6 @@ solution: target-types: - type: CM0 device: RteTest_ARMCM0 - target-set: - - set: - images: - - project-context: testProject1.Debug build-types: - type: Debug @@ -20,4 +16,3 @@ solution: - project: ./TestProject1/testProject1.cproject.yml - project: ./TestProject2/testProject2.cproject.yml - project: ./TestProject3/testProject3.cproject.yml - - project: ./TestProject4/testProject4.cproject.yml diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index ea7587d32..8f2602e0d 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -6477,15 +6477,15 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_MultiBundleComponent) { EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); auto errMsg = streamRedirect.GetErrorString(); EXPECT_EQ(string::npos, errMsg.find("components from multiple bundles are specified:")); + streamRedirect.ClearStringStreams(); - // testProject2, 3, 4 - failed - const char* failProjects[] = { "testProject2", "testProject3", "testProject4" }; + // testProject2, 3 - failed + const char* failProjects[] = { "testProject2", "testProject3" }; const char* expectedComponents[][2] = { {"ARM::RteTestBundle&BundleOne:G0", "ARM::RteTestBundle&BundleTwo:G0"}, - {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle&BundleTwo:G0"}, - {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle:G0"} + {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle&BundleTwo:G0"} }; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 2; i++) { argv[7] = (char*)failProjects[i]; EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); errMsg = streamRedirect.GetErrorString(); From 37243b12285e6d9b1f3a9fc442e8f5fc47912a45 Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Tue, 17 Mar 2026 10:55:35 +0100 Subject: [PATCH 3/4] Fix bugs and minimize changes --- test/local_packs/S/SomeVendor.RteTest.pdsc | 26 +--------------------- tools/projmgr/src/ProjMgrWorker.cpp | 4 ++-- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/test/local_packs/S/SomeVendor.RteTest.pdsc b/test/local_packs/S/SomeVendor.RteTest.pdsc index 48c911d02..e0e73ee86 100644 --- a/test/local_packs/S/SomeVendor.RteTest.pdsc +++ b/test/local_packs/S/SomeVendor.RteTest.pdsc @@ -21,12 +21,6 @@ - - - - - - @@ -37,7 +31,7 @@ - + Test bundle one https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#Component_Bundle @@ -46,18 +40,6 @@ - - Bundle One, component G1, only in bundle 1 - - - - - - Bundle One, component G2 - - - - @@ -69,12 +51,6 @@ - - Bundle Two, component G2 - - - - diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 535320e3a..a88c94afb 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -1938,8 +1938,8 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { error = true; } - string bundleId = matchedComponent->GetCbundleName(); - string classId = matchedComponent->GetCclassName(); + string bundleId = matchedComponentInstance->GetCbundleName(); + string classId = matchedComponentInstance->GetCclassName(); if (!bundleId.empty()) { processedBundles[classId][bundleId].push_back(item.component); if (processedBundles[classId].size() > 1) { From a1c881e324ab963de798f41f800fd467981c196d Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Wed, 18 Mar 2026 14:43:08 +0100 Subject: [PATCH 4/4] Refine error message and combine unit tests --- test/local_packs/S/SomeVendor.RteTest.pdsc | 31 +++++++++++-- tools/projmgr/src/ProjMgrWorker.cpp | 25 +++++++---- .../TestProject2/testProject2.cproject.yml | 7 ++- .../TestProject3/testProject3.cproject.yml | 6 --- .../multiBundleComponent.csolution.yml | 1 - tools/projmgr/test/src/ProjMgrUnitTests.cpp | 43 ++++++++++++------- 6 files changed, 78 insertions(+), 35 deletions(-) delete mode 100644 tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml diff --git a/test/local_packs/S/SomeVendor.RteTest.pdsc b/test/local_packs/S/SomeVendor.RteTest.pdsc index e0e73ee86..754388acc 100644 --- a/test/local_packs/S/SomeVendor.RteTest.pdsc +++ b/test/local_packs/S/SomeVendor.RteTest.pdsc @@ -30,7 +30,7 @@ - + Test bundle one https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#Component_Bundle @@ -41,7 +41,6 @@ - Test bundle two https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#element_bundle @@ -52,7 +51,6 @@ - Component G without bundle, but the same class and group as in bundle @@ -60,6 +58,33 @@ + + Test bundle one + https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#Component_Bundle + + Bundle One, component G0, version differs from bundle + + + + + + + Test bundle two + https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#element_bundle + + Bundle Two, component G, version differs from bundle + + + + + + + Component G without bundle, but the same class and group as in bundle + + + + + diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index a88c94afb..90239bac5 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -1934,16 +1934,16 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { return pair.first.compare(aggCompId) == 0; }); if (itr != processedComponents.end()) { - // multiple variant of the same component found + // multiple variants of the same component found error = true; } string bundleId = matchedComponentInstance->GetCbundleName(); - string classId = matchedComponentInstance->GetCclassName(); if (!bundleId.empty()) { + string classId = matchedComponentInstance->GetCclassName(); processedBundles[classId][bundleId].push_back(item.component); if (processedBundles[classId].size() > 1) { - // multiple bundle of the same component found + // multiple bundles of the same class found (without considering Cvendor) error = true; } } @@ -2029,25 +2029,34 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { // check if same component variants are specified multiple times for (const auto& pair : processedComponents) { if (pair.second.size() > 1) { - string errMsg = "multiple variants of the same component are specified:"; + string errMsg = "multiple Cvariants of the same component are mutually exclusive:"; for (const auto& comp : pair.second) { errMsg += ("\n - " + comp); } ProjMgrLogger::Get().Error(errMsg, context.name); } } - // check if same component bundles are specified multiple times (without considering Cvendor) - for (const auto& [_, bundleMap] : processedBundles) { + // check if different bundles are specified for the same class + string errMsg; + bool hasConflict = false; + for (const auto& [classId, bundleMap] : processedBundles) { if (bundleMap.size() > 1) { - string errMsg = "components from multiple bundles are specified:"; + if (!hasConflict) { + errMsg = "components in the same Cclass must belong to the same Cbundle."; + hasConflict = true; + } + errMsg += "\nConflicting Cbundle in Cclass '" + classId + "':"; for (const auto& [bundleId, components] : bundleMap) { + errMsg += "\n - '" + bundleId + "' component(s):"; for (const auto& comp : components) { errMsg += "\n - " + comp; } } - ProjMgrLogger::Get().Error(errMsg, context.name); } } + if (hasConflict) { + ProjMgrLogger::Get().Error(errMsg, context.name); + } } // Add required components into RTE diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml index e5c7ef098..41f30489a 100644 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject2/testProject2.cproject.yml @@ -2,5 +2,10 @@ project: components: - component: Startup - component: CORE + # Cclass RteTestBundle - component: ARM::RteTestBundle&BundleOne:G0 - - component: ARM::RteTestBundle&BundleTwo:G0 + - component: ARM::RteTestBundle&BundleOne:G1 + - component: SomeVendor::RteTestBundle&BundleTwo:G0 + # Cclass RteTestBundle2 + - component: SomeVendor::RteTestBundle2&BundleOne:G0 + - component: SomeVendor::RteTestBundle2&BundleTwo:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml deleted file mode 100644 index fea3d9a6b..000000000 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/TestProject3/testProject3.cproject.yml +++ /dev/null @@ -1,6 +0,0 @@ -project: - components: - - component: Startup - - component: CORE - - component: ARM::RteTestBundle&BundleOne:G0 - - component: SomeVendor::RteTestBundle&BundleTwo:G0 diff --git a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml index 3940c9554..7db5e2aee 100644 --- a/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml +++ b/tools/projmgr/test/data/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml @@ -15,4 +15,3 @@ solution: projects: - project: ./TestProject1/testProject1.cproject.yml - project: ./TestProject2/testProject2.cproject.yml - - project: ./TestProject3/testProject3.cproject.yml diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 8f2602e0d..27b989b60 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -6458,7 +6458,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_MultiVariantComponent) { auto errMsg = streamRedirect.GetErrorString(); EXPECT_NE(string::npos, - errMsg.find("multiple variants of the same component are specified:\n - Device:Test variant\n - Device:Test variant&Variant name")); + errMsg.find("multiple Cvariants of the same component are mutually exclusive:\n - Device:Test variant\n - Device:Test variant&Variant name")); } TEST_F(ProjMgrUnitTests, RunProjMgr_MultiBundleComponent) { @@ -6472,28 +6472,39 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_MultiBundleComponent) { argv[5] = (char*)testoutput_folder.c_str(); argv[6] = (char*)"--context"; - // testProject1 - successed argv[7] = (char*)"testProject1"; EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); auto errMsg = streamRedirect.GetErrorString(); EXPECT_EQ(string::npos, errMsg.find("components from multiple bundles are specified:")); streamRedirect.ClearStringStreams(); + argv[7] = (char*)"testProject2"; + EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); + errMsg = streamRedirect.GetErrorString(); + EXPECT_NE(string::npos, errMsg.find("components in the same Cclass must belong to the same Cbundle.")); + EXPECT_NE(string::npos, errMsg.find("Conflicting Cbundle in Cclass 'RteTestBundle':")); + EXPECT_NE(string::npos, errMsg.find(" - 'BundleOne' component(s):")); + EXPECT_NE(string::npos, errMsg.find(" - ARM::RteTestBundle&BundleOne:G0")); + EXPECT_NE(string::npos, errMsg.find("- ARM::RteTestBundle&BundleOne:G1")); + EXPECT_NE(string::npos, errMsg.find(" - 'BundleTwo' component(s):")); + EXPECT_NE(string::npos, errMsg.find(" - SomeVendor::RteTestBundle&BundleTwo:G0")); + EXPECT_NE(string::npos, errMsg.find("Conflicting Cbundle in Cclass 'RteTestBundle2':")); + // testProject2, 3 - failed - const char* failProjects[] = { "testProject2", "testProject3" }; - const char* expectedComponents[][2] = { - {"ARM::RteTestBundle&BundleOne:G0", "ARM::RteTestBundle&BundleTwo:G0"}, - {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle&BundleTwo:G0"} - }; - for (int i = 0; i < 2; i++) { - argv[7] = (char*)failProjects[i]; - EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); - errMsg = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errMsg.find("components from multiple bundles are specified:")); - EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][0])); - EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][1])); - streamRedirect.ClearStringStreams(); - } + //const char* failProjects[] = { "testProject2", "testProject3" }; + //const char* expectedComponents[][2] = { + // {"ARM::RteTestBundle&BundleOne:G0", "ARM::RteTestBundle&BundleTwo:G0"}, + // {"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle&BundleTwo:G0"} + //}; + //for (int i = 0; i < 2; i++) { + // argv[7] = (char*)failProjects[i]; + // EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); + // errMsg = streamRedirect.GetErrorString(); + // EXPECT_NE(string::npos, errMsg.find("components in the same Cclass must belong to the same Cbundle")); + // EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][0])); + // EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][1])); + // streamRedirect.ClearStringStreams(); + //} } TEST_F(ProjMgrUnitTests, RunProjMgr_ListPacks_ContextSet) {