diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index f8379bbdf..f517f886f 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -526,8 +526,10 @@ bool ProjMgrWorker::LoadAllRelevantPacks() { m_loadedPacks.clear(); // the list will be updated, it should not contain dangling pointers // Get required pdsc files std::list pdscFiles; + bool noPackRequirements = true; for (const auto& context : m_selectedContexts) { auto& contextItem = m_contexts.at(context); + noPackRequirements &= contextItem.packRequirements.empty(); for (const auto& [pdscFile, pathVer] : contextItem.pdscFiles) { const string& path = pathVer.first; if (!path.empty()) { @@ -543,12 +545,12 @@ bool ProjMgrWorker::LoadAllRelevantPacks() { } } // Check load packs policy - if (pdscFiles.empty() && (m_loadPacksPolicy == LoadPacksPolicy::REQUIRED)) { + if (noPackRequirements && (m_loadPacksPolicy == LoadPacksPolicy::REQUIRED)) { ProjMgrLogger::Get().Error("required packs must be specified"); return false; } // Get installed packs - if (pdscFiles.empty() || (m_loadPacksPolicy == LoadPacksPolicy::ALL) || (m_loadPacksPolicy == LoadPacksPolicy::LATEST)) { + if (noPackRequirements || (m_loadPacksPolicy == LoadPacksPolicy::ALL) || (m_loadPacksPolicy == LoadPacksPolicy::LATEST)) { const bool latest = (m_loadPacksPolicy == LoadPacksPolicy::LATEST) || (m_loadPacksPolicy == LoadPacksPolicy::DEFAULT); if (!m_kernel->GetEffectivePdscFiles(pdscFiles, latest)) { ProjMgrLogger::Get().Error("parsing installed packs failed"); @@ -585,16 +587,15 @@ bool ProjMgrWorker::LoadPacks(ContextItem& context) { if (!InitializeTarget(context)) { return false; } + bool deferredFail = false; if (!CollectAllRequiredPdscFiles()) { PrintContextErrors(context.name); - if(!m_rpcMode) { - return false; - } + // defer return due to pdsc collection failure + deferredFail = true; } if ((m_loadedPacks.empty() || m_rpcMode) && !LoadAllRelevantPacks()) { - if(!m_rpcMode) { - return false; - } + // defer return due to pack loading failure + deferredFail = true; } // Filter context specific packs set selectedPacks; @@ -624,6 +625,10 @@ bool ProjMgrWorker::LoadPacks(ContextItem& context) { filter.SetSelectedPackages(selectedPacks); context.rteActiveTarget->SetPackageFilter(filter); context.rteActiveTarget->UpdateFilterModel(); + // report deferred failure; in rpc mode continue processing despite it + if (!m_rpcMode && deferredFail) { + return false; + } return CheckRteErrors(); } @@ -4807,12 +4812,12 @@ bool ProjMgrWorker::ListGenerators(vector& generators) { set generatorsSet; map >> sortedGeneratorsMap; StrMap generatorsDescription; + bool deferredFail = false; // classic generators for (const auto& selectedContext : m_selectedContexts) { ContextItem& context = m_contexts[selectedContext]; - if (!ProcessContext(context, false, true, false)) { - return false; - } + // defer failure report + deferredFail |= !ProcessContext(context, false, true, false); for (const auto& [id, generator] : context.generators) { for (const auto& [gpdsc, item] : context.gpdscs) { if (item.generator == id) { @@ -4827,6 +4832,11 @@ bool ProjMgrWorker::ListGenerators(vector& generators) { } } } + if (deferredFail) { + // report deferred failure + return false; + } + // global generators for (const auto& [options, contexts] : m_extGenerator->GetUsedGenerators()) { sortedGeneratorsMap.insert({ options.id, {} }); @@ -5678,22 +5688,31 @@ std::string ProjMgrWorker::GetSelectedToochain(void) { bool ProjMgrWorker::ProcessGlobalGenerators(ContextItem* selectedContext, const string& generatorId, string& projectType, StrVec& siblings) { - // iterate over contexts with same build and target types - m_selectedContexts.clear(); - for (auto& [_, context] : m_contexts) { - if ((context.type.build != selectedContext->type.build) || - (context.type.target != selectedContext->type.target)) { - continue; - } - if (!ParseContextLayers(context)) { - return false; + if (m_activeTargetType.empty()) { + // if active target type is not given, select all contexts with same build and target types + m_selectedContexts.clear(); + for (auto& [_, context] : m_contexts) { + if ((context.type.build != selectedContext->type.build) || + (context.type.target != selectedContext->type.target)) { + continue; + } + m_selectedContexts.push_back(context.name); } - m_selectedContexts.push_back(context.name); } - for (auto& context : m_selectedContexts) { - if (!ProcessContext(m_contexts.at(context), false, true, false)) { - return false; + // parse layers and process selected contexts + bool deferredFail = false; + for (auto& contextName : m_selectedContexts) { + if (!ParseContextLayers(m_contexts.at(contextName))) { + // defer failure report due to layers parsing + deferredFail = true; + continue; } + // defer failure report due to context processing + deferredFail |= !ProcessContext(m_contexts.at(contextName), false, true, false); + } + // report deferred failure + if (deferredFail) { + return false; } StrVec contextVec; const string& genDir = selectedContext->extGen[generatorId].path; @@ -6147,7 +6166,8 @@ void ProjMgrWorker::CollectUnusedPacks() { continue; } context.unusedPacks.clear(); - for (const auto& [packId, _] : context.rteFilteredModel->GetPackages()) { + for (const auto& [_, packItem] : context.rteFilteredModel->GetPackages()) { + const auto packId = packItem->GetPackageID(); if (context.packages.find(packId) == context.packages.end()) { CollectionUtils::PushBackUniquely(context.unusedPacks, packId); } diff --git a/tools/projmgr/test/data/TestGenerator/RTE/Device/RteTestGen_ARMCM0/ac6_linker_script.sct.src b/tools/projmgr/test/data/TestGenerator/RTE/Device/RteTestGen_ARMCM0/ac6_linker_script.sct.src new file mode 100644 index 000000000..7820e1f12 --- /dev/null +++ b/tools/projmgr/test/data/TestGenerator/RTE/Device/RteTestGen_ARMCM0/ac6_linker_script.sct.src @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------------- + Stack seal size definition + *----------------------------------------------------------------------------*/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define __STACKSEAL_SIZE 8 +#else +#define __STACKSEAL_SIZE 0 +#endif + +/*---------------------------------------------------------------------------- + Scatter File Definitions definition + *----------------------------------------------------------------------------*/ + +LR_ROM0 __ROM0_BASE __ROM0_SIZE { + + ER_ROM0 __ROM0_BASE __ROM0_SIZE { + *.o (RESET, +First) + *(InRoot$$Sections) + *(+RO +XO) + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + ER_CMSE_VENEER AlignExpr(+0, 32) (__ROM0_SIZE - AlignExpr(ImageLength(ER_ROM0), 32)) { + *(Veneer$$CMSE) + } +#endif + + RW_NOINIT __RAM0_BASE UNINIT (__RAM0_SIZE - __HEAP_SIZE - __STACK_SIZE - __STACKSEAL_SIZE) { + *.o(.bss.noinit) + *.o(.bss.noinit.*) + } + + RW_RAM0 AlignExpr(+0, 8) (__RAM0_SIZE - __HEAP_SIZE - __STACK_SIZE - __STACKSEAL_SIZE - AlignExpr(ImageLength(RW_NOINIT), 8)) { + *(+RW +ZI) + } + +#if __HEAP_SIZE > 0 + ARM_LIB_HEAP (AlignExpr(+0, 8)) EMPTY __HEAP_SIZE { ; Reserve empty region for heap + } +#endif + + ARM_LIB_STACK (__RAM0_BASE + __RAM0_SIZE - __STACKSEAL_SIZE) EMPTY -__STACK_SIZE { ; Reserve empty region for stack + } + +#if __STACKSEAL_SIZE > 0 + STACKSEAL +0 EMPTY __STACKSEAL_SIZE { ; Reserve empty region for stack seal immediately after stack + } +#endif + +#if __RAM1_SIZE > 0 + RW_RAM1 __RAM1_BASE __RAM1_SIZE { + .ANY (+RW +ZI) + } +#endif + +#if __RAM2_SIZE > 0 + RW_RAM2 __RAM2_BASE __RAM2_SIZE { + .ANY (+RW +ZI) + } +#endif + +#if __RAM3_SIZE > 0 + RW_RAM3 __RAM3_BASE __RAM3_SIZE { + .ANY (+RW +ZI) + } +#endif +} + +#if __ROM1_SIZE > 0 +LR_ROM1 __ROM1_BASE __ROM1_SIZE { + ER_ROM1 +0 __ROM1_SIZE { + .ANY (+RO +XO) + } +} +#endif + +#if __ROM2_SIZE > 0 +LR_ROM2 __ROM2_BASE __ROM2_SIZE { + ER_ROM2 +0 __ROM2_SIZE { + .ANY (+RO +XO) + } +} +#endif + +#if __ROM3_SIZE > 0 +LR_ROM3 __ROM3_BASE __ROM3_SIZE { + ER_ROM3 +0 __ROM3_SIZE { + .ANY (+RO +XO) + } +} +#endif diff --git a/tools/projmgr/test/data/TestGenerator/RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h b/tools/projmgr/test/data/TestGenerator/RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h new file mode 100644 index 000000000..b91550663 --- /dev/null +++ b/tools/projmgr/test/data/TestGenerator/RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h @@ -0,0 +1,101 @@ +#ifndef REGIONS_RTETESTGEN_ARMCM0_H +#define REGIONS_RTETESTGEN_ARMCM0_H + + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- +//------ With VS Code: Open Preview for Configuration Wizard ------------------- + +// Auto-generated using information from packs +// Device Family Pack (DFP): ARM::RteTestGenerator@0.1.0 + +// ROM Configuration +// ======================= +// __ROM0 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +// Contains Startup and Vector Table +#define __ROM0_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __ROM0_SIZE 0x0 +// + +// __ROM1 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +#define __ROM1_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __ROM1_SIZE 0x0 +// + +// __ROM2 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +#define __ROM2_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __ROM2_SIZE 0x0 +// + +// __ROM3 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +#define __ROM3_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __ROM3_SIZE 0x0 +// + +// + +// RAM Configuration +// ======================= +// __RAM0 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +// Contains uninitialized RAM, Stack, and Heap +#define __RAM0_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __RAM0_SIZE 0x0 +// + +// __RAM1 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +#define __RAM1_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __RAM1_SIZE 0x0 +// + +// __RAM2 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +#define __RAM2_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __RAM2_SIZE 0x0 +// + +// __RAM3 (unused) +// Base address <0x0-0xFFFFFFFF:8> +// Defines base address of memory region. +#define __RAM3_BASE 0x0 +// Region size [bytes] <0x0-0xFFFFFFFF:8> +// Defines size of memory region. +#define __RAM3_SIZE 0x0 +// + +// + +// Stack / Heap Configuration +// Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +#define __STACK_SIZE 0x00000200 +#define __HEAP_SIZE 0x00000000 +// + + +#endif /* REGIONS_RTETESTGEN_ARMCM0_H */ diff --git a/tools/projmgr/test/data/TestSolution/PackMissing/ref/missing_pack.cbuild-idx.yml b/tools/projmgr/test/data/TestSolution/PackMissing/ref/missing_pack.cbuild-idx.yml index c9d51be68..5826d545a 100644 --- a/tools/projmgr/test/data/TestSolution/PackMissing/ref/missing_pack.cbuild-idx.yml +++ b/tools/projmgr/test/data/TestSolution/PackMissing/ref/missing_pack.cbuild-idx.yml @@ -1,5 +1,5 @@ build-idx: - generated-by: csolution version 0.0.0+g79b66b5f + generated-by: csolution version 0.0.0 csolution: ../data/TestSolution/PackMissing/missing_pack.csolution.yml tmpdir: tmp cprojects: @@ -12,7 +12,6 @@ build-idx: messages: errors: - "required pack: ARM::Missing_DFP@0.0.9 not installed" - - "specified device 'RteTest_ARMCM0' not found in the installed packs. Use:\n cpackget add Vendor::PackName" - processing context 'project+CM0' failed info: - missing_pack.cbuild-pack.yml - file generated successfully @@ -26,7 +25,6 @@ build-idx: messages: errors: - "required pack: ARM::Missing_PACK@0.0.1 not installed" - - "specified device 'RteTest_ARMCM3' not found in the installed packs. Use:\n cpackget add Vendor::PackName" - processing context 'project+Gen' failed info: - missing_pack.cbuild-pack.yml - file generated successfully @@ -42,7 +40,6 @@ build-idx: - "required pack: ARM::Missing_DFP@>=0.0.5 not installed" - "required pack: ARM::Missing_PACK not installed" - "required pack: ARM::RteTest@3.0.1 not installed" - - "specified device 'RteTest_ARMCM0' not found in the installed packs. Use:\n cpackget add Vendor::PackName" - processing context 'project+Miss' failed info: - missing_pack.cbuild-pack.yml - file generated successfully diff --git a/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+CM0.cbuild.yml index 3eec4d566..edb64a8fc 100644 --- a/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+CM0.cbuild.yml @@ -1,9 +1,23 @@ build: - generated-by: csolution version 0.0.0+g658d82cc + generated-by: csolution version 0.0.0 solution: ../data/TestSolution/PackMissing/missing_pack.csolution.yml project: ../data/TestSolution/PackMissing/project.cproject.yml context: project+CM0 compiler: AC6 + device: ARM::RteTest_ARMCM0 + device-pack: ARM::RteTest_DFP@0.2.0 + device-books: + - name: http://infocenter.arm.com/help/topic/com.arm.doc.dui0497a/index.html + title: Cortex-M0 Device Generic Users Guide + dbgconf: + - file: ../data/TestSolution/PackMissing/.cmsis/missing_pack+CM0.dbgconf + version: 0.0.2 + processor: + fpu: off + core: Cortex-M0 + packs: + - pack: ARM::RteTest_DFP@0.2.0 + path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 misc: ASM: - -ASM-project @@ -17,6 +31,17 @@ build: - -Link-project define: - DEF-project + - ARMCM0 + - _RTE_ + define-asm: + - ARMCM0 + - _RTE_ + add-path: + - ../data/TestSolution/PackMissing/RTE/_CM0 + - ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include + add-path-asm: + - ../data/TestSolution/PackMissing/RTE/_CM0 + - ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include output-dirs: intdir: tmp/project/CM0 outdir: out/project/CM0 @@ -28,3 +53,63 @@ build: file: compile_commands.json - type: comp-db file: compile_macros.h + components: + - component: ARM::Device:Startup&RteTest Startup@2.0.3 + condition: ARMCM0 RteTest + from-pack: ARM::RteTest_DFP@0.2.0 + selected-by: Startup + files: + - file: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include/ARMCM0.h + category: header + version: 2.0.3 + - file: https://arm-software.github.io/CMSIS_5/Core_A/html/startup_c_pg.html + category: doc + version: 2.0.3 + - file: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM0/ARMCM0_ac6.sct + category: linkerScript + attr: config + version: 1.0.0 + - file: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM0/startup_ARMCM0.c + category: sourceC + attr: config + version: 2.0.3 + - file: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM0/system_ARMCM0.c + category: sourceC + attr: config + version: 1.0.0 + - component: ARM::RteTest:CORE@0.1.1 + condition: Cortex-M Device + from-pack: ARM::RteTest_DFP@0.2.0 + selected-by: RteTest:CORE@0.1.1 + implements: RteTest:CORE@1.1.2 + files: + - file: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Doc/html/index.html + category: doc + version: 0.1.1 + apis: + - api: RteTest:CORE@1.1.2 + from-pack: ARM::RteTest_DFP@0.2.0 + implemented-by: ARM::RteTest:CORE@0.1.1 + files: + - file: https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_apis_pg.html + category: doc + version: 1.1.2 + linker: + script: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM0/ARMCM0_ac6.sct + groups: + - group: Sources + files: + - file: ../data/TestSolution/PackMissing/main.c + category: sourceC + constructed-files: + - file: ../data/TestSolution/PackMissing/RTE/_CM0/RTE_Components.h + category: header + licenses: + - license: + license-agreement: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Doc/license.txt + packs: + - pack: ARM::RteTest_DFP@0.2.0 + components: + - component: ARM::Device:Startup&RteTest Startup@2.0.3 + - component: ARM::RteTest:CORE@0.1.1 + - component: RteTest:CORE(API) diff --git a/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+Gen.cbuild.yml b/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+Gen.cbuild.yml index f520d038e..359759991 100644 --- a/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+Gen.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/PackMissing/ref/project+Gen.cbuild.yml @@ -1,9 +1,23 @@ build: - generated-by: csolution version 0.0.0+g658d82cc + generated-by: csolution version 0.0.0 solution: ../data/TestSolution/PackMissing/missing_pack.csolution.yml project: ../data/TestSolution/PackMissing/project.cproject.yml context: project+Gen compiler: AC6 + device: ARM::RteTest_ARMCM3 + device-pack: ARM::RteTest_DFP@0.2.0 + device-books: + - name: http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/index.html + title: Cortex-M3 Device Generic Users Guide + dbgconf: + - file: ../data/TestSolution/PackMissing/.cmsis/missing_pack+Gen.dbgconf + version: 0.0.2 + processor: + fpu: off + core: Cortex-M3 + packs: + - pack: ARM::RteTest_DFP@0.2.0 + path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 misc: ASM: - -ASM-project @@ -17,6 +31,17 @@ build: - -Link-project define: - DEF-project + - ARMCM3 + - _RTE_ + define-asm: + - ARMCM3 + - _RTE_ + add-path: + - ../data/TestSolution/PackMissing/RTE/_Gen + - ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM3/Include + add-path-asm: + - ../data/TestSolution/PackMissing/RTE/_Gen + - ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM3/Include output-dirs: intdir: tmp/project/Gen outdir: out/project/Gen @@ -28,3 +53,63 @@ build: file: compile_commands.json - type: comp-db file: compile_macros.h + components: + - component: ARM::Device:Startup&RteTest Startup@2.0.3 + condition: ARMCM3 RteTest + from-pack: ARM::RteTest_DFP@0.2.0 + selected-by: Startup + files: + - file: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM3/Include/ARMCM3.h + category: header + version: 2.0.3 + - file: https://arm-software.github.io/CMSIS_5/Core_A/html/startup_c_pg.html + category: doc + version: 2.0.3 + - file: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM3/ARMCM3_ac6.sct + category: linkerScript + attr: config + version: 1.2.0 + - file: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM3/startup_ARMCM3.c + category: sourceC + attr: config + version: 2.0.3 + - file: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM3/system_ARMCM3.c + category: sourceC + attr: config + version: 1.2.2 + - component: ARM::RteTest:CORE@0.1.1 + condition: Cortex-M Device + from-pack: ARM::RteTest_DFP@0.2.0 + selected-by: RteTest:CORE@0.1.1 + implements: RteTest:CORE@1.1.2 + files: + - file: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Doc/html/index.html + category: doc + version: 0.1.1 + apis: + - api: RteTest:CORE@1.1.2 + from-pack: ARM::RteTest_DFP@0.2.0 + implemented-by: ARM::RteTest:CORE@0.1.1 + files: + - file: https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_apis_pg.html + category: doc + version: 1.1.2 + linker: + script: ../data/TestSolution/PackMissing/RTE/Device/RteTest_ARMCM3/ARMCM3_ac6.sct + groups: + - group: Sources + files: + - file: ../data/TestSolution/PackMissing/main.c + category: sourceC + constructed-files: + - file: ../data/TestSolution/PackMissing/RTE/_Gen/RTE_Components.h + category: header + licenses: + - license: + license-agreement: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Doc/license.txt + packs: + - pack: ARM::RteTest_DFP@0.2.0 + components: + - component: ARM::Device:Startup&RteTest Startup@2.0.3 + - component: ARM::RteTest:CORE@0.1.1 + - component: RteTest:CORE(API) diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 1b91d934e..328eabd7a 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -3604,6 +3604,71 @@ TEST_F(ProjMgrUnitTests, ListMultipleGenerators) { EXPECT_EQ(expected, set(generators.begin(), generators.end())); } +TEST_F(ProjMgrUnitTests, ListGenerators_DeferredFailure) { + // When ProcessContext fails for a context (e.g. missing pack path), + // ListGenerators must still iterate over ALL selected contexts before + // returning false (deferred-failure semantics). + vector generators; + m_csolutionFile = testinput_folder + "/TestSolution/test_local_pack_path_not_found.csolution.yml"; + m_rootDir = fs::path(m_csolutionFile).parent_path().generic_string(); + EXPECT_TRUE(PopulateContexts()); + EXPECT_TRUE(m_worker.ParseContextSelection({})); // all contexts + // Must return false (pack path not found) but must NOT assert/crash, + // proving all contexts were visited before the deferred failure is reported. + EXPECT_FALSE(m_worker.ListGenerators(generators)); +} + +TEST_F(ProjMgrUnitTests, ListGenerators_AllContextsIterated) { + // Verifies that ListGenerators iterates over ALL contexts before returning false (deferred-failure semantics) + StdStreamRedirect streamRedirect; + char* argv[5]; + const string& csolution = testinput_folder + "/TestSolution/test_local_pack_path_not_found.csolution.yml"; + argv[1] = (char*)"list"; + argv[2] = (char*)"generators"; + argv[3] = (char*)"--solution"; + argv[4] = (char*)csolution.c_str(); + EXPECT_EQ(1, RunProjMgr(5, argv, 0)); + + // Each of the contexts must emit a pack-path error + const string expectedErr = "SolutionSpecificPack/ARM does not exist"; + const string errStr = streamRedirect.GetErrorString(); + size_t count = 0; + size_t pos = 0; + while ((pos = errStr.find(expectedErr, pos)) != string::npos) { + count++; + pos += expectedErr.length(); + } + EXPECT_EQ(4U, count); +} + +TEST_F(ProjMgrUnitTests, ProcessGlobalGenerators_ActiveTargetType) { + // Tests ProcessGlobalGenerators when m_activeTargetType is non-empty + // (set via --active), ProcessGlobalGenerators skips context re-derivation and + // uses the pre-populated m_selectedContexts as-is + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; + const string& dstGlobalGenerator = etc_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + const string& srcBridgeTool = testinput_folder + "/ExternalGenerator/bridge tool.sh"; + const string& dstBridgeTool = bin_folder + "/bridge tool.sh"; + RteFsUtils::CopyCheckFile(srcBridgeTool, dstBridgeTool, false); + + StdStreamRedirect streamRedirect; + char* argv[7]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"run"; + argv[3] = (char*)"-g"; + argv[4] = (char*)"RteTestExternalGenerator"; + argv[5] = (char*)"--active"; + argv[6] = (char*)"CM0"; + RunProjMgr(7, argv, m_envp); // return code is host-dependent + EXPECT_EQ(string::npos, streamRedirect.GetErrorString().find("one or more selected contexts are unrelated")); + + RteFsUtils::RemoveFile(dstGlobalGenerator); + RteFsUtils::RemoveFile(dstBridgeTool); +} + TEST_F(ProjMgrUnitTests, RunProjMgr_MultipleGenerators) { char* argv[7]; // convert --solution solution.yml