diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 9a38903ac..ae26e1724 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -897,6 +897,7 @@ class ProjMgrWorker { std::vector& combinations, const ConnectPtrVec& previous = ConnectPtrVec()); void PushBackUniquely(ConnectionsCollectionVec& vec, const ConnectionsCollection& value); void PushBackUniquely(std::vector& vec, const ToolchainItem& value); + void GetRegisteredToolchainEnvVars(void); void GetRegisteredToolchains(void); bool GetLatestToolchain(ToolchainItem& toolchain); bool GetToolchainConfig(const std::string& name, const std::string& version, std::string& configPath, std::string& selectedConfigVersion); diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 6a01ff63d..5a3115966 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -1723,7 +1723,7 @@ bool ProjMgrWorker::ProcessToolchain(ContextItem& context) { context.toolchain = GetToolchain(context.compiler); - GetRegisteredToolchains(); + GetRegisteredToolchainEnvVars(); if (!m_regToolchainsEnvVars.empty()) { // check if the required environment variable is set auto itr = std::find_if(m_regToolchainsEnvVars.begin(), m_regToolchainsEnvVars.end(), [&context](const auto& item) { @@ -4480,18 +4480,21 @@ bool ProjMgrWorker::IsContextSelected(const string& context) { } bool ProjMgrWorker::ListToolchains(vector& toolchains) { + // If list toolchains command is fired + if (m_selectedContexts[0].empty()) { + // list registered toolchains + GetRegisteredToolchains(); + if (m_toolchains.empty()) { + return false; + } + toolchains = m_toolchains; + return true; + } + bool allSupported = true; for (const auto& selectedContext : m_selectedContexts) { ContextItem& context = m_contexts[selectedContext]; - if (selectedContext.empty()) { - // list registered toolchains - GetRegisteredToolchains(); - if (m_toolchains.empty()) { - return false; - } - toolchains = m_toolchains; - return true; - } + // list required toolchains for selected contexts if (!LoadPacks(context)) { return false; @@ -4515,10 +4518,7 @@ bool ProjMgrWorker::ListEnvironment(EnvironmentList& env) { return true; } -void ProjMgrWorker::GetRegisteredToolchains(void) { - if (!m_toolchains.empty()) { - return; - } +void ProjMgrWorker::GetRegisteredToolchainEnvVars(void) { // extract toolchain info from environment variables static const regex regEx = regex("(\\w+)_TOOLCHAIN_(\\d+)_(\\d+)_(\\d+)=(.*)"); for (const auto& envVar : m_envVars) { @@ -4530,6 +4530,17 @@ void ProjMgrWorker::GetRegisteredToolchains(void) { m_regToolchainsEnvVars[sm[1]][string(sm[2]) + '.' + string(sm[3]) + '.' + string(sm[4])] = sm[5]; } } + + if (m_regToolchainsEnvVars.empty()) { + m_toolchainErrors[MessageType::Warning].insert("no compiler registered. Add path to compiler 'bin' directory with environment variable _TOOLCHAIN___. is one of AC6, GCC, IAR, CLANG"); + } +} + +void ProjMgrWorker::GetRegisteredToolchains(void) { + if (!m_toolchains.empty()) { + return; + } + GetRegisteredToolchainEnvVars(); // iterate over registered toolchains for (const auto& [toolchainName, toolchainVersions] : m_regToolchainsEnvVars) { for (const auto& [toolchainVersion, toolchainRoot] : toolchainVersions) { @@ -4542,10 +4553,6 @@ void ProjMgrWorker::GetRegisteredToolchains(void) { } } } - - if (m_regToolchainsEnvVars.empty()) { - m_toolchainErrors[MessageType::Warning].insert("no compiler registered. Add path to compiler 'bin' directory with environment variable _TOOLCHAIN___. is one of AC6, GCC, IAR, CLANG"); - } } bool ProjMgrWorker::GetLatestToolchain(ToolchainItem& toolchain) { diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 4ae6cb5cc..558b7c5eb 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -1926,6 +1926,52 @@ TEST_F(ProjMgrUnitTests, ListToolchainsSolution) { EXPECT_EQ(outStr2, expected2); } +TEST_F(ProjMgrUnitTests, ListToolchains_with_unknown_toolchain) { + StdStreamRedirect streamRedirect; + char* envp[4]; + string ac6 = "AC6_TOOLCHAIN_6_18_0=" + testinput_folder; + string gcc = "GCC_TOOLCHAIN_11_3_1=" + testinput_folder; + string unknown = "UNKNOWN_TOOLCHAIN_1_2_3=" + testinput_folder; + envp[0] = (char*)ac6.c_str(); + envp[1] = (char*)gcc.c_str(); + envp[2] = (char*)unknown.c_str(); + envp[3] = (char*)'\0'; + char* argv[5]; + const string& csolution = testinput_folder + "/TestSolution/toolchain.csolution.yml"; + argv[1] = (char*)"list"; + argv[2] = (char*)"toolchains"; + argv[3] = (char*)"--solution"; + argv[4] = (char*)csolution.c_str(); + + // Test listing required toolchains + EXPECT_EQ(0, RunProjMgr(5, argv, envp)); + const string& expected = "AC6@>=0.0.0\nAC6@>=6.18.0\nGCC@11.3.1\n"; + const string& outStr = streamRedirect.GetOutString(); + const string& errStr = streamRedirect.GetErrorString(); + EXPECT_EQ(outStr, expected); + EXPECT_TRUE(errStr.empty()); + + // Test with no input solution + streamRedirect.ClearStringStreams(); + EXPECT_EQ(1, RunProjMgr(3, argv, envp)); + const string& expected2 = "AC6@6.18.0\nGCC@11.3.1\n"; + const string& outStr2 = streamRedirect.GetOutString(); + const string& errStr2 = streamRedirect.GetErrorString(); + EXPECT_EQ(outStr2, expected2); + EXPECT_TRUE(errStr2.find("error csolution: no toolchain cmake files found for 'UNKNOWN' in") != std::string::npos); + + // Test with converting the solution + streamRedirect.ClearStringStreams(); + argv[1] = (char*)"convert"; + argv[2] = (char*)"--solution"; + argv[3] = (char*)csolution.c_str(); + + // Test listing required toolchains + EXPECT_EQ(0, RunProjMgr(4, argv, envp)); + const string& errStr3 = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr3.empty()); +} + TEST_F(ProjMgrUnitTests, ListLayersUniquelyCompatibleBoard) { StdStreamRedirect streamRedirect; char* argv[8];