📄 directcommands.cpp
字号:
#include <sdk.h>
#include <wx/log.h>
#include <wx/intl.h>
#include <wx/filename.h>
#include <wx/msgdlg.h>
#include <wx/stream.h>
#include <wx/wfstream.h>
#include <wx/txtstrm.h>
#include <wx/regex.h> // used in QUICK hack at line 574
#include <compiler.h>
#include <cbproject.h>
#include <projectbuildtarget.h>
#include <globals.h>
#include <manager.h>
#include <messagemanager.h>
#include <macrosmanager.h>
#include "directcommands.h"
#include "compilergcc.h"
#include "makefilegenerator.h"
#include "customvars.h"
#include <depslib.h>
pfDetails::pfDetails(DirectCommands* cmds, ProjectBuildTarget* target, ProjectFile* pf)
{
wxString sep = wxFileName::GetPathSeparator();
wxFileName tmp;
wxFileName prjbase(cmds->m_pProject->GetBasePath());
source_file_native = pf->relativeFilename;
source_file_absolute_native = pf->file.GetFullPath();
tmp = pf->GetObjName();
if (FileTypeOf(pf->relativeFilename) == ftHeader)
object_file_native = pf->GetObjName(); // support for precompiled headers
else
object_file_native = (target ? target->GetObjectOutput() : _T(".")) +
sep +
tmp.GetFullPath();
wxFileName o_file(object_file_native);
o_file.MakeAbsolute(prjbase.GetFullPath());
object_dir_native = o_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
object_file_absolute_native = o_file.GetFullPath();
tmp.SetExt(_T("depend"));
dep_file_native = (target ? target->GetDepsOutput() : _T(".")) +
sep +
tmp.GetFullPath();
wxFileName d_file(dep_file_native);
d_file.MakeAbsolute(prjbase.GetFullPath());
dep_dir_native = d_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
dep_file_absolute_native = o_file.GetFullPath();
source_file = UnixFilename(source_file_native);
cmds->QuoteStringIfNeeded(source_file);
object_file = UnixFilename(object_file_native);
cmds->QuoteStringIfNeeded(object_file);
dep_file = UnixFilename(dep_file_native);
cmds->QuoteStringIfNeeded(dep_file);
object_dir = UnixFilename(object_dir_native);
cmds->QuoteStringIfNeeded(object_dir);
dep_dir = UnixFilename(dep_dir_native);
cmds->QuoteStringIfNeeded(dep_dir);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_native);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_native);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_absolute_native);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_native);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir_native);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_absolute_native);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file);
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(source_file);
}
DirectCommands::DirectCommands(CompilerGCC* compilerPlugin, Compiler* compiler, cbProject* project, int logPageIndex)
: m_PageIndex(logPageIndex),
m_pCompilerPlugin(compilerPlugin),
m_pCompiler(compiler),
m_pProject(project),
m_pCurrTarget(0)
{
//ctor
if (!m_pProject)
return; // probably a compile file cmd without a project
depsStart();
wxFileName cwd;
cwd.Assign(m_pProject->GetBasePath());
depsSetCWD(cwd.GetPath(wxPATH_GET_VOLUME).mb_str());
wxFileName fname(m_pProject->GetFilename());
fname.SetExt(_T("depend"));
depsCacheRead(fname.GetFullPath().mb_str());
}
DirectCommands::~DirectCommands()
{
//dtor
if (!m_pProject)
return; // probably a compile file cmd without a project
struct depsStats stats;
depsGetStats(&stats);
if (stats.cache_updated)
{
wxFileName fname(m_pProject->GetFilename());
fname.SetExt(_T("depend"));
depsCacheWrite(fname.GetFullPath().mb_str());
}
Manager::Get()->GetMessageManager()->DebugLog(
_("Scanned %d files for #includes, cache used %d, cache updated %d"),
stats.scanned, stats.cache_used, stats.cache_updated);
depsDone();
}
// static
void DirectCommands::QuoteStringIfNeeded(wxString& str)
{
if (!str.IsEmpty() && str.Find(_T(' ')) != -1 && str.GetChar(0) != _T('"'))
str = wxString(_T("\"")) + str + _T("\"");
}
// static
void DirectCommands::AppendArray(const wxArrayString& from, wxArrayString& to)
{
for (unsigned int i = 0; i < from.GetCount(); ++i)
{
to.Add(from[i]);
}
}
void DirectCommands::AddCommandsToArray(const wxString& cmds, wxArrayString& array)
{
wxString cmd = cmds;
while (!cmd.IsEmpty())
{
int idx = cmd.Find(_T("\n"));
wxString cmdpart = idx != -1 ? cmd.Left(idx) : cmd;
cmdpart.Trim(false);
cmdpart.Trim(true);
if (!cmdpart.IsEmpty())
array.Add(cmdpart);
if (idx == -1)
break;
cmd.Remove(0, idx + 1);
}
}
int MySortProjectFilesByWeight(ProjectFile** one, ProjectFile** two)
{
return (*one)->weight - (*two)->weight;
}
MyFilesArray DirectCommands::GetProjectFilesSortedByWeight(ProjectBuildTarget* target, bool compile, bool link)
{
MyFilesArray files;
for (int i = 0; i < m_pProject->GetFilesCount(); ++i)
{
ProjectFile* pf = m_pProject->GetFile(i);
// require compile
if (compile && !pf->compile)
continue;
// require link
if (link && !pf->link)
continue;
// if the file does not belong in this target (if we have a target), skip it
if (target && (pf->buildTargets.Index(target->GetTitle()) == wxNOT_FOUND))
continue;
files.Add(pf);
}
files.Sort(MySortProjectFilesByWeight);
return files;
}
wxArrayString DirectCommands::CompileFile(ProjectBuildTarget* target, ProjectFile* pf, bool force)
{
wxArrayString ret;
// is it compilable?
if (!pf->compile || pf->compilerVar.IsEmpty())
return ret;
if (!force)
{
DepsSearchStart(target);
pfDetails pfd(this, target, pf);
if (!IsObjectOutdated(pfd))
return ret;
}
if (target)
ret.Add(wxString(COMPILER_TARGET_CHANGE) + target->GetTitle());
AppendArray(GetCompileFileCommand(target, pf), ret);
return ret;
}
wxArrayString DirectCommands::GetCompileFileCommand(ProjectBuildTarget* target, ProjectFile* pf)
{
wxLogNull ln;
wxArrayString ret;
// is it compilable?
if (!pf->compile || pf->compilerVar.IsEmpty())
return ret;
pfDetails pfd(this, target, pf);
MakefileGenerator mg(m_pCompilerPlugin, m_pProject, _T(""), 0); // don't worry! we just need a couple of utility funcs from it
// lookup file's type
FileType ft = FileTypeOf(pf->relativeFilename);
// create output dir
if (!pfd.object_dir_native.IsEmpty() && !wxDirExists(pfd.object_dir_native))
{
if (!CreateDirRecursively(pfd.object_dir_native, 0755))
wxMessageBox(_("Can't create object output directory ") + pfd.object_dir_native);
}
bool isResource = ft == ftResource;
bool isHeader = ft == ftHeader;
#ifndef __WXMSW__
// not supported under non-win32 platforms
if (isResource)
return ret;
#endif
Compiler* compiler = target ? CompilerFactory::Compilers[target->GetCompilerIndex()] : m_pCompiler;
wxString compilerCmd = mg.CreateSingleFileCompileCmd(pf->useCustomBuildCommand
? pf->buildCommand
: compiler->GetCommand(isResource ? ctCompileResourceCmd : ctCompileObjectCmd),
target,
pf,
pfd.source_file,
pfd.object_file,
pfd.dep_file);
if (!compilerCmd.IsEmpty())
{
switch (compiler->GetSwitches().logging)
{
case clogFull:
ret.Add(wxString(COMPILER_SIMPLE_LOG) + compilerCmd);
break;
case clogSimple:
if (isHeader)
ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Precompiling header: ") + pfd.source_file_native);
else
ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Compiling: ") + pfd.source_file_native);
break;
default:
break;
}
AddCommandsToArray(compilerCmd, ret);
}
return ret;
}
/// This is to be used *only* for files not belonging to a project!!!
wxArrayString DirectCommands::GetCompileSingleFileCommand(const wxString& filename)
{
wxLogNull ln;
wxArrayString ret;
// lookup file's type
FileType ft = FileTypeOf(filename);
// is it compilable?
if (ft != ftSource)
return ret;
wxFileName fname(filename);
fname.SetExt(m_pCompiler->GetSwitches().objectExtension);
wxString o_filename = fname.GetFullPath();
fname.SetExt(EXECUTABLE_EXT);
wxString exe_filename = fname.GetFullPath();
wxString s_filename = filename;
QuoteStringIfNeeded(s_filename);
QuoteStringIfNeeded(o_filename);
MakefileGenerator mg(m_pCompilerPlugin, 0, _T(""), 0); // don't worry! we just need a couple of utility funcs from it
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -