📄 compilergcc.cpp
字号:
m_Queue.Clear();
}
else
m_timerIdleWakeUp.Start(100);
return 0;
}
void CompilerGCC::DoClearTargetMenu()
{
if (m_TargetMenu)
{
wxMenuItemList& items = m_TargetMenu->GetMenuItems();
while (wxMenuItemList::Node* node = items.GetFirst())
{
if (node->GetData())
m_TargetMenu->Delete(node->GetData());
}
// mandrav: The following lines DO NOT clear the menu!
// wxMenuItemList& items = m_TargetMenu->GetMenuItems();
// bool olddelete=items.GetDeleteContents();
// items.DeleteContents(true);
// items.Clear();
// items.DeleteContents(olddelete);
}
m_HasTargetAll = false;
}
void CompilerGCC::DoRecreateTargetMenu()
{
if (!m_IsAttached)
return;
DoClearTargetMenu();
if (m_ToolTarget)
m_ToolTarget->Clear();
if (!CheckProject())
return;
if (m_Project->GetBuildTargetsCount() == 0)
return;
// find out if at least one target is included in "all"
// (if not, no need to add "all" in menus and target combo)
bool atLeastOneBuildableTarget = false;
for (int i = 0; i < m_Project->GetBuildTargetsCount(); ++i)
{
ProjectBuildTarget* bt = m_Project->GetBuildTarget(i);
if (bt->GetIncludeInTargetAll())
{
atLeastOneBuildableTarget = true;
break;
}
}
m_TargetIndex = m_Project->GetActiveBuildTarget();
if (atLeastOneBuildableTarget)
{
if (m_TargetMenu)
m_TargetMenu->AppendCheckItem(idMenuSelectTargetAll, _("All"), _("Compile target 'all' in current project"));
if (m_ToolTarget)
m_ToolTarget->Append(_("All"));
}
else
{
if (m_TargetIndex == -1)
m_TargetIndex = 0;
}
m_HasTargetAll = atLeastOneBuildableTarget;
int targetsCount = m_Project->GetBuildTargetsCount();
for (int x = 0; x < targetsCount; ++x)
{
ProjectBuildTarget* target = m_Project->GetBuildTarget(x);
if (!target)
break;
wxString caption;
caption.Printf(_("Compile target '%s' in current project"), target->GetTitle().c_str());
if (m_TargetMenu)
m_TargetMenu->AppendCheckItem(idMenuSelectTargetOther[x], target->GetTitle(), caption);
if (m_ToolTarget)
m_ToolTarget->Append(target->GetTitle());
}
Connect( idMenuSelectTargetOther[0], idMenuSelectTargetOther[MAX_TARGETS - 1],
wxEVT_COMMAND_MENU_SELECTED,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
&CompilerGCC::OnSelectTarget );
DoUpdateTargetMenu();
SwitchCompiler(m_Project->GetCompilerIndex());
}
void CompilerGCC::DoUpdateTargetMenu()
{
if (!m_TargetMenu)
return;
if (!m_HasTargetAll && m_TargetIndex == -1)
m_TargetIndex = 0;
if (m_Project)
m_Project->SetActiveBuildTarget(m_TargetIndex);
m_TargetMenu->Check(idMenuSelectTargetAll, m_TargetIndex == -1);
for (int i = 0; i < MAX_TARGETS; ++i)
{
m_TargetMenu->Check(idMenuSelectTargetOther[i], i == m_TargetIndex);
}
if (m_ToolTarget)
m_ToolTarget->SetSelection(m_TargetIndex + (m_HasTargetAll ? 1 : 0));
}
bool CompilerGCC::DoPrepareMultiProjectCommand(MultiProjectJob job)
{
ProjectManager* prjMan = Manager::Get()->GetProjectManager();
ProjectsArray* projects = prjMan->GetProjects();
if (projects->GetCount() <= 1)
return false;
m_Queue.Clear();
AskForActiveProject();
m_BackupActiveProject = m_Project;
m_ProjectIndex = 0;
m_DoAllProjects = job;
prjMan->SetProject(projects->Item(0), false);
AskForActiveProject();
return true;
}
void CompilerGCC::DoPrepareQueue()
{
if (m_LastTempMakefile.IsEmpty() || m_Queue.GetCount() == 0)
{
m_QueueIndex = 0;
if (m_DoAllProjects == mpjNone)
{
ClearLog();
DoClearErrors();
}
DoCreateMakefile();
wxStartTimer();
}
}
ProjectBuildTarget* CompilerGCC::DoAskForTarget()
{
if (!CheckProject())
return 0L;
return m_Project->GetBuildTarget(m_TargetIndex);
}
int CompilerGCC::DoGUIAskForTarget()
{
if (!CheckProject())
return -1;
return m_Project->SelectTarget(m_TargetIndex);
}
void CompilerGCC::DoDeleteTempMakefile()
{
// delete temp Makefile
if (m_DeleteTempMakefile && !m_LastTempMakefile.IsEmpty())
wxRemoveFile(m_LastTempMakefile);
m_LastTempMakefile = _T("");
}
bool CompilerGCC::UseMake(ProjectBuildTarget* target)
{
int idx = m_CompilerIdx;
if (target)
idx = target->GetCompilerIndex();
else if (m_Project)
idx = m_Project->GetCompilerIndex();
if (CompilerFactory::CompilerIndexOK(idx))
return CompilerFactory::Compilers[idx]->GetSwitches().buildMethod == cbmUseMake;
return false;
}
bool CompilerGCC::CompilerValid(ProjectBuildTarget* target)
{
int idx = target ? target->GetCompilerIndex() : (m_Project ? m_Project->GetCompilerIndex() : CompilerFactory::GetDefaultCompilerIndex());
bool ret = CompilerFactory::CompilerIndexOK(idx);
if (!ret)
{
wxString msg;
msg.Printf(_("This %s is configured to use an invalid compiler.\nThe operation failed..."), target ? _("target") : _("project"));
wxMessageBox(msg, _("Error"), wxICON_ERROR);
}
return ret;
}
bool CompilerGCC::DoCreateMakefile(bool temporary, const wxString& makefile)
{
DoDeleteTempMakefile();
// display error about incorrect compile environment
if (!m_EnvironmentMsg.IsEmpty())
{
wxMessageBox(m_EnvironmentMsg, _("Error"), wxICON_ERROR);
m_EnvironmentMsg.Clear(); // once is enough, per session...
}
// verify current project
AskForActiveProject();
if (!m_Project)
return false;
if (UseMake())
{
// if the project has a custom makefile, use that (i.e. don't create makefile)
if (temporary && m_Project->IsMakefileCustom())
{
m_LastTempMakefile = m_Project->GetMakefile();
m_DeleteTempMakefile = false;
return true;
}
// invoke Makefile generation
if (temporary)
m_LastTempMakefile = wxFileName::CreateTempFileName(_T("cbmk"), 0L);
else
{
m_LastTempMakefile = makefile;
if (m_LastTempMakefile.IsEmpty())
{
m_LastTempMakefile = ProjectMakefile();
if (m_LastTempMakefile.IsEmpty())
m_LastTempMakefile = _T("Makefile");
}
}
}
PrintBanner();
wxSetWorkingDirectory(m_Project->GetBasePath());
if (UseMake())
{
MakefileGenerator generator(this, m_Project, m_LastTempMakefile, m_PageIndex);
bool ret = generator.CreateMakefile();
// if exporting Makefile, reset variable so that it's not deleted on
// next Makefile generation :)
if (!temporary)
m_LastTempMakefile = _T("");
m_DeleteTempMakefile = temporary;
return ret;
}
return true;
}
void CompilerGCC::PrintBanner()
{
if (!CompilerValid())
return;
if (!m_Project)
return;
Manager::Get()->GetMessageManager()->SwitchTo(m_PageIndex);
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Project : %s"), m_Project->GetTitle().c_str());
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Compiler : %s (%s)"), CompilerFactory::Compilers[m_Project->GetCompilerIndex()]->GetName().c_str(),
CompilerFactory::Compilers[m_Project->GetCompilerIndex()]->GetSwitches().buildMethod == cbmUseMake ? _("using GNU \"make\"") : _("called directly"));
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Directory : %s"), m_Project->GetBasePath().c_str());
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _T("--------------------------------------------------------------------------------"));
}
void CompilerGCC::DoGotoNextError()
{
m_Errors.Next();
m_pListLog->FocusError(m_Errors.GetFocusedError());
}
void CompilerGCC::DoGotoPreviousError()
{
m_Errors.Previous();
m_pListLog->FocusError(m_Errors.GetFocusedError());
}
void CompilerGCC::DoClearErrors()
{
m_Errors.Clear();
m_pListLog->Clear();
}
int CompilerGCC::Run(ProjectBuildTarget* target)
{
if (!CheckProject())
return -1;
DoPrepareQueue();
if (!CompilerValid(target))
return -1;
Manager::Get()->GetMessageManager()->Open();
if (!target)
{
if (m_TargetIndex == -1) // only ask for target if target 'all' is selected
{
int idx = -1;
int bak = m_TargetIndex;
if (m_Project->GetBuildTargetsCount() == 1)
idx = 0;
else
idx = DoGUIAskForTarget();
m_TargetIndex = idx;
target = DoAskForTarget();
m_TargetIndex = bak;
}
else
target = DoAskForTarget();
}
if (!target)
return -1;
wxString out = UnixFilename(target->GetOutputFilename());
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(out);
wxString cmd;
wxFileName f(out);
f.MakeAbsolute(m_Project->GetBasePath());
// m_CdRun = f.GetPath(wxPATH_GET_VOLUME);
m_CdRun = target->GetWorkingDir();
// for console projects, use helper app to wait for a key after
// execution ends...
if (target->GetTargetType() == ttConsoleOnly)
{
#ifndef __WXMSW__
// for non-win platforms, use m_ConsoleShell to run the console app
wxString shell = m_ConsoleShell;
shell.Replace(_T("$TITLE"), _T("'") + m_Project->GetTitle() + _T("'"));
cmd << shell << _T(" ");
#endif
// should console runner be used?
if (target->GetUseConsoleRunner())
{
wxString baseDir = ConfigManager::Get()->Read(_T("/app_path"));
#ifdef __WXMSW__
#define CONSOLE_RUNNER "console_runner.exe"
#else
#define CONSOLE_RUNNER "console_runner"
#endif
if (wxFileExists(baseDir + wxT("/" CONSOLE_RUNNER)))
cmd << baseDir << wxT("/" CONSOLE_RUNNER " ");
}
}
if (target->GetTargetType() == ttDynamicLib ||
target->GetTargetType() == ttStaticLib)
{
// check for hostapp
if (target->GetHostApplication().IsEmpty())
{
wxMessageBox(_("You must select a host application to \"run\" a library..."));
return -1;
}
wxString tmp = target->GetHostApplication();
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(tmp);
cmd << _T("\"") << tmp << _T("\" ") << target->GetExecutionParameters();
}
else if (target->GetTargetType() != ttCommandsOnly)
{
cmd << _T("\"");
cmd << f.GetFullPath();
cmd << _T("\" ");
cmd << target->GetExecutionParameters();
}
else
{
// commands-only target?
wxMessageBox(_("You can't \"run\" a commands-only target..."));
return -1;
}
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Checking for existence: %s"), out.c_str());
if (!wxFileExists(out))
{
int ret = wxMessageBox(_("It seems that this project has not been built yet.\n"
"Do you want to build it now?"),
_("Information"),
wxYES | wxNO | wxCANCEL | wxICON_QUESTION);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -