📄 compilergcc.cpp
字号:
return;
if (!CheckProject())
return;
FileType ft = FileTypeOf(arg);
if (arg.IsEmpty())
{
// popup menu in empty space in ProjectManager
menu->Append(idMenuCompileAll, _("Build all projects"));
menu->Append(idMenuRebuildAll, _("Rebuild all projects"));
}
else
{
// see if the arg is a project name
bool found = false;
ProjectsArray* array = Manager::Get()->GetProjectManager()->GetProjects();
if (array)
{
for (size_t i = 0; i < array->GetCount(); ++i)
{
cbProject* cur = array->Item(i);
if (cur && cur->GetTitle() == arg)
{
found = true;
break;
}
}
}
if (found)
{
// popup menu on a project
menu->AppendSeparator();
menu->Append(idMenuCompileFromProjectManager, _("Build\tCtrl-F9"));
menu->Append(idMenuRebuildFromProjectManager, _("Rebuild\tCtrl-F11"));
menu->Append(idMenuCleanFromProjectManager, _("Clean"));
menu->Append(idMenuDistCleanFromProjectManager, _("Dist-clean"));
wxMenu* subMenu = new wxMenu();
subMenu->Append(idMenuCompileTargetFromProjectManager, _("Build"));
subMenu->Append(idMenuRebuildTargetFromProjectManager, _("Rebuild"));
subMenu->Append(idMenuCleanTargetFromProjectManager, _("Clean"));
subMenu->Append(idMenuDistCleanTargetFromProjectManager, _("Dist-clean"));
subMenu->AppendSeparator();
subMenu->Append(idMenuTargetCompilerOptions, _("Build options"));
menu->Append(idMenuTargetCompilerOptionsSub, _("Specific build target..."), subMenu);
menu->AppendSeparator();
menu->Append(idMenuProjectCompilerOptions, _("Build options"));
}
else if (ft == ftSource || ft == ftHeader)
{
// popup menu on a compilable file
menu->AppendSeparator();
menu->Append(idMenuCompileFileFromProjectManager, _("Compile file"));
}
}
}
bool CompilerGCC::BuildToolBar(wxToolBar* toolBar)
{
if (!m_IsAttached || !toolBar)
return false;
m_pTbar = toolBar;
wxString my_16x16=Manager::isToolBar16x16(toolBar) ? _T("_16x16") : _T("");
Manager::Get()->AddonToolBar(toolBar,_T("compiler_toolbar")+my_16x16);
// neither the generic nor Motif native toolbars really support this
#if (wxUSE_TOOLBAR_NATIVE && !USE_GENERIC_TBAR) && !defined(__WXMOTIF__) && !defined(__WXX11__) && !defined(__WXMAC__)
m_ToolTarget = XRCCTRL(*toolBar, "idToolTarget", wxComboBox);
#endif
toolBar->Realize();
DoRecreateTargetMenu(); // make sure the tool target combo is up-to-date
return true;
}
void CompilerGCC::SetupEnvironment()
{
if (!CompilerFactory::CompilerIndexOK(m_CompilerIdx))
return;
m_EnvironmentMsg.Clear();
wxString path;
Manager::Get()->GetMessageManager()->DebugLog(_("Setting up compiler environment..."));
// reset PATH to original value
if (!m_OriginalPath.IsEmpty())
wxSetEnv(_T("PATH"), m_OriginalPath);
// look for valid compiler in path
if (wxGetEnv(_T("PATH"), &path))
{
if (m_OriginalPath.IsEmpty())
m_OriginalPath = path;
wxArrayInt compilers;
if(m_Project)
{
for (int x = 0; x < m_Project->GetBuildTargetsCount(); ++x)
{
ProjectBuildTarget* target = m_Project->GetBuildTarget(x);
int idx = target->GetCompilerIndex();
// one time per compiler
if (compilers.Index(idx) != wxNOT_FOUND || !CompilerFactory::CompilerIndexOK(idx))
continue;
compilers.Add(idx);
SetEnvironmentForCompilerIndex(idx, path);
}
}
else
SetEnvironmentForCompilerIndex(CompilerFactory::GetDefaultCompilerIndex(), path);
}
else
m_EnvironmentMsg = _("Could not read the PATH environment variable!\n"
"This can't be good. There may be problems running "
"system commands and the application might not behave "
"the way it was designed to...");
// wxGetEnv("PATH", &path);
// Manager::Get()->GetMessageManager()->Log(m_PageIndex, "PATH set to: %s", path.c_str());
}
void CompilerGCC::SetEnvironmentForCompilerIndex(int idx, wxString& envPath)
{
if (!CompilerFactory::CompilerIndexOK(idx))
return;
Compiler* compiler = CompilerFactory::Compilers[idx];
wxString sep = wxFileName::GetPathSeparator();
wxString masterPath = compiler->GetMasterPath();
while (masterPath.Last() == '\\' || masterPath.Last() == '/')
masterPath.RemoveLast();
wxString gcc = compiler->GetPrograms().C;
const wxArrayString& extraPaths = compiler->GetExtraPaths();
wxPathList pathList;
pathList.Add(masterPath + sep + _T("bin"));
for (unsigned int i = 0; i < extraPaths.GetCount(); ++i)
{
if (!extraPaths[i].IsEmpty())
pathList.Add(extraPaths[i]);
}
pathList.AddEnvList(_T("PATH"));
wxString binPath = pathList.FindAbsoluteValidPath(gcc);
// it seems, under Win32, the above command doesn't search in paths with spaces...
// look directly for the file in question in masterPath
if (binPath.IsEmpty() || !pathList.Member(wxPathOnly(binPath)))
{
if (wxFileExists(masterPath + sep + _T("bin") + sep + gcc))
binPath = masterPath + sep + _T("bin");
else if (wxFileExists(masterPath + sep + gcc))
binPath = masterPath;
else
{
for (unsigned int i = 0; i < extraPaths.GetCount(); ++i)
{
if (!extraPaths[i].IsEmpty())
{
if (wxFileExists(extraPaths[i] + sep + gcc))
{
binPath = extraPaths[i];
break;
}
}
}
}
}
if (binPath.IsEmpty() || !pathList.Member(wxPathOnly(binPath)))
{
m_EnvironmentMsg << _("Can't find compiler executable in your search path for ") << compiler->GetName() << _T('\n');
Manager::Get()->GetMessageManager()->DebugLog(_("Can't find compiler executable in your search path (%s)..."), compiler->GetName().c_str());
}
else
{
m_EnvironmentMsg.Clear();
#ifdef __WXMSW__
#define PATH_SEP _T(";")
#else
#define PATH_SEP _T(":")
#endif
// add extra compiler paths in PATH
wxString oldpath = envPath;
envPath.Clear();
for (unsigned int i = 0; i < extraPaths.GetCount(); ++i)
{
if (!extraPaths[i].IsEmpty())
{
envPath += extraPaths[i] + PATH_SEP;
}
}
envPath = envPath + oldpath;
// add bin path to PATH env. var.
if (wxFileExists(masterPath + sep + _T("bin") + sep + gcc))
envPath = masterPath + sep + _T("bin") + PATH_SEP + envPath;
else if (wxFileExists(masterPath + sep + gcc))
envPath = masterPath + PATH_SEP + envPath;
wxSetEnv(_T("PATH"), envPath);
#undef PATH_SEP
}
}
void CompilerGCC::SaveOptions()
{
// save compiler sets
CompilerFactory::SaveSettings();
}
void CompilerGCC::LoadOptions()
{
// load compiler sets
CompilerFactory::LoadSettings();
}
int CompilerGCC::GetCurrentCompilerIndex()
{
return CompilerFactory::CompilerIndexOK(m_CompilerIdx) ? m_CompilerIdx : 0;
}
void CompilerGCC::SwitchCompiler(int compilerIdx)
{
if (!CompilerFactory::CompilerIndexOK(compilerIdx))
return;
m_CompilerIdx = compilerIdx;
SetupEnvironment();
}
void CompilerGCC::AskForActiveProject()
{
m_Project = Manager::Get()->GetProjectManager()->GetActiveProject();
}
bool CompilerGCC::CheckProject()
{
AskForActiveProject();
if (m_Project && m_Project->GetCompilerIndex() != m_CompilerIdx)
SwitchCompiler(m_Project->GetCompilerIndex());
return m_Project;
}
wxString CompilerGCC::ProjectMakefile()
{
AskForActiveProject();
if (!m_Project)
return wxEmptyString;
return m_Project->GetMakefile();
}
void CompilerGCC::ClearLog()
{
if (m_Log)
m_Log->GetTextControl()->Clear();
}
FileTreeData* CompilerGCC::DoSwitchProjectTemporarily()
{
wxTreeCtrl* tree = Manager::Get()->GetProjectManager()->GetTree();
wxTreeItemId sel = tree->GetSelection();
FileTreeData* ftd = (FileTreeData*)tree->GetItemData(sel);
if (!ftd)
return 0L;
// copy ftd to a new instance, because after the SetProject() call
// that follows, ftd will no longer be valid...
FileTreeData* newFtd = new FileTreeData(ftd->GetProject(), ftd->GetFileIndex());
Manager::Get()->GetProjectManager()->SetProject(ftd->GetProject(), false);
AskForActiveProject();
return newFtd;
}
int CompilerGCC::DoRunQueue()
{
wxLogNull ln;
// leave if already running
if (m_Process)
return -2;
MessageManager* msgMan = Manager::Get()->GetMessageManager();
msgMan->SwitchTo(m_PageIndex);
// leave if no active project
AskForActiveProject();
// make sure all project files are saved
if (m_Project && !m_Project->SaveAllFiles())
msgMan->Log(_("Could not save all files..."));
if (m_Queue.GetCount() == 0)
{
m_Log->GetTextControl()->SetDefaultStyle(wxTextAttr(*wxBLUE, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)));
msgMan->Log(m_PageIndex, _("Nothing to be done."));
m_Log->GetTextControl()->SetDefaultStyle(wxTextAttr(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)));
m_LastExitCode = 0;
OnJobEnd();
return 0;
}
// leave if no commands in queue
if (m_QueueIndex >= m_Queue.GetCount())
{
msgMan->DebugLog(_("Queue has been emptied! (count=%d, index=%d)"), m_Queue.GetCount(), m_QueueIndex);
return -3;
}
m_Log->GetTextControl()->SetDefaultStyle(wxTextAttr(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)));
wxString dir;// = m_Project->GetBasePath();
wxString cmd;
// loop added for compiler log when not working with Makefiles
wxString mySimpleLog = wxString(COMPILER_SIMPLE_LOG);
wxString myTargetChange = wxString(COMPILER_TARGET_CHANGE);
while (true)
{
cmd = m_Queue[m_QueueIndex];
// msgMan->Log(m_PageIndex, "cmd='%s' in '%s'", cmd.c_str(), m_CdRun.c_str());
// logging
if (cmd.StartsWith(mySimpleLog))
{
cmd.Remove(0, mySimpleLog.Length());
msgMan->Log(m_PageIndex, cmd);
}
// compiler change
else if (cmd.StartsWith(myTargetChange))
{
cmd.Remove(0, myTargetChange.Length());
// using other compiler now: find it and set it
ProjectBuildTarget* bt = m_Project->GetBuildTarget(cmd);
if (bt)
{
SwitchCompiler(bt->GetCompilerIndex());
// re-apply the env vars for this target
if (CompilerFactory::CompilerIndexOK(m_CompilerIdx))
CompilerFactory::Compilers[m_CompilerIdx]->GetCustomVars().ApplyVarsToEnvironment();
m_Project->GetCustomVars().ApplyVarsToEnvironment();
bt->GetCustomVars().ApplyVarsToEnvironment();
}
else
msgMan->Log(m_PageIndex, _("Can't locate target '%s'!"), cmd.c_str());
}
else
{
// compile command; apply custom vars
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(cmd);
break;
}
++m_QueueIndex;
if (m_QueueIndex >= m_Queue.GetCount())
{
msgMan->Log(m_PageIndex, _("Nothing to be done."));
m_LastExitCode = 0;
OnJobEnd();
return 0;
}
}
// if message manager is auto-hiding, this will lock it open
Manager::Get()->GetMessageManager()->LockOpen();
bool pipe = true;
int flags = wxEXEC_ASYNC;
if (m_RunAfterCompile && m_IsRun && m_QueueIndex == m_Queue.GetCount() - 1)
{
pipe = false; // no need to pipe output channels...
flags |= wxEXEC_NOHIDE;
m_IsRun = false;
dir = m_CdRun;
#ifndef __WXMSW__
wxSetEnv(_T("LD_LIBRARY_PATH"), _T("."));
#endif
}
m_Process = new PipedProcess((void**)&m_Process, this, idGCCProcess, pipe, dir);
m_Pid = wxExecute(cmd, flags, m_Process);
if ( !m_Pid )
{
m_Log->GetTextControl()->SetDefaultStyle(wxTextAttr(*wxRED, *wxWHITE));
msgMan->Log(m_PageIndex, _("Execution of '%s' in '%s' failed."), m_Queue[m_QueueIndex].c_str(), wxGetCwd().c_str());
m_Log->GetTextControl()->SetDefaultStyle(wxTextAttr(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)));
delete m_Process;
m_Process = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -