void ConfigManager::InitPaths() { ConfigManager::config_folder = ConfigManager::GetUserDataFolder(); ConfigManager::home_folder = wxStandardPathsBase::Get().GetUserConfigDir(); ConfigManager::app_path = ::DetermineExecutablePath(); wxString res_path = ::DetermineResourcesPath(); // if non-empty, the app has overriden it (e.g. "--prefix" was passed in the command line) if (data_path_global.IsEmpty()) { if (platform::windows) ConfigManager::data_path_global = app_path + _T("\\share\\codeblocks"); else if (platform::macosx) ConfigManager::data_path_global = res_path + _T("/share/codeblocks"); else ConfigManager::data_path_global = wxStandardPathsBase::Get().GetDataDir(); } else ConfigManager::data_path_global = UnixFilename(data_path_global); #ifdef CB_AUTOCONF if (plugin_path_global.IsEmpty()) { if (platform::windows || platform::macosx) ConfigManager::plugin_path_global = data_path_global; else { // It seems we can not longer rely on wxStandardPathsBase::Get().GetPluginsDir(), // because its behaviour has changed on some systems (at least Fedora 14 64-bit). // So we create the pathname manually ConfigManager::plugin_path_global = ((const wxStandardPaths&)wxStandardPaths::Get()).GetInstallPrefix() + _T("/lib/codeblocks/plugins"); // first assume, we use standard-paths if (!wxDirExists(ConfigManager::plugin_path_global) && wxIsPlatform64Bit()) { // if standard-path does not exist and we are on 64-bit system, use lib64 instead ConfigManager::plugin_path_global = ((const wxStandardPaths&)wxStandardPaths::Get()).GetInstallPrefix() + _T("/lib64/codeblocks/plugins"); } } } #endif wxString dataPathUser = ConfigManager::config_folder + wxFILE_SEP_PATH + _T("share"); #ifdef __linux__ if (!has_alternate_user_data_path) dataPathUser = wxString::FromUTF8(g_build_filename (g_get_user_data_dir(), NULL)); #endif // __linux__ ConfigManager::data_path_user = dataPathUser + wxFILE_SEP_PATH + _T("codeblocks"); CreateDirRecursively(ConfigManager::config_folder); CreateDirRecursively(ConfigManager::data_path_user + _T("/plugins/")); CreateDir(ConfigManager::data_path_user + _T("/scripts/")); ConfigManager::temp_folder = wxStandardPathsBase::Get().GetTempDir(); }
void NewFromTemplateDlg::EditScript(const wxString& filename) { if (filename.IsEmpty()) return; // edited before? bool first_time = false; wxString script = ConfigManager::GetFolder(sdDataUser) + _T("/templates/wizard/") + filename; if (!wxFileExists(script)) { first_time = true; script = ConfigManager::GetFolder(sdDataGlobal) + _T("/templates/wizard/") + filename; } cbEditor* ed = Manager::Get()->GetEditorManager()->Open(script); if (ed) { ed->GetControl()->SetFocus(); if (first_time) { // first time editing this script; change the filename to point to the user's dir ed->SetFilename(ConfigManager::GetFolder(sdDataUser) + _T("/templates/wizard/") + filename); ed->SetModified(true); // also make sure the destination directory exists CreateDirRecursively(ConfigManager::GetFolder(sdDataUser) + _T("/templates/wizard/") + filename); } EndModal(wxID_CANCEL); return; } cbMessageBox(_("Couldn't open script:\n") + script, _("Error"), wxICON_ERROR, this); }
void ConfigManager::InitPaths() { #ifdef __WINDOWS__ ConfigManager::config_folder = GetPortableConfigDir(); #else ConfigManager::config_folder = wxStandardPathsBase::Get().GetUserDataDir(); #endif ConfigManager::home_folder = wxStandardPathsBase::Get().GetUserConfigDir(); ConfigManager::app_path = ::DetermineExecutablePath(); wxString res_path = ::DetermineResourcesPath(); // if non-empty, the app has overriden it (e.g. "--prefix" was passed in the command line) if (data_path_global.IsEmpty()) { if(platform::windows) ConfigManager::data_path_global = app_path + _T("/share/codeblocks"); else if(platform::macosx) ConfigManager::data_path_global = res_path + _T("/share/codeblocks"); else ConfigManager::data_path_global = wxStandardPathsBase::Get().GetDataDir(); } #ifdef CB_AUTOCONF if (plugin_path_global.IsEmpty()) { if(platform::windows || platform::macosx) ConfigManager::plugin_path_global = data_path_global; else { ConfigManager::plugin_path_global = wxStandardPathsBase::Get().GetPluginsDir() + _T("/plugins"); // first assume, we use standard-paths if(!wxDirExists(ConfigManager::plugin_path_global) && wxIsPlatform64Bit()) { // if standard-path does not exist and we are on 64-bit system, use lib64 instead ConfigManager::plugin_path_global = ((const wxStandardPaths&)wxStandardPaths::Get()).GetInstallPrefix() + _T("/lib64/codeblocks/plugins"); } } } #endif ConfigManager::data_path_user = ConfigManager::relo ? data_path_global : config_folder + _T("/share/codeblocks"); CreateDirRecursively(ConfigManager::config_folder); CreateDirRecursively(ConfigManager::data_path_user + _T("/plugins/")); CreateDir(ConfigManager::data_path_user + _T("/scripts/")); ConfigManager::temp_folder = wxStandardPathsBase::Get().GetTempDir(); };
void UpdateDlg::InstallFile() { UpdateStatus(_("Please wait...")); UpdateRec* rec = GetRecFromListView(); if (!rec) { wxMessageBox(_("No file selected!"), _("Error"), wxICON_ERROR); UpdateStatus(_("Ready"), 0, 0); return; } wxYield(); if (rec->title == _T("WebUpdate Mirrors list")) { InstallMirrors(GetPackagePath() + rec->local_file); rec->installed = true; ApplyFilter(); UpdateStatus(_("Ready"), 0, 0); return; } else if (!rec->installable) { UpdateStatus(_("Ready"), 0, 0); return; } if (!CreateDirRecursively(GetPackagePath())) { UpdateStatus(_("Ready"), 0, 0); wxMessageBox(_("Can't create directory ") + GetPackagePath(), _("Error"), wxICON_ERROR); return; } wxArrayString files; DevPakInstaller inst; if (inst.Install(rec->name, GetPackagePath() + rec->local_file, GetBasePath(), &files)) { // wxFileName fname(GetPackagePath() + rec->local_file); // fname.SetExt("entry"); // fname.SetName(rec->title); // CreateEntryFile(rec, fname.GetFullPath(), files); CreateEntryFile(rec, GetPackagePath() + rec->entry, files); wxMessageBox(_("DevPak installed"), _("Message"), wxICON_INFORMATION); // refresh installed_version rec->installed = true; rec->installed_version = rec->version; SetListColumnText(-1, 2, rec->installed_version); } else { wxMessageBox(_("DevPak was not installed.\nStatus:\n") + inst.GetStatus(), _("Error"), wxICON_ERROR); } UpdateStatus(_("Ready"), 0, 0); }
bool ConfigManager::SetUserDataFolder(const wxString &user_data_path) { wxString udp = wxFileName::DirName(user_data_path).GetFullPath(); if (!CreateDirRecursively(udp)) { cbMessageBox(wxString::Format(_("The --user-data-dir directory %s does not exist and could not be created. Please check the path and try again"), user_data_path.c_str()), _("Command Line Error")); return false; } has_alternate_user_data_path = true; ConfigManager::alternate_user_data_path = udp; return true; }
void UpdateDlg::DownloadFile(bool dontInstall) { UpdateStatus(_("Please wait...")); UpdateRec* rec = GetRecFromListView(); if (!rec) { wxMessageBox(_("No file selected!"), _("Error"), wxICON_ERROR); UpdateStatus(_("Ready"), 0, 0); return; } if (rec->version == rec->installed_version) { if (wxMessageBox(_("You seem to have installed the latest version.\nAre you sure you want to proceed?"), _("Confirmation"), wxICON_QUESTION | wxYES_NO) == wxNO) return; } if (!CreateDirRecursively(GetPackagePath())) { wxMessageBox(_("Can't create directory ") + GetPackagePath(), _("Error"), wxICON_ERROR); return; } if (wxFileExists(GetPackagePath() + rec->local_file)) { if (wxMessageBox(_("This file already exists!\nAre you sure you want to download it again?"), _("Confirmation"), wxICON_QUESTION | wxYES_NO) == wxNO && rec->installable) { if (!dontInstall && wxMessageBox(_("Do you want to force-install it?"), _("Confirmation"), wxICON_QUESTION | wxYES_NO) == wxYES) InstallFile(); return; } } m_Net.SetServer(rec->remote_server); EnableButtons(false); if (!m_Net.DownloadFile(rec->remote_file, GetPackagePath() + rec->local_file)) { rec->downloaded = false; UpdateStatus(_("Error downloading file: ") + rec->remote_server + _T(" > ") + rec->remote_file, 0, 0); return; } else rec->downloaded = true; UpdateStatus(_("Ready"), 0, 0); EnableButtons(); }
void ConfigManager::MigrateFolders() { #ifdef __linux__ // if the old config-folder (~/.codeblocks) does not exist, we have nothing to do. if (!wxDirExists(wxStandardPaths::Get().GetUserDataDir())) return; // ConfigManager::config_folder might be the portable-path but we want to migrate the standard-conform folder, // but only if it not aöready exists wxString newConfigFolder = wxString::FromUTF8(g_build_filename (g_get_user_config_dir(), "codeblocks", NULL)); // if the new config folder already exist, we step out immediately if (wxDirExists(newConfigFolder)) return; wxString oldConfigFolder = wxStandardPaths::Get().GetUserDataDir(); wxString oldDataFolder = oldConfigFolder + wxFILE_SEP_PATH + _T("share") + wxFILE_SEP_PATH + _T("codeblocks"); wxString newDataFolder = wxString::FromUTF8(g_build_filename (g_get_user_data_dir(), NULL)) + wxFILE_SEP_PATH + _T("codeblocks"); wxString msg; msg = F(_("The places where the configuration files and user-data files are stored\n" "have been changed to be more standard-conform.\n" "\n" "Now moving \"%s\"\n" "to \"%s\"\n" "and \"%s\"\n" "to \"%s\".\n"), oldDataFolder.wx_str(), newDataFolder.wx_str(), oldConfigFolder.wx_str(), newConfigFolder.wx_str()); cbMessageBox(msg, _("Try to migrate config-folder ..."), wxICON_INFORMATION); bool success = true; if (wxDirExists(oldDataFolder)) { // make sure the target-folder exists CreateDirRecursively(newDataFolder); success = wxRenameFile(oldDataFolder, newDataFolder); wxRmdir(oldConfigFolder + wxFILE_SEP_PATH + _T("share")); } if (success) { // make sure the target-folder exists CreateDirRecursively(newConfigFolder); success = wxRenameFile(oldConfigFolder, newConfigFolder); } if (!success) { msg = F(_("Error moving \"%s\"\n" "to \"%s\"\n" "or \"%s\"\n" "to \"%s\".\n\n" "Please check the folders manually (access rights?) !\n" "A new configuration will be created from scratch!"), oldDataFolder.wx_str(), newDataFolder.wx_str(), oldConfigFolder.wx_str(), newConfigFolder.wx_str()); cbMessageBox(msg, _("Error migrating config-folder ..."), wxICON_ERROR); } #endif // __linux__ }
wxArrayString DirectCommands::GetTargetLinkCommands(ProjectBuildTarget* target, bool force) { wxArrayString ret; wxString output = target->GetOutputFilename(); Manager::Get()->GetMacrosManager()->ReplaceMacros(output, target); wxFileName out = UnixFilename(output); wxString linkfiles; wxString FlatLinkFiles; wxString resfiles; bool IsOpenWatcom = target->GetCompilerID().IsSameAs(_T("ow")); time_t outputtime; depsTimeStamp(output.mb_str(), &outputtime); if (!outputtime) force = true; if (AreExternalDepsOutdated(out.GetFullPath(), target->GetAdditionalOutputFiles(), target->GetExternalDeps())) force = true; Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler; wxString prependHack; // part of the following hack if (target->GetTargetType() == ttStaticLib) { // QUICK HACK: some linkers (e.g. bcc, dmc) require a - or + in front of // object files for static library. What we 'll do here until we redesign // the thing, is to accept this symbol as part of the $link_objects macro // like this: // $+link_objects // $-link_objects // $-+link_objects // $+-link_objects // // So, we first scan the command for this special case and, if found, // set a flag so that the linkfiles array is filled with the correct options wxString compilerCmd = compiler->GetCommand(ctLinkStaticCmd); wxRegEx re(_T("\\$([-+]+)link_objects")); if (re.Matches(compilerCmd)) prependHack = re.GetMatch(compilerCmd, 1); } // get all the linkable objects for the target MyFilesArray files = GetProjectFilesSortedByWeight(target, false, true); wxString allfile; if (files.GetCount() == 0) { ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking stage skipped (build target has no object files to link)")); return ret; } if (IsOpenWatcom && target->GetTargetType() != ttStaticLib) linkfiles << _T("file "); for (unsigned int i = 0; i < files.GetCount(); ++i) { ProjectFile* pf = files[i]; // we have to test again for each file if it is to be compiled // and we can't check the file for existence because we 're still // generating the command lines that will create the files... wxString macro = _T("$compiler"); if(m_pCompiler->GetParentID().Matches(_T("lcy"))) { if(pf->file.GetExt().Lower().IsSameAs(FileFilters::LD_EXT)) continue; } // allfile = allfile + _T(" ") + pf->GetObjName().BeforeLast(_T('.'))+_T('.')+pf->file.GetExt(); compiler->GenerateCommandLine(macro, target, pf, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString); if (macro.IsEmpty()) continue; const pfDetails& pfd = pf->GetFileDetails(target); wxString Object = (target->GetUseFlatObjects())?pfd.object_file_flat:pfd.object_file; if (FileTypeOf(pf->relativeFilename) == ftResource) { // ----------------------------------------- // Following lines have been modified for OpenWatcom if (IsOpenWatcom) resfiles << _T("option resource=") << Object << _T(" "); else resfiles << Object << _T(" "); // ------------------------------------------ } else { // ----------------------------------------- // Following lines have been modified for OpenWatcom if (IsOpenWatcom && target->GetTargetType() != ttStaticLib) { linkfiles << prependHack << Object << _T(","); // see QUICK HACK above (prependHack) FlatLinkFiles << prependHack << pfd.object_file_flat << _T(","); // see QUICK HACK above (prependHack) } else { linkfiles << prependHack << Object << _T(" "); // see QUICK HACK above (prependHack) FlatLinkFiles << prependHack << pfd.object_file_flat << _T(" "); // see QUICK HACK above (prependHack) } // ----------------------------------------- } // timestamp check if (!force) { time_t objtime; depsTimeStamp(pfd.object_file_native.mb_str(), &objtime); if (objtime > outputtime) force = true; } // Why was this here? // if(m_doYield) // Manager::Yield(); } if (IsOpenWatcom) { linkfiles.Trim(); if (linkfiles.Right(1).IsSameAs(_T(","))) linkfiles = linkfiles.BeforeLast(_T(',')); } if (!force) return ret; if(target->GetCompilerID().Lower().Matches(_T("dsp"))) /// 2012-8-29 lcy { // FlatLinkFiles.Replace(_T(".obj"),_T(".cln")); FlatLinkFiles.Replace(_T("\\"),_T(" ")); // linkfiles.Replace(_T(".obj"),_T(".cln")); linkfiles.Replace(_T("\\"),_T(" ")); } // create output dir out.MakeAbsolute(m_pProject->GetBasePath()); wxString dstname = out.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); Manager::Get()->GetMacrosManager()->ReplaceMacros(dstname, target); if (!dstname.IsEmpty() && !CreateDirRecursively(dstname, 0755)) { cbMessageBox(_("Can't create output directory ") + dstname); } // add actual link command wxString kind_of_output; CommandType ct = ctCount; // get rid of compiler warning switch (target->GetTargetType()) { case ttConsoleOnly: ct = ctLinkConsoleExeCmd; kind_of_output = _("console executable"); break; case ttExecutable: ct = ctLinkExeCmd; kind_of_output = _("executable"); break; case ttDynamicLib: ct = ctLinkDynamicCmd; kind_of_output = _("dynamic library"); break; case ttStaticLib: ct = ctLinkStaticCmd; kind_of_output = _("static library"); break; case ttNative: ct = ctLinkNativeCmd; kind_of_output = _("native"); break; case ttCommandsOnly: // add target post-build commands ret.Clear(); AppendArray(GetPostBuildCommands(target), ret); return ret; break; default: wxString ex; ex.Printf(_T("Encountered invalid TargetType (value = %d)"), target->GetTargetType()); cbThrow(ex); break; } wxString compilerCmd = compiler->GetCommand(ct); compiler->GenerateCommandLine(compilerCmd, target, 0, _T(""), linkfiles, FlatLinkFiles, resfiles); if(target->GetCompilerID().Lower().Matches(_T("dsp"))) /// 2012-8-29 lcy { compilerCmd.Replace(_("#allfile"),allfile); } if (!compilerCmd.IsEmpty()) { switch (compiler->GetSwitches().logging) { case clogFull: ret.Add(wxString(COMPILER_SIMPLE_LOG) + compilerCmd); break; default: // linker always simple log (if not full) ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking ") + kind_of_output + _T(": ") + output); break; } // for an explanation of the following, see GetTargetCompileCommands() if (target && ret.GetCount() != 0) ret.Add(wxString(COMPILER_TARGET_CHANGE) + target->GetTitle()); // the 'true' will make sure all commands will be prepended by // COMPILER_WAIT signal AddCommandsToArray(compilerCmd, ret, true, true); } else ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping linking (no linker program set): ") + output); return ret; }
wxArrayString DirectCommands::GetCompileFileCommand(ProjectBuildTarget* target, ProjectFile* pf) { wxArrayString ret; wxArrayString retGenerated; // is it compilable? if (!pf->compile || pf->compilerVar.IsEmpty()) return ret; const pfDetails& pfd = pf->GetFileDetails(target); Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler; // wxString Object = (compiler->GetSwitches().UseFlatObjects)?pfd.object_file_flat:pfd.object_file; wxString Object = (target->GetUseFlatObjects())?pfd.object_file_flat:pfd.object_file; // lookup file's type FileType ft = FileTypeOf(pf->relativeFilename); // create output dir if (!pfd.object_dir_native.IsEmpty() && !CreateDirRecursively(pfd.object_dir_native, 0755)) { cbMessageBox(_("Can't create object output directory ") + pfd.object_dir_native); } bool isResource = ft == ftResource; bool isHeader = ft == ftHeader; // allowed resources under all platforms: makes sense when cross-compiling for // windows under linux. // and anyway, if the user is dumb enough to try to compile resources without // having a resource compiler, (s)he deserves the upcoming build error ;) //#ifndef __WXMSW__ // // not supported under non-win32 platforms // if (isResource) // return ret; //#endif wxString compilerCmd,source_file,tempCompilerCmd(wxEmptyString); if (!isHeader || compiler->GetSwitches().supportsPCH) { const CompilerTool& tool = compiler->GetCompilerTool(isResource ? ctCompileResourceCmd : ctCompileObjectCmd, pf->file.GetExt()); // does it generate other files to compile? for (size_t i = 0; i < pf->generatedFiles.size(); ++i) { AppendArray(GetCompileFileCommand(target, pf->generatedFiles[i]), retGenerated); // recurse } pfCustomBuild& pcfb = pf->customBuild[compiler->GetID()]; compilerCmd = pcfb.useCustomBuildCommand ? pcfb.buildCommand : tool.command; if (target->GetUseFullSourcePaths()) { source_file = UnixFilename(pfd.source_file_absolute_native); // for resource files, use short from if path because if windres bug with spaces-in-paths if (isResource) source_file = pf->file.GetShortPath(); } else source_file = pfd.source_file; QuoteStringIfNeeded(source_file); compiler->GenerateCommandLine(compilerCmd, target, pf, source_file, Object, pfd.object_file_flat, pfd.dep_file); } if (!compilerCmd.IsEmpty()) // my lcy 1 { switch (compiler->GetSwitches().logging) { case clogFull: ret.Add(wxString(COMPILER_SIMPLE_LOG) + compilerCmd); break; case clogSimple: if (isHeader) ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Precompiling header: ") + pfd.source_file_native); else ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Compiling: ") + pfd.source_file_native); break; default: break; } AddCommandsToArray(compilerCmd, ret); if(m_pCurrTarget->GetGenerateEachLit()) AddCommandsToArray(GenerateLitForEachObj(Object,compiler->GetPrograms().OBJDUMP),ret); if (isHeader) ret.Add(wxString(COMPILER_WAIT)); if (retGenerated.GetCount()) { // not only append commands for (any) generated files to be compiled // but also insert a "pause" to allow this file to generate its files first if (!isHeader) // if isHeader, the "pause" has already been added ret.Add(wxString(COMPILER_WAIT)); AppendArray(retGenerated, ret); } // if it's a PCH, delete the previously generated PCH to avoid problems // (it 'll be recreated anyway) if (FileTypeOf(pf->relativeFilename) == ftHeader && pf->compile) { wxString ObjectAbs = (m_pCurrTarget->GetUseFlatObjects())?pfd.object_file_flat_absolute_native:pfd.object_file_absolute_native; wxRemoveFile(ObjectAbs); } } else // lcy skip { ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping file (no compiler program set): ") + pfd.source_file_native); } return ret; }
bool PluginManager::ExtractFile(const wxString& bundlename, const wxString& src_filename, const wxString& dst_filename, bool isMandatory) { // Manager::Get()->GetLogManager()->DebugLog(F(_T("ExtractFile:"))); // Manager::Get()->GetLogManager()->DebugLog(F(_T("Plugin filename: ") + bundlename)); // Manager::Get()->GetLogManager()->DebugLog(F(_T("Source filename: ") + src_filename)); // Manager::Get()->GetLogManager()->DebugLog(F(_T("Destination filename: ") + dst_filename)); // check if the destination file already exists if (wxFileExists(dst_filename) && !wxFile::Access(dst_filename, wxFile::write)) { // Manager::Get()->GetLogManager()->DebugLog(F(_T("Destination file in use"))); cbMessageBox(_("The destination file is in use.\nAborting..."), _("Warning"), wxICON_WARNING); return false; } // make sure destination dir exists CreateDirRecursively(wxFileName(dst_filename).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)); // actually extract file // Manager::Get()->GetLogManager()->DebugLog(F(_T("Extracting..."))); wxFileSystem* fs = new wxFileSystem; wxFSFile* f = fs->OpenFile(bundlename + _T("#zip:") + src_filename); if (f) { // open output file for writing wxFile output(dst_filename, wxFile::write); if (!output.IsOpened()) { // Manager::Get()->GetLogManager()->DebugLog(F(_T("Can't open destination file for writing"))); wxString msg = wxString::Format(_("Can't open destination file '%s' for writing..."), dst_filename.c_str()); cbMessageBox(msg, _("Error"), wxICON_ERROR); delete f; delete fs; return false; } // copy file wxInputStream* is = f->GetStream(); char tmp[1025] = {}; while (!is->Eof() && is->CanRead()) { memset(tmp, 0, sizeof(tmp)); is->Read(tmp, sizeof(tmp) - 1); output.Write(tmp, is->LastRead()); } delete f; // Manager::Get()->GetLogManager()->DebugLog(F(_T("Extracted"))); } else { // Manager::Get()->GetLogManager()->DebugLog(F(_T("File not found in plugin"))); if (isMandatory) { wxString msg = wxString::Format(_("File '%s' not found in plugin '%s'"), src_filename.c_str(), bundlename.c_str()); cbMessageBox(msg, _("Error"), wxICON_ERROR); delete fs; return false; } } delete fs; return true; }
wxArrayString DirectCommands::GetTargetLinkCommands(ProjectBuildTarget* target, bool force) const { wxArrayString ret; wxString output = target->GetOutputFilename(); Manager::Get()->GetMacrosManager()->ReplaceMacros(output, target); wxFileName out = UnixFilename(output); wxString linkfiles; wxString FlatLinkFiles; wxString resfiles; bool IsOpenWatcom = target->GetCompilerID().IsSameAs(_T("ow")); time_t outputtime; depsTimeStamp(output.mb_str(), &outputtime); if (!outputtime) force = true; wxArrayString fileMissing; if ( AreExternalDepsOutdated(target, out.GetFullPath(), &fileMissing) ) force = true; if (!fileMissing.IsEmpty()) { wxString warn; #ifdef NO_TRANSLATION warn.Printf(wxT("WARNING: Target '%s': Unable to resolve %lu external dependenc%s:"), target->GetFullTitle().wx_str(), static_cast<unsigned long>(fileMissing.Count()), wxString(fileMissing.Count() == 1 ? wxT("y") : wxT("ies")).wx_str()); #else warn.Printf(_("WARNING: Target '%s': Unable to resolve %lu external dependency/ies:"), target->GetFullTitle().wx_str(), static_cast<unsigned long>(fileMissing.Count())); #endif // NO_TRANSLATION ret.Add(COMPILER_WARNING_LOG + warn); for (size_t i = 0; i < fileMissing.Count(); ++i) ret.Add(COMPILER_NOTE_LOG + wxString(wxT(' '), 8) + fileMissing[i]); } Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler; wxString prependHack; // part of the following hack if (target->GetTargetType() == ttStaticLib) { // QUICK HACK: some linkers (e.g. bcc, dmc) require a - or + in front of // object files for static library. What we 'll do here until we redesign // the thing, is to accept this symbol as part of the $link_objects macro // like this: // $+link_objects // $-link_objects // $-+link_objects // $+-link_objects // // So, we first scan the command for this special case and, if found, // set a flag so that the linkfiles array is filled with the correct options wxString compilerCmd = compiler ? compiler->GetCommand(ctLinkStaticCmd) : wxString(wxEmptyString); wxRegEx re(_T("\\$([-+]+)link_objects")); if (re.Matches(compilerCmd)) prependHack = re.GetMatch(compilerCmd, 1); } // get all the linkable objects for the target MyFilesArray files = GetProjectFilesSortedByWeight(target, false, true); if (files.GetCount() == 0) { if (target->GetTargetType() != ttCommandsOnly) ret.Add(COMPILER_SIMPLE_LOG + _("Linking stage skipped (build target has no object files to link)")); return ret; } if (IsOpenWatcom && target->GetTargetType() != ttStaticLib) linkfiles << _T("file "); bool subseq(false); for (unsigned int i = 0; i < files.GetCount(); ++i) { ProjectFile* pf = files[i]; // we have to test again for each file if it is to be compiled // and we can't check the file for existence because we 're still // generating the command lines that will create the files... wxString macro = _T("$compiler"); m_pGenerator->GenerateCommandLine(macro, target, pf, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString); if (macro.IsEmpty()) continue; const pfDetails& pfd = pf->GetFileDetails(target); wxString Object = (compiler->GetSwitches().UseFlatObjects) ? pfd.object_file_flat : pfd.object_file; if (FileTypeOf(pf->relativeFilename) == ftResource) { if (subseq) resfiles << _T(" "); // ----------------------------------------- // Following lines have been modified for OpenWatcom if (IsOpenWatcom) resfiles << _T("option resource=") << Object; else resfiles << Object; // ------------------------------------------ } else { // ----------------------------------------- // Following lines have been modified for OpenWatcom if (IsOpenWatcom && target->GetTargetType() == ttStaticLib) { if (subseq) { linkfiles << _T(" "); FlatLinkFiles << _T(" "); } linkfiles << prependHack << Object; // see QUICK HACK above (prependHack) FlatLinkFiles << prependHack << pfd.object_file_flat; // see QUICK HACK above (prependHack) } else { if (subseq) { linkfiles << compiler->GetSwitches().objectSeparator; FlatLinkFiles << compiler->GetSwitches().objectSeparator; } linkfiles << prependHack << Object; // see QUICK HACK above (prependHack) FlatLinkFiles << prependHack << pfd.object_file_flat; // see QUICK HACK above (prependHack) } // ----------------------------------------- } subseq = true; // timestamp check if (!force) { time_t objtime; depsTimeStamp(pfd.object_file_native.mb_str(), &objtime); // Honor compiler request to Use Flat Objects // (Settings/compiler/otherSettings/advancedOptions/Others/UseFlatObjects) if (compiler->GetSwitches().UseFlatObjects) depsTimeStamp(pfd.object_file_flat.mb_str(), &objtime); if (!objtime) force = true; if (objtime > outputtime) force = true; } } if (IsOpenWatcom) { linkfiles.Trim(); } if (!force) return ret; // create output dir out.MakeAbsolute(m_pProject->GetBasePath()); wxString dstname = out.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); Manager::Get()->GetMacrosManager()->ReplaceMacros(dstname, target); if (!dstname.IsEmpty() && !CreateDirRecursively(dstname, 0755)) { cbMessageBox(_("Can't create output directory ") + dstname); } // add actual link command wxString kind_of_output; CommandType ct = ctCount; // get rid of compiler warning switch (target->GetTargetType()) { case ttConsoleOnly: ct = ctLinkConsoleExeCmd; kind_of_output = _("console executable"); break; case ttExecutable: ct = ctLinkExeCmd; kind_of_output = _("executable"); break; case ttDynamicLib: ct = ctLinkDynamicCmd; kind_of_output = _("dynamic library"); break; case ttStaticLib: ct = ctLinkStaticCmd; kind_of_output = _("static library"); break; case ttNative: ct = ctLinkNativeCmd; kind_of_output = _("native"); break; case ttCommandsOnly: // add target post-build commands ret.Clear(); AppendArray(GetPostBuildCommands(target), ret); return ret; break; default: wxString ex; ex.Printf(_T("Encountered invalid TargetType (value = %d)"), target->GetTargetType()); cbThrow(ex); break; } wxString compilerCmd = compiler->GetCommand(ct); m_pGenerator->GenerateCommandLine(compilerCmd, target, 0, _T(""), linkfiles, FlatLinkFiles, resfiles); if (!compilerCmd.IsEmpty()) { switch (compiler->GetSwitches().logging) { case clogFull: ret.Add(COMPILER_SIMPLE_LOG + compilerCmd); break; case clogSimple: // fall-through case clogNone: // fall-through default: // linker always simple log (if not full) ret.Add(COMPILER_SIMPLE_LOG + _("Linking ") + kind_of_output + _T(": ") + output); break; } // for an explanation of the following, see GetTargetCompileCommands() if (target && ret.GetCount() != 0) ret.Add(COMPILER_TARGET_CHANGE + target->GetTitle()); // the 'true' will make sure all commands will be prepended by // COMPILER_WAIT signal AddCommandsToArray(compilerCmd, ret, true, true); } else ret.Add(COMPILER_SIMPLE_LOG + _("Skipping linking (no linker program set): ") + output); return ret; }
wxArrayString DirectCommands::GetCompileFileCommand(ProjectBuildTarget* target, ProjectFile* pf) const { wxArrayString ret; wxArrayString ret_generated; // is it compilable? if (!pf || !pf->compile) return ret; if (pf->compilerVar.IsEmpty()) { Manager::Get()->GetLogManager()->DebugLog(_("Cannot resolve compiler var for project file.")); return ret; } Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler; if (!compiler) { Manager::Get()->GetLogManager()->DebugLog(_("Can't access compiler for file.")); return ret; } const pfDetails& pfd = pf->GetFileDetails(target); wxString object = (compiler->GetSwitches().UseFlatObjects) ? pfd.object_file_flat : pfd.object_file; wxString object_dir = (compiler->GetSwitches().UseFlatObjects) ? pfd.object_dir_flat_native : pfd.object_dir_native; // create output dir if (!object_dir.IsEmpty() && !CreateDirRecursively(object_dir, 0755)) Manager::Get()->GetLogManager()->DebugLog(_("Can't create object output directory:\n") + object_dir); // lookup file's type const FileType ft = FileTypeOf(pf->relativeFilename); bool is_resource = ft == ftResource; bool is_header = ft == ftHeader; // allowed resources under all platforms: makes sense when cross-compiling for // windows under linux. // and anyway, if the user is dumb enough to try to compile resources without // having a resource compiler, (s)he deserves the upcoming build error ;) wxString compiler_cmd; if (!is_header || compiler->GetSwitches().supportsPCH) { const CompilerTool* tool = compiler->GetCompilerTool(is_resource ? ctCompileResourceCmd : ctCompileObjectCmd, pf->file.GetExt()); // does it generate other files to compile? for (size_t i = 0; i < pf->generatedFiles.size(); ++i) AppendArray(GetCompileFileCommand(target, pf->generatedFiles[i]), ret_generated); // recurse pfCustomBuild& pcfb = pf->customBuild[compiler->GetID()]; if (pcfb.useCustomBuildCommand) compiler_cmd = pcfb.buildCommand; else if (tool) compiler_cmd = tool->command; else compiler_cmd = wxEmptyString; wxString source_file; if (compiler->GetSwitches().UseFullSourcePaths) source_file = UnixFilename(pfd.source_file_absolute_native); else source_file = pfd.source_file; #ifdef command_line_generation Manager::Get()->GetLogManager()->DebugLog(F(_T("GetCompileFileCommand[1]: compiler_cmd='%s', source_file='%s', object='%s', object_dir='%s'."), compiler_cmd.wx_str(), source_file.wx_str(), object.wx_str(), object_dir.wx_str())); #endif // for resource files, use short from if path because if windres bug with spaces-in-paths if (is_resource && compiler->GetSwitches().UseFullSourcePaths) source_file = pf->file.GetShortPath(); QuoteStringIfNeeded(source_file); #ifdef command_line_generation Manager::Get()->GetLogManager()->DebugLog(F(_T("GetCompileFileCommand[2]: source_file='%s'."), source_file.wx_str())); #endif m_pGenerator->GenerateCommandLine(compiler_cmd, target, pf, source_file, object, pfd.object_file_flat, pfd.dep_file); } if (!is_header && compiler_cmd.IsEmpty()) { ret.Add(COMPILER_SIMPLE_LOG + _("Skipping file (no compiler program set): ") + pfd.source_file_native ); return ret; } switch (compiler->GetSwitches().logging) { case clogFull: ret.Add(COMPILER_SIMPLE_LOG + compiler_cmd); break; case clogSimple: if (is_header) ret.Add(COMPILER_SIMPLE_LOG + _("Pre-compiling header: ") + pfd.source_file_native ); else ret.Add(COMPILER_SIMPLE_LOG + _("Compiling: ") + pfd.source_file_native ); break; case clogNone: // fall-through default: break; } AddCommandsToArray(compiler_cmd, ret); if (is_header) ret.Add(COMPILER_WAIT); if (ret_generated.GetCount()) { // not only append commands for (any) generated files to be compiled // but also insert a "pause" to allow this file to generate its files first if (!is_header) // if is_header, the "pause" has already been added ret.Add(COMPILER_WAIT); AppendArray(ret_generated, ret); } // if it's a PCH, delete the previously generated PCH to avoid problems // (it 'll be recreated anyway) if ( (ft == ftHeader) && pf->compile ) { wxString object_abs = (compiler->GetSwitches().UseFlatObjects) ? pfd.object_file_flat_absolute_native : pfd.object_file_absolute_native; if ( wxFileExists(object_abs) && !wxRemoveFile(object_abs) ) Manager::Get()->GetLogManager()->DebugLog(_("Cannot remove old PCH file:\n") + object_abs); } return ret; }
void TemplateManager::SaveUserTemplate(cbProject* prj) { if (!prj) return; // save project & all files if (!prj->SaveAllFiles() || !prj->Save()) { cbMessageBox(_("Could not save project and/or all its files. Aborting..."), _("Error"), wxICON_ERROR); return; } // create destination dir wxString templ = ConfigManager::GetConfigFolder() + wxFILE_SEP_PATH + _T("UserTemplates"); if (!CreateDirRecursively(templ, 0755)) { cbMessageBox(_("Couldn't create directory for user templates:\n") + templ, _("Error"), wxICON_ERROR); return; } // check if it exists and ask a different title wxString title = prj->GetTitle(); while (true) { // ask for template title (unique) wxTextEntryDialog dlg(0, _("Enter a title for this template"), _("Enter title"), title); PlaceWindow(&dlg); if (dlg.ShowModal() != wxID_OK) return; title = dlg.GetValue(); if (!wxDirExists(templ + wxFILE_SEP_PATH + title)) { templ << wxFILE_SEP_PATH << title; wxMkdir(templ, 0755); break; } else cbMessageBox(_("You have another template with the same title.\nPlease choose another title...")); } wxBusyCursor busy; // copy project and all files to destination dir int count = 0; int total_count = prj->GetFilesCount(); templ << wxFILE_SEP_PATH; wxFileName fname; for (int i = 0; i < total_count; ++i) { wxString src = prj->GetFile(i)->file.GetFullPath(); wxString dst = templ + prj->GetFile(i)->relativeToCommonTopLevelPath; #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(F(_T("Copying %s to %s"), src.wx_str(), dst.wx_str())); #else Manager::Get()->GetLogManager()->DebugLog(F(_T("Copying %s to %s"), src.c_str(), dst.c_str())); #endif if (!CreateDirRecursively(dst)) Manager::Get()->GetLogManager()->DebugLog(_T("Failed creating directory for ") + dst); if (wxCopyFile(src, dst, true)) ++count; else #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(F(_T("Failed copying %s to %s"), src.wx_str(), dst.wx_str())); #else Manager::Get()->GetLogManager()->DebugLog(F(_T("Failed copying %s to %s"), src.c_str(), dst.c_str())); #endif } // cbProject doesn't have a GetRelativeToCommonTopLevelPath() function, so we simulate it here // to find out the real destination file to create... wxString topLevelPath = prj->GetCommonTopLevelPath(); fname.Assign(prj->GetFilename()); fname.MakeRelativeTo(topLevelPath); fname.Assign(templ + fname.GetFullPath()); if (!CreateDirRecursively(fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), 0755)) { cbMessageBox(_("Failed to create the directory for the project file!"), _("Error"), wxICON_ERROR); ++count; } else { if (!wxCopyFile(prj->GetFilename(), fname.GetFullPath())) { Manager::Get()->GetLogManager()->DebugLog(_T("Failed to copy the project file: ") + fname.GetFullPath()); cbMessageBox(_("Failed to copy the project file!"), _("Error"), wxICON_ERROR); ++count; } } if (count == total_count) cbMessageBox(_("User-template saved successfully"), _("Information"), wxICON_INFORMATION | wxOK); else cbMessageBox(_("Some files could not be saved with the template..."), _("Error"), wxICON_ERROR); }
cbProject* TemplateManager::NewProjectFromUserTemplate(NewFromTemplateDlg& dlg, wxString* pFilename) { cbProject* prj = NULL; if (!dlg.SelectedUserTemplate()) { Manager::Get()->GetLogManager()->DebugLog(_T("TemplateManager::NewProjectFromUserTemplate() called when no user template was selected ?!?")); return NULL; } wxString path = Manager::Get()->GetConfigManager(_T("template_manager"))->Read(_T("/projects_path")); wxString sep = wxFileName::GetPathSeparator(); // select directory to copy user template files path = ChooseDirectory(0, _("Choose a directory to create the new project"), path, _T(""), false, true); if (path.IsEmpty()) { return NULL; } else if(path.Mid(path.Length() - 1) == wxFILE_SEP_PATH) { path.RemoveLast(); } // check for existing files; if found, notify about overwriting them wxDir dir(path); if (dir.HasFiles() || dir.HasSubDirs()) { if (cbMessageBox(path + _(" already contains other files.\n" "If you continue, files with the same names WILL BE OVERWRITTEN.\n" "Are you sure you want to continue?"), _("Files exist in directory"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT) != wxID_YES) { return 0; } } wxBusyCursor busy; wxString templ = ConfigManager::GetConfigFolder() + wxFILE_SEP_PATH + _T("UserTemplates"); templ << sep << dlg.GetSelectedUserTemplate(); if (!wxDirExists(templ)) { #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(F(_T("Cannot open user-template source path '%s'!"), templ.wx_str())); #else Manager::Get()->GetLogManager()->DebugLog(F(_T("Cannot open user-template source path '%s'!"), templ.c_str())); #endif return NULL; } // copy files wxString project_filename; wxArrayString files; wxDir::GetAllFiles(templ, &files); int count = 0; int total_count = files.GetCount(); for (size_t i = 0; i < files.GetCount(); ++i) { wxFileName dstname(files[i]); dstname.MakeRelativeTo(templ + sep); wxString src = files[i]; wxString dst = path + sep + dstname.GetFullPath(); // Manager::Get()->GetLogManager()->DebugLog("dst=%s, dstname=%s", dst.c_str(), dstname.GetFullPath().c_str()); if (!CreateDirRecursively(dst)) Manager::Get()->GetLogManager()->DebugLog(_T("Failed creating directory for ") + dst); if (wxCopyFile(src, dst, true)) { if (FileTypeOf(dst) == ftCodeBlocksProject) project_filename = dst; ++count; } else #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(F(_T("Failed copying %s to %s"), src.wx_str(), dst.wx_str())); #else Manager::Get()->GetLogManager()->DebugLog(F(_T("Failed copying %s to %s"), src.c_str(), dst.c_str())); #endif } if (count != total_count) cbMessageBox(_("Some files could not be loaded with the template..."), _("Error"), wxICON_ERROR); else { // open new project if (project_filename.IsEmpty()) cbMessageBox(_("User-template saved successfully but no project file exists in it!")); else { // ask to rename the project file, if need be wxFileName fname(project_filename); wxString newname = wxGetTextFromUser(_("If you want, you can change the project's filename here (without extension):"), _("Change project's filename"), fname.GetName()); if (!newname.IsEmpty() && newname != fname.GetName()) { fname.SetName(newname); wxRenameFile(project_filename, fname.GetFullPath()); project_filename = fname.GetFullPath(); } prj = Manager::Get()->GetProjectManager()->LoadProject(project_filename); if(prj && !newname.IsEmpty()) { prj->SetTitle(newname); for (int i = 0; i < prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* bt = prj->GetBuildTarget(i); wxString outputFileName = bt->GetOutputFilename(); wxFileName outFname(outputFileName); if (bt->GetTargetType() == ttLibrary) { Compiler* projectCompiler = CompilerFactory::GetCompiler(bt->GetCompilerID()); if (projectCompiler) newname.Prepend(projectCompiler->GetSwitches().libPrefix); } outFname.SetName(newname); bt->SetOutputFilename(outFname.GetFullPath()); } Manager::Get()->GetProjectManager()->RebuildTree(); // so the tree shows the new name CodeBlocksEvent evt(cbEVT_PROJECT_OPEN, 0, prj); Manager::Get()->ProcessEvent(evt); } } } if (prj && pFilename) *pFilename = prj->GetFilename(); return prj; }