private async Task <SourceFile> CreateSourceFileAsync(string filePath, Configuration targetConfig, Project realProject) { try { await JoinableTaskFactory.SwitchToMainThreadAsync(); dynamic project = realProject.Object; String configurationName = targetConfig.ConfigurationName; dynamic config = project.Configurations.Item(configurationName); String toolSetName = "Win32"; if (config == null) { String targetConfigName = string.Format("{0}|{1}", configurationName, targetConfig.PlatformName); foreach (dynamic cfg in project.Configurations) { String configName = cfg.Name.ToString() as String; if (configName == targetConfigName) { config = cfg; toolSetName = targetConfig.PlatformName; break; } } } else { toolSetName = config.PlatformToolsetShortName; } if (String.IsNullOrEmpty(toolSetName)) { toolSetName = config.PlatformToolsetFriendlyName; } String projectDirectory = project.ProjectDirectory; String projectName = project.Name; SourceFile sourceForAnalysis = new SourceFile(filePath, projectDirectory, projectName); dynamic toolsCollection = config.Tools; foreach (var tool in toolsCollection) { // Project-specific includes if (ImplementsInterface(tool, "Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool")) { sourceForAnalysis.AddMacro("_DEBUG"); sourceForAnalysis.AddMacro("_MT"); var runTimeLib = (int)tool.RuntimeLibrary; if (1 == runTimeLib || 0 == runTimeLib) { } else if (3 == runTimeLib) { sourceForAnalysis.AddMacro("_DLL"); } else { throw new Exception("Not supported run time library - are you sure you are in debug mode?"); } String includes = tool.FullIncludePath; String definitions = GetAttributeFromProject("PreprocessorDefinitions", filePath, targetConfig, realProject); string languageStandard = GetAttributeFromProject("LanguageStandard", filePath, targetConfig, realProject); string languageFlag = "/std:c++14"; if (languageStandard == "stdcpplatest") { languageFlag = "/std:c++latest"; } else if (languageStandard == "stdcpp17") { languageFlag = "/std:c++17"; } string warningLevel = ""; string warningLevelString = GetAttributeFromProject("WarningLevel", filePath, targetConfig, realProject); if (warningLevelString.StartsWith("TurnOffAllWarnings")) { warningLevel = "/W0"; } else if (warningLevelString == "Level1") { warningLevel = "/W1"; } else if (warningLevelString == "Level2") { warningLevel = "/W2"; } else if (warningLevelString == "Level3") { warningLevel = "/W3"; } else if (warningLevelString == "Level4") { warningLevel = "/W4"; } else { warningLevel = "/Wall"; } string setWarningAsError = ""; string setWarningAsErrorString = GetAttributeFromProject("TreatWarningAsError", filePath, targetConfig, realProject); if (setWarningAsErrorString.StartsWith("true")) { setWarningAsError = "/WX"; } else { setWarningAsError = "/WX-"; } String macrosToUndefine = tool.UndefinePreprocessorDefinitions; String[] includePaths = includes.Split(';'); for (int i = 0; i < includePaths.Length; ++i) { includePaths[i] = Environment.ExpandEnvironmentVariables(config.Evaluate(includePaths[i])); } ; sourceForAnalysis.LanguageStandard = languageFlag; sourceForAnalysis.AddIncludePaths(includePaths); sourceForAnalysis.AddIncludePath("."); sourceForAnalysis.AddMacros(definitions.Split(';')); sourceForAnalysis.TreatWarningAsError = setWarningAsError; sourceForAnalysis.WarningLevel = warningLevel; sourceForAnalysis.AddMacrosToUndefine(macrosToUndefine.Split(';')); break; } } return(sourceForAnalysis); } catch (Exception ex) { AddTextToOutputWindow(ex.Message); return(null); } }
void Link(SourceFile sourceFile) { SaveOpenedFiles(); var thread = new System.Threading.Thread(() => { try { if (!IsWindbgPluginLoaded()) { throw new Exception("windbg plugin is not loaded - please load it first."); } else { AddTextToOutputWindow("Sending blink request to windbg plugin."); } Channel channel = new Channel("127.0.0.1:30051", ChannelCredentials.Insecure); var client = new Greeter.GreeterClient(channel); string compilationFlags = ""; foreach (var include in sourceFile.IncludePaths) { var newInclude = include; if (newInclude.EndsWith("\\")) { newInclude = include.Substring(0, include.Length - 1); } compilationFlags += "/imsvc\"" + newInclude + "\"" + " "; } foreach (var define in sourceFile.Macros) { compilationFlags += "/D\"" + define + "\"" + " "; } compilationFlags += sourceFile.TreatWarningAsError + " "; compilationFlags += sourceFile.WarningLevel + " "; compilationFlags += sourceFile.LanguageStandard + " "; JoinableTaskFactory.Run(async() => { var reply = client.Compile(new LinkCommandRequest { ClangFilePath = Environment.ExpandEnvironmentVariables(@"%BSOD_SURVIVOR_DIR%\bin\clang-cl.exe"), LdPath = Environment.ExpandEnvironmentVariables(@"%BSOD_SURVIVOR_DIR%\bin\lld-link.exe"), MasmPath = @"ml64.exe", CompilationFlags = compilationFlags, FilePath = sourceFile.FilePath, LinkerFlags = "", ObjCopyPath = Environment.ExpandEnvironmentVariables(@"%BSOD_SURVIVOR_DIR%\bin\llvm-objcopy.exe") }); while (await reply.ResponseStream.MoveNext()) { if (reply.ResponseStream.Current.IsLogging) { string message = reply.ResponseStream.Current.Message; string newNamePrefix = "$$__$$"; if (message.IndexOf(newNamePrefix) != -1 && -1 == message.IndexOf("starting to") && message.IndexOf("clang-cl") != -1) { var error = message.Substring(message.IndexOf("\n")); var last = error.IndexOf("(", error.IndexOf(newNamePrefix)); var start = error.LastIndexOf("\n", error.IndexOf(newNamePrefix)) + 1; if (last != -1 && start != -1) { var fileName = error.Substring(start, last - start); message = message.Replace(fileName, sourceFile.FilePath); } } AddTextToOutputWindow(message); } else { if (!reply.ResponseStream.Current.Success) { throw new Exception(String.Format("Failed to link {0} with error:\n {1}", sourceFile.FilePath, reply.ResponseStream.Current.Message)); } } } AddTextToOutputWindow("Link succeeded"); MessageBox.Show("Linking succeeded"); }); } catch (Exception e) { AddTextToOutputWindow(e.Message); MessageBox.Show("Linking failed, please see output window for more details."); } }); thread.Start(); }
private async Task <List <ConfiguredFiles> > GetActiveSelectionsAsync() { Dictionary <Project, ConfiguredFiles> confMap = new Dictionary <Project, ConfiguredFiles>(); foreach (SelectedItem selItem in _dte.SelectedItems) { Project project = null; if (project == null && selItem.ProjectItem != null) { project = selItem.ProjectItem.ContainingProject; } if (project == null) { project = selItem.Project; } if (project == null || !IsVisualCppProject(project.Kind)) { continue; } Configuration configuration = await GetConfigurationAsync(project); if (!confMap.ContainsKey(project)) { // create new Map key entry for project ConfiguredFiles configuredFiles = new ConfiguredFiles(); confMap.Add(project, configuredFiles); configuredFiles.Files = new List <SourceFile>(); configuredFiles.Configuration = configuration; } ConfiguredFiles currentConfiguredFiles = confMap[project]; if (currentConfiguredFiles == null) { continue; } if (selItem.ProjectItem == null) { // project selected List <SourceFile> projectSourceFileList = await GetProjectFilesAsync(project, configuration); foreach (SourceFile _ in projectSourceFileList) { AddEntry(currentConfiguredFiles, projectSourceFileList); } } else { dynamic projectItem = selItem.ProjectItem.Object; if (IsCppFile(projectItem)) { dynamic file = selItem.ProjectItem.Object; // non project selected if (file != null) { project.Save(); // document selected SourceFile sourceFile = await CreateSourceFileAsync(file.FullPath, configuration, project); AddEntry(currentConfiguredFiles, sourceFile); } } } } List <ConfiguredFiles> configuredFilesList = new List <ConfiguredFiles>(); foreach (ConfiguredFiles configuredFiles in confMap.Values) { if (configuredFiles.Files.Any()) { configuredFilesList.Add(configuredFiles); } } return(configuredFilesList); }