void CompileOptionsBase::RemoveLibDir(const wxString& option) { wxString entry = UnixFilename(option); int idx = m_LibDirs.Index(entry, case_sensitive); if (idx != wxNOT_FOUND) { m_LibDirs.RemoveAt(idx); SetModified(true); } }
void CompileOptionsBase::RemoveBuildScript(const wxString& script) { wxString envopt = UnixFilename(script); int idx = m_Scripts.Index(envopt, case_sensitive); if (idx != wxNOT_FOUND) { m_Scripts.RemoveAt(idx); SetModified(true); } }
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(); }
// class constructor PipedProcess::PipedProcess(void** pvThis, wxEvtHandler* parent, int id, bool pipe, const wxString& dir) : wxProcess(parent, id), m_Parent(parent), m_Id(id), m_Pid(0), m_pvThis(pvThis) { wxSetWorkingDirectory(UnixFilename(dir)); if (pipe) Redirect(); }
// class constructor PipedProcess::PipedProcess(PipedProcess** pvThis, wxEvtHandler* parent, int id, bool pipe, const wxString& dir) : wxProcess(parent, id), m_Parent(parent), m_Id(id), m_Pid(0), m_pvThis(pvThis) { const wxString &unixDir = UnixFilename(dir); if (!unixDir.empty()) wxSetWorkingDirectory(unixDir); if (pipe) Redirect(); }
void CompileTargetBase::SetImportLibraryFilename(const wxString& filename) { if (filename.IsEmpty()) { m_ImportLibraryFilename = _T("$(TARGET_NAME)"); SetModified(true); return; } else if (m_ImportLibraryFilename == filename) return; m_ImportLibraryFilename = UnixFilename(filename); }
void CompileTargetBase::SetOutputFilename(const wxString& filename) { if (filename.IsEmpty()) { m_OutputFilename = SuggestOutputFilename(); SetModified(true); return; } else if (m_OutputFilename == filename) return; m_OutputFilename = UnixFilename(filename); GenerateTargetFilename(m_OutputFilename); SetModified(true); }
wxString ParserBase::FindFirstFileInIncludeDirs(const wxString& file) { wxString FirstFound = m_GlobalIncludes.GetItem(file); if (FirstFound.IsEmpty()) { wxArrayString FoundSet = FindFileInIncludeDirs(file,true); if (FoundSet.GetCount()) { FirstFound = UnixFilename(FoundSet[0]); m_GlobalIncludes.AddItem(file, FirstFound); } } return FirstFound; }
void CompileOptionsBase::SetBuildScripts(const wxArrayString& scripts) { if (m_Scripts == scripts) return; // make sure we don't have duplicate entries // that's why we don't assign the array but rather copy it entry by entry... m_Scripts.Clear(); for (size_t i = 0; i < scripts.GetCount(); ++i) { wxString entry = UnixFilename(scripts[i]); if (m_Scripts.Index(entry, case_sensitive) == wxNOT_FOUND) m_Scripts.Add(entry); } SetModified(true); }
bool Parser::RemoveFile(const wxString& filename) { TRACK_THREAD_LOCKER(s_TokensTreeCritical); wxCriticalSectionLocker locker(s_TokensTreeCritical); THREAD_LOCKER_SUCCESS(s_TokensTreeCritical); size_t index = m_TokensTree->GetFileIndex(UnixFilename(filename)); const bool result = m_TokensTree->m_FilesStatus.count(index); m_TokensTree->RemoveFile(filename); m_TokensTree->m_FilesMap.erase(index); m_TokensTree->m_FilesStatus.erase(index); m_TokensTree->m_FilesToBeReparsed.erase(index); m_TokensTree->m_Modified = true; return result; }
wxString CompileTargetBase::SuggestOutputFilename() { wxString suggestion; switch (m_TargetType) { case ttConsoleOnly: // fall through case ttExecutable: suggestion = GetExecutableFilename(); break; case ttDynamicLib: suggestion = GetDynamicLibFilename(); break; case ttStaticLib: suggestion = GetStaticLibFilename(); break; case ttNative: suggestion = GetNativeFilename(); break; default: suggestion.Clear(); break; } wxFileName fname(suggestion); return UnixFilename(fname.GetFullName()); }
bool Parser::AddFile(const wxString& filename, cbProject* project, bool isLocal) { if (project != m_Project) return false; wxString file = UnixFilename(filename); if (IsFileParsed(file)) return false; if (m_ParsingType == ptUndefined) m_ParsingType = ptAddFileToParser; AddParse(file); if (project) m_NeedMarkFileAsLocal = true; return true; }
bool ScriptingManager::LoadBuffer(const wxString& buffer, const wxString& debugName) { // includes guard to avoid recursion wxString incName = UnixFilename(debugName); if (m_IncludeSet.find(incName) != m_IncludeSet.end()) { Manager::Get()->GetLogManager()->LogWarning(F(_T("Ignoring Include(\"%s\") because it would cause recursion..."), incName.wx_str())); return true; } m_IncludeSet.insert(incName); // wxCriticalSectionLocker c(cs); s_ScriptErrors.Clear(); // compile script SquirrelObject script; try { script = SquirrelVM::CompileBuffer(cbU2C(buffer), cbU2C(debugName)); } catch (SquirrelError e) { cbMessageBox(wxString::Format(_T("Filename: %s\nError: %s\nDetails: %s"), debugName.c_str(), cbC2U(e.desc).c_str(), s_ScriptErrors.c_str()), _("Script compile error"), wxICON_ERROR); m_IncludeSet.erase(incName); return false; } // run script try { SquirrelVM::RunScript(script); } catch (SquirrelError e) { cbMessageBox(wxString::Format(_T("Filename: %s\nError: %s\nDetails: %s"), debugName.c_str(), cbC2U(e.desc).c_str(), s_ScriptErrors.c_str()), _("Script run error"), wxICON_ERROR); m_IncludeSet.erase(incName); return false; } m_IncludeSet.erase(incName); return true; }
size_t ParserBase::FindTokensInFile(const wxString& fileName, TokenIdxSet& result, short int kindMask) { result.clear(); wxString file = UnixFilename(fileName); TRACE(_T("Parser::FindTokensInFile() : Searching for file '%s' in tokens tree..."), file.wx_str()); TRACK_THREAD_LOCKER(s_TokensTreeCritical); wxCriticalSectionLocker locker(s_TokensTreeCritical); THREAD_LOCKER_SUCCESS(s_TokensTreeCritical); TokenIdxSet tmpresult; if ( !m_TokensTree->FindTokensInFile(file, tmpresult, kindMask) ) return 0; for (TokenIdxSet::iterator it = tmpresult.begin(); it != tmpresult.end(); ++it) { Token* token = m_TokensTree->at(*it); if (token) result.insert(*it); } return result.size(); }
void PluginsConfigurationDlg::FillList() { wxListCtrl* list = XRCCTRL(*this, "lstPlugins", wxListCtrl); if (list->GetColumnCount() == 0) { list->InsertColumn(0, _T("Title")); list->InsertColumn(1, _T("Version")); list->InsertColumn(2, _T("Enabled"), wxLIST_FORMAT_CENTER); list->InsertColumn(3, _T("Filename")); } PluginManager* man = Manager::Get()->GetPluginManager(); const PluginElementsArray& plugins = man->GetPlugins(); // populate Plugins checklist list->DeleteAllItems(); for (unsigned int i = 0; i < plugins.GetCount(); ++i) { const PluginElement* elem = plugins[i]; long idx = list->InsertItem(i, elem->info.title); list->SetItem(idx, 1, elem->info.version); list->SetItem(idx, 2, elem->plugin->IsAttached() ? _("Yes") : _("No")); list->SetItem(idx, 3, UnixFilename(elem->fileName)); list->SetItemData(idx, (long)elem); if (!elem->plugin->IsAttached()) list->SetItemTextColour(idx, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); else list->SetItemTextColour(idx, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); } list->SetColumnWidth(0, wxLIST_AUTOSIZE); list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER); list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER); list->SetColumnWidth(3, wxLIST_AUTOSIZE); list->SortItems(sortByTitle, 0); }
void MSVC10Loader::SetConfigurationValuesPath(const TiXmlElement* root, const char* key, size_t target, const wxString& defconfig, wxString* globaltarget) { wxString config; for (const TiXmlElement* e=root->FirstChildElement(key); e; e=e->NextSiblingElement(key)) { if (!GetConfigurationName(e,config,defconfig)) continue; wxString* value; if (config.IsEmpty()) { if (!globaltarget) continue; value = globaltarget; } else value = (wxString*)((char*)&m_pc[config]+target); *value = UnixFilename(GetText(e)); if ((*value).Last()!=wxFILE_SEP_PATH) *value += wxFILE_SEP_PATH; } }
bool Parser::IsFileParsed(const wxString& filename) { bool isParsed = false; { TRACK_THREAD_LOCKER(s_TokensTreeCritical); wxCriticalSectionLocker locker(s_TokensTreeCritical); THREAD_LOCKER_SUCCESS(s_TokensTreeCritical); isParsed = m_TokensTree->IsFileParsed(UnixFilename(filename)); } if (!isParsed) { TRACK_THREAD_LOCKER(s_ParserCritical); wxCriticalSectionLocker locker(s_ParserCritical); THREAD_LOCKER_SUCCESS(s_ParserCritical); StringList::iterator it = std::find(m_BatchParseFiles.begin(), m_BatchParseFiles.end(), filename); isParsed = it != m_BatchParseFiles.end(); } return isParsed; }
/** external deps are manually set by the user * e.g. a static library linked to the project is an external dep (if set as such by the user) * so that a re-linking is forced if the static lib is updated */ bool DirectCommands::AreExternalDepsOutdated(ProjectBuildTarget* target, const wxString& buildOutput, wxArrayString* filesMissing) const { Compiler* compiler = CompilerFactory::GetCompiler(target->GetCompilerID()); // if no output, probably a commands-only target; nothing to relink // but we have to check other dependencies time_t timeOutput = 0; if (!buildOutput.IsEmpty()) { wxString output = buildOutput; Manager::Get()->GetMacrosManager()->ReplaceMacros(output); depsTimeStamp(output.mb_str(), &timeOutput); // if build output exists, check for updated static libraries if (timeOutput) { // look for static libraries in target/project library dirs wxArrayString libs = target->GetLinkLibs(); const wxArrayString& prjLibs = target->GetParentProject()->GetLinkLibs(); const wxArrayString& cmpLibs = compiler->GetLinkLibs(); AppendArray(prjLibs, libs); AppendArray(cmpLibs, libs); const wxArrayString& prjLibDirs = target->GetParentProject()->GetLibDirs(); const wxArrayString& cmpLibDirs = compiler->GetLibDirs(); wxArrayString libDirs = target->GetLibDirs(); AppendArray(prjLibDirs, libDirs); AppendArray(cmpLibDirs, libDirs); for (size_t i = 0; i < libs.GetCount(); ++i) { wxString lib = libs[i]; // if user manually pointed to a library, without using the lib dirs, // then just check the file directly w/out involving the search dirs... if (lib.Contains(_T("/")) || lib.Contains(_T("\\"))) { Manager::Get()->GetMacrosManager()->ReplaceMacros(lib, target); lib = UnixFilename(lib); time_t timeExtDep; depsTimeStamp(lib.mb_str(), &timeExtDep); if (timeExtDep > timeOutput) { // force re-link Manager::Get()->GetLogManager()->DebugLog(F(_T("Forcing re-link of '%s/%s' because '%s' is newer"), target->GetParentProject()->GetTitle().wx_str(), target->GetTitle().wx_str(), lib.wx_str())); return true; } continue; } if (!lib.StartsWith(compiler->GetSwitches().libPrefix)) lib = compiler->GetSwitches().libPrefix + lib; if (!lib.EndsWith(_T(".") + compiler->GetSwitches().libExtension)) lib += _T(".") + compiler->GetSwitches().libExtension; for (size_t l = 0; l < libDirs.GetCount(); ++l) { wxString dir = libDirs[l] + wxFILE_SEP_PATH + lib; Manager::Get()->GetMacrosManager()->ReplaceMacros(dir, target); dir = UnixFilename(dir); time_t timeExtDep; depsTimeStamp(dir.mb_str(), &timeExtDep); if (timeExtDep > timeOutput) { // force re-link Manager::Get()->GetLogManager()->DebugLog(F(_T("Forcing re-link of '%s/%s' because '%s' is newer"), target->GetParentProject()->GetTitle().wx_str(), target->GetTitle().wx_str(), dir.wx_str())); return true; } } } } } // array is separated by ; wxArrayString extDeps = GetArrayFromString(target->GetExternalDeps(), _T(";")); wxArrayString addFiles = GetArrayFromString(target->GetAdditionalOutputFiles(), _T(";")); for (size_t i = 0; i < extDeps.GetCount(); ++i) { if (extDeps[i].IsEmpty()) continue; Manager::Get()->GetMacrosManager()->ReplaceMacros(extDeps[i]); time_t timeExtDep; depsTimeStamp(extDeps[i].mb_str(), &timeExtDep); // if external dep doesn't exist, no need to relink // but we have to check other dependencies if (!timeExtDep) { if (filesMissing) filesMissing->Add(extDeps[i]); continue; } // let's check the additional output files for (size_t j = 0; j < addFiles.GetCount(); ++j) { if (addFiles[j].IsEmpty()) continue; Manager::Get()->GetMacrosManager()->ReplaceMacros(addFiles[j]); time_t timeAddFile; depsTimeStamp(addFiles[j].mb_str(), &timeAddFile); // if additional file doesn't exist, we can skip it if (!timeAddFile) { if (filesMissing) filesMissing->Add(addFiles[j]); continue; } // if external dep is newer than additional file, relink if (timeExtDep > timeAddFile) return true; } // if no output, probably a commands-only target; nothing to relink // but we have to check other dependencies if (buildOutput.IsEmpty()) continue; // now check the target's output // this is moved last because, for "commands only" targets, // it would return before we had a chance to check the // additional output files (above) // if build output doesn't exist, relink if (!timeOutput) return true; // if external dep is newer than build output, relink if (timeExtDep > timeOutput) return true; } return false; // no force relink }
bool MSVC7WorkspaceLoader::Open(const wxString& filename, wxString& Title) { bool askForCompiler = false; bool askForTargets = false; switch (cbMessageBox(_("Do you want the imported projects to use the default compiler?\n" "(If you answer No, you will be asked for each and every project" " which compiler to use...)"), _("Question"), wxICON_QUESTION | wxYES_NO | wxCANCEL)) { case wxID_YES: askForCompiler = false; break; case wxID_NO: askForCompiler = true; break; case wxID_CANCEL: return false; } switch (cbMessageBox(_("Do you want to import all configurations (e.g. Debug/Release) from the " "imported projects?\n" "(If you answer No, you will be asked for each and every project" " which configurations to import...)"), _("Question"), wxICON_QUESTION | wxYES_NO | wxCANCEL)) { case wxID_YES: askForTargets = false; break; case wxID_NO: askForTargets = true; break; case wxID_CANCEL: return false; } wxFileInputStream file(filename); if (!file.Ok()) return false; // error opening file??? wxArrayString comps; wxTextInputStream input(file); // read "header" if (!file.Eof()) { // skip unicode BOM, if present EncodingDetector detector(filename); if (detector.IsOK() && detector.UsesBOM()) { int skipBytes = detector.GetBOMSizeInBytes(); for (int i = 0; i < skipBytes; ++i) { char c; file.Read(&c, 1); } } wxString line = input.ReadLine(); // skip initial empty lines (if any) while (line.IsEmpty() && !file.Eof()) { line = input.ReadLine(); } comps = GetArrayFromString(line, _T(",")); line = comps[0]; line.Trim(true); line.Trim(false); if (line != _T("Microsoft Visual Studio Solution File")) { Manager::Get()->GetLogManager()->DebugLog(_T("Unsupported format.")); return false; } line = comps.GetCount() > 1 ? comps[1] : wxString(wxEmptyString); line.Trim(true); line.Trim(false); wxString _version = line.AfterLast(' '); // want the version number if ((_version != _T("7.00")) && (_version != _T("8.00"))) Manager::Get()->GetLogManager()->DebugLog(_T("Version not recognized. Will try to parse though...")); } ImportersGlobals::UseDefaultCompiler = !askForCompiler; ImportersGlobals::ImportAllTargets = !askForTargets; wxProgressDialog progress(_("Importing MSVC 7 solution"), _("Please wait while importing MSVC 7 solution..."), 100, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); int count = 0; wxArrayString keyvalue; cbProject* project = 0; cbProject* firstproject = 0; wxString uuid; bool depSection = false; // ProjectDependencies section? bool slnConfSection = false; // SolutionConfiguration section? bool projConfSection = false; // ProjectConfiguration section? bool global = false; // global section or project section? wxFileName wfname = filename; wfname.Normalize(); Manager::Get()->GetLogManager()->DebugLog(_T("Workspace dir: ") + wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)); while (!file.Eof()) { wxString line = input.ReadLine(); line.Trim(true); line.Trim(false); if (line.StartsWith(_T("Project("))) { // example wanted line: //Project("{UUID of the solution}") = "project name to display", "project filename", "project UUID". // UUID type 4 for projects (i.e. random based), UUID type 1 for solutions (i.e. time+host based) keyvalue = GetArrayFromString(line, _T("=")); if (keyvalue.GetCount() != 2) continue; // ignore keyvalue[0], i.e. solution UUID/GUID // the second part contains the project title and filename comps = GetArrayFromString(keyvalue[1], _T(",")); if (comps.GetCount() < 3) continue; // read project title and trim quotes wxString prjTitle = comps[0]; prjTitle.Trim(true); prjTitle.Trim(false); if (prjTitle.IsEmpty()) continue; if (prjTitle.GetChar(0) == _T('\"')) { prjTitle.Truncate(prjTitle.Length() - 1); prjTitle.Remove(0, 1); } // read project filename and trim quotes wxString prjFile = comps[1]; prjFile.Trim(true); prjFile.Trim(false); if (prjFile.IsEmpty()) continue; if (prjFile.GetChar(0) == _T('\"')) { prjFile.Truncate(prjFile.Length() - 1); prjFile.Remove(0, 1); } // read project UUID, i.e. "{35AFBABB-DF05-43DE-91A7-BB828A874015}" uuid = comps[2]; uuid.Replace(_T("\""), _T("")); // remove quotes ++count; wxFileName fname(UnixFilename(prjFile)); fname.Normalize(wxPATH_NORM_ALL, wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), wxPATH_NATIVE); #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(F(_T("Found project '%s' in '%s'"), prjTitle.wx_str(), fname.GetFullPath().wx_str())); #else Manager::Get()->GetLogManager()->DebugLog(F(_T("Found project '%s' in '%s'"), prjTitle.c_str(), fname.GetFullPath().c_str())); #endif int percentage = ((int)file.TellI())*100 / (int)(file.GetLength()); if (!progress.Update(percentage, _("Importing project: ") + prjTitle)) break; project = Manager::Get()->GetProjectManager()->LoadProject(fname.GetFullPath(), false); if (!firstproject) firstproject = project; if (project) registerProject(uuid, project); } else if (line.StartsWith(_T("GlobalSection(ProjectDependencies)"))) { depSection = true; global = true; } else if (line.StartsWith(_T("ProjectSection(ProjectDependencies)"))) { depSection = true; global = false; } else if (line.StartsWith(_T("GlobalSection(ProjectConfiguration)"))) { projConfSection = true; } else if (line.StartsWith(_T("GlobalSection(SolutionConfiguration)"))) { slnConfSection = true; } else if (line.StartsWith(_T("EndGlobalSection")) || line.StartsWith(_T("EndProjectSection"))) { depSection = false; projConfSection = false; slnConfSection = false; } else if (depSection) { // start reading a dependency keyvalue = GetArrayFromString(line, _T("=")); if (keyvalue.GetCount() != 2) continue; if (global) { // {31635C8-67BF-4808-A918-0FBF822771BD}.0 = {658BFA12-8417-49E5-872A-33F0973544DC} // i.e. project on the left of '=' depend on the project on the right keyvalue[0]= keyvalue[0].BeforeFirst(_T('.')); addDependency(keyvalue[0], keyvalue[1]); } else { // {F87429BF-4583-4A67-BD6F-6CA8AA27702A} = {F87429BF-4583-4A67-BD6F-6CA8AA27702A} // i.e. both uuid are the dependency addDependency(uuid, keyvalue[1]); } } else if (slnConfSection) { // either "Debug = Debug" in V8 or "ConfigName.0 = Debug" in V7 // ignore every on the left of equal sign line = line.AfterLast('='); line.Trim(true); line.Trim(false); addWorkspaceConfiguration(line); } else if (projConfSection && line.StartsWith(_T("{"))) { // {X}.Debug TA.ActiveCfg = Debug TA|Win32 ---> match solution configuration to project configuration or just say what is the active config? // {X}.Debug TA.Build.0 = Debug TA|Win32 ---> we have to build (others are not build) keyvalue = GetArrayFromString(line, _T("=")); wxArrayString key = GetArrayFromString(keyvalue[0], _T(".")); wxArrayString value = GetArrayFromString(keyvalue[1], _T("|")); if (key[2] == _T("Build")) addConfigurationMatching(key[0], key[1], value[0]); } } Manager::Get()->GetProjectManager()->SetProject(firstproject); updateProjects(); ImportersGlobals::ResetDefaults(); Title = wxFileName(filename).GetName() + _(" workspace"); return count != 0; }
bool cbMGMakefile::reLoadDependecies(const wxString &p_DepsFileName,ProjectBuildTarget *p_pTarget,Compiler* p_pCompiler) { m_Deps.Clear(); if ( !wxFileExists( p_DepsFileName ) ) return false; wxString l_Buf; wxString l_VarName; wxTextFile l_DepFile; bool IsSkipThisFile = true; if (l_DepFile.Open( p_DepsFileName, wxConvFile )) { for ( unsigned long i = 0; i < l_DepFile.GetLineCount(); i++ ) { l_Buf = l_DepFile[i]; l_Buf.Trim(true); // Wrong! Don't uncomment it! Being deleted '\t' symbol! l_Buf.Trim(false); if ( l_Buf.IsEmpty() ) { l_VarName.Clear(); IsSkipThisFile = true; continue; } if ( _T('#') == l_Buf[0] ) continue; if ( _T('\t') == l_Buf[0] ) { if ( !IsSkipThisFile ) { if ( _T('"') == l_Buf[1] ) { wxString l_TmpName = l_Buf.AfterFirst( _T('\t') ); if (!l_TmpName.IsEmpty() && l_TmpName.GetChar(0) == _T('"') && l_TmpName.Last() == _T('"')) l_TmpName = l_TmpName.Mid(1, l_TmpName.Length() - 2); QuoteStringIfNeeded( l_TmpName ); m_Deps.AppendValue( l_VarName, l_TmpName ); } } } else { l_VarName = l_Buf.AfterFirst(_T(' ')); bool IsSource = l_VarName.Matches( _T("source:*") ); if ( IsSource ) { l_VarName = l_VarName.AfterFirst( _T(':') ); } /* * You would MUST found source file and get his filename from project * !!! .depend file content lowcase filenames */ wxFileName l_DepFileName = l_VarName; ProjectFile *pf = m_pProj->GetFileByFilename( l_DepFileName.GetFullPath(), l_DepFileName.IsRelative(), false ); if ( pf ) { const pfDetails& pfd = pf->GetFileDetails( p_pTarget ); if ( p_pCompiler->GetSwitches().UseFullSourcePaths ) { l_VarName = UnixFilename( pfd.source_file_absolute_native ); } else { l_VarName = pfd.source_file; } QuoteStringIfNeeded( l_VarName ); IsSkipThisFile = false; } else { IsSkipThisFile = true; } } } } /* FIXME (kisoftcb#1#): Next code for debug only! wxTextFile l_DebFile; l_DebFile.Create( _T("D:/DepsFile.log") ); m_Deps.SaveAllVars( l_DebFile ); l_DebFile.Write(); l_DebFile.Close(); */ }
bool cbMGMakefile::SaveMakefile() { bool l_Ret = false; wxString l_FullFilename = m_Path + m_Filename; if ( m_Overwrite && wxFileExists( l_FullFilename ) ) wxRemoveFile( l_FullFilename ); wxTextFile l_File; if ( !l_File.Create( l_FullFilename ) ) { wxString lMsg = _( "File " ) + l_FullFilename + _(" is exists!\nOverwrite?" ); if (wxID_YES == cbMessageBox(lMsg, _("Warning"), wxICON_EXCLAMATION | wxYES_NO, (wxWindow *)Manager::Get()->GetAppWindow())) { wxRemoveFile( l_FullFilename ); } else { return l_Ret; } } // for active target only! wxString l_ActiveTargetName = m_pProj->GetActiveBuildTarget(); ProjectBuildTarget* l_pTarget = m_pProj->GetBuildTarget( l_ActiveTargetName ); if ( !l_pTarget ) { wxString l_Msg = _( "Can't found an active target!\n" "C::B MakefileGen could not complete the operation." ); cbMessageBox( l_Msg, _( "Error" ), wxICON_ERROR | wxOK, (wxWindow *)Manager::Get()->GetAppWindow() ); Manager::Get()->GetMessageManager()->DebugLog( l_Msg ); return l_Ret; } const wxString& l_CompilerId = l_pTarget->GetCompilerID(); Compiler* l_pCompiler = CompilerFactory::GetCompiler( l_CompilerId ); if ( !getDependencies( l_pTarget, l_pCompiler ) ) return false; m_Variables.AddVariable(_T("CPP"),l_pCompiler->GetPrograms().CPP); m_Variables.AddVariable(_T("CC"),l_pCompiler->GetPrograms().C); m_Variables.AddVariable(_T("LD"),l_pCompiler->GetPrograms().LD); m_Variables.AddVariable(_T("LIB"),l_pCompiler->GetPrograms().LIB); m_Variables.AddVariable(_T("WINDRES"),l_pCompiler->GetPrograms().WINDRES); const wxArrayString& l_CommandsBeforeBuild = l_pTarget->GetCommandsBeforeBuild(); const wxArrayString& l_CommandsAfterBuild = l_pTarget->GetCommandsAfterBuild(); wxString l_TargetFileName = l_pTarget->GetOutputFilename(); Manager::Get()->GetMacrosManager()->ReplaceMacros(l_TargetFileName, l_pTarget); wxFileName l_OutFileName = UnixFilename(l_TargetFileName); cbMGRule l_Rule; if ( 0 == l_ActiveTargetName.CmpNoCase( _T( "default" ) ) ) { l_Rule.SetTarget( _T( "all" ) ); } else { l_Rule.SetTarget( l_ActiveTargetName ); } wxString l_Pre; if ( l_CommandsBeforeBuild.GetCount() > 0 ) { l_Pre = cmdbefore + _T(" "); } l_Pre += l_OutFileName.GetFullPath(); if ( l_CommandsAfterBuild.GetCount() > 0 ) { l_Pre += _T(" ") + cmdafter; } l_Rule.SetPrerequisites( l_Pre ); m_Rules.Add( l_Rule ); if ( l_CommandsBeforeBuild.GetCount() > 0 ) { l_Rule.Clear(); l_Rule.SetTarget( cmdphony ); l_Rule.SetPrerequisites( cmdbefore ); m_Rules.Add( l_Rule ); l_Rule.Clear(); l_Rule.SetTarget( cmdbefore ); for ( unsigned long idx = 0; idx < l_CommandsBeforeBuild.GetCount(); idx ++ ) { l_Rule.AddCommand( l_CommandsBeforeBuild[ idx ] ); } m_Rules.Add( l_Rule ); } if ( l_CommandsAfterBuild.GetCount() > 0 ) { l_Rule.Clear(); l_Rule.SetTarget( cmdphony ); l_Rule.SetPrerequisites( cmdafter ); m_Rules.Add( l_Rule ); l_Rule.Clear(); l_Rule.SetTarget( cmdafter ); for ( unsigned long idx = 0; idx < l_CommandsAfterBuild.GetCount(); idx ++ ) { l_Rule.AddCommand( l_CommandsAfterBuild[ idx ] ); } m_Rules.Add( l_Rule ); } l_Rule.Clear(); l_Rule.SetTarget( l_OutFileName.GetFullPath() ); l_Rule.SetPrerequisites( objs ); wxString kind_of_output = _T( "unknown" ); CommandType ct = ctInvalid; // get rid of compiler warning switch ( l_pTarget->GetTargetType() ) { case ttConsoleOnly: ct = ctLinkConsoleExeCmd; kind_of_output = _T( "console executable" ); break; case ttExecutable: ct = ctLinkExeCmd; kind_of_output = _T( "executable" ); break; case ttDynamicLib: ct = ctLinkDynamicCmd; kind_of_output = _T( "dynamic library" ); break; case ttStaticLib: ct = ctLinkStaticCmd; kind_of_output = _T( "static library" ); break; case ttNative: ct = ctLinkNativeCmd; kind_of_output = _T( "native" ); break; case ttCommandsOnly: ct = ctLinkConsoleExeCmd; kind_of_output = _T( "commands only" ); break; // case ttCommandsOnly: // // add target post-build commands // ret.Clear(); // AppendArray(GetPostBuildCommands(target), ret); // return ret; // break; break; } /*if(ttCommandsOnly == lTarget->GetTargetType()) { GetPostBuildCommands(lTarget); } else*/ { l_Rule.AddCommand( _T( "echo Building " ) + kind_of_output + _T( " " ) + l_OutFileName.GetFullPath() ); wxString l_LinkerCmd = l_pCompiler->GetCommand( ct ); l_pCompiler->GenerateCommandLine( l_LinkerCmd, l_pTarget, NULL, l_OutFileName.GetFullPath(), oobjs, wxEmptyString, wxEmptyString ); l_Rule.AddCommand( l_LinkerCmd ); } m_Rules.Add( l_Rule ); // Form rules wxString l_Tmp; unsigned long ii; wxString macro; wxString file; wxString object; wxString FlatObject; wxString deps; cbMGSortFilesArray files = GetProjectFilesSortedByWeight(l_pTarget,true,false); unsigned long lnb_files = files.GetCount(); for ( ii = 0; ii < lnb_files; ii++ ) { l_Rule.Clear(); ProjectFile* pf = files[ ii ]; const pfDetails& pfd = pf->GetFileDetails( l_pTarget ); wxString l_Object = ( l_pCompiler->GetSwitches().UseFlatObjects )?pfd.object_file_flat:pfd.object_file; wxString l_CompilerCmd; // lookup file's type FileType ft = FileTypeOf( pf->relativeFilename ); bool isResource = ft == ftResource; bool isHeader = ft == ftHeader; if ( !isHeader || l_pCompiler->GetSwitches().supportsPCH ) { pfCustomBuild& pcfb = pf->customBuild[l_pCompiler->GetID()]; l_CompilerCmd = pcfb.useCustomBuildCommand ? pcfb.buildCommand : l_pCompiler->GetCommand( isResource ? ctCompileResourceCmd : ctCompileObjectCmd ); wxString l_SourceFile; if ( l_pCompiler->GetSwitches().UseFullSourcePaths ) { l_SourceFile = UnixFilename( pfd.source_file_absolute_native ); // for resource files, use short from if path because if windres bug with spaces-in-paths if ( isResource ) { l_SourceFile = pf->file.GetShortPath(); } } else { l_SourceFile = pfd.source_file; } QuoteStringIfNeeded( l_SourceFile ); l_pCompiler->GenerateCommandLine( l_CompilerCmd, l_pTarget, pf, l_SourceFile, l_Object, pfd.object_file_flat, pfd.dep_file ); m_Variables.AppendValue( _T( "OBJS" ), l_Object ); l_Rule.SetTarget( l_Object ); l_Rule.SetPrerequisites( l_SourceFile ); l_Rule.AddCommand( _T( "echo Compiling: " ) + l_SourceFile ); l_Rule.AddCommand( l_CompilerCmd ); m_Rules.Add( l_Rule ); } } for ( unsigned long i=0; i < m_Deps.Count(); i++ ) { l_Rule.Clear(); l_Rule.SetTarget( m_Deps.GetVarName( i ) ); l_Rule.SetPrerequisites( m_Deps.GetVariable( i ) ); m_Rules.Add( l_Rule ); } l_Rule.Clear(); l_Rule.SetTarget( cmdphony ); l_Rule.SetPrerequisites( cmdclean ); m_Rules.Add( l_Rule ); l_Rule.Clear(); l_Rule.SetTarget( cmdclean ); l_Rule.AddCommand( _T( "echo Delete $(OBJS) " ) + l_OutFileName.GetFullPath() ); #ifdef __WXMSW__ l_Rule.AddCommand( _T( "del /f $(OBJS) " ) + l_OutFileName.GetFullPath() ); #else l_Rule.AddCommand( _T( "rm -f $(OBJS) " ) + l_OutFileName.GetFullPath() ); #endif m_Rules.Add( l_Rule ); // save header l_File.AddLine( sHeader ); l_File.AddLine( wxEmptyString ); m_Variables.SaveAllVars( l_File ); SaveAllRules( l_File ); l_File.Write(); l_File.Close(); l_Ret = true; return l_Ret; }
bool WorkspaceLoader::Open(const wxString& filename, wxString& Title) { TiXmlDocument doc; if (!TinyXML::LoadDocument(filename, &doc)) return false; // ProjectManager* pMan = Manager::Get()->GetProjectManager(); // LogManager* pMsg = Manager::Get()->GetLogManager(); if (!GetpMan() || !GetpMsg()) return false; // BUG: Race condition. to be fixed by Rick. // If I click close AFTER pMan and pMsg are calculated, // I get a segfault. // I modified classes projectmanager and logmanager, // so that when self==NULL, they do nothing // (constructors, destructors and static functions excempted from this) // This way, we'll use the *manager::Get() functions to check for nulls. TiXmlElement* root = doc.FirstChildElement("CodeBlocks_workspace_file"); if (!root) { // old tag root = doc.FirstChildElement("Code::Blocks_workspace_file"); if (!root) { GetpMsg()->DebugLog(_T("Not a valid Code::Blocks workspace file...")); return false; } } TiXmlElement* wksp = root->FirstChildElement("Workspace"); if (!wksp) { GetpMsg()->DebugLog(_T("No 'Workspace' element in file...")); return false; } Title = cbC2U(wksp->Attribute("title")); // Conversion to unicode is automatic (see wxString::operator= ) TiXmlElement* proj = wksp->FirstChildElement("Project"); if (!proj) { GetpMsg()->DebugLog(_T("Workspace file contains no projects...")); return false; } // first loop to load projects while (proj) { if(Manager::isappShuttingDown() || !GetpMan() || !GetpMsg()) return false; wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename"))); if (projectFilename.IsEmpty()) { GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?")); } else { wxFileName fname(projectFilename); wxFileName wfname(filename); fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)); int active = 0; int ret = proj->QueryIntAttribute("active", &active); switch (ret) { case TIXML_SUCCESS: if (active == 1) { cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), true); // activate it if(!pProject) { cbMessageBox(_("Unable to open ") + projectFilename, _("Opening WorkSpace") + filename, wxICON_WARNING); } } break; case TIXML_WRONG_TYPE: GetpMsg()->DebugLog(F(_T("Error %s: %s"), doc.Value(), doc.ErrorDesc())); GetpMsg()->DebugLog(_T("Wrong attribute type (expected 'int')")); break; default: cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), false); // don't activate it if(!pProject) { cbMessageBox(_("Unable to open ") + projectFilename, _("Opening WorkSpace") + filename, wxICON_WARNING); } break; } } proj = proj->NextSiblingElement("Project"); } // second loop to setup dependencies proj = wksp->FirstChildElement("Project"); while (proj) { cbProject* thisprj = 0; wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename"))); if (projectFilename.IsEmpty()) { GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?")); thisprj = 0; } else { wxFileName fname(projectFilename); wxFileName wfname(filename); fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)); thisprj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath()); } if (thisprj) { TiXmlElement* dep = proj->FirstChildElement("Depends"); while (dep) { wxFileName fname(UnixFilename(cbC2U(dep->Attribute("filename")))); wxFileName wfname(filename); fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)); cbProject* depprj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath()); if (depprj) Manager::Get()->GetProjectManager()->AddProjectDependency(thisprj, depprj); dep = dep->NextSiblingElement("Depends"); } } proj = proj->NextSiblingElement("Project"); } return true; }
bool MSVC7Loader::DoImport(TiXmlElement* conf) { ProjectBuildTarget* bt = m_pProject->GetBuildTarget(m_ConfigurationName); if (!bt) bt = m_pProject->AddBuildTarget(m_ConfigurationName); bt->SetCompilerID(m_pProject->GetCompilerID()); // See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcext/html/vxlrfvcprojectenginelibraryruntimelibraryoption.asp m_OutDir = ReplaceMSVCMacros(cbC2U(conf->Attribute("OutputDirectory"))); m_IntDir = ReplaceMSVCMacros(cbC2U(conf->Attribute("IntermediateDirectory"))); if (m_IntDir.StartsWith(_T(".\\"))) m_IntDir.Remove(0,2); bt->SetObjectOutput(m_IntDir); // see MSDN: ConfigurationTypes Enumeration wxString conftype = cbC2U(conf->Attribute("ConfigurationType")); if (conftype.IsSameAs(_T("1"))) // typeApplication 1, no difference between console or gui here, we must check the subsystem property of the linker bt->SetTargetType(ttExecutable); else if (conftype.IsSameAs(_T("2"))) // typeDynamicLibrary 2 bt->SetTargetType(ttDynamicLib); else if (conftype.IsSameAs(_T("4"))) // typeStaticLibrary 4 bt->SetTargetType(ttStaticLib); else if (conftype.IsSameAs(_T("-1"))) // typeNative -1, check subsystem property of the linker to make sure bt->SetTargetType(ttNative); else if (conftype.IsSameAs(_T("10"))) // typeGeneric 10 bt->SetTargetType(ttCommandsOnly); else // typeUnknown 0 { bt->SetTargetType(ttCommandsOnly); Manager::Get()->GetLogManager()->DebugLog(_T("unrecognized project type")); } TiXmlElement* tool = conf->FirstChildElement("Tool"); if (!tool) { Manager::Get()->GetLogManager()->DebugLog(_T("No 'Tool' node...")); return false; } for (; tool; tool=tool->NextSiblingElement("Tool")) { if (strcmp(tool->Attribute("Name"), "VCLinkerTool") == 0 || strcmp(tool->Attribute("Name"), "VCLibrarianTool") == 0) { // linker wxString tmp; if ((bt->GetTargetType()==ttExecutable) || (bt->GetTargetType()==ttNative)) { tmp = cbC2U(tool->Attribute("SubSystem")); //subSystemNotSet 0 //subSystemConsole 1 //subSystemWindows 2 if (tmp.IsSameAs(_T("1"))) { bt->SetTargetType(ttConsoleOnly); //bt->AddLinkerOption("/SUBSYSTEM:CONSOLE"); // don't know if it is necessary } else if (tmp.IsSameAs(_T("3"))) bt->SetTargetType(ttNative); } // else we keep executable tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("OutputFile"))); tmp = UnixFilename(tmp); if (tmp.Last() == _T('.')) tmp.RemoveLast(); if (bt->GetTargetType() == ttStaticLib) { // convert the lib name Compiler* compiler = CompilerFactory::GetCompiler(m_pProject->GetCompilerID()); if (compiler) { wxString prefix = compiler->GetSwitches().libPrefix; wxString suffix = compiler->GetSwitches().libExtension; wxFileName fname = tmp; if (!fname.GetName().StartsWith(prefix)) fname.SetName(prefix + fname.GetName()); fname.SetExt(suffix); tmp = fname.GetFullPath(); } } bt->SetOutputFilename(tmp); m_TargetPath = wxFileName(tmp).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); m_TargetFilename = wxFileName(tmp).GetFullName(); tmp = cbC2U(tool->Attribute("AdditionalLibraryDirectories")); wxArrayString arr; ParseInputString(tmp, arr); for (unsigned int i = 0; i < arr.GetCount(); ++i) { bt->AddLibDir(ReplaceMSVCMacros(arr[i])); } if (!m_ConvertSwitches) // no point importing this option, if converting to GCC { tmp = cbC2U(tool->Attribute("IgnoreDefaultLibraryNames")); arr = GetArrayFromString(tmp, _T(";")); if (arr.GetCount()==1) arr = GetArrayFromString(tmp, _T(",")); for (unsigned int i = 0; i < arr.GetCount(); ++i) { bt->AddLinkerOption(wxString(_T("/NODEFAULTLIB:")) + arr[i]); } } #if 0 // no need since "/nologo" appear on the invocation commands of compilers/linkers if (!m_ConvertSwitches) { tmp = tool->Attribute("SuppressStartupBanner"); if (tmp.IsSameAs("TRUE")) bt->AddLinkerOption("/nologo"); } #endif tmp = cbC2U(tool->Attribute("GenerateDebugInformation")); if (tmp.IsSameAs(_T("TRUE"))) { //bt->AddCompilerOption(m_ConvertSwitches ? "-g" : "/Zi"); // no ! if (!m_ConvertSwitches) bt->AddLinkerOption(_T("/debug")); } // other options: /MACHINE:I386, /INCREMENTAL:YES, /STACK:10000000 if (!m_ConvertSwitches) { arr = GetArrayFromString(ReplaceMSVCMacros(cbC2U(tool->Attribute("AdditionalOptions"))), _T(" ")); for (unsigned int i = 0; i < arr.GetCount(); ++i) bt->AddLinkerOption(arr[i]); } // else ignore all options tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("AdditionalDependencies"))); arr = GetArrayFromString(tmp, _T(" ")); for (unsigned int i = 0; i < arr.GetCount(); ++i) { tmp = arr[i]; if (tmp.Right(4).CmpNoCase(_T(".lib")) == 0) tmp.Remove(tmp.Length() - 4); if ((tmp == _T("/dll")) || (tmp == _T("/DLL"))) bt->AddLinkerOption(_T("--dll")); else bt->AddLinkLib(tmp); } if (!m_ConvertSwitches) { tmp = cbC2U(tool->Attribute("LinkIncremental")); if (tmp.IsSameAs(_T("1"))) // 1 -> no, default is yes bt->AddLinkerOption(_T("/INCREMENTAL:NO")); } if (!m_ConvertSwitches) { tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("ProgramDatabaseFile"))); if (!tmp.IsEmpty()) bt->AddLinkerOption(wxString(_T("/pdb:")) + UnixFilename(tmp)); } if (!m_ConvertSwitches) { tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("ModuleDefinitionFile"))); if (!tmp.IsEmpty()) bt->AddLinkerOption(_T("/DEF:\"") + tmp + _T("\"")); } } else if (strcmp(tool->Attribute("Name"), "VCCLCompilerTool") == 0) { unsigned int i; wxString tmp; wxArrayString arr; // compiler tmp = cbC2U(tool->Attribute("AdditionalIncludeDirectories")); // vc70 uses ";" while vc71 uses "," separators // NOTE (mandrav#1#): No, that is *not* the case (what were they thinking at MS?) // try with comma (,) which is the newest I believe ParseInputString(tmp, arr); // This will parse recursively for (i = 0; i < arr.GetCount(); ++i) { bt->AddIncludeDir(ReplaceMSVCMacros(arr[i])); bt->AddResourceIncludeDir(ReplaceMSVCMacros(arr[i])); } tmp = cbC2U(tool->Attribute("PreprocessorDefinitions")); arr = GetArrayFromString(tmp, _T(",")); if (arr.GetCount() == 1) // if it fails, try with semicolon arr = GetArrayFromString(tmp, _T(";")); for (unsigned int j = 0; j < arr.GetCount(); ++j) { if (m_ConvertSwitches) bt->AddCompilerOption(wxString(_T("-D")) + arr[j]); else bt->AddCompilerOption(wxString(_T("/D")) + arr[j]); } tmp = cbC2U(tool->Attribute("WarningLevel")); if (m_ConvertSwitches) { if (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("-w")); else if (tmp.IsSameAs(_T("1")) || tmp.IsSameAs(_T("2")) || tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("-W")); else if (tmp.IsSameAs(_T("4"))) bt->AddCompilerOption(_T("-Wall")); } else { bt->AddCompilerOption(wxString(_T("/W")) + tmp); } /* For more details on "DebugInformationFormat", please visit http://msdn2.microsoft.com/en-us/library/aa652260(VS.71).aspx http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.debugoption(VS.80).aspx */ tmp = cbC2U(tool->Attribute("DebugInformationFormat")); if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(m_ConvertSwitches ? _T("") : _T("/Zi")); else if (tmp.IsSameAs(_T("4"))) bt->AddCompilerOption(m_ConvertSwitches ? _T("-g") : _T("/ZI")); tmp = cbC2U(tool->Attribute("InlineFunctionExpansion")); if (!m_ConvertSwitches && tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/Ob1")); /* Optimization : optimizeDisabled 0 optimizeMinSpace 1 optimizeMaxSpeed 2 optimizeFull 3 optimizeCustom 4 */ tmp = cbC2U(tool->Attribute("Optimization")); if (m_ConvertSwitches) { if (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("-O0")); else if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("-O1")); else if (tmp.IsSameAs(_T("2"))) bt->AddCompilerOption(_T("-O2")); else if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("-O3")); //else if (tmp.IsSameAs("4")) bt->AddCompilerOption("-O1"); // nothing to do ? } else { if (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("/Od")); else if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/O1")); else if (tmp.IsSameAs(_T("2"))) bt->AddCompilerOption(_T("/O2")); else if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("/Ox")); //else if (tmp.IsSameAs("4")) bt->AddCompilerOption("/O1"); // nothing to do ? } if (!m_ConvertSwitches) { tmp = cbC2U(tool->Attribute("Detect64BitPortabilityProblems")); if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption(_T("/Wp64")); tmp = cbC2U(tool->Attribute("MinimalRebuild")); if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption(_T("/Gm")); /* RuntimeLibrary : rtMultiThreaded 0 --> /MT rtMultiThreadedDebug 1 --> /MTd rtMultiThreadedDLL 2 --> /MD rtMultiThreadedDebugDLL 3 --> /MDd rtSingleThreaded 4 --> /ML rtSingleThreadedDebug 5 --> /MLd */ tmp = cbC2U(tool->Attribute("RuntimeLibrary")); if (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("/MT")); else if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/MTd")); else if (tmp.IsSameAs(_T("2"))) bt->AddCompilerOption(_T("/MD")); else if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("/MDd")); else if (tmp.IsSameAs(_T("4"))) bt->AddCompilerOption(_T("/ML")); else if (tmp.IsSameAs(_T("5"))) bt->AddCompilerOption(_T("/MLd")); #if 0 tmp = cbC2U(tool->Attribute("SuppressStartupBanner")); if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption("/nologo"); #endif /* runtimeBasicCheckNone 0 runtimeCheckStackFrame 1 --> /RTCs or /GZ runtimeCheckUninitVariables 2 runtimeBasicCheckAll 3 */ tmp = cbC2U(tool->Attribute("BasicRuntimeChecks")); if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/GZ")); tmp = cbC2U(tool->Attribute("ExceptionHandling")); if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption(_T("EHsc")); // add C++ exception handling } tmp = cbC2U(tool->Attribute("RuntimeTypeInfo")); if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption(m_ConvertSwitches ? _T("-frtti") : _T("/GR")); /* AdditionalOptions=" /Zm1000 /GR -DCMAKE_INTDIR=\"Debug\"" ObjectFile="Debug\" /Zm<n> max memory alloc (% of default) */ tmp = cbC2U(tool->Attribute("AdditionalOptions")); //tmp = ReplaceMSVCMacros(tmp); arr = GetArrayFromString(tmp, _T(" ")); for (i=0; i<arr.GetCount(); ++i) { if (arr[i].IsSameAs(_T("/D")) || arr[i].IsSameAs(_T("-D"))) { bt->AddCompilerOption((m_ConvertSwitches? _T("-D"):_T("/D")) + arr[i+1]); ++i; } else if (arr[i].StartsWith(_T("/D")) || arr[i].StartsWith(_T("-D"))) bt->AddCompilerOption((m_ConvertSwitches? _T("-D"):_T("/D")) + arr[i].Mid(2)); else if (arr[i].IsSameAs(_T("/Zi"))) bt->AddCompilerOption(m_ConvertSwitches? _T("-g"):_T("/Zi")); else if (!m_ConvertSwitches) bt->AddCompilerOption(arr[i]); } tmp = cbC2U(tool->Attribute("ForcedIncludeFiles")); if (!tmp.IsEmpty()) { wxArrayString FIfiles; ParseInputString(tmp, FIfiles); for (size_t j = 0; j < FIfiles.GetCount(); ++j) bt->AddCompilerOption(m_ConvertSwitches? _T("-include ") + ReplaceMSVCMacros(FIfiles[j]) : _T("/FI ") + ReplaceMSVCMacros(FIfiles[j])); } } else if (strcmp(tool->Attribute("Name"), "VCPreBuildEventTool") == 0) { // pre-build step wxString cmd = ReplaceMSVCMacros(cbC2U(tool->Attribute("CommandLine"))); if (!cmd.IsEmpty()) bt->AddCommandsBeforeBuild(cmd); } else if (strcmp(tool->Attribute("Name"), "VCPostBuildEventTool") == 0) { // post-build step wxString cmd = ReplaceMSVCMacros(cbC2U(tool->Attribute("CommandLine"))); if (!cmd.IsEmpty()) bt->AddCommandsAfterBuild(cmd); } } return true; }
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; }
void pfDetails::Update(ProjectBuildTarget* target, ProjectFile* pf) { wxString sep = wxFILE_SEP_PATH; wxFileName tmp; wxFileName prjbase(target->GetParentProject()->GetBasePath()); wxString objOut = target ? target->GetObjectOutput() : _T("."); wxString depsOut = target ? target->GetDepsOutput() : _T("."); // we must replace any macros here early because if the macros expand // to absolute paths (like global vars usually do), we 're gonna create // invalid filenames below Manager::Get()->GetMacrosManager()->ReplaceMacros(objOut, target); Manager::Get()->GetMacrosManager()->ReplaceMacros(depsOut, target); source_file_native = pf->relativeFilename; source_file_absolute_native = pf->file.GetFullPath(); tmp = pf->GetObjName(); FileType ft = FileTypeOf(pf->relativeFilename); Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : CompilerFactory::GetDefaultCompiler(); // support for precompiled headers if (target && ft == ftHeader && compiler && compiler->GetSwitches().supportsPCH) { switch (target->GetParentProject()->GetModeForPCH()) { case pchSourceDir: { // if PCH is for a file called all.h, we create // all.h.gch/<target>_all.h.gch // (that's right: a directory) wxString new_gch = target->GetTitle() + _T('_') + pf->GetObjName(); // make sure we 're not generating subdirs size_t len = new_gch.Length(); for (size_t i = 0; i < len; ++i) { wxChar c = new_gch[i]; if (c == _T('/') || c == _T('\\') || c == _T('.')) new_gch[i] = _T('_'); } wxFileName fn(source_file_native); object_file_native = fn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + fn.GetName() + _T('.') + compiler->GetSwitches().PCHExtension + wxFILE_SEP_PATH + new_gch; object_file_flat_native = object_file_native; break; } case pchObjectDir: { object_file_native = objOut + sep + tmp.GetFullPath(); object_file_flat_native = objOut + sep + tmp.GetFullName(); break; } case pchSourceFile: { object_file_native = pf->GetObjName(); object_file_flat_native = object_file_native; break; } } } else { if (pf->GetParentProject()) { wxFileName fname(pf->relativeToCommonTopLevelPath); if (pf->generatedFiles.size()) { // for files generating other files, // use the first generated file's "object name" fname.Assign(pf->generatedFiles[0]->relativeToCommonTopLevelPath); } /* NOTE: In case the source file resides in a different volume * than the volume where project file is, * then the object file will be created as follows. * * Project object output dir: C:\Foo\obj\Debug * Source: D:\Source\foo.cpp * Obj file: C:\Foo\obj\Debug\D\Source\foo.o */ wxString fileVol = fname.GetVolume(); wxString obj_file_full_path = fname.GetFullPath(); bool diffVolume = false; if (platform::windows && (!fileVol.IsEmpty() && !fileVol.IsSameAs(prjbase.GetVolume()))) { objOut += fileVol; obj_file_full_path = obj_file_full_path.AfterFirst(_T('\\')); diffVolume = true; } if (ft == ftResource || ft == ftResourceBin) { if (pf->GetParentProject()->GetExtendedObjectNamesGeneration()) { object_file_native = objOut + sep + obj_file_full_path; object_file_flat_native = objOut + sep + fname.GetFullName(); object_file_native += FileFilters::RESOURCEBIN_DOT_EXT; object_file_flat_native += FileFilters::RESOURCEBIN_DOT_EXT; } else { fname.SetExt(FileFilters::RESOURCEBIN_EXT); wxString obj_file_path = fname.GetFullPath(); if (diffVolume) obj_file_path = obj_file_path.AfterFirst(_T('\\')); object_file_native = objOut + sep + obj_file_path; object_file_flat_native = objOut + sep + fname.GetFullName(); } } else { if (pf->GetParentProject()->GetExtendedObjectNamesGeneration()) { object_file_native = objOut + sep + obj_file_full_path; object_file_flat_native = objOut + sep + fname.GetFullName(); if (compiler) { object_file_native += _T('.') + compiler->GetSwitches().objectExtension; object_file_flat_native += _T('.') + compiler->GetSwitches().objectExtension; } } else { if (compiler) fname.SetExt(compiler->GetSwitches().objectExtension); wxString obj_file_path = fname.GetFullPath(); if (diffVolume) obj_file_path = obj_file_path.AfterFirst(_T('\\')); object_file_native = objOut + sep + obj_file_path; object_file_flat_native = objOut + sep + fname.GetFullName(); } } } } wxFileName o_file(object_file_native); wxFileName o_file_flat(object_file_flat_native); o_file.MakeAbsolute(prjbase.GetFullPath()); o_file_flat.MakeAbsolute(prjbase.GetFullPath()); object_dir_native = o_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); object_dir_flat_native = o_file_flat.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); object_file_absolute_native = o_file.GetFullPath(); object_file_flat_absolute_native = o_file_flat.GetFullPath(); tmp.SetExt(_T("depend")); dep_file_native = depsOut + sep + tmp.GetFullPath(); wxFileName d_file(dep_file_native); d_file.MakeAbsolute(prjbase.GetFullPath()); dep_dir_native = d_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); dep_file_absolute_native = o_file.GetFullPath(); source_file = UnixFilename(source_file_native); QuoteStringIfNeeded(source_file); object_file = UnixFilename(object_file_native); QuoteStringIfNeeded(object_file); object_file_flat = UnixFilename(object_file_flat_native); QuoteStringIfNeeded(object_file_flat); dep_file = UnixFilename(dep_file_native); QuoteStringIfNeeded(dep_file); object_dir = UnixFilename(object_dir_native); QuoteStringIfNeeded(object_dir); object_dir_flat = UnixFilename(object_dir_flat_native); QuoteStringIfNeeded(object_dir_flat); dep_dir = UnixFilename(dep_dir_native); QuoteStringIfNeeded(dep_dir); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_absolute_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_absolute_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_absolute_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(source_file); }
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; }
bool ClassWizardDlg::DoImpl() { // Create the implementation file wxFileName implementationFname(UnixFilename(m_Implementation)); implementationFname.MakeAbsolute(m_ImplDir); DoForceDirectory(implementationFname); // Create a new editor/file (probably based on a template setup by the user) cbEditor* new_ed = Manager::Get()->GetEditorManager()->New(implementationFname.GetFullPath()); if (!new_ed) { cbMessageBox(_T("Class wizard can't continue.\n" "Possibly the implementation file name is invalid.\n" "Please check the entered file name."), _T("Error"), wxICON_ERROR, this); return false; } // Obtain the buffer of the new file and replace any macros that might exist wxString buffer = new_ed->GetControl()->GetText(); Manager::Get()->GetMacrosManager()->ReplaceMacros(buffer); buffer << _T("#include ") << m_HeaderInclude << m_EolStr; if (m_NameSpaces.GetCount()) { buffer << m_EolStr; for (unsigned int i=0; i<m_NameSpaces.GetCount(); ++i) { buffer << _T("namespace ") << m_NameSpaces[i] << _T(" {") << m_EolStr; } } buffer << m_EolStr; buffer << m_Name << _T("::") << m_Name << _T("(") << m_Arguments << _T(")") << m_EolStr; buffer << _T("{") << m_EolStr; buffer << m_TabStr << _T("//ctor") << m_EolStr; buffer << _T("}") << m_EolStr; if (m_HasDestructor) { buffer << m_EolStr; buffer << m_Name << _T("::~") << m_Name << _T("()") << m_EolStr; buffer << _T("{") << m_EolStr; buffer << m_TabStr << _T("//dtor") << m_EolStr; buffer << _T("}") << m_EolStr; } if (m_HasCopyCtor) { buffer << m_EolStr; buffer << m_Name << _T("::") << m_Name << _T("(const ") << m_Name << _T("& other)") << m_EolStr;; buffer << _T("{") << m_EolStr; buffer << m_TabStr << _T("//copy ctor") << m_EolStr; buffer << _T("}") << m_EolStr; } if (m_HasAssignmentOp) { buffer << m_EolStr; buffer << m_Name << _T("& ") << m_Name << _T("::operator=(const ") << m_Name << _T("& rhs)") << m_EolStr;; buffer << _T("{") << m_EolStr; buffer << m_TabStr << _T("if (this == &rhs) return *this; // handle self assignment") << m_EolStr; buffer << m_TabStr << _T("//assignment operator") << m_EolStr; buffer << m_TabStr << _T("return *this;") << m_EolStr; buffer << _T("}") << m_EolStr; } if (m_NameSpaces.GetCount()) { buffer << m_EolStr; for (int i=m_NameSpaces.GetCount(); i>0; --i) { buffer << _T("} // namespace ") << m_NameSpaces[i-1] << m_EolStr; } } new_ed->GetControl()->SetText(buffer); if (!new_ed->Save()) { wxString msg; msg.Printf(_("Could not save implementation file %s.\nAborting..."), implementationFname.GetFullPath().c_str()); cbMessageBox(msg, _("Error"), wxICON_ERROR, this); return false; } m_Implementation = implementationFname.GetFullPath(); return true; }
bool ClassWizardDlg::DoHeader() { // Create the header file wxFileName headerFname(UnixFilename(m_Header)); headerFname.MakeAbsolute(m_IncludeDir); DoForceDirectory(headerFname); // Create a new editor/file (probably based on a template setup by the user) cbEditor* new_ed = Manager::Get()->GetEditorManager()->New(headerFname.GetFullPath()); if (!new_ed) { cbMessageBox(_T("Class wizard can't continue.\n" "Possibly the header file name is invalid.\n" "Please check the entered file name."), _T("Error"), wxICON_ERROR, this); return false; } // Obtain the buffer of the new file and replace any macros that might exist wxString buffer = new_ed->GetControl()->GetText(); Manager::Get()->GetMacrosManager()->ReplaceMacros(buffer); // let's start with the header file if (m_GuardBlock) { buffer << _T("#ifndef ") << m_GuardWord << m_EolStr; buffer << _T("#define ") << m_GuardWord << m_EolStr; buffer << m_EolStr; } if (!m_AncestorFilename.IsEmpty() && !m_AncestorFilename.IsSameAs(_T("<>"))) { buffer << _T("#include ") << m_AncestorFilename << m_EolStr; buffer << m_EolStr; } for (unsigned int i=0; i<m_NameSpaces.GetCount(); ++i) { buffer << _T("namespace ") << m_NameSpaces[i] << _T(" {") << m_EolStr; } buffer << m_EolStr; // Begin of class buffer << _T("class ") << m_Name; if (m_Inherits) { buffer << _T(" : ") << m_AncestorScope << _T(" ") << m_Ancestor; } buffer << m_EolStr; buffer << _T("{") << m_EolStr; // focus: public buffer << m_TabStr << _T("public:") << m_EolStr; // ctor if (m_Documentation) { buffer << m_TabStr << m_TabStr << _T("/** Default constructor */") << m_EolStr; } buffer << m_TabStr << m_TabStr << m_Name << _T("(") << m_Arguments << _T(")") << (!m_GenerateImplementation ? _T(" {}") : _T(";")) << m_EolStr; if (m_HasDestructor) { if (m_Documentation) { buffer << m_TabStr << m_TabStr << _T("/** Default destructor */") << m_EolStr; } buffer << m_TabStr << m_TabStr; if (m_VirtualDestructor) { buffer << _T("virtual "); } buffer << _T('~') << m_Name << _T("()"); buffer << (!m_GenerateImplementation ? _T(" {}") : _T(";")) << m_EolStr; } if (m_HasCopyCtor) { if (m_Documentation) { buffer << m_TabStr << m_TabStr << _T("/** Copy constructor") << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" * \\param other Object to copy from") << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" */") << m_EolStr; } buffer << m_TabStr << m_TabStr; buffer << m_Name << _T("(const ") << m_Name << _T("& other)"); buffer << (!m_GenerateImplementation ? _T(" {}") : _T(";")) << m_EolStr; } if (m_HasAssignmentOp) { if (m_Documentation) { buffer << m_TabStr << m_TabStr << _T("/** Assignment operator") << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" * \\param other Object to assign from") << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" * \\return A reference to this") << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" */") << m_EolStr; } buffer << m_TabStr << m_TabStr; buffer << m_Name << _T("& ") << _T("operator=(const ") << m_Name << _T("& other)"); buffer << (!m_GenerateImplementation ? _T(" { return *this; }") : _T(";")) << m_EolStr; } buffer << m_EolStr; bool addnewline = false; std::vector<MemberVar>::iterator it = m_MemberVars.begin(); while( it != m_MemberVars.end() ) { if (!(*it).Get.IsEmpty()) { addnewline = true; if (m_Documentation) { buffer << m_TabStr << m_TabStr << _T("/** Access ") << (*it).Var << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" * \\return The current value of ") << (*it).Var << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" */") << m_EolStr; } buffer << m_TabStr << m_TabStr << (*it).Typ << _T(" ") << (*it).Get << _T("() { return ") << (*it).Var << _T("; }") << m_EolStr; } if (!(*it).Set.IsEmpty()) { addnewline = true; if (m_Documentation) { buffer << m_TabStr << m_TabStr << _T("/** Set ") << (*it).Var << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" * \\param val New value to set") << m_EolStr; buffer << m_TabStr << m_TabStr << _T(" */") << m_EolStr; } buffer << m_TabStr << m_TabStr << _T("void ") << (*it).Set << _T("(") << (*it).Typ << _T(" val) { ") << (*it).Var << _T(" = val; }") << m_EolStr; } ++it; } if (addnewline) buffer << m_EolStr; addnewline = false; for( it = m_MemberVars.begin(); it != m_MemberVars.end(); ++it ) { if ((*it).Scp == 0) { addnewline = true; buffer << m_TabStr << m_TabStr << (*it).Typ << _T(" ") << (*it).Var << _T(";"); if (m_Documentation) buffer << _T(" //!< Member variable \"") << (*it).Var << _T("\""); buffer << m_EolStr; } } if (addnewline) buffer << m_EolStr; // focus: protected buffer << m_TabStr << _T("protected:") << m_EolStr; for( it = m_MemberVars.begin(); it != m_MemberVars.end(); ++it ) { if ((*it).Scp == 1) { buffer << m_TabStr << m_TabStr << (*it).Typ << _T(" ") << (*it).Var << _T(";"); if (m_Documentation) buffer << _T(" //!< Member variable \"") << (*it).Var << _T("\""); buffer << m_EolStr; } } buffer << m_EolStr; // focus: private buffer << m_TabStr << _T("private:") << m_EolStr; for( it = m_MemberVars.begin(); it != m_MemberVars.end(); ++it ) { if ((*it).Scp == 2) { buffer << m_TabStr << m_TabStr << (*it).Typ << _T(" ") << (*it).Var << _T(";"); if (m_Documentation) buffer << _T(" //!< Member variable \"") << (*it).Var << _T("\""); buffer << m_EolStr; } } // End of class buffer << _T("};") << m_EolStr; if (m_NameSpaces.GetCount()) { buffer << m_EolStr; for (int i=m_NameSpaces.GetCount(); i>0; --i) { buffer << _T("} // namespace ") << m_NameSpaces[i-1] << m_EolStr; } } if (m_GuardBlock) { buffer << m_EolStr; buffer << _T("#endif // ") << m_GuardWord << m_EolStr; } new_ed->GetControl()->SetText(buffer); if (!new_ed->Save()) { wxString msg; msg.Printf(_("Could not save header file %s.\nAborting..."), headerFname.GetFullPath().c_str()); cbMessageBox(msg, _("Error"), wxICON_ERROR, this); return false; } m_Header = headerFname.GetFullPath(); 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) { 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; }