//{ Vera int CppCheck::ExecuteVera(cbProject* Project) { if ( !DoVersion(_T("vera++"), _T("vera_app")) ) return -1; wxFile InputFile; wxString InputsFile = _T("VeraInput.txt"); if ( !InputFile.Create(InputsFile, true) ) { cbMessageBox(_("Failed to create input file '") + InputsFile + _("' for vera++.\nPlease check file/folder access rights."), _("Error"), wxICON_ERROR | wxOK, Manager::Get()->GetAppWindow()); return -1; } for (FilesList::iterator it = Project->GetFilesList().begin(); it != Project->GetFilesList().end(); ++it) { ProjectFile* pf = *it; // filter to avoid including non C/C++ files if ( pf->relativeFilename.EndsWith(FileFilters::C_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CPP_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CC_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CXX_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CPLPL_DOT_EXT) || (FileTypeOf(pf->relativeFilename) == ftHeader) || (FileTypeOf(pf->relativeFilename) == ftTemplateSource) ) { InputFile.Write(pf->relativeFilename + _T("\n")); } } InputFile.Close(); return DoVeraExecute(InputsFile); }
void Parser::ReparseModifiedFiles() { if (!Done()) { wxString msg(_T("Parser::ReparseModifiedFiles : The Parser is not done.")); msg += NotDoneReason(); CCLogger::Get()->DebugLog(msg); m_ReparseTimer.Start(reparse_timer_delay, wxTIMER_ONE_SHOT); return; } if (!m_NeedsReparse) m_NeedsReparse = true; std::queue<wxString> files_list; { TRACK_THREAD_LOCKER(s_TokensTreeCritical); wxCriticalSectionLocker locker(s_TokensTreeCritical); THREAD_LOCKER_SUCCESS(s_TokensTreeCritical); TokenFilesSet::iterator it; // loop two times so that we reparse modified *header* files first // because they usually hold definitions which need to exist // when we parse the normal source files... for (it = m_TokensTree->m_FilesToBeReparsed.begin(); it != m_TokensTree->m_FilesToBeReparsed.end(); ++it) { wxString filename = m_TokensTree->m_FilenamesMap.GetString(*it); if (FileTypeOf(filename) == ftSource) // ignore source files (*.cpp etc) continue; files_list.push(filename); m_TokensTree->RemoveFile(*it); } for (it = m_TokensTree->m_FilesToBeReparsed.begin(); it != m_TokensTree->m_FilesToBeReparsed.end(); ++it) { wxString filename = m_TokensTree->m_FilenamesMap.GetString(*it); if (FileTypeOf(filename) != ftSource) // ignore non-source files (*.h etc) continue; files_list.push(filename); m_TokensTree->RemoveFile(*it); } } if (!files_list.empty() && m_ParsingType == ptUndefined) m_ParsingType = ptReparseFile; else m_NeedsReparse = false; while (!files_list.empty()) { AddParse(files_list.front()); files_list.pop(); } }
wxString CompilerMINGWGenerator::SetupIncludeDirs(Compiler* compiler, ProjectBuildTarget* target) { wxString result = CompilerCommandGenerator::SetupIncludeDirs(compiler, target); m_VerStr = compiler->GetVersionString(); wxString pch_prepend = wxEmptyString; long gcc_major = 4; if ( !m_VerStr.IsEmpty() ) m_VerStr.BeforeFirst('.').ToLong(&gcc_major); bool HasPCH = false; // We don't know yet if there are any header files to be compiled... // for PCH to work, the very first include dir *must* be the object output dir // *only* if PCH is generated in the object output dir if (target && target->GetParentProject()->GetModeForPCH() == pchObjectDir) { wxArrayString includedDirs; // avoid adding duplicate dirs... wxString sep = wxFILE_SEP_PATH; // find all PCH in project for (FilesList::iterator it = target->GetParentProject()->GetFilesList().begin(); it != target->GetParentProject()->GetFilesList().end(); ++it) { ProjectFile* f = *it; if (FileTypeOf(f->relativeFilename) == ftHeader && f->compile) { // it is a PCH; add it's object dir to includes wxFileName fn(f->GetObjName()); wxString objName = (compiler->GetSwitches().UseFlatObjects) ? fn.GetFullName() : fn.GetFullPath(); wxString dir = wxFileName(target->GetObjectOutput() + sep + objName).GetPath(); if (includedDirs.Index(dir) == wxNOT_FOUND) { includedDirs.Add(dir); QuoteStringIfNeeded(dir); if ( gcc_major < 4 ) pch_prepend << compiler->GetSwitches().includeDirs << dir << _T(' '); else pch_prepend << _T("-iquote") << dir << _T(' '); } HasPCH = true; // there is at least one header file to be compiled } } // for gcc-4.0+, use the following: // pch_prepend << _T("-iquote") << dir << _T(' '); // for earlier versions, -I- must be used if ( gcc_major < 4 ) pch_prepend << _T("-I- "); int count = (int)includedDirs.GetCount(); for (int i = 0; i < count; ++i) { QuoteStringIfNeeded(includedDirs[i]); pch_prepend << compiler->GetSwitches().includeDirs << includedDirs[i] << _T(' '); } pch_prepend << _T("-I. "); } // add in array if (HasPCH) result.Prepend(pch_prepend); return result; }
void DisassemblyTextCtrl::SyncEditor(const wxString& filename, int line, bool setMarker) /// { if (setMarker) ClearActiveMarkFromAllEditors(); // wxString testfile(filename); FileType ft = FileTypeOf(filename); if (ft != ftSource && ft != ftHeader && ft != ftResource) return; // don't try to open unknown files cbProject* project = Manager::Get()->GetProjectManager()->GetActiveProject(); ProjectFile* f = project ? project->GetFileByFilename(filename, false, true) : 0; wxFileName fname(filename); if (project && fname.IsRelative()) fname.MakeAbsolute(project->GetBasePath()); // gdb can't work with spaces in filenames, so we have passed it the shorthand form (C:\MYDOCU~1 etc) // revert this change now so the file can be located and opened... // we do this by calling GetLongPath() cbEditor* ed = Manager::Get()->GetEditorManager()->Open(fname.GetLongPath()); if (ed) { ed->Show(true); if (f && !ed->GetProjectFile()) ed->SetProjectFile(f); ed->GotoLine(line - 1, false); if (setMarker) { ed->SetDebugLine(line - 1); ed->SetFirstVisibleLineA(line-5); } } // else // Log(_("Cannot open file: ") + fname.GetLongPath()); }
// ---------------------------------------------------------------------------- bool ThreadSearchFrame::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& files) // ---------------------------------------------------------------------------- { bool success = true; // Safe case initialisation // first check to see if a workspace is passed. If so, only this will be loaded wxString foundWorkspace; for (unsigned int i = 0; i < files.GetCount(); ++i) { FileType ft = FileTypeOf(files[i]); if (ft == ftCodeBlocksWorkspace || ft == ftMSVC6Workspace || ft == ftMSVC7Workspace) { foundWorkspace = files[i]; break; } } if (!foundWorkspace.IsEmpty()) success &= OpenGeneric(foundWorkspace); else { wxBusyCursor useless; wxPaintEvent e; ProcessEvent(e); Freeze(); for (unsigned int i = 0; i < files.GetCount(); ++i) success &= OpenGeneric(files[i]); Thaw(); } return success; }
cbDebuggerPlugin::SyncEditorResult cbDebuggerPlugin::SyncEditor(const wxString& filename, int line, bool setMarker) { if (setMarker) { EditorManager* edMan = Manager::Get()->GetEditorManager(); for (int i = 0; i < edMan->GetEditorsCount(); ++i) { cbEditor* ed = edMan->GetBuiltinEditor(i); if (ed) ed->SetDebugLine(-1); } } FileType ft = FileTypeOf(filename); if (ft != ftSource && ft != ftHeader && ft != ftResource) { // if the line is >= 0 and ft == ftOther assume, that we are in header without extension if (line < 0 || ft != ftOther) { ShowLog(false); Log(_("Unknown file: ") + filename, Logger::error); InfoWindow::Display(_("Unknown file"), _("File: ") + filename, 5000); return SyncFileUnknown; // don't try to open unknown files } } cbProject* project = Manager::Get()->GetProjectManager()->GetActiveProject(); ProjectFile* f = project ? project->GetFileByFilename(filename, false, true) : nullptr; wxString unixfilename = UnixFilename(filename); wxFileName fname(unixfilename); if (project && fname.IsRelative()) fname.MakeAbsolute(project->GetBasePath()); // gdb can't work with spaces in filenames, so we have passed it the shorthand form (C:\MYDOCU~1 etc) // revert this change now so the file can be located and opened... // we do this by calling GetLongPath() cbEditor* ed = Manager::Get()->GetEditorManager()->Open(fname.GetLongPath()); if (ed) { ed->Show(true); if (f && !ed->GetProjectFile()) ed->SetProjectFile(f); ed->GotoLine(line - 1, false); if (setMarker) ed->SetDebugLine(line - 1); return SyncOk; } else { ShowLog(false); Log(_("Cannot open file: ") + filename, Logger::error); InfoWindow::Display(_("Cannot open file"), _("File: ") + filename, 5000); return SyncFileNotFound; } }
bool ClangPlugin::IsSourceOf(const wxFileName& candidateFile, const wxFileName& activeFile, bool& isCandidate) { if (candidateFile.GetName().CmpNoCase(activeFile.GetName()) == 0) { isCandidate = (candidateFile.GetName() != activeFile.GetName()); if (FileTypeOf(candidateFile.GetFullName()) == ftSource) { if (candidateFile.GetPath() != activeFile.GetPath()) { wxArrayString fileArray; wxDir::GetAllFiles(candidateFile.GetPath(wxPATH_GET_VOLUME), &fileArray, candidateFile.GetName() + wxT(".*"), wxDIR_FILES | wxDIR_HIDDEN); for (size_t i = 0; i < fileArray.GetCount(); ++i) if (wxFileName(fileArray[i]).GetFullName() == activeFile.GetFullName()) return false; } return candidateFile.FileExists(); } } return false; }
void cbWorkspace::Load() { wxString fname = m_Filename.GetFullPath(); #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(F(_T("Loading workspace \"%s\""), fname.wx_str())); #else Manager::Get()->GetLogManager()->DebugLog(F(_T("Loading workspace \"%s\""), fname.c_str())); #endif if (!m_Filename.FileExists()) { Manager::Get()->GetLogManager()->DebugLog(_T("File does not exist.")); if (!m_IsDefault) { wxString msg; msg.Printf(_("Workspace '%s' does not exist..."), fname.c_str()); cbMessageBox(msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); // workspace wasn't loaded succesfully m_IsOK = false; return; } } if (FileTypeOf(fname) == ftCodeBlocksWorkspace) { IBaseWorkspaceLoader* pWsp = new WorkspaceLoader; wxString Title; m_IsOK = pWsp && (pWsp->Open(fname, Title) || m_IsDefault); if(!Title.IsEmpty()) { m_Title = Title; } delete pWsp; } m_Filename.SetExt(FileFilters::WORKSPACE_EXT); SetModified(false); }
/// This is to be used *only* for files not belonging to a project!!! wxArrayString DirectCommands::GetCleanSingleFileCommand(const wxString& filename) { wxArrayString ret; // lookup file's type FileType ft = FileTypeOf(filename); // is it compilable? if (ft != ftSource) return ret; wxFileName fname(filename); fname.SetExt(m_pCompiler->GetSwitches().objectExtension); wxString o_filename = fname.GetFullPath(); fname.SetExt(FileFilters::EXECUTABLE_EXT); // lcy set ext to file name. wxString exe_filename = fname.GetFullPath(); ret.Add(o_filename); ret.Add(exe_filename); return ret; }
// map target to pfDetails void ProjectFile::UpdateFileDetails(ProjectBuildTarget* target) { if (!project) return; if (!compile && !link) return; // update PCH output name (in case project PCH mode was changed) if (FileTypeOf(relativeFilename) == ftHeader) SetObjName(relativeToCommonTopLevelPath); if (!target) // update all targets { int tcount = project->GetBuildTargetsCount(); for (int x = 0; x < tcount; ++x) { ProjectBuildTarget* bt = project->GetBuildTarget(x); DoUpdateFileDetails(bt); } } else DoUpdateFileDetails(target); }
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; }
bool cbMGMakefile::formFileForTarget( ProjectBuildTarget *p_BuildTarget, wxTextFile &p_File ) { bool l_Ret = false; if ( !p_BuildTarget ) { 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()->GetLogManager()->DebugLog( l_Msg ); return l_Ret; } wxString l_TargetName = p_BuildTarget->GetTitle(); l_TargetName.Replace( _T( " " ), _T( "_" ) ); wxString l_ObjsName = _T("OBJS_") + l_TargetName.Upper(); wxString l_CmdBefore = cmdbefore + _T('_') + l_TargetName; wxString l_CmdAfter = cmdafter + _T('_') + l_TargetName; wxString l_CmdClean = cmdclean + _T('_') + l_TargetName; m_Rules.Clear(); const wxString& l_CompilerId = p_BuildTarget->GetCompilerID(); Compiler* l_pCompiler = CompilerFactory::GetCompiler( l_CompilerId ); if( !l_pCompiler ) { wxString l_Msg = _( "Can't found an compiler settings!\n" "C::B MakefileGen could not complete the operation." ); cbMessageBox( l_Msg, _( "Error" ), wxICON_ERROR | wxOK, (wxWindow *)Manager::Get()->GetAppWindow() ); Manager::Get()->GetLogManager()->DebugLog( l_Msg ); return false; } if ( !getDependencies( p_BuildTarget, l_pCompiler ) ) return false; if ( !m_VariablesIsSaved ) { 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 = p_BuildTarget->GetCommandsBeforeBuild(); const wxArrayString& l_CommandsAfterBuild = p_BuildTarget->GetCommandsAfterBuild(); wxString l_TargetFileName = p_BuildTarget->GetOutputFilename(); Manager::Get()->GetMacrosManager()->ReplaceMacros(l_TargetFileName, p_BuildTarget); #ifdef USE_PRINTLOG printLog( _T( "cbMGMakefile::formFileForTarget" ), l_TargetFileName ); #endif wxFileName l_OutFileName = UnixFilename(l_TargetFileName); wxString l_OutFileNameFullPath = l_OutFileName.GetFullPath(); QuoteStringIfNeeded( l_OutFileNameFullPath ); wxString l_OutFileNameFullPathMakefileFriendly = l_OutFileNameFullPath; ConvertToMakefileFriendly( l_OutFileNameFullPathMakefileFriendly ); cbMGRule l_Rule; if ( 0 == l_TargetName.CmpNoCase( _T( "default" ) ) ) { l_Rule.SetTarget( _T( "all" ) ); } else { l_Rule.SetTarget( l_TargetName ); } wxString l_Pre; if ( l_CommandsBeforeBuild.GetCount() > 0 ) { l_Pre = l_CmdBefore; } l_Pre += l_OutFileNameFullPathMakefileFriendly; if ( l_CommandsAfterBuild.GetCount() > 0 ) { l_Pre += _T(" ") + l_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( l_CmdBefore ); m_Rules.Add( l_Rule ); l_Rule.Clear(); l_Rule.SetTarget( l_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( l_CmdAfter ); m_Rules.Add( l_Rule ); l_Rule.Clear(); l_Rule.SetTarget( l_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_OutFileNameFullPathMakefileFriendly ); l_Rule.SetPrerequisites( _T("$(") + l_ObjsName + _T(")") ); wxString kind_of_output = _T( "unknown" ); CommandType ct = ctCount; bool l_TargetTypeValid = true; switch ( p_BuildTarget->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; default: l_TargetTypeValid = false; 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_OutFileNameFullPath ); if( l_TargetTypeValid ) { wxString l_LinkerCmd = l_pCompiler->GetCommand( ct ); #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(wxString::Format( _("LinkerCmd: %s"), l_LinkerCmd.wx_str()) ); #else Manager::Get()->GetLogManager()->DebugLog(wxString::Format( _("LinkerCmd: %s"), l_LinkerCmd.c_str()) ); #endif l_pCompiler->GenerateCommandLine( l_LinkerCmd, p_BuildTarget, NULL, l_OutFileNameFullPath, // _T("$$(") + l_TargetName + _T(")"), /* fix by oBFusCATed */ _T("$$(") + l_ObjsName + _T(")"), 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(p_BuildTarget,true,false); unsigned long lnb_files = files.GetCount(); // fix by Sasquatch_47 //need to clear the m_Objs string for cases where one is generating a makefile for more than one configuration m_Objs.clear(); for ( ii = 0; ii < lnb_files; ii++ ) { l_Rule.Clear(); ProjectFile* pf = files[ ii ]; const pfDetails& pfd = pf->GetFileDetails( p_BuildTarget ); 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; wxString l_SourceFileMakefileFriendly; if ( l_pCompiler->GetSwitches().UseFullSourcePaths ) { wxString l_fName = pfd.source_file_absolute_native; if( l_fName != wxEmptyString ) { #ifdef USE_DEBUGSAVE p_File.AddLine( _T("# File: ") + pfd.source_file_absolute_native ); p_File.AddLine( _T("# File: ") + l_fName ); p_File.AddLine( wxEmptyString ); #endif #ifdef USE_PRINTLOG printLog( _T( "cbMGMakefile::formFileForTarget" ), l_fName ); #endif l_SourceFile = UnixFilename( l_fName ); // 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; } l_SourceFileMakefileFriendly = l_SourceFile; ConvertToMakefileFriendly( l_SourceFileMakefileFriendly ); QuoteStringIfNeeded( l_SourceFile ); #if wxCHECK_VERSION(2, 9, 0) Manager::Get()->GetLogManager()->DebugLog(wxString::Format( _("CompilerCmd: %s"), l_CompilerCmd.wx_str()) ); #else Manager::Get()->GetLogManager()->DebugLog(wxString::Format( _("CompilerCmd: %s"), l_CompilerCmd.c_str()) ); #endif /* FIXME: traps after next command */ l_pCompiler->GenerateCommandLine( l_CompilerCmd, p_BuildTarget, pf, l_SourceFile, l_Object, pfd.object_file_flat, pfd.dep_file ); if ( m_Objs.size() ) { m_Objs += _T(' '); } m_Objs += l_Object; l_Rule.SetTarget( l_Object ); l_Rule.SetPrerequisites( l_SourceFileMakefileFriendly ); 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( l_CmdClean ); m_Rules.Add( l_Rule ); l_Rule.Clear(); l_Rule.SetTarget( l_CmdClean ); l_Rule.AddCommand( _T( "echo Delete $(" ) + l_ObjsName + _T( ") " ) + l_OutFileNameFullPath ); #ifdef __WXMSW__ l_Rule.AddCommand( _T( "-del /f $(" ) + l_ObjsName + _T( ") " ) + l_OutFileNameFullPath ); #else l_Rule.AddCommand( _T( "-rm -f $(" ) + l_ObjsName + _T( ") " ) + l_OutFileNameFullPath ); #endif m_Rules.Add( l_Rule ); if ( !m_VariablesIsSaved ) { m_Variables.SaveAllVars( p_File ); m_VariablesIsSaved = true; } p_File.AddLine( _T("# Target: ") + l_TargetName ); p_File.AddLine( wxEmptyString ); p_File.AddLine( l_ObjsName + _T("=") + m_Objs ); p_File.AddLine( wxEmptyString ); SaveAllRules( p_File ); p_File.AddLine( wxEmptyString ); p_File.AddLine( wxEmptyString ); l_Ret = true; return l_Ret; }
void ProjectFile::SetObjName(const wxString& name) { bool extendedObjectNames = project->GetExtendedObjectNamesGeneration(); wxFileName fname(name); m_ObjName = name; FileType ft = FileTypeOf(name); if (ft == ftResource || ft == ftResourceBin) { if (extendedObjectNames) m_ObjName += FileFilters::RESOURCEBIN_DOT_EXT; else { fname.SetExt(FileFilters::RESOURCEBIN_EXT); m_ObjName = fname.GetFullPath(); } } else if (ft == ftHeader) // support precompiled headers? { Compiler* compiler = CompilerFactory::GetCompiler(project->GetCompilerID()); if (compiler && compiler->GetSwitches().supportsPCH) { // PCHs are always using the extended name mode (at least for GCC) // the extension is set to "h.gch" if (project->GetModeForPCH() == pchSourceFile) fname.Assign(relativeFilename); fname.SetExt(compiler->GetSwitches().PCHExtension); m_ObjName = fname.GetFullPath(); } } else { if (project) { Compiler* compiler = CompilerFactory::GetCompiler(project->GetCompilerID()); if (compiler) { if (extendedObjectNames) m_ObjName += _T('.') + compiler->GetSwitches().objectExtension; else { fname.SetExt(compiler->GetSwitches().objectExtension); m_ObjName = fname.GetFullPath(); } } } else { if (extendedObjectNames) m_ObjName += _T(".o"); // fallback? else { fname.SetExt(_T(".o")); m_ObjName = fname.GetFullPath(); } } } //#ifdef __WXMSW__ // // special case for windows and files on a different drive // if (name.Length() > 1 && name.GetChar(1) == _T(':')) // { // m_ObjName.Remove(1, 1); // NOTE (mandrav): why remove the colon??? // } //#endif }
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; }
cbProject* ProjectManager::LoadProject(const wxString& filename, bool activateIt) { cbProject* result = nullptr; if (!wxFileExists(filename) || !BeginLoadingProject()) { return nullptr; } // "Try" block (loop which only gets executed once) // These blocks are extremely useful in constructs that need // premature exits. Instead of having multiple return points, // multiple return values and/or gotos, // you just break out of the loop (which only gets executed once) to exit. do { cbProject* project = IsOpen(filename); if (project) { // already open result = project; break; } if (FileTypeOf(filename) == ftCodeBlocksProject) { project = new cbProject(filename); // We need to do this because creating cbProject allows the app to be // closed in the middle of the operation. So the class destructor gets // called in the middle of a method call. if (!project->IsLoaded()) { delete project; break; } result = project; } else // !ftCodeBlocksProject { // the plugin handler should call begin/end on its own... EndLoadingProject(nullptr); cbMimePlugin* plugin = Manager::Get()->GetPluginManager()->GetMIMEHandlerForFile(filename); if (plugin) plugin->OpenFile(filename); } break; } while (false); // we 're done EndLoadingProject(result); if (activateIt) { if (m_IsLoadingWorkspace) // postpone the call to SetProject() until EndLoadingWorkspace() is called // (we must call RebuildTree() before SetProject() is called) m_pProjectToActivate = result; else SetProject(result, true); } return result; }
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; }
//{ CppCheck int CppCheck::ExecuteCppCheck(cbProject* Project) { if ( !DoVersion(_T("cppcheck"), _T("cppcheck_app")) ) return -1; TCppCheckAttribs CppCheckAttribs; wxFile InputFile; CppCheckAttribs.InputFileName = _T("CppCheckInput.txt"); if ( !InputFile.Create(CppCheckAttribs.InputFileName, true) ) { cbMessageBox(_("Failed to create input file 'CppCheckInput.txt' for cppcheck.\nPlease check file/folder access rights."), _("Error"), wxICON_ERROR | wxOK, Manager::Get()->GetAppWindow()); return -1; } for (FilesList::iterator it = Project->GetFilesList().begin(); it != Project->GetFilesList().end(); ++it) { ProjectFile* pf = *it; // filter to avoid including non C/C++ files if ( pf->relativeFilename.EndsWith(FileFilters::C_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CPP_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CC_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CXX_DOT_EXT) || pf->relativeFilename.EndsWith(FileFilters::CPLPL_DOT_EXT) || (FileTypeOf(pf->relativeFilename) == ftHeader) || (FileTypeOf(pf->relativeFilename) == ftTemplateSource) ) { InputFile.Write(pf->relativeFilename + _T("\n")); } } InputFile.Close(); MacrosManager* MacrosMgr = Manager::Get()->GetMacrosManager(); ProjectBuildTarget* Target = Project->GetBuildTarget(Project->GetActiveBuildTarget()); // project include dirs const wxArrayString& IncludeDirs = Project->GetIncludeDirs(); for (unsigned int Dir = 0; Dir < IncludeDirs.GetCount(); ++Dir) { wxString IncludeDir(IncludeDirs[Dir]); if (Target) MacrosMgr->ReplaceMacros(IncludeDir, Target); else MacrosMgr->ReplaceMacros(IncludeDir); CppCheckAttribs.IncludeList += _T("-I\"") + IncludeDir + _T("\" "); } if (Target) { // target include dirs const wxArrayString& targetIncludeDirs = Target->GetIncludeDirs(); for (unsigned int Dir = 0; Dir < targetIncludeDirs.GetCount(); ++Dir) { wxString IncludeDir(targetIncludeDirs[Dir]); MacrosMgr->ReplaceMacros(IncludeDir, Target); CppCheckAttribs.IncludeList += _T("-I\"") + IncludeDir + _T("\" "); } } // project #defines const wxArrayString& Defines = Project->GetCompilerOptions(); for (unsigned int Opt = 0; Opt < Defines.GetCount(); ++Opt) { wxString Define(Defines[Opt]); if (Target) MacrosMgr->ReplaceMacros(Define, Target); else MacrosMgr->ReplaceMacros(Define); if ( Define.StartsWith(_T("-D")) ) CppCheckAttribs.DefineList += Define + _T(" "); } if (Target) { // target #defines const wxArrayString& targetDefines = Target->GetCompilerOptions(); for (unsigned int Opt = 0; Opt < targetDefines.GetCount(); ++Opt) { wxString Define(targetDefines[Opt]); MacrosMgr->ReplaceMacros(Define, Target); if ( Define.StartsWith(_T("-D")) ) CppCheckAttribs.DefineList += Define + _T(" "); } } return DoCppCheckExecute(CppCheckAttribs); }
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); }
int CodeBlocksApp::ParseCmdLine(MainFrame* handlerFrame, const wxString& CmdLineString) { // code shamelessely taken from the console wxWindows sample :) bool filesInCmdLine = false; #if wxUSE_CMDLINE_PARSER wxCmdLineParser& parser = *Manager::GetCmdLineParser(); if ( CmdLineString.IsEmpty() ) parser.SetCmdLine(argc, argv); else parser.SetCmdLine(CmdLineString); // wxApp::argc is a wxChar** // don't display errors as plugins will have the chance to parse the command-line // too, so we don't know here what exactly are the supported options int res = parser.Parse(false); if (res == -1) { return -1; } else { if (handlerFrame) { m_HasProject = false; m_HasWorkSpace = false; int count = parser.GetParamCount(); parser.Found(_T("file"), &m_AutoFile); filesInCmdLine = (count != 0) || (!m_AutoFile.empty()); for (int param = 0; param < count; ++param) { // is it a project/workspace? FileType ft = FileTypeOf(parser.GetParam(param)); wxFileName fn(parser.GetParam(param)); fn.Normalize(); // really important so that two same files with different names are not loaded twice if (ft == ftCodeBlocksProject) { m_HasProject = true; m_DelayedFilesToOpen.Add(parser.GetParam(param)); } else if (ft == ftCodeBlocksWorkspace) { // only one workspace can be opened m_HasWorkSpace = true; m_DelayedFilesToOpen.Clear(); // remove all other files m_DelayedFilesToOpen.Add(fn.GetFullPath()); // and add only the workspace break; // and stop processing any more files } //else if (ft == ftSource || ft == ftHeader || ft == ftResource) else if (wxFile::Exists(fn.GetFullPath())) //also try to open non source, header and resource files { m_DelayedFilesToOpen.Add(fn.GetFullPath()); } } // batch jobs m_Batch = m_HasProject || m_HasWorkSpace; m_Batch = m_Batch && (m_Build || m_ReBuild || m_Clean); } else { wxString val; parser.Found(_T("prefix"), &m_Prefix); parser.Found(_T("user-data-dir"), &m_UserDataDir); #ifdef __WXMSW__ m_DDE = !parser.Found(_T("no-dde")); m_Assocs = !parser.Found(_T("no-check-associations")); #else m_DDE = !parser.Found(_T("no-ipc")); #endif m_SafeMode = parser.Found(_T("safe-mode")); m_Splash = !parser.Found(_T("no-splash-screen")); m_HasDebugLog = parser.Found(_T("debug-log")); m_CrashHandler = !parser.Found(_T("no-crash-handler")); wxLog::EnableLogging(parser.Found(_T("verbose"))); if ( parser.Found(_T("personality"), &val) || parser.Found(_T("profile"), &val) ) { SetupPersonality(val); } // batch jobs m_BatchNotify = parser.Found(_T("batch-build-notify")); m_BatchWindowAutoClose = !parser.Found(_T("no-batch-window-close")); m_Build = parser.Found(_T("build")); m_ReBuild = parser.Found(_T("rebuild")); m_Clean = parser.Found(_T("clean")); parser.Found(_T("target"), &m_BatchTarget); parser.Found(_T("script"), &m_Script); // initial setting for batch flag (will be reset when ParseCmdLine() is called again). m_Batch = m_Build || m_ReBuild || m_Clean; if (parser.Found(_T("no-log")) == false) Manager::Get()->GetLogManager()->SetLog(new TextCtrlLogger, LogManager::app_log); if (parser.Found(_T("log-to-file"))) Manager::Get()->GetLogManager()->SetLog(new FileLogger(_T("codeblocks.log")), LogManager::app_log); if (m_HasDebugLog) Manager::Get()->GetLogManager()->SetLog(new TextCtrlLogger, LogManager::debug_log); if (parser.Found(_T("debug-log-to-file"))) Manager::Get()->GetLogManager()->SetLog(new FileLogger(_T("codeblocks-debug.log")), LogManager::debug_log); } // Always parse the debugger attach parameters. parser.Found(_T("dbg-attach"), &m_DebuggerAttach); parser.Found(_T("dbg-config"), &m_DebuggerConfig); } #endif // wxUSE_CMDLINE_PARSER return filesInCmdLine ? 1 : 0; }
/// This is to be used *only* for files not belonging to a project!!! wxArrayString DirectCommands::GetCompileSingleFileCommand(const wxString& filename) { wxArrayString ret; // lookup file's type FileType ft = FileTypeOf(filename); // is it compilable? if (ft != ftSource) return ret; wxFileName fname(filename); fname.SetExt(m_pCompiler->GetSwitches().objectExtension); wxString o_filename = fname.GetFullPath(); wxString srcExt = fname.GetExt(); // if(m_pCompiler->GetName().Matches(_T("dsp"))) /// 2012-8-27 lcy // fname.SetExt(FileFilters::DSP563_EXT); // else if(m_pCompiler->GetName().Matches(_T("mc"))) // fname.SetExt(FileFilters::OR32_EXT); // else fname.SetExt(FileFilters::EXECUTABLE_EXT); wxString exe_filename = fname.GetFullPath(); wxString s_filename = filename; QuoteStringIfNeeded(s_filename); QuoteStringIfNeeded(o_filename); Compiler* compiler = CompilerFactory::GetDefaultCompiler(); wxString compilerCmd = compiler->GetCommand(ctCompileObjectCmd, srcExt); compiler->GenerateCommandLine(compilerCmd, 0, 0, s_filename, o_filename, o_filename, wxEmptyString); wxString linkerCmd = compiler->GetCommand(ctLinkConsoleExeCmd, fname.GetExt()); compiler->GenerateCommandLine(linkerCmd, 0, 0, wxEmptyString, o_filename, o_filename, wxEmptyString); // wxString asmCmd = compiler->GetCommand(ctCompileAsmCmd, _T("asm")); /// 2012-8-27 lcy // compiler->GenerateCommandLine(asmCmd, // 0, // 0, // wxEmptyString, // o_filename, // o_filename, // wxEmptyString); if (!compilerCmd.IsEmpty()) // my 2 { switch (m_pCompiler->GetSwitches().logging) { case clogFull: ret.Add(wxString(COMPILER_SIMPLE_LOG) + compilerCmd); break; case clogSimple: ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Compiling: ") + filename); break; default: break; } AddCommandsToArray(compilerCmd, ret); } else ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping file (no compiler program set): ") + filename); if (!linkerCmd.IsEmpty()) { switch (m_pCompiler->GetSwitches().logging) { case clogFull: ret.Add(wxString(COMPILER_SIMPLE_LOG) + linkerCmd); break; default: ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking console executable: ") + exe_filename); break; } AddCommandsToArray(linkerCmd, ret, true); } else ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping linking (no linker program set): ") + exe_filename); // if (!asmCmd.IsEmpty()) // { // switch (m_pCompiler->GetSwitches().logging) // { // case clogFull: // ret.Add(wxString(COMPILER_SIMPLE_LOG) + asmCmd); // break; // // default: // ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking console executable: ") + exe_filename); // break; // } // AddCommandsToArray(asmCmd, ret, true); // } // else // ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping linking (no linker program set): ") + exe_filename); return ret; }
// ---------------------------------------------------------------------------- bool ThreadSearchFrame::OpenGeneric(const wxString& filename, bool addToHistory) // ---------------------------------------------------------------------------- { if (filename.IsEmpty()) return false; // Split the window to show notebook and file panel //(pecan 2008/5/19) if (not GetConfig()->GetThreadSearchPlugin() ) return false; GetConfig()->GetThreadSearchPlugin()->SplitThreadSearchWindow(); wxFileName fname(filename); fname.ClearExt(); fname.SetExt(_T("cbp")); switch(FileTypeOf(filename)) { // // Workspace // ////case ftCodeBlocksWorkspace: //// // verify that it's not the same as the one already open //// if (filename != Manager::Get()->GetProjectManager()->GetWorkspace()->GetFilename() && //// DoCloseCurrentWorkspace()) //// { //// wxBusyCursor wait; // loading a worspace can take some time -> showhourglass //// bool ret = Manager::Get()->GetProjectManager()->LoadWorkspace(filename); //// if (ret && addToHistory) //// AddToRecentProjectsHistory(Manager::Get()->GetProjectManager()->GetWorkspace()->GetFilename()); //// return ret; //// } //// else //// return false; //// break; // // Project // ////case ftCodeBlocksProject: ////{ //// // Make a check whether the project exists in current workspace //// cbProject* prj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath()); //// if (!prj) //// { //// wxBusyCursor wait; // loading a worspace can take some time -> showhourglass //// return DoOpenProject(filename, addToHistory); //// } //// else //// { //// // NOTE (Morten#1#): A message here will prevent batch-builds from working and is shown sometimes even if correct //// Manager::Get()->GetProjectManager()->SetProject(prj, false); //// return true; //// } ////} // // Source files // case ftHeader: // fallthrough case ftSource: // fallthrough case ftResource: return DoOpenFile(filename, addToHistory); // // For all other files, ask MIME plugin for a suitable handler // default: { ////cbMimePlugin* plugin = Manager::Get()->GetPluginManager()->GetMIMEHandlerForFile(filename); ////// warn user that "Files extension handler" is disabled ////if (!plugin) ////{ //// cbMessageBox(_("Could not open file ") + filename + _(",\nbecause no extension handler could be found."), _("Error"), wxICON_ERROR); //// return false; ////} ////if (plugin->OpenFile(filename) == 0) ////{ //// AddToRecentFilesHistory(filename); //// return true; ////} ////return false; return DoOpenFile(filename, addToHistory); //(pecan 2008/3/15) }//default } 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; }
/// This is to be used *only* for files not belonging to a project!!! wxArrayString DirectCommands::GetCompileSingleFileCommand(const wxString& filename) const { wxArrayString ret; // lookup file's type FileType ft = FileTypeOf(filename); // is it compilable? if (ft != ftSource) return ret; wxFileName fname(filename); fname.SetExt(m_pCompiler->GetSwitches().objectExtension); wxString o_filename = fname.GetFullPath(); wxString srcExt = fname.GetExt(); fname.SetExt(FileFilters::EXECUTABLE_EXT); wxString exe_filename = fname.GetFullPath(); wxString s_filename = filename; QuoteStringIfNeeded(s_filename); QuoteStringIfNeeded(o_filename); Compiler* compiler = CompilerFactory::GetDefaultCompiler(); if (!compiler) return ret; // please leave this check here for convenience: single file compilation is "special" if (!m_pGenerator) cbThrow(_T("Command generator not initialised through ctor!")); wxString compilerCmd = compiler->GetCommand(ctCompileObjectCmd, srcExt); m_pGenerator->GenerateCommandLine(compilerCmd, 0, 0, s_filename, o_filename, o_filename, wxEmptyString); wxString linkerCmd = compiler->GetCommand(ctLinkConsoleExeCmd, fname.GetExt()); m_pGenerator->GenerateCommandLine(linkerCmd, 0, 0, wxEmptyString, o_filename, o_filename, wxEmptyString); if (!compilerCmd.IsEmpty()) { switch (m_pCompiler->GetSwitches().logging) { case clogFull: ret.Add(COMPILER_SIMPLE_LOG + compilerCmd); break; case clogSimple: ret.Add(COMPILER_SIMPLE_LOG + _("Compiling: ") + filename); break; case clogNone: // fall-through default: break; } AddCommandsToArray(compilerCmd, ret); } else ret.Add(COMPILER_SIMPLE_LOG + _("Skipping file (no compiler program set): ") + filename); if (!linkerCmd.IsEmpty()) { switch (m_pCompiler->GetSwitches().logging) { case clogFull: ret.Add(COMPILER_SIMPLE_LOG + linkerCmd); break; case clogSimple: // fall-through case clogNone: // fall-through default: // linker always simple log (if not full) ret.Add(COMPILER_SIMPLE_LOG + _("Linking console executable: ") + exe_filename); break; } AddCommandsToArray(linkerCmd, ret, true); } else ret.Add(COMPILER_SIMPLE_LOG + _("Skipping linking (no linker program set): ") + exe_filename); 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; }
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; }
void ClangPlugin::OnTimer(wxTimerEvent& event) { if (!IsAttached()) return; const int evId = event.GetId(); if (evId == idEdOpenTimer) { cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor(); if (!ed || !IsProviderFor(ed)) return; else if (m_Proxy.GetTranslationUnitId(ed->GetFilename()) != wxNOT_FOUND) { m_DiagnosticTimer.Start(DIAGNOSTIC_DELAY, wxTIMER_ONE_SHOT); return; } wxString compileCommand; ProjectFile* pf = ed->GetProjectFile(); ProjectBuildTarget* target = nullptr; Compiler* comp = nullptr; if (pf && pf->GetParentProject() && !pf->GetBuildTargets().IsEmpty() ) { target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]); comp = CompilerFactory::GetCompiler(target->GetCompilerID()); if (pf->GetUseCustomBuildCommand(target->GetCompilerID())) { compileCommand = pf->GetCustomBuildCommand(target->GetCompilerID()).AfterFirst(wxT(' ')); } } if (compileCommand.IsEmpty()) compileCommand = wxT("$options $includes"); cbProject* proj = (pf ? pf->GetParentProject() : nullptr); if (!comp && proj) comp = CompilerFactory::GetCompiler(proj->GetCompilerID()); if (!comp) { cbProject* tmpPrj = Manager::Get()->GetProjectManager()->GetActiveProject(); if (tmpPrj) comp = CompilerFactory::GetCompiler(tmpPrj->GetCompilerID()); } if (!comp) comp = CompilerFactory::GetDefaultCompiler(); comp->GetCommandGenerator(proj)->GenerateCommandLine(compileCommand, target, pf, ed->GetFilename(), g_InvalidStr, g_InvalidStr, g_InvalidStr ); wxStringTokenizer tokenizer(compileCommand); compileCommand.Empty(); wxString pathStr; while (tokenizer.HasMoreTokens()) { wxString flag = tokenizer.GetNextToken(); // make all include paths absolute, so clang does not choke if Code::Blocks switches directories if (flag.StartsWith(wxT("-I"), &pathStr)) { wxFileName path(pathStr); if (path.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE)) flag = wxT("-I") + path.GetFullPath(); } compileCommand += flag + wxT(" "); } compileCommand += GetCompilerInclDirs(comp->GetID()); if (FileTypeOf(ed->GetFilename()) == ftHeader) // try to find the associated source { const wxString& source = GetSourceOf(ed); if (!source.IsEmpty()) { m_Proxy.CreateTranslationUnit(source, compileCommand); if (m_Proxy.GetTranslationUnitId(ed->GetFilename()) != wxNOT_FOUND) return; // got it } } m_Proxy.CreateTranslationUnit(ed->GetFilename(), compileCommand); m_DiagnosticTimer.Start(DIAGNOSTIC_DELAY, wxTIMER_ONE_SHOT); } else if (evId == idReparseTimer) { EditorManager* edMgr = Manager::Get()->GetEditorManager(); cbEditor* ed = edMgr->GetBuiltinActiveEditor(); if (!ed) return; if (ed != m_pLastEditor) { m_TranslUnitId = m_Proxy.GetTranslationUnitId(ed->GetFilename()); m_pLastEditor = ed; } if (m_TranslUnitId == wxNOT_FOUND) return; std::map<wxString, wxString> unsavedFiles; for (int i = 0; i < edMgr->GetEditorsCount(); ++i) { ed = edMgr->GetBuiltinEditor(i); if (ed && ed->GetModified()) unsavedFiles.insert(std::make_pair(ed->GetFilename(), ed->GetControl()->GetText())); } m_Proxy.Reparse(m_TranslUnitId, unsavedFiles); DiagnoseEd(m_pLastEditor, dlMinimal); } else if (evId == idDiagnosticTimer) { cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor(); if (!ed) return; if (ed != m_pLastEditor) { m_TranslUnitId = m_Proxy.GetTranslationUnitId(ed->GetFilename()); m_pLastEditor = ed; } if (m_TranslUnitId == wxNOT_FOUND) return; DiagnoseEd(ed, dlFull); } else event.Skip(); }