void CompilersFoundDlg::MSWUpdateToolchain(CompilerPtr compiler) { wxUnusedVar(compiler); #ifdef __WXMSW__ if(compiler->GetCompilerFamily() == COMPILER_FAMILY_MINGW) { // Clang and VC lacks 2 tools: make and windres // so we copy those from the default MinGW compiler wxString make = compiler->GetTool("MAKE"); wxString resourceCompiler = compiler->GetTool("ResourceCompiler"); for(size_t i = 0; i < m_allCompilers.size(); ++i) { CompilerPtr c = m_allCompilers.at(i); if(c->GetCompilerFamily() == COMPILER_FAMILY_CLANG || c->GetCompilerFamily() == COMPILER_FAMILY_VC) { c->SetTool("MAKE", make); c->SetTool("ResourceCompiler", resourceCompiler); if(c->GetCompilerFamily() == COMPILER_FAMILY_CLANG) { // Clang under Windows, needs the include paths from the MinGW compiler IncludePathLocator locator(NULL); wxArrayString includePaths, excludePaths; locator.Locate(includePaths, excludePaths, false, compiler->GetTool("CXX")); // Convert the include paths to semi colon separated list wxString mingwIncludePaths = wxJoin(includePaths, ';'); c->SetGlobalIncludePath(mingwIncludePaths); } } } } #endif }
CompilerPtr CompilerLocatorCLANG::Locate(const wxString& folder) { m_compilers.clear(); wxFileName clang(folder, "clang"); #ifdef __WXMSW__ clang.SetExt("exe"); #endif bool found = clang.FileExists(); if ( ! found ) { // try to see if we have a bin folder here clang.AppendDir("bin"); found = clang.FileExists(); } if ( found ) { CompilerPtr compiler( new Compiler(NULL) ); compiler->SetCompilerFamily(COMPILER_FAMILY_CLANG); // get the compiler version compiler->SetName( GetCompilerFullName(clang.GetFullPath() ) ); compiler->SetGenerateDependeciesFile(true); m_compilers.push_back( compiler ); clang.RemoveLastDir(); AddTools(compiler, clang.GetPath()); // Update the toolchain (if Windows) #ifdef __WXMSW__ CompilerPtr defaultMinGWCmp = BuildSettingsConfigST::Get()->GetDefaultCompiler(COMPILER_FAMILY_MINGW); if ( defaultMinGWCmp ) { compiler->SetTool("MAKE", defaultMinGWCmp->GetTool("MAKE")); compiler->SetTool("ResourceCompiler", defaultMinGWCmp->GetTool("ResourceCompiler")); // Update the include paths IncludePathLocator locator(NULL); wxArrayString includePaths, excludePaths; locator.Locate(includePaths, excludePaths, false, defaultMinGWCmp->GetTool("CXX")); // Convert the include paths to semi colon separated list wxString mingwIncludePaths = wxJoin(includePaths, ';'); compiler->SetGlobalIncludePath( mingwIncludePaths ); } #endif return compiler; } return NULL; }
void CompilersDetectorManager::MSWFixClangToolChain(CompilerPtr compiler, const ICompilerLocator::CompilerVec_t& allCompilers) { // Update the toolchain (if Windows) #ifdef __WXMSW__ ICompilerLocator::CompilerVec_t compilers; if(allCompilers.empty()) { BuildSettingsConfigCookie cookie; CompilerPtr cmp = BuildSettingsConfigST::Get()->GetFirstCompiler(cookie); while(cmp) { compilers.push_back(cmp); cmp = BuildSettingsConfigST::Get()->GetNextCompiler(cookie); } } else { compilers.insert(compilers.end(), allCompilers.begin(), allCompilers.end()); } 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) { compiler->SetTool("MAKE", mingwCmp->GetTool("MAKE")); compiler->SetTool("ResourceCompiler", mingwCmp->GetTool("ResourceCompiler")); // Update the include paths IncludePathLocator locator(NULL); wxArrayString includePaths, excludePaths; locator.Locate(includePaths, excludePaths, false, mingwCmp->GetTool("CXX")); // Convert the include paths to semi colon separated list wxString mingwIncludePaths = wxJoin(includePaths, ';'); compiler->SetGlobalIncludePath(mingwIncludePaths); // Keep the mingw's bin path wxFileName mingwGCC(mingwCmp->GetTool("CXX")); compiler->SetPathVariable(mingwGCC.GetPath()); break; } } } #endif }
// do the actual cleanup void CompileRequest::Process(IManager* manager) { wxString cmd; wxString errMsg; wxStringMap_t om; BuildSettingsConfig* bsc(manager ? manager->GetBuildSettingsConfigManager() : BuildSettingsConfigST::Get()); BuildManager* bm(manager ? manager->GetBuildManager() : BuildManagerST::Get()); clCxxWorkspace* w(manager ? manager->GetWorkspace() : clCxxWorkspaceST::Get()); EnvironmentConfig* env(manager ? manager->GetEnv() : EnvironmentConfig::Instance()); ProjectPtr proj = w->FindProjectByName(m_info.GetProject(), errMsg); if(!proj) { AppendLine(_("Cant find project: ") + m_info.GetProject()); return; } wxString pname(proj->GetName()); // BuilderPtr builder = bm->GetBuilder(wxT("GNU makefile for g++/gcc")); BuilderPtr builder = bm->GetSelectedBuilder(); if(m_fileName.IsEmpty() == false) { // we got a complie request of a single file cmd = m_preprocessOnly ? builder->GetPreprocessFileCmd(m_info.GetProject(), m_info.GetConfiguration(), m_fileName, errMsg) : builder->GetSingleFileCmd(m_info.GetProject(), m_info.GetConfiguration(), m_fileName); } else if(m_info.GetProjectOnly()) { switch(m_info.GetKind()) { case QueueCommand::kRebuild: cmd = builder->GetPORebuildCommand(m_info.GetProject(), m_info.GetConfiguration()); break; default: case QueueCommand::kBuild: cmd = builder->GetPOBuildCommand(m_info.GetProject(), m_info.GetConfiguration()); break; } } else { cmd = builder->GetBuildCommand(m_info.GetProject(), m_info.GetConfiguration()); } // Notify plugins that a compile process is going to start clBuildEvent event(wxEVT_BUILD_STARTING); event.SetProjectName(pname); event.SetConfigurationName(m_info.GetConfiguration()); if(EventNotifier::Get()->ProcessEvent(event)) { // the build is being handled by some plugin, no need to build it // using the standard way return; } // Send the EVENT_STARTED : even if this event is sent, next event will // be post, so no way to be sure the the build process has not started SendStartMsg(); // if we require to run the makefile generation command only, replace the 'cmd' with the // generation command line BuildConfigPtr bldConf = w->GetProjBuildConf(m_info.GetProject(), m_info.GetConfiguration()); if(m_premakeOnly && bldConf) { BuildConfigPtr bldConf = w->GetProjBuildConf(m_info.GetProject(), m_info.GetConfiguration()); if(bldConf) { cmd = bldConf->GetMakeGenerationCommand(); } } if(bldConf) { wxString cmpType = bldConf->GetCompilerType(); CompilerPtr cmp = bsc->GetCompiler(cmpType); if(cmp) { // Add the 'bin' folder of the compiler to the PATH environment variable wxString scxx = cmp->GetTool("CXX"); scxx.Trim().Trim(false); scxx.StartsWith("\"", &scxx); scxx.EndsWith("\"", &scxx); // Strip the double quotes wxFileName cxx(scxx); wxString pathvar; pathvar << cxx.GetPath() << clPATH_SEPARATOR; // If we have an additional path, add it as well if(!cmp->GetPathVariable().IsEmpty()) { pathvar << cmp->GetPathVariable() << clPATH_SEPARATOR; } pathvar << "$PATH"; om["PATH"] = pathvar; } } if(cmd.IsEmpty()) { // if we got an error string, use it if(errMsg.IsEmpty() == false) { AppendLine(errMsg); } else { AppendLine(_("Command line is empty. Build aborted.")); } return; } WrapInShell(cmd); DirSaver ds; DoSetWorkingDirectory(proj, false, m_fileName.IsEmpty() == false); // expand the variables of the command cmd = ExpandAllVariables(cmd, w, m_info.GetProject(), m_info.GetConfiguration(), m_fileName); // print the build command AppendLine(cmd + wxT("\n")); if(m_info.GetProjectOnly() || m_fileName.IsEmpty() == false) { // set working directory DoSetWorkingDirectory(proj, false, m_fileName.IsEmpty() == false); } // print the prefix message of the build start. This is important since the parser relies // on this message if(m_info.GetProjectOnly() || m_fileName.IsEmpty() == false) { wxString configName(m_info.GetConfiguration()); // also, send another message to the main frame, indicating which project is being built // and what configuration wxString text; text << wxGetTranslation(BUILD_PROJECT_PREFIX) << m_info.GetProject() << wxT(" - ") << configName << wxT(" ]"); if(m_fileName.IsEmpty()) { text << wxT("----------\n"); } else if(m_preprocessOnly) { text << wxT(" (Preprocess Single File)----------\n"); } else { text << wxT(" (Single File Build)----------\n"); } AppendLine(text); } EnvSetter envir(env, &om, proj->GetName()); m_proc = CreateAsyncProcess(this, cmd); if(!m_proc) { wxString message; message << _("Failed to start build process, command: ") << cmd << _(", process terminated with exit code: 0"); AppendLine(message); return; } }