From 01c6df1e8ca367de095fb98e0eb1438bb0d04678 Mon Sep 17 00:00:00 2001 From: Eran Ifrah <eran@codelite.org> Date: Sun, 12 Jan 2025 18:54:16 +0200 Subject: [PATCH] CodeLite doesn't detect existing mingw-w64 installations Added new compiler locator (MSW only) that checks for gcc/clang using the PATH env variable. fixes: https://github.com/eranif/codelite/issues/3326 Signed-off-by: Eran Ifrah <eran@codelite.org> --- .../CompilerLocator/CompilerLocatorMSYS2.cpp | 52 ++++++++++--------- .../CompilerLocator/CompilerLocatorMSYS2.hpp | 18 +++++-- Plugin/CompilersDetectorManager.cpp | 50 +++++++++--------- Plugin/compiler.cpp | 2 +- Plugin/globals.cpp | 2 +- 5 files changed, 69 insertions(+), 55 deletions(-) diff --git a/Plugin/CompilerLocator/CompilerLocatorMSYS2.cpp b/Plugin/CompilerLocator/CompilerLocatorMSYS2.cpp index a427e38394..8e4539c716 100644 --- a/Plugin/CompilerLocator/CompilerLocatorMSYS2.cpp +++ b/Plugin/CompilerLocator/CompilerLocatorMSYS2.cpp @@ -1,11 +1,10 @@ #include "CompilerLocatorMSYS2.hpp" -#include "GCCMetadata.hpp" -#include "Platform/Platform.hpp" #include "compiler.h" #include "file_logger.h" #include <wx/filename.h> +#include <wx/tokenzr.h> // -------------------------------------------------- // -------------------------------------------------- @@ -36,27 +35,39 @@ std::vector<std::unordered_map<wxString, wxString>> TOOLCHAINS = { }; } -CompilerLocatorMSYS2Usr::CompilerLocatorMSYS2Usr() -{ - m_repository = ""; - m_msys2.SetChroot("\\usr"); -} +CompilerLocatorMSYS2Usr::CompilerLocatorMSYS2Usr() { m_msys2.SetChroot("\\usr"); } CompilerLocatorMSYS2Usr::~CompilerLocatorMSYS2Usr() {} -CompilerLocatorMSYS2Mingw64::CompilerLocatorMSYS2Mingw64() -{ - m_repository = "mingw64"; - m_msys2.SetChroot("\\mingw64"); -} +CompilerLocatorMSYS2Mingw64::CompilerLocatorMSYS2Mingw64() { m_msys2.SetChroot("\\mingw64"); } CompilerLocatorMSYS2Mingw64::~CompilerLocatorMSYS2Mingw64() {} -CompilerLocatorMSYS2Clang64::CompilerLocatorMSYS2Clang64() +CompilerLocatorMSYS2Clang64::CompilerLocatorMSYS2Clang64() { m_msys2.SetChroot("\\clang64"); } +CompilerLocatorMSYS2Clang64::~CompilerLocatorMSYS2Clang64() {} + +CompilerLocatorMSYS2Env::CompilerLocatorMSYS2Env() {} +CompilerLocatorMSYS2Env::~CompilerLocatorMSYS2Env() {} + +bool CompilerLocatorMSYS2Env::Locate() { - m_repository = "clang64"; - m_msys2.SetChroot("\\clang64"); + clDEBUG() << "Locating compiler based on PATH environment variable" << endl; + m_compilers.clear(); + wxString path_env; + if (!::wxGetEnv("PATH", &path_env)) { + return false; + } + + wxArrayString paths_to_try = ::wxStringTokenize(path_env, ";", wxTOKEN_STRTOK); + for (const auto& path : paths_to_try) { + clDEBUG() << "Tyring to locate compiler at:" << path << endl; + auto cmp = CompilerLocatorMSYS2::Locate(path); + if (cmp) { + clDEBUG() << "Found compiler:" << cmp->GetName() << endl; + m_compilers.push_back(cmp); + } + } + return !m_compilers.empty(); } -CompilerLocatorMSYS2Clang64::~CompilerLocatorMSYS2Clang64() {} // -------------------------------------------------- // -------------------------------------------------- @@ -102,13 +113,6 @@ CompilerPtr CompilerLocatorMSYS2::TryToolchain(const wxString& folder, return nullptr; } - // define the toolchain name - wxString basename = m_repository; - if (!basename.empty()) { - basename << "/"; - } - basename << "gcc"; - // create new compiler CompilerPtr compiler(new Compiler(nullptr)); compiler->SetName(gxx.GetFullPath()); @@ -132,7 +136,7 @@ CompilerPtr CompilerLocatorMSYS2::TryToolchain(const wxString& folder, CompilerPtr CompilerLocatorMSYS2::Locate(const wxString& folder) { - // check for g++ + // check for g++/clang++ for (const auto& toolchain : TOOLCHAINS) { auto cmp = TryToolchain(folder, toolchain); if (cmp) { diff --git a/Plugin/CompilerLocator/CompilerLocatorMSYS2.hpp b/Plugin/CompilerLocator/CompilerLocatorMSYS2.hpp index 7aa43d0cd0..b784e2b444 100644 --- a/Plugin/CompilerLocator/CompilerLocatorMSYS2.hpp +++ b/Plugin/CompilerLocator/CompilerLocatorMSYS2.hpp @@ -1,11 +1,9 @@ -#ifndef COMPILERLOCATORMSYS2_HPP -#define COMPILERLOCATORMSYS2_HPP +#pragma once #include "ICompilerLocator.h" #include "Platform/MSYS2.hpp" #include <unordered_map> -#include <vector> #include <wx/filename.h> /// Locate for GCC compilers @@ -13,7 +11,6 @@ class WXDLLIMPEXP_SDK CompilerLocatorMSYS2 : public ICompilerLocator { protected: MSYS2 m_msys2; - wxString m_repository; protected: wxFileName GetFileName(const wxString& bin_dir, const wxString& fullname) const; @@ -55,4 +52,15 @@ class WXDLLIMPEXP_SDK CompilerLocatorMSYS2Mingw64 : public CompilerLocatorMSYS2 CompilerLocatorMSYS2Mingw64(); virtual ~CompilerLocatorMSYS2Mingw64(); }; -#endif // COMPILERLOCATORMSYS2_HPP + +class WXDLLIMPEXP_SDK CompilerLocatorMSYS2Env : public CompilerLocatorMSYS2 +{ +public: + CompilerLocatorMSYS2Env(); + virtual ~CompilerLocatorMSYS2Env(); + + /** + * @brief locate all compilers based on the PATH env variable + */ + bool Locate() override; +}; diff --git a/Plugin/CompilersDetectorManager.cpp b/Plugin/CompilersDetectorManager.cpp index f1ba294a7c..c5fce61ad3 100644 --- a/Plugin/CompilersDetectorManager.cpp +++ b/Plugin/CompilersDetectorManager.cpp @@ -62,6 +62,7 @@ CompilersDetectorManager::CompilersDetectorManager() m_detectors.push_back(ICompilerLocator::Ptr_t(new CompilerLocatorMSYS2ClangUsr())); m_detectors.push_back(ICompilerLocator::Ptr_t(new CompilerLocatorMSYS2ClangClang64())); m_detectors.push_back(ICompilerLocator::Ptr_t(new CompilerLocatorMSYS2ClangMingw64())); + m_detectors.push_back(ICompilerLocator::Ptr_t(new CompilerLocatorMSYS2Env())); #elif defined(__WXGTK__) m_detectors.push_back(ICompilerLocator::Ptr_t(new CompilerLocatorGCC())); @@ -91,9 +92,9 @@ bool CompilersDetectorManager::Locate() wxStringSet_t S; clDEBUG() << "scanning for compilers..." << endl; - for(auto locator : m_detectors) { - if(locator->Locate()) { - for(auto compiler : locator->GetCompilers()) { + for (auto locator : m_detectors) { + if (locator->Locate()) { + for (auto compiler : locator->GetCompilers()) { /* Resolve symlinks and detect compiler duplication, e.g.: * /usr/bin/g++ (GCC) * -> /usr/bin/g++-9 (GCC-9) @@ -103,8 +104,8 @@ bool CompilersDetectorManager::Locate() * separate environment (vcvars*.bat) and its CXX is just * 'cl.exe' */ wxString cxxPath = GetRealCXXPath(compiler); - if(compiler->GetCompilerFamily() == COMPILER_FAMILY_VC || - (!cxxPath.IsEmpty() && S.count(cxxPath) == 0)) { + if (compiler->GetCompilerFamily() == COMPILER_FAMILY_VC || + (!cxxPath.IsEmpty() && S.count(cxxPath) == 0)) { S.insert(cxxPath); m_compilersFound.push_back(compiler); } @@ -112,7 +113,7 @@ bool CompilersDetectorManager::Locate() } } - for(auto compiler : m_compilersFound) { + for (auto compiler : m_compilersFound) { MSWFixClangToolChain(compiler, m_compilersFound); } @@ -123,9 +124,9 @@ bool CompilersDetectorManager::Locate() CompilerPtr CompilersDetectorManager::Locate(const wxString& folder) { m_compilersFound.clear(); - for(auto detector : m_detectors) { + for (auto detector : m_detectors) { CompilerPtr comp = detector->Locate(folder); - if(comp) { + if (comp) { MSWFixClangToolChain(comp); return comp; } @@ -135,9 +136,9 @@ CompilerPtr CompilersDetectorManager::Locate(const wxString& folder) bool CompilersDetectorManager::FoundMinGWCompiler() const { - for(size_t i = 0; i < m_compilersFound.size(); ++i) { + for (size_t i = 0; i < m_compilersFound.size(); ++i) { CompilerPtr compiler = m_compilersFound.at(i); - if(compiler->GetCompilerFamily() == COMPILER_FAMILY_MINGW) { + if (compiler->GetCompilerFamily() == COMPILER_FAMILY_MINGW) { // we found at least one MinGW compiler return true; } @@ -148,16 +149,17 @@ bool CompilersDetectorManager::FoundMinGWCompiler() const void CompilersDetectorManager::MSWSuggestToDownloadMinGW(bool prompt) { #ifdef __WXMSW__ - if(!prompt || - ::wxMessageBox(_("Could not locate any MinGW compiler installed on your machine, would you like to " - "install one now?"), - "CodeLite", wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTER | wxICON_QUESTION) == wxYES) { + if (!prompt || ::wxMessageBox(_("Could not locate any MinGW compiler installed on your machine, would you like to " + "install one now?"), + "CodeLite", + wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTER | wxICON_QUESTION) == wxYES) { // open the install compiler page ::wxLaunchDefaultBrowser("https://docs.codelite.org/build/mingw_builds/#prepare-a-working-environment"); // Prompt the user on how to proceed - ::wxMessageBox(_("After the installation process is done\nClick the 'Scan' button"), "CodeLite", + ::wxMessageBox(_("After the installation process is done\nClick the 'Scan' button"), + "CodeLite", wxOK | wxCENTER | wxICON_INFORMATION); } #endif // __WXMSW__ @@ -169,10 +171,10 @@ void CompilersDetectorManager::MSWFixClangToolChain(CompilerPtr compiler, // Update the toolchain (if Windows) #ifdef __WXMSW__ ICompilerLocator::CompilerVec_t compilers; - if(allCompilers.empty()) { + if (allCompilers.empty()) { BuildSettingsConfigCookie cookie; CompilerPtr cmp = BuildSettingsConfigST::Get()->GetFirstCompiler(cookie); - while(cmp) { + while (cmp) { compilers.push_back(cmp); cmp = BuildSettingsConfigST::Get()->GetNextCompiler(cookie); } @@ -180,20 +182,20 @@ void CompilersDetectorManager::MSWFixClangToolChain(CompilerPtr compiler, compilers.insert(compilers.end(), allCompilers.begin(), allCompilers.end()); } - if(compiler->GetCompilerFamily() == COMPILER_FAMILY_CLANG) { - for(size_t i = 0; i < compilers.size(); ++i) { + if (compiler->GetCompilerFamily() == COMPILER_FAMILY_CLANG) { + for (size_t i = 0; i < compilers.size(); ++i) { CompilerPtr mingwCmp = compilers.at(i); - if(mingwCmp->GetCompilerFamily() == COMPILER_FAMILY_MINGW) { + if (mingwCmp->GetCompilerFamily() == COMPILER_FAMILY_MINGW) { // Update the make and windres tool if no effective path is set - if(compiler->GetTool("MAKE").StartsWith("mingw32-make.exe")) { + if (compiler->GetTool("MAKE").StartsWith("mingw32-make.exe")) { compiler->SetTool("MAKE", mingwCmp->GetTool("MAKE")); } - if(compiler->GetTool("ResourceCompiler") == "windres.exe") { + if (compiler->GetTool("ResourceCompiler") == "windres.exe") { compiler->SetTool("ResourceCompiler", mingwCmp->GetTool("ResourceCompiler")); } // MSYS2 Clang comes with its own headers and libraries - if(!compiler->GetName().Matches("CLANG ??bit ( MSYS2* )")) { + if (!compiler->GetName().Matches("CLANG ??bit ( MSYS2* )")) { // Update the include paths GCCMetadata compiler_md("MinGW"); wxArrayString includePaths; @@ -217,7 +219,7 @@ void CompilersDetectorManager::MSWFixClangToolChain(CompilerPtr compiler, wxString CompilersDetectorManager::GetRealCXXPath(const CompilerPtr compiler) const { - if(compiler->GetName() == "rustc") { + if (compiler->GetName() == "rustc") { // rustc is a dummy compiler, do not touch it return compiler->GetTool("CXX"); } diff --git a/Plugin/compiler.cpp b/Plugin/compiler.cpp index 231f7c7558..314d1b76db 100644 --- a/Plugin/compiler.cpp +++ b/Plugin/compiler.cpp @@ -503,7 +503,7 @@ wxString Compiler::GetSwitch(const wxString& name) const wxString Compiler::GetTool(const wxString& name) const { - std::map<wxString, wxString>::const_iterator iter = m_tools.find(name); + auto iter = m_tools.find(name); if (iter == m_tools.end()) { if (name == wxT("CC")) { // an upgrade, return the CXX diff --git a/Plugin/globals.cpp b/Plugin/globals.cpp index 100970911d..0d5d01ad33 100644 --- a/Plugin/globals.cpp +++ b/Plugin/globals.cpp @@ -757,7 +757,7 @@ DoReadProjectTemplatesFromFolder(const wxString& folder, std::list<ProjectPtr>& continue; } list.push_back(proj); - clSYSTEM() << "Found template project:" << files[i] << "." << proj->GetName() << endl; + clDEBUG() << "Found template project:" << files[i] << "." << proj->GetName() << endl; // load template icon wxFileName fn(files.Item(i)); fn.SetFullName("icon.png");