示例#1
0
void ProjectSettings::SetBuildConfiguration(const BuildConfigPtr bc)
{
    if(!bc) return;

    // delete the old build configuration pointer if any
    std::map<wxString, BuildConfigPtr>::iterator iter = m_configs.find(bc->GetName());
    if(iter != m_configs.end()) m_configs.erase(iter);

    // replace with the new one
    m_configs[bc->GetName()] = bc;
}
示例#2
0
QueueCommand::QueueCommand(int kind)
    : m_projectOnly(false)
    , m_kind(kind)
    , m_cleanLog(true)
    , m_checkBuildSuccess(false)
{
    // Fill with default values
    if ( clCxxWorkspaceST::Get()->IsOpen() ) {
        m_project = clCxxWorkspaceST::Get()->GetActiveProjectName();
        BuildConfigPtr buildPtr = clCxxWorkspaceST::Get()->GetProjBuildConf(m_project, "");
        wxASSERT_MSG( buildPtr, "No active project" );
        
        // If a 'Build' or 'Clean' kinds where requested 
        // and the project build configuration is Custom build
        // change the kind to CustomBuild and set the proper build
        // targets
        if ( m_kind == kBuild && buildPtr->IsCustomBuild() ) {
            // change the type to CustomBuild
            m_kind = kCustomBuild;
            SetCustomBuildTarget("Build");
            
        } else if ( m_kind == kClean && buildPtr->IsCustomBuild() ) {
            // change the type to CustomBuild
            m_kind = kCustomBuild;
            SetCustomBuildTarget("Clean");
        
        } else {
            m_configuration = buildPtr->GetName();
            
        }
    }
}
void EditConfigurationDialog::RenameConfiguration(const wxString &oldName, const wxString &newName)
{
	ProjectSettingsPtr settings = ManagerST::Get()->GetProjectSettings(m_projectName);
	if(settings){
		BuildConfigPtr bldConf = settings->GetBuildConfiguration(oldName);
		if(bldConf){
			settings->RemoveConfiguration(oldName);
			bldConf->SetName(newName);
			settings->SetBuildConfiguration(bldConf);
			//save changes
			ManagerST::Get()->SetProjectSettings(m_projectName, settings);

			//update the control
			m_configurationsList->Clear();
			ProjectSettingsCookie cookie;
			BuildConfigPtr bldConf = settings->GetFirstBuildConfiguration(cookie);
			while(bldConf){
				m_configurationsList->Append(bldConf->GetName());
				bldConf = settings->GetNextBuildConfiguration(cookie);
			}
			if(m_configurationsList->GetCount()>0)
				m_configurationsList->SetSelection(0);
		}
	}
}
示例#4
0
void ShellCommand::DoSetWorkingDirectory(ProjectPtr proj, bool isCustom, bool isFileOnly)
{
    //when using custom build, user can select different working directory
    if (proj) {
        if (isCustom) {
            //first set the path to the project working directory
            ::wxSetWorkingDirectory(proj->GetFileName().GetPath());

            BuildConfigPtr buildConf = WorkspaceST::Get()->GetProjBuildConf(m_info.GetProject(), m_info.GetConfiguration());
            if (buildConf) {
                wxString wd = buildConf->GetCustomBuildWorkingDir();
                if (wd.IsEmpty()) {
                    // use the project path
                    wd = proj->GetFileName().GetPath();
                } else {
                    // expand macros from path
                    wd = ExpandAllVariables(wd, WorkspaceST::Get(), proj->GetName(), buildConf->GetName(), wxEmptyString);
                }
                ::wxSetWorkingDirectory(wd);
            }
        } else {
            if(m_info.GetProjectOnly() || isFileOnly) {
                //first set the path to the project working directory
                ::wxSetWorkingDirectory(proj->GetFileName().GetPath());
            }
        }
    }
}
示例#5
0
void BatchBuildDlg::DoInitialize()
{
    // load the previously saved batch build file
    wxFileName fn(WorkspaceST::Get()->GetWorkspaceFileName());
    fn.SetExt(wxT("batch_build"));

    wxString content;
    wxArrayString arr;
    if (ReadFileWithConversion(fn.GetFullPath(), content)) {
        arr = wxStringTokenize(content, wxT("\n"), wxTOKEN_STRTOK);
        for (size_t i=0; i<arr.GetCount(); i++) {
            int idx = m_checkListConfigurations->Append(arr.Item(i));
            m_checkListConfigurations->Check((unsigned int)idx);
        }
    }

    // loop over all projects, for each project collect all available
    // build configurations and add them to the check list control
    wxArrayString projects;
    WorkspaceST::Get()->GetProjectList(projects);
    for (size_t i=0; i<projects.GetCount(); i++) {
        ProjectPtr p = ManagerST::Get()->GetProject(projects.Item(i));
        if (p) {
            ProjectSettingsPtr settings = p->GetSettings();
            if (settings) {
                ProjectSettingsCookie cookie;
                BuildConfigPtr bldConf = settings->GetFirstBuildConfiguration(cookie);
                while (bldConf) {
                    wxString item(p->GetName() + wxT(" | ") + bldConf->GetName());

                    int where = arr.Index(item);
                    if (where == wxNOT_FOUND) {
                        // append this item
                        m_checkListConfigurations->Append(item);
                    } else {
                        // this item already been added,
                        // remove it from the arr and continue
                        arr.RemoveAt((size_t)where);
                    }

                    bldConf = settings->GetNextBuildConfiguration(cookie);
                }
            }
        }
    }

    // check to see which configuration was left in 'arr'
    // and remove them from the checklistbox
    for (size_t i=0; i<arr.GetCount(); i++) {
        int where = m_checkListConfigurations->FindString(arr.Item(i));
        if (where != wxNOT_FOUND) {
            m_checkListConfigurations->Delete((unsigned int)where);
        }
    }
    arr.clear();

    if (m_checkListConfigurations->GetCount()>0) {
        m_checkListConfigurations->Select(0);
    }
}
示例#6
0
wxString CMakePlugin::GetSelectedProjectConfig() const
{
    BuildConfigPtr configPtr = GetSelectedBuildConfig();

    if(configPtr) return configPtr->GetName();

    return wxEmptyString;
}
示例#7
0
void CMakePlugin::DoRunCMake(ProjectPtr p)
{
    CHECK_PTR_RET(p);

    BuildConfigPtr buildConf = p->GetBuildConfiguration();
    CHECK_COND_RET(buildConf);

// Apply the environment variables before we do anything here
#ifdef __WXMSW__
    // On Windows, we need to set the bin folder of the selected compiler
    wxFileName fnCxx(buildConf->GetCompiler()->GetTool("CXX"));
    wxStringMap_t om;
    wxString pathvar;
    pathvar << fnCxx.GetPath() << clPATH_SEPARATOR << "$PATH";
    om["PATH"] = pathvar;
    EnvSetter es(NULL, &om, p->GetName(), buildConf->GetName());
#else
    EnvSetter es(p);
#endif

    CMakeGenerator generator;
    if(generator.CanGenerate(p)) {
        generator.Generate(p);
    }

    const wxString& args = buildConf->GetBuildSystemArguments();
    wxString cmakeExe = GetCMake()->GetPath().GetFullPath();
    // Did the user provide a generator to use?
    bool hasGeneratorInArgs = (args.Find(" -G") != wxNOT_FOUND);

    // Build the working directory
    wxFileName fnWorkingDirectory(CMakeBuilder::GetWorkspaceBuildFolder(false), "");
    wxString workingDirectory = fnWorkingDirectory.GetPath();

    // Ensure that the build directory exists
    fnWorkingDirectory.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
    ::WrapWithQuotes(cmakeExe);

    wxString command;
    command << cmakeExe << " .. " << args;
    if(!hasGeneratorInArgs) {
#ifdef __WXMSW__
        // On Windows, generate MinGW makefiles
        command << " -G\"MinGW Makefiles\"";
#endif
    }

    // Execute it
    IProcess* proc = ::CreateAsyncProcess(this, command, IProcessCreateDefault, fnWorkingDirectory.GetPath());
    if(!proc) {
        ::wxMessageBox(_("Failed to execute:\n") + command, "CodeLite", wxICON_ERROR | wxOK | wxCENTER,
            EventNotifier::Get()->TopFrame());
        return;
    }
    m_mgr->ShowOutputPane(_("Build"));
    m_mgr->ClearOutputTab(kOutputTab_Build);
    m_mgr->AppendOutputTabText(kOutputTab_Build, command + "\n");
}
示例#8
0
void QMakePlugin::OnExportMakefile(wxCommandEvent& event)
{
    if(m_qmakeProcess) return;

    QmakePluginData::BuildConfPluginData bcpd;

    ProjectPtr pProj = m_mgr->GetSelectedProject();
    CHECK_PTR_RET(pProj);

    BuildConfigPtr bldConf = pProj->GetBuildConfiguration();
    CHECK_PTR_RET(bldConf);

    wxString project = pProj->GetName();
    wxString config = bldConf->GetName();

    if(!DoGetData(project, config, bcpd)) {
        event.Skip();
        return;
    }

    if(bcpd.m_enabled) {
        // This project/configuration is qmake project
        QMakeProFileGenerator generator(m_mgr, project, config);

        // Regenerate the .pro file
        generator.Generate();

        // run qmake
        wxString qmake_exe = m_conf->Read(wxString::Format(wxT("%s/qmake"), bcpd.m_qmakeConfig.c_str()));
        wxString qmakespec = m_conf->Read(wxString::Format(wxT("%s/qmakespec"), bcpd.m_qmakeConfig.c_str()));
        wxString qtdir = m_conf->Read(wxString::Format(wxT("%s/qtdir"), bcpd.m_qmakeConfig.c_str()));

        // Create qmake comand
        wxString qmake_exe_line;
        qmake_exe.Trim().Trim(false);
        qmakespec.Trim().Trim(false);

        // Set QTDIR
        DirSaver ds;
        {

            wxString errMsg;
            ProjectPtr p = m_mgr->GetWorkspace()->FindProjectByName(project, errMsg);
            if(!p) { return; }

            qmake_exe_line << wxT("\"") << qmake_exe << wxT("\" -spec ") << qmakespec << wxT(" ")
                           << generator.GetProFileName();
            wxStringMap_t om;
            om.insert(std::make_pair("QTDIR", qtdir));
            EnvSetter envGuard(NULL, &om, project, config);
            m_mgr->ClearOutputTab(kOutputTab_Build);
            m_mgr->AppendOutputTabText(kOutputTab_Build, wxString() << "-- " << qmake_exe_line << "\n");
            m_qmakeProcess =
                ::CreateAsyncProcess(this, qmake_exe_line, IProcessCreateDefault, p->GetFileName().GetPath());
        }
    }
    event.Skip();
}
示例#9
0
void PSGeneralPage::Load(BuildConfigPtr buildConf)
{
    Clear();
    m_configName = buildConf->GetName();
    m_checkBoxEnabled->SetValue( buildConf->IsProjectEnabled() );
    m_pgPropArgs->SetValue( buildConf->GetCommandArguments() );
    m_pgPropDebugArgs->SetValueFromString( buildConf->GetDebugArgs() );
    m_pgPropIntermediateFolder->SetValueFromString( buildConf->GetIntermediateDirectory() );
    m_pgPropGUIApp->SetValue( buildConf->IsGUIProgram() );
    m_pgPropOutputFile->SetValueFromString( buildConf->GetOutputFileName() );
    m_pgPropPause->SetValue( buildConf->GetPauseWhenExecEnds() );
    m_pgPropProgram->SetValueFromString( buildConf->GetCommand() );
    m_pgPropWorkingDirectory->SetValue( buildConf->GetWorkingDirectory() );
    // Project type
    wxPGChoices choices;
    choices.Add(Project::STATIC_LIBRARY);
    choices.Add(Project::DYNAMIC_LIBRARY);
    choices.Add(Project::EXECUTABLE);
    m_pgPropProjectType->SetChoices( choices );
    m_pgPropProjectType->SetChoiceSelection( choices.Index(buildConf->GetProjectType() ) );

    // Compilers
    choices.Clear();
    wxString cmpType = buildConf->GetCompilerType();
    BuildSettingsConfigCookie cookie;
    CompilerPtr cmp = BuildSettingsConfigST::Get()->GetFirstCompiler(cookie);
    while (cmp) {
        choices.Add(cmp->GetName());
        cmp = BuildSettingsConfigST::Get()->GetNextCompiler(cookie);
    }
    m_pgPropCompiler->SetChoices( choices );
    m_pgPropCompiler->SetChoiceSelection( choices.Index( buildConf->GetCompiler()->GetName() ) );

    // Debuggers
    choices.Clear();
    wxString dbgType = buildConf->GetDebuggerType();
    wxArrayString dbgs = DebuggerMgr::Get().GetAvailableDebuggers();
    choices.Add(dbgs);
    m_pgPropDebugger->SetChoices( choices );
    m_pgPropDebugger->SetChoiceSelection( choices.Index(buildConf->GetDebuggerType()) );
    m_pgPropUseSeparateDebuggerArgs->SetValue( buildConf->GetUseSeparateDebugArgs() );
    m_dlg->SetIsProjectEnabled( buildConf->IsProjectEnabled() );
}
void ConfigurationManagerDlg::LoadProjectConfiguration(const wxString &projectName)
{
	std::map<int, ConfigEntry>::iterator iter = m_projSettingsMap.begin();
	for (; iter != m_projSettingsMap.end(); iter++) {
		if (iter->second.project == projectName) {
			iter->second.choiceControl->Clear();

			ProjectSettingsPtr proSet = ManagerST::Get()->GetProjectSettings(projectName);
			if (proSet) {
				ProjectSettingsCookie cookie;
				BuildConfigPtr bldConf = proSet->GetFirstBuildConfiguration(cookie);
				while (bldConf) {
					iter->second.choiceControl->Append(bldConf->GetName());
					bldConf = proSet->GetNextBuildConfiguration(cookie);
				}

				//append the EDIT & NEW commands
				iter->second.choiceControl->Append(clCMD_EDIT);
				iter->second.choiceControl->Append(clCMD_NEW);

				//select the build configuration according to the build matrix
				BuildMatrixPtr matrix = ManagerST::Get()->GetWorkspaceBuildMatrix();
				if (!matrix) {
					return;
				}

				wxString configName = matrix->GetProjectSelectedConf(m_choiceConfigurations->GetStringSelection(), projectName);
				int match = iter->second.choiceControl->FindString(configName);
				if (match != wxNOT_FOUND) {
					iter->second.choiceControl->SetStringSelection(configName);
				} else {
					iter->second.choiceControl->SetSelection(0);
				}

				return;
			}
		}
	}
}
void ConfigurationManagerDlg::AddEntry(const wxString &projectName, const wxString &selectedConf)
{
	wxFlexGridSizer *mainSizer = dynamic_cast<wxFlexGridSizer*>(m_scrolledWindow->GetSizer());
	if (!mainSizer) return;

	wxArrayString choices;
	wxChoice *choiceConfig = new wxChoice( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices, 0 );

	// Get all configuration of the project
	ProjectSettingsPtr settings = ManagerST::Get()->GetProjectSettings(projectName);
	if (settings) {
		ProjectSettingsCookie cookie;
		BuildConfigPtr bldConf = settings->GetFirstBuildConfiguration(cookie);
		while (bldConf) {
			choiceConfig->Append(bldConf->GetName());
			bldConf = settings->GetNextBuildConfiguration(cookie);
		}
	}
	choiceConfig->Append(clCMD_NEW);
	choiceConfig->Append(clCMD_EDIT);
	ConnectChoice(choiceConfig, ConfigurationManagerDlg::OnConfigSelected);
	wxStaticText *text = new wxStaticText( m_scrolledWindow, wxID_ANY, projectName, wxDefaultPosition, wxDefaultSize, 0 );

	int where = choiceConfig->FindString(selectedConf);
	if (where == wxNOT_FOUND) {
		where = 0;
	}
	choiceConfig->SetSelection(where);
	mainSizer->Add(text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
	mainSizer->Add(choiceConfig, 1, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);

	ConfigEntry entry;
	entry.project = projectName;
	entry.projectSettings = settings;
	entry.choiceControl = choiceConfig;

	m_projSettingsMap[choiceConfig->GetId()] = entry;
}
示例#12
0
EditConfigurationDialog::EditConfigurationDialog( wxWindow* parent, const wxString &projectName, int id, wxString title, wxPoint pos, wxSize size, int style ) 
: wxDialog( parent, id, title, pos, size, style )
, m_projectName(projectName)
{
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	
	wxBoxSizer* bSizer15;
	bSizer15 = new wxBoxSizer( wxVERTICAL );
	
	m_panel6 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxBoxSizer* bSizer17;
	bSizer17 = new wxBoxSizer( wxHORIZONTAL );
	
	m_configurationsList = new wxListBox( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); 
	bSizer17->Add( m_configurationsList, 1, wxALL|wxEXPAND, 5 );
	
	ProjectSettingsPtr settings = ManagerST::Get()->GetProjectSettings(m_projectName);
	if(settings){
		ProjectSettingsCookie cookie;
		BuildConfigPtr bldConf = settings->GetFirstBuildConfiguration(cookie);
		while(bldConf){
			m_configurationsList->Append(bldConf->GetName());
			bldConf = settings->GetNextBuildConfiguration(cookie);
		}
	}
	if(m_configurationsList->GetCount() > 0)
		m_configurationsList->SetSelection(0);

	wxBoxSizer* bSizer18;
	bSizer18 = new wxBoxSizer( wxVERTICAL );
	
	m_buttonDelete = new wxButton( m_panel6, wxID_ANY, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer18->Add( m_buttonDelete, 0, wxALL, 5 );
	
	m_buttonRename = new wxButton( m_panel6, wxID_ANY, wxT("&Rename"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer18->Add( m_buttonRename, 0, wxALL, 5 );
	bSizer17->Add( bSizer18, 0, wxEXPAND, 5 );
	
	m_panel6->SetSizer( bSizer17 );
	m_panel6->Layout();
	bSizer17->Fit( m_panel6 );
	bSizer15->Add( m_panel6, 1, wxALL|wxEXPAND, 5 );
	
	m_staticline9 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
	bSizer15->Add( m_staticline9, 0, wxEXPAND | wxALL, 5 );
	
	wxBoxSizer* bSizer16;
	bSizer16 = new wxBoxSizer( wxHORIZONTAL );
	
	m_buttonClose = new wxButton( this, wxID_OK, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer16->Add( m_buttonClose, 0, wxALL, 5 );
	
	bSizer15->Add( bSizer16, 0, wxALIGN_CENTER, 5 );
	
	this->SetSizer( bSizer15 );
	this->Layout();

	ConnectListBoxDClick(m_configurationsList, EditConfigurationDialog::OnItemDclick);
	ConnectButton(m_buttonClose, EditConfigurationDialog::OnButtonClose);
	ConnectButton(m_buttonRename, EditConfigurationDialog::OnButtonRename);
	ConnectButton(m_buttonDelete, EditConfigurationDialog::OnButtonDelete);
}
示例#13
0
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;
    }
}
示例#14
0
bool clCxxWorkspace::RemoveProject(const wxString& name, wxString& errMsg)
{
    ProjectPtr proj = FindProjectByName(name, errMsg);
    if(!proj) {
        return false;
    }

    // remove the associated build configuration with this
    // project
    RemoveProjectFromBuildMatrix(proj);

    // remove the project from the internal map
    std::map<wxString, ProjectPtr>::iterator iter = m_projects.find(proj->GetName());
    if(iter != m_projects.end()) {
        m_projects.erase(iter);
    }

    // update the xml file
    wxXmlNode* root = m_doc.GetRoot();
    wxXmlNode* child = root->GetChildren();
    while(child) {
        if(child->GetName() == wxT("Project") && child->GetPropVal(wxT("Name"), wxEmptyString) == name) {
            if(child->GetPropVal(wxT("Active"), wxEmptyString).CmpNoCase(wxT("Yes")) == 0) {
                // the removed project was active,
                // select new project to be active
                if(!m_projects.empty()) {
                    std::map<wxString, ProjectPtr>::iterator iter = m_projects.begin();
                    SetActiveProject(iter->first, true);
                }
            }
            root->RemoveChild(child);
            delete child;
            break;
        }
        child = child->GetNext();
    }

    // go over the dependencies list of each project and remove the project
    iter = m_projects.begin();
    for(; iter != m_projects.end(); iter++) {
        ProjectPtr p = iter->second;
        if(p) {
            wxArrayString configs;
            // populate the choice control with the list of available configurations for this project
            ProjectSettingsPtr settings = p->GetSettings();
            if(settings) {
                ProjectSettingsCookie cookie;
                BuildConfigPtr bldConf = settings->GetFirstBuildConfiguration(cookie);
                while(bldConf) {
                    configs.Add(bldConf->GetName());
                    bldConf = settings->GetNextBuildConfiguration(cookie);
                }
            }

            // update each configuration of this project
            for(size_t i = 0; i < configs.GetCount(); i++) {

                wxArrayString deps = p->GetDependencies(configs.Item(i));
                int where = deps.Index(name);
                if(where != wxNOT_FOUND) {
                    deps.RemoveAt((size_t)where);
                }

                // update the configuration
                p->SetDependencies(deps, configs.Item(i));
            }
        }
    }
    return SaveXmlFile();
}
示例#15
0
void clCxxWorkspace::AddProjectToBuildMatrix(ProjectPtr prj)
{
    if(!prj) {
        wxMessageBox(_("AddProjectToBuildMatrix was called with NULL project"), _("CodeLite"), wxICON_WARNING | wxOK);
        return;
    }

    BuildMatrixPtr matrix = GetBuildMatrix();
    wxString selConfName = matrix->GetSelectedConfigurationName();

    std::list<WorkspaceConfigurationPtr> wspList = matrix->GetConfigurations();
    std::list<WorkspaceConfigurationPtr>::iterator iter = wspList.begin();
    for(; iter != wspList.end(); iter++) {
        WorkspaceConfigurationPtr workspaceConfig = (*iter);
        WorkspaceConfiguration::ConfigMappingList prjList = workspaceConfig->GetMapping();
        wxString wspCnfName = workspaceConfig->GetName();

        ProjectSettingsCookie cookie;

        // getSettings is a bit misleading, since it actually create new instance which represents the layout
        // of the XML
        ProjectSettingsPtr settings = prj->GetSettings();
        BuildConfigPtr prjBldConf = settings->GetFirstBuildConfiguration(cookie);
        BuildConfigPtr matchConf;

        if(!prjBldConf) {
            // the project does not have any settings, create new one and add it
            prj->SetSettings(settings);

            settings = prj->GetSettings();
            prjBldConf = settings->GetFirstBuildConfiguration(cookie);
            matchConf = prjBldConf;

        } else {

            matchConf = prjBldConf;

            // try to locate the best match to add to the workspace
            while(prjBldConf) {
                wxString projBldConfName = prjBldConf->GetName();
                if(wspCnfName == projBldConfName) {
                    // we found a suitable match use it instead of the default one
                    matchConf = prjBldConf;
                    break;
                }
                prjBldConf = settings->GetNextBuildConfiguration(cookie);
            }
        }

        ConfigMappingEntry entry(prj->GetName(), matchConf->GetName());
        prjList.push_back(entry);
        (*iter)->SetConfigMappingList(prjList);
        matrix->SetConfiguration((*iter));
    }

    // and set the configuration name
    matrix->SetSelectedConfigurationName(selConfName);

    // this will also reset the build matrix pointer
    SetBuildMatrix(matrix);
}
示例#16
0
void ProjectSettings::SetBuildConfiguration(const BuildConfigPtr bc)
{
    m_configs[bc->GetName()] = bc;
}
示例#17
0
wxArrayString PluginManager::GetProjectCompileFlags(const wxString& projectName, bool isCppFile)
{
    if(IsWorkspaceOpen() == false) return wxArrayString();

    wxArrayString args;

    // Next apppend the user include paths
    wxString errMsg;

    // First, we need to find the currently active workspace configuration
    BuildMatrixPtr matrix = GetWorkspace()->GetBuildMatrix();
    if(!matrix) {
        return wxArrayString();
    }

    wxString workspaceSelConf = matrix->GetSelectedConfigurationName();

    // Now that we got the selected workspace configuration, extract the related project configuration
    ProjectPtr proj = GetWorkspace()->FindProjectByName(projectName, errMsg);
    if(!proj) {
        return args;
    }

    wxString projectSelConf = matrix->GetProjectSelectedConf(workspaceSelConf, proj->GetName());
    BuildConfigPtr dependProjbldConf = GetWorkspace()->GetProjBuildConf(proj->GetName(), projectSelConf);
    if(dependProjbldConf && dependProjbldConf->IsCustomBuild() == false) {
        // Get the include paths and add them
        wxString projectIncludePaths = dependProjbldConf->GetIncludePath();
        wxArrayString projectIncludePathsArr = wxStringTokenize(projectIncludePaths, wxT(";"), wxTOKEN_STRTOK);
        for(size_t i = 0; i < projectIncludePathsArr.GetCount(); i++) {
            args.Add(wxString::Format(wxT("-I%s"), projectIncludePathsArr[i].c_str()));
        }
        // get the compiler options and add them
        wxString projectCompileOptions = dependProjbldConf->GetCompileOptions();
        wxArrayString projectCompileOptionsArr = wxStringTokenize(projectCompileOptions, wxT(";"), wxTOKEN_STRTOK);
        for(size_t i = 0; i < projectCompileOptionsArr.GetCount(); i++) {
            wxString cmpOption(projectCompileOptionsArr.Item(i));
            cmpOption.Trim().Trim(false);
            wxString tmp;
            // Expand backticks / $(shell ...) syntax supported by codelite
            if(cmpOption.StartsWith(wxT("$(shell "), &tmp) || cmpOption.StartsWith(wxT("`"), &tmp)) {
                cmpOption = tmp;
                tmp.Clear();
                if(cmpOption.EndsWith(wxT(")"), &tmp) || cmpOption.EndsWith(wxT("`"), &tmp)) {
                    cmpOption = tmp;
                }
                if(m_backticks.find(cmpOption) == m_backticks.end()) {
                    // Expand the backticks into their value
                    wxArrayString outArr;
                    // Apply the environment before executing the command
                    EnvSetter setter(EnvironmentConfig::Instance(), NULL, projectName, dependProjbldConf->GetName());
                    ProcUtils::SafeExecuteCommand(cmpOption, outArr);
                    wxString expandedValue;
                    for(size_t j = 0; j < outArr.size(); j++) {
                        expandedValue << outArr.Item(j) << wxT(" ");
                    }
                    m_backticks[cmpOption] = expandedValue;
                    cmpOption = expandedValue;
                } else {
                    cmpOption = m_backticks.find(cmpOption)->second;
                }
            }
            args.Add(cmpOption);
        }
        // get the compiler preprocessor and add them as well
        wxString projectPreps = dependProjbldConf->GetPreprocessor();
        wxArrayString projectPrepsArr = wxStringTokenize(projectPreps, wxT(";"), wxTOKEN_STRTOK);
        for(size_t i = 0; i < projectPrepsArr.GetCount(); i++) {
            args.Add(wxString::Format(wxT("-D%s"), projectPrepsArr[i].c_str()));
        }
    }
    return args;
}
示例#18
0
void LLDBPlugin::OnDebugStart(clDebugEvent& event)
{
    if(event.GetDebuggerName() != LLDB_DEBUGGER_NAME) {
        event.Skip();
        return;
    }

    CL_DEBUG("LLDB: Initial working directory is restored to: " + ::wxGetCwd());
    {
        // Get the executable to debug
        wxString errMsg;
        ProjectPtr pProject = clCxxWorkspaceST::Get()->FindProjectByName(event.GetProjectName(), errMsg);
        if(!pProject) {
            ::wxMessageBox(wxString() << _("Could not locate project: ") << event.GetProjectName(), "LLDB Debugger",
                           wxICON_ERROR | wxOK | wxCENTER);
            return;
        }

        DirSaver ds;
        ::wxSetWorkingDirectory(pProject->GetFileName().GetPath());

        // Load LLDB settings
        LLDBSettings settings;
        settings.Load();

        BuildConfigPtr bldConf = clCxxWorkspaceST::Get()->GetProjBuildConf(pProject->GetName(), wxEmptyString);
        if(!bldConf) {
            ::wxMessageBox(wxString() << _("Could not locate the requested buid configuration"), "LLDB Debugger",
                           wxICON_ERROR | wxOK | wxCENTER);
            return;
        }

        // Launch codelite-lldb now.
        // Choose wether we need to debug a local or remote target

        // Honour the project settings
        if(bldConf->GetIsDbgRemoteTarget()) {
            long nPort(wxNOT_FOUND);
            bldConf->GetDbgHostPort().ToCLong(&nPort);
            settings.SetProxyIp(bldConf->GetDbgHostName());
            settings.SetProxyPort(nPort);
            settings.EnableFlag(kLLDBOptionUseRemoteProxy, true);
        }

        if(!settings.IsUsingRemoteProxy()) {
            // Not using a remote proxy, launch the debug server
            if(!m_connector.LaunchLocalDebugServer(settings.GetDebugserver())) { return; }
        }

        // Determine the executable to debug, working directory and arguments
        EnvSetter env(NULL, NULL, pProject ? pProject->GetName() : wxString(), bldConf->GetName());
        wxString exepath = bldConf->GetCommand();
        wxString args;
        wxString workingDirectory;
        // Get the debugging arguments.
        if(bldConf->GetUseSeparateDebugArgs()) {
            args = bldConf->GetDebugArgs();
        } else {
            args = bldConf->GetCommandArguments();
        }

        workingDirectory = ::ExpandVariables(bldConf->GetWorkingDirectory(), pProject, m_mgr->GetActiveEditor());
        exepath = ::ExpandVariables(exepath, pProject, m_mgr->GetActiveEditor());

        {
            DirSaver ds;
            ::wxSetWorkingDirectory(workingDirectory);
            wxFileName execToDebug(exepath);
            if(execToDebug.IsRelative()) { execToDebug.MakeAbsolute(); }

            //////////////////////////////////////////////////////////////////////
            // Launch terminal for IO redirection
            //////////////////////////////////////////////////////////////////////
            TerminateTerminal();

            bool isWindows = wxPlatformInfo::Get().GetOperatingSystemId() & wxOS_WINDOWS;
            if(!bldConf->IsGUIProgram() && !isWindows) {
                m_debuggerTerminal.Launch(clDebuggerTerminalPOSIX::MakeExeTitle(execToDebug.GetFullPath(), args));

                if(m_debuggerTerminal.IsValid()) {
                    CL_DEBUG("Successfully launched terminal %s", m_debuggerTerminal.GetTty());

                } else {
                    // Failed to launch it...
                    DoCleanup();
                    ::wxMessageBox(_("Failed to start terminal for debugger"), "CodeLite",
                                   wxICON_ERROR | wxOK | wxCENTER);
                    return;
                }
            }

            if(!isWindows) { workingDirectory = ::wxGetCwd(); }

            CL_DEBUG("LLDB: Using executable : " + execToDebug.GetFullPath());
            CL_DEBUG("LLDB: Working directory: " + workingDirectory);

            //////////////////////////////////////////////////////////////////////
            // Initiate the connection to codelite-lldb
            //////////////////////////////////////////////////////////////////////

            LLDBConnectReturnObject retObj;
            if(m_connector.Connect(retObj, settings, 5)) {

                // Get list of breakpoints and add them ( we will apply them later on )
                BreakpointInfo::Vec_t gdbBps;
                m_mgr->GetAllBreakpoints(gdbBps);

                // remove all breakpoints from previous session
                m_connector.DeleteAllBreakpoints();

                // apply the serialized breakpoints
                m_connector.AddBreakpoints(gdbBps);

                // Setup pivot folder if needed
                SetupPivotFolder(retObj);

                LLDBCommand startCommand;
                startCommand.FillEnvFromMemory();

                // If the current platform is Windows, use the executable as it appears in the project settings
                startCommand.SetExecutable(isWindows ? exepath : execToDebug.GetFullPath());

                startCommand.SetCommandArguments(args);
                // Since we called 'wxSetWorkingDirectory' earlier, wxGetCwd() should give use the
                // correct working directory for the debugger
                startCommand.SetWorkingDirectory(workingDirectory);
                startCommand.SetRedirectTTY(m_debuggerTerminal.GetTty());
                m_connector.Start(startCommand);

                clDebugEvent cl_event(wxEVT_DEBUG_STARTED);
                EventNotifier::Get()->AddPendingEvent(cl_event);

            } else {
                // Failed to connect, notify and perform cleanup
                DoCleanup();
                wxString message;
                message << _("Could not connect to codelite-lldb at '")
                        << (settings.IsUsingRemoteProxy() ? settings.GetTcpConnectString()
                                                          : m_connector.GetConnectString())
                        << "'";
                ::wxMessageBox(message, "CodeLite", wxICON_ERROR | wxOK | wxCENTER);
                return;
            }
        }
    }
    CL_DEBUG("LLDB: Working directory is restored to: " + ::wxGetCwd());
}
示例#19
0
void ContinuousBuild::DoBuild(const wxString& fileName)
{
	PRINT_MESSAGE(wxT("DoBuild\n"));
	// Make sure a workspace is opened
	if (!m_mgr->IsWorkspaceOpen()) {
		PRINT_MESSAGE(wxT("No workspace opened!\n"));
		return;
	}
		

	// Filter non source files
	FileExtManager::FileType type = FileExtManager::GetType(fileName);
	switch(type) {
		case FileExtManager::TypeSourceC:
		case FileExtManager::TypeSourceCpp:
		case FileExtManager::TypeResource:
			break;

		default: {
			PRINT_MESSAGE(wxT("Non source file\n"));
			return;
		}
	}

	wxString projectName = m_mgr->GetProjectNameByFile(fileName);
	if(projectName.IsEmpty()) {
		PRINT_MESSAGE(wxT("Project name is empty\n"));
		return;
	}
	
	wxString errMsg;
	ProjectPtr project = m_mgr->GetSolution()->FindProjectByName(projectName, errMsg);
	if(!project){
		PRINT_MESSAGE(wxT("Could not find project for file\n"));
		return;
	}

	// get the selected configuration to be build
	BuildConfigPtr bldConf = m_mgr->GetSolution()->GetProjBuildConf( project->GetName(), wxEmptyString );
	if ( !bldConf ) {
		PRINT_MESSAGE(wxT("Failed to locate build configuration\n"));
		return;
	}

	BuilderPtr builder = m_mgr->GetBuildManager()->GetBuilder( wxT( "GNU makefile for g++/gcc" ) );
	if(!builder){
		PRINT_MESSAGE(wxT("Failed to located builder\n"));
		return;
	}

	// Only normal file builds are supported
	if(bldConf->IsCustomBuild()){
		PRINT_MESSAGE(wxT("Build is custom. Skipping\n"));
		return;
	}

	// get the single file command to use
	wxString cmd      = builder->GetSingleFileCmd(projectName, bldConf->GetName(), fileName);
	WrapInShell(cmd);

	if( m_buildProcess.IsBusy() ) {
		// add the build to the queue
		if (m_files.Index(fileName) == wxNOT_FOUND) {
			m_files.Add(fileName);

			// update the UI
			m_view->AddFile(fileName);
		}
		return;
	}
	
	PRINT_MESSAGE(wxString::Format(wxT("cmd:%s\n"), cmd.c_str()));
	if(!m_buildProcess.Execute(cmd, fileName, project->GetFileName().GetPath(), this))
		return;

	// Set some messages
	m_mgr->SetStatusMessage(wxString::Format(wxT("Compiling %s..."), wxFileName(fileName).GetFullName().c_str()), 0);

	// Add this file to the UI queue
	m_view->AddFile(fileName);
}
示例#20
0
void MacBundler::showSettingsDialogFor(ProjectPtr project)
{
    // project->GetSettings()->GetGlobalSettings();
    // project->GetSettings()->GetBuildConfiguration(name);

    ProjectSettingsCookie cookie;

    ProjectSettingsPtr settings = project->GetSettings();
    if(not settings) {
        wxMessageBox(_("Cannot continue, impossible to access project settings."));
        return;
    }

    std::map<wxString, BuildConfigPtr> configs;
    wxArrayString choices;

    // TODO: allow putting the rules in the config root and not in every target
    BuildConfigPtr buildConfig = settings->GetFirstBuildConfiguration(cookie);
    while(buildConfig) {

        configs[buildConfig->GetName()] = buildConfig;
        choices.Add(buildConfig->GetName());

        buildConfig = settings->GetNextBuildConfiguration(cookie);
    }

    bool accepted = false;
    bool generateInfoPlistFile = false;
    bool generateIcon = false;

    wxArrayString targetsToSet;

    wxString iconName(wxT("icon.icns"));

    {
        BundleConfigDialog configDlg(project, m_mgr->GetTheApp()->GetTopWindow(), choices, m_mgr);
        configDlg.ShowModal();
        accepted = configDlg.getResults(targetsToSet, &generateInfoPlistFile, &generateIcon);
        iconName = configDlg.getIconDestName();

        if(accepted and generateInfoPlistFile) {
            wxFileName projPath = project->GetFileName();
            projPath.SetFullName(wxT(""));
            const wxString projectDirName = projPath.GetFullPath();
            const wxString infoPlistFile = projectDirName + wxT("/Info.plist");

            if(wxFileExists(infoPlistFile)) {
                int out = wxMessageBox(wxString::Format(_("The following file:\n%s\nalready exists, overwrite it?\n"),
                                                        infoPlistFile.c_str()),
                                       _("Warning"),
                                       wxYES_NO);
                if(out == wxYES) {
                    wxTextFile file;
                    file.Open(infoPlistFile);
                    file.Clear();
                    configDlg.writeInfoPlistFile(file);
                    file.Close();
                }
            } else {
                wxTextFile file;
                if(not file.Create(infoPlistFile)) {
                    wxMessageBox(_("Could not create Info.plist file\n") + infoPlistFile);
                } else {
                    configDlg.writeInfoPlistFile(file);
                    file.Close();
                }
            }

            if(wxFileExists(infoPlistFile)) {
                // FIXME: if the file was already present, it will be added again and appear twice in the file tree
                wxArrayString paths;
                paths.Add(infoPlistFile);
                m_mgr->CreateVirtualDirectory(project->GetName(), wxT("osx"));
                m_mgr->AddFilesToVirtualFolder(project->GetName() + wxT(":osx"), paths);
            }
        } // nend if create info.plist

        if(accepted and generateIcon) {
            wxString iconSourcePath = configDlg.getIconSource();
            if(not iconSourcePath.IsEmpty()) {
                // sips doesn't like double slashes in path names
                iconSourcePath.Replace(wxT("//"), wxT("/"));

                wxFileName projPath = project->GetFileName();
                projPath.SetFullName(wxT(""));
                const wxString projectDirName = projPath.GetFullPath();
                wxString iconFileDest = projectDirName + wxT("/") + configDlg.getIconDestName();

                // sips doesn't like double slashes in path names
                iconFileDest.Replace(wxT("//"), wxT("/"));

                std::cout << "Copying icon '" << iconSourcePath.mb_str() << "' to project\n";

                if(iconSourcePath.EndsWith(wxT(".icns"))) {
                    if(not wxCopyFile(iconSourcePath, iconFileDest)) {
                        wxMessageBox(_("Sorry, could not copy icon"));
                    }
                } else {
                    wxString cmd =
                        wxT("sips -s format icns '") + iconSourcePath + wxT("' --out '") + iconFileDest + wxT("'");
                    std::cout << cmd.mb_str() << std::endl;
                    wxExecute(cmd, wxEXEC_SYNC);
                    if(not wxFileExists(iconFileDest)) {
                        wxMessageBox(_("Sorry, could not convert selected icon to icns format"));
                    }
                }

                // FIXME: if the file was already present, it will be added again and appear twice in the file tree
                if(wxFileExists(iconFileDest)) {
                    wxArrayString paths;
                    paths.Add(iconFileDest);
                    m_mgr->CreateVirtualDirectory(project->GetName(), wxT("osx"));
                    m_mgr->AddFilesToVirtualFolder(project->GetName() + wxT(":osx"), paths);
                }
            } // end if icon not null
        }     // end if generate icon
    }
    if(!accepted) return;

    for(int n = 0; n < targetsToSet.GetCount(); n++) {
        BuildConfigPtr buildConfig = configs[targetsToSet[n]];

        wxString outputFileName = buildConfig->GetOutputFileName();
        wxString output = wxT("$(ProjectName).app/Contents/MacOS/$(ProjectName)");
        buildConfig->SetOutputFileName(wxT("$(IntermediateDirectory)/") + output);
        buildConfig->SetCommand(wxT("./") + output);

        if(generateInfoPlistFile or generateIcon) {
            // get existing custom makefile targets, if any
            wxString customPreBuild = buildConfig->GetPreBuildCustom();

            wxString deps, rules;
            deps = customPreBuild.BeforeFirst(wxT('\n'));
            rules = customPreBuild.AfterFirst(wxT('\n'));

            rules = rules.Trim();
            rules = rules.Trim(false);

            deps = deps.Trim();
            deps = deps.Trim(false);

            if(generateInfoPlistFile) {
                // augment existing rules with new rules to manage Info.plist file
                deps.Append(wxT(" $(IntermediateDirectory)/$(ProjectName).app/Contents/Info.plist"));
                rules.Append(wxString(wxT("\n## rule to copy the Info.plist file into the bundle\n")) +
                             wxT("$(IntermediateDirectory)/$(ProjectName).app/Contents/Info.plist: Info.plist\n") +
                             wxT("\tmkdir -p '$(IntermediateDirectory)/$(ProjectName).app/Contents' && cp -f "
                                 "Info.plist '$(IntermediateDirectory)/$(ProjectName).app/Contents/Info.plist'"));
            }
            if(generateIcon) {
                // augment existing rules with new rules to manage Info.plist file
                deps.Append(wxT(" $(IntermediateDirectory)/$(ProjectName).app/Contents/Resources/") + iconName);
                rules.Append(
                    wxT("\n## rule to copy the icon file into the "
                        "bundle\n$(IntermediateDirectory)/$(ProjectName).app/Contents/Resources/") +
                    iconName + wxT(": ") + iconName +
                    wxT("\n\tmkdir -p '$(IntermediateDirectory)/$(ProjectName).app/Contents/Resources/' && cp -f ") +
                    iconName + wxT(" '$(IntermediateDirectory)/$(ProjectName).app/Contents/Resources/") + iconName +
                    wxT("'"));
            }

            // set the new rules
            rules = rules.Trim();
            rules = rules.Trim(false);
            deps = deps.Trim();
            deps = deps.Trim(false);

            wxString prebuilstep;
            prebuilstep << deps << wxT("\n");
            prebuilstep << rules;
            prebuilstep << wxT("\n");

            // Set the content only if there is real content to add
            wxString tmpPreBuildStep(prebuilstep);
            tmpPreBuildStep.Trim().Trim(false);
            buildConfig->SetPreBuildCustom(prebuilstep);
        } // end if

        settings->SetBuildConfiguration(buildConfig);

    } // end for

    project->SetSettings(settings);
}
示例#21
0
wxString MacroManager::DoExpand(
    const wxString& expression, IManager* manager, const wxString& project, bool applyEnv, const wxString& confToBuild)
{
    wxString expandedString(expression);
    clCxxWorkspace* workspace = clCxxWorkspaceST::Get();

    if(!manager) {
        manager = clGetManager();
    }

    size_t retries = 0;
    wxString dummyname, dummfullname;
    while((retries < 5) && FindVariable(expandedString, dummyname, dummyname)) {
        ++retries;
        DollarEscaper de(expandedString);
        if(workspace) {
            expandedString.Replace(wxT("$(WorkspaceName)"), workspace->GetName());
            ProjectPtr proj = workspace->GetProject(project);
            if(proj) {
                wxString prjBuildWd;
                wxString prjRunWd;

                wxString project_name(proj->GetName());

                // make sure that the project name does not contain any spaces
                project_name.Replace(wxT(" "), wxT("_"));

                BuildConfigPtr bldConf = workspace->GetProjBuildConf(proj->GetName(), confToBuild);
                if(bldConf) {
                    bool isCustom = bldConf->IsCustomBuild();
                    expandedString.Replace(wxT("$(ProjectOutputFile)"), bldConf->GetOutputFileName());
                    // An alias
                    expandedString.Replace(wxT("$(OutputFile)"), bldConf->GetOutputFileName());

                    // When custom build project, use the working directory set in the
                    // custom build tab, otherwise use the project file's path
                    prjBuildWd = isCustom ? bldConf->GetCustomBuildWorkingDir() : proj->GetFileName().GetPath();
                    prjRunWd = bldConf->GetWorkingDirectory();
                }

                expandedString.Replace(wxT("$(ProjectWorkingDirectory)"), prjBuildWd);
                expandedString.Replace(wxT("$(ProjectRunWorkingDirectory)"), prjRunWd);
                expandedString.Replace(wxT("$(ProjectPath)"), proj->GetFileName().GetPath());
                expandedString.Replace(wxT("$(WorkspacePath)"), workspace->GetWorkspaceFileName().GetPath());
                expandedString.Replace(wxT("$(ProjectName)"), project_name);

                if(bldConf) {
                    expandedString.Replace(wxT("$(IntermediateDirectory)"), bldConf->GetIntermediateDirectory());
                    expandedString.Replace(wxT("$(ConfigurationName)"), bldConf->GetName());
                    expandedString.Replace(wxT("$(OutDir)"), bldConf->GetIntermediateDirectory());
                }

                if(expandedString.Find(wxT("$(ProjectFiles)")) != wxNOT_FOUND)
                    expandedString.Replace(wxT("$(ProjectFiles)"), proj->GetFiles());

                if(expandedString.Find(wxT("$(ProjectFilesAbs)")) != wxNOT_FOUND)
                    expandedString.Replace(wxT("$(ProjectFilesAbs)"), proj->GetFiles(true));
            }
        }

        if(manager) {
            IEditor* editor = manager->GetActiveEditor();
            if(editor) {
                wxFileName fn(editor->GetFileName());

                expandedString.Replace(wxT("$(CurrentFileName)"), fn.GetName());

                wxString fpath(fn.GetPath());
                fpath.Replace(wxT("\\"), wxT("/"));
                expandedString.Replace(wxT("$(CurrentFilePath)"), fpath);
                expandedString.Replace(wxT("$(CurrentFileExt)"), fn.GetExt());
                expandedString.Replace(wxT("$(CurrentFileFullName)"), fn.GetFullName());

                wxString ffullpath(fn.GetFullPath());
                ffullpath.Replace(wxT("\\"), wxT("/"));
                expandedString.Replace(wxT("$(CurrentFileFullPath)"), ffullpath);
                expandedString.Replace(wxT("$(CurrentSelection)"), editor->GetSelection());
                if(expandedString.Find(wxT("$(CurrentSelectionRange)")) != wxNOT_FOUND) {
                    int start = editor->GetSelectionStart(), end = editor->GetSelectionEnd();

                    wxString output = wxString::Format(wxT("%i:%i"), start, end);
                    expandedString.Replace(wxT("$(CurrentSelectionRange)"), output);
                }
            }
        }

        // exapand common macros
        wxDateTime now = wxDateTime::Now();
        expandedString.Replace(wxT("$(User)"), wxGetUserName());
        expandedString.Replace(wxT("$(Date)"), now.FormatDate());

        if(manager && applyEnv) {
            expandedString.Replace(wxT("$(CodeLitePath)"), manager->GetInstallDirectory());

            // Apply the environment and expand the variables
            EnvSetter es(NULL, NULL, project, confToBuild);
            expandedString = manager->GetEnv()->ExpandVariables(expandedString, false);
        }
    }
    return expandedString;
}