wxString QMakePlugin::DoGetBuildCommand(const wxString &project, const wxString &config, bool projectOnly) { wxUnusedVar ( config ); wxString errMsg; ProjectPtr p = m_mgr->GetWorkspace()->FindProjectByName(project, errMsg); if ( !p ) { return wxEmptyString; } BuildConfigPtr bldConf = WorkspaceST::Get()->GetProjBuildConf(project, config); wxString cmd; if ( !projectOnly ) { cmd << wxT("@cd \"") << p->GetFileName().GetPath() << wxT("\" && "); } // fix: replace all Windows like slashes to POSIX wxString command = bldConf->GetCompiler()->GetTool("MAKE"); command.Replace(wxT("\\"), wxT("/")); cmd << command << wxT(" \"") << p->GetName() << wxT(".mk\""); return cmd; }
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); } }
void LLDBDebuggerPlugin::OnDebugStart(clDebugEvent& event) { event.Skip(); return; if ( ::PromptForYesNoDialogWithCheckbox(_("Would you like to use LLDB debugger as your primary debugger?"), "UseLLDB") != wxID_YES ) { event.Skip(); return; } // Get the executable to debug wxString errMsg; ProjectPtr pProject = WorkspaceST::Get()->FindProjectByName(event.GetProjectName(), errMsg); if ( !pProject ) { event.Skip(); return; } wxSetWorkingDirectory ( pProject->GetFileName().GetPath() ); BuildConfigPtr bldConf = WorkspaceST::Get()->GetProjBuildConf ( pProject->GetName(), wxEmptyString ); if ( !bldConf ) { event.Skip(); return; } // Show the terminal ShowTerminal("LLDB Console Window"); if ( m_debugger.Start("/home/eran/devl/TestArea/TestHang/Debug/TestHang") ) { m_debugger.AddBreakpoint("main"); m_debugger.ApplyBreakpoints(); m_debugger.Run("/tmp/in", "/tmp/out", "/tmp/err", wxArrayString(), wxArrayString(), ::wxGetCwd()); } }
void clCxxWorkspace::RemoveProjectFromBuildMatrix(ProjectPtr prj) { 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++) { WorkspaceConfiguration::ConfigMappingList prjList = (*iter)->GetMapping(); WorkspaceConfiguration::ConfigMappingList::iterator it = prjList.begin(); for(; it != prjList.end(); it++) { if((*it).m_project == prj->GetName()) { prjList.erase(it); break; } } (*iter)->SetConfigMappingList(prjList); matrix->SetConfiguration((*iter)); } // and set the configuration name matrix->SetSelectedConfigurationName(selConfName); // this will also reset the build matrix pointer SetBuildMatrix(matrix); }
wxString QMakePlugin::DoGetBuildCommand(const wxString& project, const wxString& config, bool projectOnly) { wxUnusedVar(config); wxString errMsg; ProjectPtr p = m_mgr->GetWorkspace()->FindProjectByName(project, errMsg); if(!p) { return wxEmptyString; } BuildConfigPtr bldConf = clCxxWorkspaceST::Get()->GetProjBuildConf(project, config); wxString cmd; wxString projectMakefile; projectMakefile << p->GetName() << ".mk"; ::WrapWithQuotes(projectMakefile); projectMakefile.Replace("\\", "/"); if(!projectOnly) { // part of a greater makefile, use $(MAKE) cmd << wxT("@cd \"") << p->GetFileName().GetPath() << wxT("\" && "); cmd << "$(MAKE) -f " << projectMakefile; } else { // project only cmd = bldConf->GetCompiler()->GetTool("MAKE"); if(!cmd.Contains("-f")) { cmd << " -f "; } cmd << " " << projectMakefile; } return cmd; }
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()); } } } }
void CMakeProjectMenu::OnMakeDirty(wxCommandEvent& event) { // Get settings const CMakeProjectSettings* settings = m_plugin->GetSelectedProjectSettings(); // Event shouldn't be called when project is not enabled wxASSERT(settings && settings->enabled); // This function just touch .cmake_dirty file ProjectPtr project = m_plugin->GetSelectedProject(); // Real project wxString projectName = project->GetName(); // Project has parent project -> touch dirty file there if (!settings->parentProject.IsEmpty()) { projectName = settings->parentProject; } // Move to project directory wxFileName dirtyFile = m_plugin->GetProjectDirectory(projectName); dirtyFile.SetFullName(".cmake_dirty"); // Update file time dirtyFile.Touch(); }
void CMakeProjectMenu::OnFileExists(wxUpdateUIEvent& event) { ProjectPtr project = m_plugin->GetSelectedProject(); if (project) event.Enable(m_plugin->ExistsCMakeLists(m_plugin->GetProjectDirectory(project->GetName()))); }
void MemCheckPlugin::OnCheckPopupProject(wxCommandEvent& event) { CHECK_CL_SHUTDOWN() ProjectPtr project = m_mgr->GetSelectedProject(); if(project) { CheckProject(project->GetName()); } }
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"); }
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(); }
NewProjectClientData(ProjectPtr project, const wxString & templateName = wxEmptyString) : m_templateName(templateName) { m_project = project; if (m_project && m_templateName.IsEmpty() ) { // use the project name m_templateName = m_project->GetName(); } }
void CMakeProjectMenu::OnCMakeListsOpen(wxCommandEvent& event) { wxUnusedVar(event); ProjectPtr project = m_plugin->GetSelectedProject(); if (project) m_plugin->OpenCMakeLists(m_plugin->GetProjectDirectory(project->GetName())); }
BuildConfigPtr CMakePlugin::GetSelectedBuildConfig() const { const clCxxWorkspace* workspace = m_mgr->GetWorkspace(); wxASSERT(workspace); const ProjectPtr projectPtr = GetSelectedProject(); wxASSERT(projectPtr); return workspace->GetProjBuildConf(projectPtr->GetName(), wxEmptyString); }
ProjectPtr clCxxWorkspace::DoAddProject(ProjectPtr proj) { if(!proj) { return NULL; } m_projects.insert(std::make_pair(proj->GetName(), proj)); proj->AssociateToWorkspace(this); return proj; }
const CMakeProjectSettings* CMakePlugin::GetSelectedProjectSettings() const { const ProjectPtr projectPtr = GetSelectedProject(); wxASSERT(projectPtr); const wxString project = projectPtr->GetName(); const wxString config = GetSelectedProjectConfig(); wxASSERT(m_settingsManager); return m_settingsManager->GetProjectSettings(project, config); }
bool clCxxWorkspace::AddProject(const wxString& path, wxString& errMsg) { if(!m_doc.IsOk()) { errMsg = wxT("No workspace open"); return false; } wxFileName fn(path); if(!fn.FileExists()) { errMsg = wxT("File does not exist"); return false; } // Load the project into ProjectPtr newProject(new Project()); if(!newProject->Load(path)) { errMsg = wxT("Corrupted project file '"); errMsg << path << wxT("'"); return false; } // Try first to find a project with similar name in the workspace ProjectPtr proj = FindProjectByName(newProject->GetName(), errMsg); if(!proj) { // No project could be find, add it to the workspace DoAddProject(newProject); // Add an entry to the workspace file fn.MakeRelativeTo(m_fileName.GetPath()); wxXmlNode* node = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Project")); node->AddProperty(wxT("Name"), fn.GetName()); node->AddProperty(wxT("Path"), fn.GetFullPath(wxPATH_UNIX)); node->AddProperty(wxT("Active"), m_projects.size() == 1 ? wxT("Yes") : wxT("No")); m_doc.GetRoot()->AddChild(node); if(!SaveXmlFile()) { wxMessageBox( _("Failed to save workspace file to disk. Please check that you have permission to write to disk"), _("CodeLite"), wxICON_ERROR | wxOK); return false; } AddProjectToBuildMatrix(newProject); return true; } else { errMsg = wxString::Format(wxT("A project with a similar name '%s' already exists in the workspace"), proj->GetName().c_str()); return false; } }
NewProjectClientData(ProjectPtr project, const wxString& templateName = wxEmptyString, bool isPluginManaged = false, bool canUseSeparateFolder = true) : m_templateName(templateName) , m_isPluginManaged(isPluginManaged) , m_canUseSeparateFolder(canUseSeparateFolder) { m_project = project; if(m_project && m_templateName.IsEmpty()) { // use the project name m_templateName = m_project->GetName(); } }
//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; } }
void WorkspaceTab::OnProjectSettings(wxCommandEvent& e) { wxUnusedVar(e); ProjectPtr proj = m_fileView->GetSelectedProject(); OpenProjectSettings(proj ? proj->GetName() : ""); }
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()); }
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); 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; }
void NewProjectWizard::OnPageChanging(wxWizardEvent& event) { if(event.GetDirection()) { wxDataViewItem sel = m_dataviewTemplates->GetSelection(); NewProjectClientData* cd = dynamic_cast<NewProjectClientData*>(m_dataviewTemplatesModel->GetClientObject(sel)); if(event.GetPage() == m_wizardPageTemplate) { // ------------------------------------------------------- // Switching from the Templates page // ------------------------------------------------------- if(!CheckProjectTemplate()) { event.Veto(); return; } // Test to see if the selected project allows enabling the 'Create under separate folder' if(cd && !cd->IsCanUseSeparateFolder()) { m_cbSeparateDir->SetValue(false); m_cbSeparateDir->Enable(false); } else { m_cbSeparateDir->Enable(true); } m_txtProjName->SetFocus(); // This should have happened in the base-class ctor, but in practice it doesn't } else if(event.GetPage() == m_wizardPageDetails) { // ------------------------------------------------------- // Switching from the Name/Path page // ------------------------------------------------------- if(!CheckProjectName() || !CheckProjectPath()) { event.Veto(); return; } } else if(event.GetPage() == m_wizardPageToolchain) { wxFileName fn(m_stxtFullFileName->GetLabel()); // make sure that there is no conflict in files between the template project and the selected path if(m_projectData.m_srcProject) { ProjectPtr p = m_projectData.m_srcProject; wxString base_dir(fn.GetPath()); std::vector<wxFileName> files; p->GetFiles(files); for(size_t i = 0; i < files.size(); ++i) { wxFileName f = files.at(i); wxString new_file = base_dir + wxT("/") + f.GetFullName(); if(wxFileName::FileExists(new_file)) { // this file already - notify the user wxString msg; msg << _("The File '") << f.GetFullName() << _("' already exists at the target directory '") << base_dir << wxT("'\n"); msg << _("Please select a different project path\n"); msg << _("The file '") << f.GetFullName() << _("' is part of the template project [") << p->GetName() << wxT("]"); wxMessageBox(msg, _("CodeLite"), wxOK | wxICON_HAND); event.Veto(); return; } } } } } event.Skip(); }
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); }
void NewProjectWizard::OnFinish(wxWizardEvent& event) { wxFileName fn( m_stxtFullFileName->GetLabel() ); // Ensure that the target folder exists fn.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL); // make sure that there is no conflict in files between the template project and the selected path if (m_projectData.m_srcProject) { ProjectPtr p = m_projectData.m_srcProject; wxString base_dir( fn.GetPath() ); std::vector<wxFileName> files; p->GetFiles(files); for (size_t i=0; i<files.size(); ++i) { wxFileName f = files.at(i); wxString new_file = base_dir + wxT("/") + f.GetFullName(); if ( wxFileName::FileExists(new_file) ) { // this file already - notify the user wxString msg; msg << _("The File '") << f.GetFullName() << _("' already exists at the target directory '") << base_dir << wxT("'\n"); msg << _("Please select a different project path\n"); msg << _("The file '") << f.GetFullName() << _("' is part of the template project [") << p->GetName() << wxT("]"); wxMessageBox(msg, _("CodeLite"), wxOK|wxICON_HAND); event.Veto(); return; } } } m_projectData.m_name = m_txtProjName->GetValue(); m_projectData.m_path = fn.GetPath(); m_projectData.m_cmpType = m_choiceCompiler->GetStringSelection(); m_projectData.m_debuggerType = m_choiceDebugger->GetStringSelection(); event.Skip(); }
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(); }
BundleConfigDialog(ProjectPtr project, wxWindow* parent, const wxArrayString& choices, IManager* manager) : wxDialog(parent, wxID_ANY, _("Mac Bundler Configuration"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , m_pluginManager(manager) { m_accepted = false; m_project_name = project->GetName(); wxStaticText* titleLabel = new wxStaticText(this, wxID_ANY, _("Choose which target(s) to \"bundle-ize\"")); m_choices_widget = new wxCheckListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); m_info_plist_cb = new wxCheckBox(this, wxID_ANY, _("Generate Info.plist file")); m_get_info_string = new wxTextCtrl(this, wxID_ANY, m_project_name + wxT(", version 1.0, copyright myself")); m_version = new wxTextCtrl(this, wxID_ANY, wxT("1.0")); m_icon_file = new wxTextCtrl(this, wxID_ANY, m_project_name + wxT(".icns")); m_identifier = new wxTextCtrl(this, wxID_ANY, wxT("com.mycompany.") + m_project_name.Lower()); m_signature = new wxTextCtrl(this, wxID_ANY, (m_project_name + wxT("????")).Left(4).Upper()); m_icon_cb = new wxCheckBox(this, wxID_ANY, _("Copy the following icon into the project")); wxStaticText* warning = new wxStaticText(this, wxID_ANY, _("Warning : applying these changes cannot be undone automatically")); wxButton* okBtn = new wxButton(this, wxID_OK, _("Apply changes")); wxButton* cancelBtn = new wxButton(this, wxID_CANCEL, _("Cancel")); okBtn->SetDefault(); m_signature->SetMaxLength(4); m_info_plist_cb->SetValue(true); m_icon_cb->SetValue(true); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* subsizer = new wxBoxSizer(wxHORIZONTAL); wxFlexGridSizer* plistSizer = new wxFlexGridSizer(5, 2, 5, 5); plistSizer->AddGrowableCol(1, 1); plistSizer->Add(new wxStaticText(this, wxID_ANY, _("Get Info Version String")), 0, wxALIGN_RIGHT); plistSizer->Add(m_get_info_string, 1, wxEXPAND); plistSizer->Add(new wxStaticText(this, wxID_ANY, _("Version Number")), 0, wxALIGN_RIGHT); plistSizer->Add(m_version, 1, wxEXPAND); plistSizer->Add(new wxStaticText(this, wxID_ANY, _("Icon File")), 0, wxALIGN_RIGHT); plistSizer->Add(m_icon_file, 1, wxEXPAND); plistSizer->Add(new wxStaticText(this, wxID_ANY, _("Bundle Identifier")), 0, wxALIGN_RIGHT); plistSizer->Add(m_identifier, 1, wxEXPAND); plistSizer->Add(new wxStaticText(this, wxID_ANY, _("4-Character Signature")), 0, wxALIGN_RIGHT); plistSizer->Add(m_signature, 1, wxEXPAND); sizer->Add(titleLabel, 0, wxEXPAND | wxALL, 10); sizer->Add(m_choices_widget, 1, wxEXPAND | wxALL, 10); sizer->Add(m_info_plist_cb, 0, wxEXPAND | wxALL, 5); sizer->Add(plistSizer, 1, wxEXPAND | wxALL, 5); sizer->Add(m_icon_cb, 0, wxALL, 10); wxStaticBoxSizer* iconBox = new wxStaticBoxSizer(wxHORIZONTAL, this); m_icon_picker = new IconPicker(this); m_icon_picker->setImage( wxT("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns")); iconBox->Add(m_icon_picker, 1, wxEXPAND); sizer->Add(iconBox, 0, wxALL, 10); sizer->Add(warning, 0, wxEXPAND | wxALL, 10); subsizer->AddStretchSpacer(); subsizer->Add(cancelBtn, 0, wxLEFT | wxRIGHT, 5); subsizer->Add(okBtn, 0, wxLEFT | wxRIGHT, 5); sizer->Add(subsizer, 0, wxEXPAND | wxALL, 10); okBtn->Connect( okBtn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BundleConfigDialog::onOk), NULL, this); cancelBtn->Connect(cancelBtn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BundleConfigDialog::onCancel), NULL, this); m_info_plist_cb->Connect(m_info_plist_cb->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BundleConfigDialog::onPlistCheckboxPressed), NULL, this); this->SetSizerAndFit(sizer); this->Centre(); // Load last stored size & position from the configuration tool SetName("BundleConfigDialog"); WindowAttrManager::Load(this); }
bool CustomBuildRequest::DoUpdateCommand(IManager* manager, wxString& cmd, ProjectPtr proj, BuildConfigPtr bldConf, bool isClean) { BuildCommandList preBuildCmds, postBuildCmds; wxArrayString pre, post; bldConf->GetPreBuildCommands(preBuildCmds); bldConf->GetPostBuildCommands(postBuildCmds); // collect all enabled commands BuildCommandList::iterator iter = preBuildCmds.begin(); for(; iter != preBuildCmds.end(); iter++) { BuildCommand command = *iter; if(command.GetEnabled()) { pre.Add(command.GetCommand()); } } iter = postBuildCmds.begin(); for(; iter != postBuildCmds.end(); iter++) { BuildCommand command = *iter; if(command.GetEnabled()) { post.Add(command.GetCommand()); } } if(pre.empty() && post.empty()) { return false; } // we need to create a makefile which includes all the pre-build, the actual build command and the post-build // commands // (in this exact order). wxString script; script << ECHO_OFF << wxT("\n"); if(pre.IsEmpty() == false && !isClean) { script << ECHO_CMD << wxT("Executing Pre Build commands ...\n"); for(size_t i = 0; i < pre.GetCount(); i++) { script << SILENCE_OP << pre.Item(i) << wxT("\n"); } script << ECHO_CMD << wxT("Done\n"); } // add the command script << cmd << wxT("\n"); if(post.IsEmpty() == false && !isClean) { script << ECHO_CMD << wxT("Executing Post Build commands ...\n"); for(size_t i = 0; i < post.GetCount(); i++) { script << SILENCE_OP << post.Item(i) << wxT("\n"); } script << ECHO_CMD << wxT("Done\n"); } // write the makefile wxFFile output; wxString fn; fn << proj->GetName() << SCRIPT_EXT; output.Open(fn, wxT("w+")); if(output.IsOpened()) { output.Write(script); output.Close(); } cmd.Clear(); #ifdef __WXMSW__ cmd << wxT("\"") << fn << wxT("\""); #else // *nix cmd << wxT("/bin/sh './") << fn << wxT("'"); #endif return true; }
// 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; } }
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; } }