private void buildDone(vsBuildScope scope, vsBuildAction action) { // fill it up taskbarItemInfo.ProgressValue = 1; // keep it red if (taskbarItemInfo.ProgressState != TaskbarItemProgressState.Error) { taskbarItemInfo.ProgressState = TaskbarItemProgressState.None; } if (scope != vsBuildScope.vsBuildScopeSolution) { return; } string msg = String.Format("Total build time: {0}", DateTime.Now - _buildStartTime); _vspkg.writeToBuildWindow("\n" + msg); _vspkg.writeStatus(msg); }
// 1: show assembly code for currently open source file // 2: show preprocessed source code private void showCppOutput(int mode = 1) { // if in a header try to open the cpp file switchToCppFile(); // get the currently active document from the IDE Document doc = dte.ActiveDocument; TextDocument tdoc = doc.Object("TextDocument") as TextDocument; if (tdoc == null) { package.showMsgBox("Could not obtain the active TextDocument object"); return; } // get currently viewed function string functionOfInterest = ""; TextSelection selection = tdoc.Selection; CodeElement codeEl = selection.ActivePoint.CodeElement[vsCMElement.vsCMElementFunction]; if (codeEl == null) { dte.StatusBar.Text = "You should place the cursor inside a function."; dte.StatusBar.Highlight(true); } else { functionOfInterest = codeEl.FullName; } // TODO: in case of a template this gets something like funcName<T>, the assembly contains funcName<actualType> // it doesn't in the case of macros either, e.g. gets _tmain but in the asm it will be wmain // http://www.viva64.com/en/a/0082/#ID0ELOBK // EditPoint directly manipulates text buffer data instead of operating with the text through the editor UI. int line = selection.ActivePoint.Line; EditPoint editPoint = tdoc.CreateEditPoint(); string curCodeLine = editPoint.GetLines(line, line + 1); // TODO: comments are removed when preprocessing and thus can't find a line with comments // get current configuration Project proj = doc.ProjectItem.ContainingProject; ConfigurationManager mgr = proj.ConfigurationManager; string platform = mgr.ActiveConfiguration.PlatformName; string conf = mgr.ActiveConfiguration.ConfigurationName; // find the currently active configuration for the current file // don't use SolutionBuild as there may be mixed platforms // use late binding for version independence dynamic file = doc.ProjectItem.Object; // as VCFile dynamic fileconfigs = file.FileConfigurations; // as IVCCollection dynamic fileconfig = fileconfigs.Item(conf + "|" + platform); // as VCFileConfiguration dynamic tool = fileconfig.Tool; // VCCLCompilerTool // save original settings to restore them later // there seems to be no better way // DTE undo contexts doesn't cover these project settings // unload/reload the project may close all open files // manipulating proj.Saved or .IsDirty does not work bool lto = tool.WholeProgramOptimization; dynamic asmtype = tool.AssemblerOutput; dynamic genPreprocessed = tool.GeneratePreprocessedFile; string asmloc = tool.AssemblerListingLocation; string objFileLocation = tool.ObjectFile; string generatedFile; if (mode == 1) { // asmListingAsmSrc => '.asm' generatedFile = Path.GetTempFileName() + ".asm"; //System.IO.Path.GetTempPath tool.WholeProgramOptimization = false; tool.AssemblerOutput = (dynamic)Enum.Parse(tool.AssemblerOutput.GetType(), "asmListingAsmSrc"); tool.AssemblerListingLocation = generatedFile; } else /*if (mode == 2)*/ { // not generally applicable //generatedFile = prj.ProjectDirectory + prjconfig.IntermediateDirectory + Replace(file.Name, ".cpp", ".i"); generatedFile = Path.GetTempFileName() + ".cpp"; tool.GeneratePreprocessedFile = (dynamic)Enum.Parse(tool.GeneratePreprocessedFile.GetType(), "preprocessYes"); // there's no separate option for this, so misuse /Fo tool.ObjectFile = generatedFile; } try { // forceBuild (even if up-to-date) and waitOnBuild fileconfig.Compile(true, true); } catch (Exception e) { package.writeStatus($"VCFileConfiguration.Compile() failed: {e.Message}. Trying command Build.Compile now..."); _dispBuildEvents_OnBuildProjConfigDoneEventHandler onProjBuildDone = null; onProjBuildDone = (project, projectConfig, platfrm, solutionConfig, success) => { dte.Events.BuildEvents.OnBuildProjConfigDone -= onProjBuildDone; // naive cleanup if (mode == 1) { tool.WholeProgramOptimization = lto; tool.AssemblerOutput = asmtype; tool.AssemblerListingLocation = asmloc; } else if (mode == 2) { tool.GeneratePreprocessedFile = genPreprocessed; tool.ObjectFile = objFileLocation; } if (success) { postCompileCpp(generatedFile, mode, functionOfInterest, curCodeLine); } }; dte.Events.BuildEvents.OnBuildProjConfigDone += onProjBuildDone; dte.ExecuteCommand("Build.Compile"); return; } // naive cleanup if (mode == 1) { tool.WholeProgramOptimization = lto; tool.AssemblerOutput = asmtype; tool.AssemblerListingLocation = asmloc; } else if (mode == 2) { tool.GeneratePreprocessedFile = genPreprocessed; tool.ObjectFile = objFileLocation; } postCompileCpp(generatedFile, mode, functionOfInterest, curCodeLine); }