Beispiel #1
0
bool SvnCommand::Execute(const wxString &command, const wxString &workingDirectory, SvnCommandHandler *handler, Subversion2 *plugin)
{
    // Dont run 2 commands at the same time
    if(m_process) {
        if(handler) {
            //handler->GetPlugin()->GetShell()->AppendText(svnANOTHER_PROCESS_RUNNING);
            delete handler;
        }
        return false;
    }

    ClearAll();

    // Wrap the command in the OS Shell
    wxString cmdShell (command);
    WrapInShell(cmdShell);


    // Apply the environment variables before executing the command
    wxStringMap_t om;
    om.insert( std::make_pair("LC_ALL", "C"));

    bool useOverrideMap = m_plugin->GetSettings().GetFlags() & SvnUsePosixLocale;
    EnvSetter env(m_plugin->GetManager()->GetEnv(), useOverrideMap ? &om : NULL);
    
    m_process = CreateAsyncProcess(this, command, IProcessCreateDefault, workingDirectory);
    if ( !m_process ) {
        return false;
    }
    m_workingDirectory = workingDirectory.c_str();
    m_command          = command.c_str();
    m_handler          = handler;
    return true;
}
Beispiel #2
0
void wxTerminal::DoProcessCommand(const wxString& command)
{
    wxString cmd(command);
    cmd.Trim().Trim(false);
    wxString path;
    // Add the shell prefix
    ::WrapInShell(cmd);
    wxString cmdShell;
    cmdShell.swap(cmd);
    
    // real command
    IProcess* cmdPrc = CreateAsyncProcess(this, cmdShell, IProcessCreateWithHiddenConsole, m_workingDir);
    if(cmdPrc) {
        m_process = cmdPrc;

    } else {
        m_process = NULL;
        m_textCtrl->SetInsertionPointEnd();
        m_textCtrl->AppendText(wxString::Format(
            _("Failed to execute command: %s\nWorking Directory: %s\n"), cmdShell.c_str(), m_workingDir.c_str()));

        if(m_exitWhenProcessDies) {
            m_textCtrl->SetInsertionPointEnd();
            m_textCtrl->AppendText(wxString(wxT("\n")) + _("Press any key to continue..."));
            m_exitOnKey = true;
        }
    }
}
Beispiel #3
0
bool SvnCommand::Execute(const wxString& command, const wxString& workingDirectory, SvnCommandHandler *handler)
{
	// Dont run 2 commands at the same time
	if(m_process) {
		if(handler) {
			//handler->GetPlugin()->GetShell()->AppendText(svnANOTHER_PROCESS_RUNNING);
			delete handler;
		}
		return false;
	}

	ClearAll();

	// Wrap the command in the OS Shell
	wxString cmdShell (command);
	WrapInShell(cmdShell);

	m_process = CreateAsyncProcess(this, command, workingDirectory);
	if ( !m_process ) {
		return false;
	}
	m_workingDirectory = workingDirectory.c_str();
	m_command          = command.c_str();
	m_handler          = handler;
	return true;
}
Beispiel #4
0
void CppCheckPlugin::DoProcess()
{
    wxString command = DoGetCommand();
    m_view->AppendLine(wxString::Format(_("Starting cppcheck: %s\n"), command.c_str()));

    m_cppcheckProcess = CreateAsyncProcess(this, command);
    if (!m_cppcheckProcess ) {
        wxMessageBox(_("Failed to launch codelite_cppcheck process!"), _("Warning"), wxOK|wxCENTER|wxICON_WARNING);
        return;
    }
}
void GitCommitListDlg::OnSelectionChanged(wxDataViewEvent& event)
{
    wxVariant v;
    if(!event.GetItem().IsOk()) {
        return;
    }

    m_dvListCtrlCommitList->GetValue(v, m_dvListCtrlCommitList->ItemToRow(event.GetItem()), 0);
    wxString commitID = v.GetString();
    wxString command = wxString::Format(wxT("%s --no-pager show %s"), m_gitPath.c_str(), commitID.c_str());
    m_process = CreateAsyncProcess(this, command, IProcessCreateDefault, m_workingDir);
}
bool DbgGdb::Attach(const DebugSessionInfo& si)
{
    // set the environment variables
    EnvSetter env(m_env, NULL, m_debuggeeProjectName, wxEmptyString);

    wxString dbgExeName;
    if(!DoLocateGdbExecutable(si.debuggerPath, dbgExeName)) {
        return false;
    }

    wxString cmd;
#if defined(__WXGTK__) || defined(__WXMAC__)
    cmd << dbgExeName;
    if(!si.ttyName.IsEmpty()) {
        cmd << wxT(" --tty=") << si.ttyName;
    }
    cmd << wxT(" --interpreter=mi ");
#else
    cmd << dbgExeName << wxT(" --interpreter=mi ");
    cmd << ProcUtils::GetProcessNameByPid(si.PID) << wxT(" ");
#endif

    // if(sudoCmd.IsEmpty() == false) {
    //    cmd.Prepend(sudoCmd + wxT(" "));
    //}

    m_attachedMode = true;
    m_debuggeePid = si.PID;
    cmd << wxT(" --pid=") << m_debuggeePid;
    wxLogMessage(cmd);

    m_observer->UpdateAddLine(wxString::Format(wxT("Current working dir: %s"), wxGetCwd().c_str()));
    m_observer->UpdateAddLine(wxString::Format(wxT("Launching gdb from : %s"), wxGetCwd().c_str()));
    m_observer->UpdateAddLine(wxString::Format(wxT("Starting debugger  : %s"), cmd.c_str()));
    
    // Build the process creation flags
    size_t createFlags = IProcessCreateDefault;
    if(m_info.flags & DebuggerInformation::kRunAsSuperuser) {
        createFlags |= IProcessCreateAsSuperuser;
    }
    m_gdbProcess = CreateAsyncProcess(this, cmd, createFlags);
    if(!m_gdbProcess) {
        return false;
    }
    m_gdbProcess->SetHardKill(true);

    DoInitializeGdb(si);
    m_observer->UpdateGotControl(DBG_END_STEPPING);
    return true;
}
Beispiel #7
0
void CppCheckPlugin::DoProcess(ProjectPtr proj)
{
    wxString command = DoGetCommand(proj);
    m_view->AppendLine(wxString::Format(_("Starting cppcheck: %s\n"), command.c_str()));

#if defined(__WXMSW__)
    // Under Windows, we set the working directory to the binary folder
    // so the configurtion files can be found
    CL_DEBUG("CppCheck: Working directory: %s", clStandardPaths::Get().GetBinFolder());
    CL_DEBUG("CppCheck: Command: %s", command);
    m_cppcheckProcess = CreateAsyncProcess(this, command, IProcessCreateDefault, clStandardPaths::Get().GetBinFolder());
#elif defined(__WXOSX__)
    CL_DEBUG("CppCheck: Working directory: %s", clStandardPaths::Get().GetDataDir());
    CL_DEBUG("CppCheck: Command: %s", command);
    m_cppcheckProcess = CreateAsyncProcess(this, command, IProcessCreateDefault, clStandardPaths::Get().GetDataDir());

#else
    m_cppcheckProcess = CreateAsyncProcess(this, command);
#endif
    if(!m_cppcheckProcess) {
        wxMessageBox(_("Failed to launch codelite_cppcheck process!"), _("Warning"), wxOK | wxCENTER | wxICON_WARNING);
        return;
    }
}
Beispiel #8
0
bool DbgGdb::Start(const wxString &debuggerPath, const wxString & exeName, int pid, const std::vector<BreakpointInfo> &bpList, const wxArrayString &cmds)
{
	wxString dbgExeName;
	if ( ! DoLocateGdbExecutable(debuggerPath, dbgExeName) ) {
		return false;
	}

	wxString cmd;

#if defined (__WXGTK__) || defined (__WXMAC__)
	//On GTK and other platforms, open a new terminal and direct all
	//debugee process into it
	wxString ptyName;
	if (!m_consoleFinder.FindConsole(wxT("EmbeddedLite: gdb"), ptyName)) {
		wxLogMessage(wxT("Failed to allocate console for debugger"));
		return false;
	}
	cmd << dbgExeName << wxT(" --tty=") << ptyName << wxT(" --interpreter=mi ");
#else
	cmd << dbgExeName << wxT(" --interpreter=mi ");
	cmd << ProcUtils::GetProcessNameByPid(pid) << wxT(" ");
#endif

	m_debuggeePid = pid;
	cmd << wxT(" --pid=") << m_debuggeePid;
	wxLogMessage(cmd);

	//set the environment variables
	EnvSetter env(m_env);

	m_observer->UpdateAddLine(wxString::Format(wxT("Current working dir: %s"), wxGetCwd().c_str()));
	m_observer->UpdateAddLine(wxString::Format(wxT("Launching gdb from : %s"), wxGetCwd().c_str()));
	m_observer->UpdateAddLine(wxString::Format(wxT("Starting debugger  : %s"), cmd.c_str()));

	m_gdbProcess = CreateAsyncProcess(this, cmd);
	if (!m_gdbProcess) {
		return false;
	}
	m_gdbProcess->SetHardKill(true);
	
	DoInitializeGdb(bpList, cmds);
	m_observer->UpdateGotControl(DBG_END_STEPPING);
	return true;
}
Beispiel #9
0
void SvnConsole::DoProcessNextCommand()
{
    // If another process is running, we try again when the process is termianted
    if (m_process) {
        return;
    }

    if(m_queue.empty())
        return;

    // Remove the command from the queue
    SvnConsoleCommand *command = m_queue.front();
    m_queue.pop_front();
    m_output.Clear();

    m_currCmd.clean();
    m_currCmd = *command;

    // Delete it
    delete command;

    EnsureVisible();

    // Print the command?
    AppendText(m_currCmd.cmd + wxT("\n"));

    // Wrap the command in the OS Shell
    wxString cmdShell (m_currCmd.cmd);

    // Apply the environment variables before executing the command
    wxStringMap_t om;
    om.insert( std::make_pair( "LC_ALL", "C" ) );
    
    bool useOverrideMap = m_plugin->GetSettings().GetFlags() & SvnUsePosixLocale;
    EnvSetter env(m_plugin->GetManager()->GetEnv(), useOverrideMap ? &om : NULL);

    m_process = CreateAsyncProcess(this, cmdShell, IProcessCreateWithHiddenConsole, m_currCmd.workingDirectory);
    if (!m_process) {
        AppendText(_("Failed to launch Subversion client.\n"));
        return;
    }
    m_sci->SetFocus();
}
Beispiel #10
0
void wxFormBuilder::DoLaunchWxFB(const wxString& file)
{
    wxString fbpath = GetWxFBPath();
    //	if (fbpath.IsEmpty()) {
    //		wxMessageBox(_("Failed to launch wxFormBuilder, no path specified\nPlease set wxFormBuilder path from
    // Plugins
    //-> wxFormBuilder -> Settings..."),
    //		             _("CodeLite"), wxOK|wxCENTER|wxICON_WARNING);
    //		return;
    //	}
    ConfFormBuilder confData;
    m_mgr->GetConfigTool()->ReadObject(wxT("wxFormBuilder"), &confData);
    wxString cmd = confData.GetCommand();
    cmd.Replace(wxT("$(wxfb)"), fbpath);
    cmd.Replace(wxT("$(wxfb_project)"), wxString::Format(wxT("\"%s\""), file.c_str()));

    WrapInShell(cmd);
    CreateAsyncProcess(this, cmd, IProcessCreateWithHiddenConsole);
}
Beispiel #11
0
void wxTerminal::DoProcessCommand(const wxString& command)
{
	wxString cmd ( command );
	cmd.Trim().Trim(false);

	if (!cmd.StartsWith(wxT("#"))) {
		// Execute it
		if (cmd.EndsWith(wxT("&"))) {
			cmd.RemoveLast();
		}

		wxString path;

		// Add the shell prefix
		wxString cmdShell = WrapInShell(cmd);
		if(CheckForCD(cmd, path)) {
			// CD command!
			m_workingDir = path;
			DoWritePrompt();

		} else {
			// real command
			IProcess *cmdPrc = CreateAsyncProcess(this, cmdShell, m_workingDir);
			if( cmdPrc ) {
				m_process = cmdPrc;
			} else {
				m_process = NULL;
				m_textCtrl->SetInsertionPointEnd();
				m_textCtrl->AppendText(wxString::Format(wxT("Failed to execute command: %s\nWorking Directory: %s\n"), cmdShell.c_str(), m_workingDir.c_str()));
				DoWritePrompt();
			}
		}
	} else {
		DoWritePrompt();
	}
	m_history.AddCommand( cmd );
}
// 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;
    }
}
Beispiel #13
0
//do the actual cleanup
void CleanRequest::Process(IManager *manager)
{
    wxString cmd;
    wxString errMsg;
    wxStringMap_t om;

    BuildSettingsConfig *bsc(manager ? manager->GetBuildSettingsConfigManager() : BuildSettingsConfigST::Get());
    BuildManager *       bm(manager ? manager->GetBuildManager() : BuildManagerST::Get());
    Workspace *          w(manager ? manager->GetWorkspace() : WorkspaceST::Get());


    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_info.GetProjectOnly()) {
        cmd = builder->GetPOCleanCommand(m_info.GetProject(), m_info.GetConfiguration());
    } else {
        cmd = builder->GetCleanCommand(m_info.GetProject(), m_info.GetConfiguration());
    }

    if ( cmd.IsEmpty() ) {
        AppendLine(_("Sorry, there is no 'Clean' command available\n"));
        return;
    }

    BuildConfigPtr bldConf = w->GetProjBuildConf(m_info.GetProject(), m_info.GetConfiguration());
    if(bldConf) {
        wxString cmpType = bldConf->GetCompilerType();
        CompilerPtr cmp = bsc->GetCompiler(cmpType);
        if(cmp) {
            wxString value( cmp->GetPathVariable() );
            if(value.Trim().Trim(false).IsEmpty() == false) {
                wxLogMessage(wxString::Format(wxT("Setting PATH to '%s'"), value.c_str()));
                om[wxT("PATH")] = value.Trim().Trim(false);
            }
        }
    } else {
        AppendLine(_("Sorry, couldn't find the Build configuration\n"));
        return;
    }

    // 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;
    }
    
    SendStartMsg();
    // Expand the variables of the command
    cmd = ExpandAllVariables(cmd, w, m_info.GetProject(), m_info.GetConfiguration(), wxEmptyString);
    WrapInShell(cmd);
    DirSaver ds;
    DoSetWorkingDirectory(proj, false, false);

    if (m_info.GetProjectOnly() ) {
        //need to change directory to project dir
        wxSetWorkingDirectory(proj->GetFileName().GetPath());
    }
    //print the build command
    AppendLine(cmd + wxT("\n"));

    // print the prefix message of the build start. This is important since the parser relies
    // on this message
    if(m_info.GetProjectOnly()) {
        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(CLEAN_PROJECT_PREFIX) << m_info.GetProject() << wxT(" - ") << configName << wxT(" ]");
        text << wxT("----------\n");
        AppendLine(text);
    }

    //apply environment settings
    EnvSetter env(NULL, &om, proj->GetName());
    m_proc = CreateAsyncProcess(this, cmd);
    if ( !m_proc ) {

        //remove environment settings applied
        wxString message;
        message << _("Failed to start clean process, command: ") << cmd << _(", process terminated with exit code: 0");
        AppendLine(message);
        return;
    }
}
Beispiel #14
0
bool DbgGdb::Start( const DebugSessionInfo& si)
{
    //set the environment variables
    EnvSetter env( m_env, NULL, m_debuggeeProjectName );

    wxString dbgExeName;
    if ( ! DoLocateGdbExecutable( si.debuggerPath, dbgExeName ) ) {
        return false;
    }

    wxString cmd;
#if defined (__WXGTK__) || defined (__WXMAC__)
    cmd << dbgExeName;
    if ( !si.ttyName.IsEmpty() ) {
        cmd << wxT( " --tty=" ) << si.ttyName;
    }
    cmd << wxT( " --interpreter=mi " ) << si.exeName;
#else
    cmd << dbgExeName << wxT( " --interpreter=mi " ) << si.exeName;
#endif

    m_debuggeePid = wxNOT_FOUND;
    m_attachedMode = false;

    m_observer->UpdateAddLine( wxString::Format( wxT( "Current working dir: %s" ), wxGetCwd().c_str() ) );
    m_observer->UpdateAddLine( wxString::Format( wxT( "Launching gdb from : %s" ), si.cwd.c_str() ) );
    m_observer->UpdateAddLine( wxString::Format( wxT( "Starting debugger  : %s" ), cmd.c_str() ) );
#ifdef __WXMSW__
    // When using remote debugging on Windows we need a console window, as this is the only
    // mechanism to send a Ctrl-C event and signal a SIGINT to interrupt the target.
    bool needs_console = GetIsRemoteDebugging() | m_info.showTerminal;
#else
    bool needs_console = m_info.showTerminal;
#endif
    m_gdbProcess = CreateAsyncProcess( this,
                                       cmd,
                                       // show console?
                                       needs_console ? IProcessCreateConsole : IProcessCreateDefault,
                                       si.cwd );
    if ( !m_gdbProcess ) {
        return false;
    }
#ifdef __WXMSW__
    if ( GetIsRemoteDebugging() ) {
        // This doesn't really make sense, but AttachConsole fails without it...
        AllocConsole();
        FreeConsole(); // Disconnect any existing console window.

        if ( !AttachConsole( m_gdbProcess->GetPid() ) )
            m_observer->UpdateAddLine( wxString::Format(wxT("AttachConsole returned error %d"), GetLastError()));

        // We can at least make the window invisible if the user doesn't want to see it.
        if ( !m_info.showTerminal )
            SetWindowPos(GetConsoleWindow(), HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW);

        // Finally we ignore SIGINT so we don't get killed by our own signal
        signal(SIGINT, SIG_IGN);
    }
#endif
    m_gdbProcess->SetHardKill( true );
    DoInitializeGdb( si );
    return true;
}
void CustomBuildRequest::Process(IManager* manager)
{
    wxString cmd;
    wxString errMsg;
    wxStringMap_t om;

    clCxxWorkspace* w(manager->GetWorkspace());
    EnvironmentConfig* env(manager->GetEnv());

    ProjectPtr proj = w->FindProjectByName(m_info.GetProject(), errMsg);
    if(!proj) {
        AppendLine(_("Cant find project: ") + m_info.GetProject());
        return;
    }

    // Notify plugins that a compile process is going to start
    clBuildEvent event(wxEVT_BUILD_STARTING);
    event.SetProjectName(proj->GetName());
    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;
    }

    SendStartMsg();

    BuildConfigPtr bldConf = w->GetProjBuildConf(m_info.GetProject(), m_info.GetConfiguration());
    if(!bldConf) {
        wxLogMessage(wxString::Format(wxT("Failed to find build configuration for project '%s' and configuration '%s'"),
                                      m_info.GetProject().c_str(),
                                      m_info.GetConfiguration().c_str()));
        return;
    }

    // try the special targets first:
    bool isClean(false);
    if(m_info.GetCustomBuildTarget() == wxT("Build")) {
        cmd = bldConf->GetCustomBuildCmd();

    } else if(m_info.GetCustomBuildTarget() == wxT("Clean")) {
        cmd = bldConf->GetCustomCleanCmd();
        isClean = true;
    } else if(m_info.GetCustomBuildTarget() == wxT("Rebuild")) {
        cmd = bldConf->GetCustomRebuildCmd();

    } else if(m_info.GetCustomBuildTarget() == wxT("Compile Single File")) {
        cmd = bldConf->GetSingleFileBuildCommand();

    } else if(m_info.GetCustomBuildTarget() == wxT("Preprocess File")) {
        cmd = bldConf->GetPreprocessFileCommand();
    }

    // if still no luck, try with the other custom targets
    if(cmd.IsEmpty()) {
        std::map<wxString, wxString> targets = bldConf->GetCustomTargets();
        std::map<wxString, wxString>::iterator iter = targets.find(m_info.GetCustomBuildTarget());
        if(iter != targets.end()) {
            cmd = iter->second;
        }
    }

    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;
    }

    // Working directory:
    // By default we use the project path
    //////////////////////////////////////////////////////

    DirSaver ds;

    // first set the path to the project working directory
    ::wxSetWorkingDirectory(proj->GetFileName().GetPath());

    // If a working directory was specified, use it instead
    wxString wd = bldConf->GetCustomBuildWorkingDir();
    wd.Trim().Trim(false);

    wxString filename;
    if(manager->GetActiveEditor()) {
        filename = manager->GetActiveEditor()->GetFileName().GetFullPath();
    }

    if(wd.IsEmpty()) {

        // use the project path
        wd = proj->GetFileName().GetPath();

    } else {

        // expand macros from the working directory
        wd = ExpandAllVariables(wd, clCxxWorkspaceST::Get(), proj->GetName(), bldConf->GetName(), filename);
    }

    {
        // Ensure that the path to the working directory exist
        wxFileName fnwd(wd, "");
        if(!fnwd.DirExists()) {
            fnwd.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
        }
    }

    ::wxSetWorkingDirectory(wd);

    // Print message to the build tab
    AppendLine(wxString::Format(_("MESSAGE: Entering directory `%s'\n"), wd.c_str()));

    // Command handling:
    //////////////////////////////////////////////////////

    // expand the variables of the command
    cmd = ExpandAllVariables(cmd, w, m_info.GetProject(), m_info.GetConfiguration(), filename);

    // in case our configuration includes post/pre build commands
    // we generate a makefile to include them as well and we update
    // the build command
    bool bCommandAltered = DoUpdateCommand(manager, cmd, proj, bldConf, isClean);

#ifdef __WXMSW__
    // Windows CD command requires the paths to be backslashe
    if(cmd.Find(wxT("cd ")) != wxNOT_FOUND) cmd.Replace(wxT("/"), wxT("\\"));
#endif

    // Wrap the build command in the shell, so it will be able
    // to perform 'chain' commands like
    // cd SOMEWHERE && make && ...

    // Dont wrap the command if it was altered previously
    if(!bCommandAltered) {
        WrapInShell(cmd);
    }

    // print the build command
    AppendLine(cmd + wxT("\n"));
    wxString configName(m_info.GetConfiguration());

    // also, send another message to the main frame, indicating which project is being built
    // and what configuration
    wxString text;
    if(isClean) {
        text << wxGetTranslation(CLEAN_PROJECT_PREFIX);
    } else {
        text << wxGetTranslation(BUILD_PROJECT_PREFIX);
    }
    text << m_info.GetProject() << wxT(" - ") << configName << wxT(" ]----------\n");

    AppendLine(text);
    
    // Avoid Unicode chars coming from the compiler by setting LC_ALL to "C"
    om["LC_ALL"] = "C";
    EnvSetter environment(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;
    }
}