// AFAIK there is no way to programmatically get the c++ standard version supported by any given VS version // instead I'm refearing to the VS docu for that information // https://msdn.microsoft.com/en-us/library/hh567368.aspx static public string GetCppStandardForProject(IVCProjectWrapper project) { string result = ""; string toolset = project.GetWrappedVersion(); string justNumbers = new String(toolset.Where(Char.IsDigit).ToArray()); int versionNumber = int.Parse(justNumbers); if (versionNumber < 120) // version 11 (2012) { result = "c++11"; } else if (versionNumber < 130) // version 12 (2013) { result = "c++14"; } else if (versionNumber < 150) // version 14 (2015) { result = "c++14"; } else if (versionNumber < 160) // version 15 (2017) { result = "c++14"; } return(result); }
public void CreateCompileCommands(Project project, string solutionConfigurationName, string solutionPlatformName, string cStandard, string additionalClangOptions, Action <CompileCommand, bool> lambda) { Logging.Logging.LogInfo("Creating command objects for project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\"."); DTE dte = project.DTE; Guid projectGuid = Utility.ProjectUtility.ReloadProject(project); IVCProjectWrapper vcProject = VCProjectEngineWrapper.VCProjectWrapperFactory.create(project.Object); if (vcProject != null && vcProject.isValid()) { Logging.Logging.LogInfo("Project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\" has been converted to VCProject " + vcProject.GetWrappedVersion() + "."); } else { Logging.Logging.LogWarning("Project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\" could not be converted to VCProject, skipping."); return; } string projectConfigurationName = ""; string projectPlatformName = ""; foreach (SolutionConfiguration2 solutionConfiguration in SolutionUtility.GetSolutionBuild2(dte).SolutionConfigurations) { if (solutionConfiguration.Name == solutionConfigurationName && solutionConfiguration.PlatformName == solutionPlatformName) { foreach (SolutionContext solutionContext in solutionConfiguration.SolutionContexts) { if (vcProject.GetProjectFile().EndsWith(solutionContext.ProjectName)) { projectConfigurationName = solutionContext.ConfigurationName; projectPlatformName = solutionContext.PlatformName; } } } } if (projectConfigurationName.Length == 0 || projectPlatformName.Length == 0) { Logging.Logging.LogWarning("No project configuration found for solution configuration, trying to use solution configuration on project."); projectConfigurationName = solutionConfigurationName; projectPlatformName = solutionPlatformName; } IVCConfigurationWrapper vcProjectConfiguration = vcProject.getConfiguration(projectConfigurationName, projectPlatformName); if (vcProjectConfiguration != null && vcProjectConfiguration.isValid()) { SetCompatibilityVersionFlag(vcProject, vcProjectConfiguration); string commandFlags = ""; { // gather include paths and preprocessor definitions of the project List <string> includeDirectories = ProjectUtility.GetIncludeDirectories(vcProject, vcProjectConfiguration, _pathResolver); List <string> preprocessorDefinitions = ProjectUtility.GetPreprocessorDefinitions(vcProject, vcProjectConfiguration); List <string> forcedIncludeFiles = ProjectUtility.GetForcedIncludeFiles(vcProject, vcProjectConfiguration, _pathResolver); foreach (string flag in _compatibilityFlags) { commandFlags += flag + " "; } commandFlags += _compatibilityVersionFlag + " "; if (!string.IsNullOrWhiteSpace(additionalClangOptions)) { commandFlags += additionalClangOptions; } foreach (string dir in includeDirectories) { commandFlags += " -isystem \"" + dir + "\" "; // using '-isystem' because it allows for use of quotes and pointy brackets in source files. In other words it's more robust. It's slower than '-I' though } foreach (string prepDef in preprocessorDefinitions) { commandFlags += " -D " + prepDef + " "; } foreach (string file in forcedIncludeFiles) { commandFlags += " -include \"" + file + "\" "; } } string cppStandard = Utility.ProjectUtility.GetCppStandardForProject(vcProject); Logging.Logging.LogInfo("Found C++ standard " + cppStandard + "."); bool isMakefileProject = vcProjectConfiguration.isMakefileConfiguration(); // create command objects for all applicable project items { List <CompileCommand> compileCommands = Utility.ProjectUtility.GetProjectItems(project).Select(item => { return(CreateCompileCommand(item, commandFlags, cppStandard, cStandard, isMakefileProject)); }).Where(command => command != null).ToList(); for (int i = 0; i < compileCommands.Count; i++) { lambda(compileCommands[i], i == compileCommands.Count - 1); } } if (projectGuid != Guid.Empty) { Utility.ProjectUtility.UnloadProject(projectGuid, dte); } } else { Logging.Logging.LogError("No project configuration found. Skipping this project"); } }
public void CreateCompileCommands(Project project, string solutionConfigurationName, string solutionPlatformName, string cStandard, string additionalClangOptions, bool nonSystemIncludesUseAngleBrackets, Action <CompileCommand> lambda) { Logging.Logging.LogInfo("Creating command objects for project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\"."); DTE dte = project.DTE; Guid projectGuid = Utility.ProjectUtility.ReloadProject(project); IVCProjectWrapper vcProject = VCProjectEngineWrapper.VCProjectWrapperFactory.create(project.Object); if (vcProject != null && vcProject.isValid()) { Logging.Logging.LogInfo("Project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\" has been converted to VCProject " + vcProject.GetWrappedVersion() + "."); } else { Logging.Logging.LogWarning("Project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\" could not be converted to VCProject, skipping."); return; } string projectConfigurationName = ""; string projectPlatformName = ""; foreach (SolutionConfiguration2 solutionConfiguration in SolutionUtility.GetSolutionBuild2(dte).SolutionConfigurations) { if (solutionConfiguration.Name == solutionConfigurationName && solutionConfiguration.PlatformName == solutionPlatformName) { foreach (SolutionContext solutionContext in solutionConfiguration.SolutionContexts) { if (vcProject.GetProjectFile().EndsWith(solutionContext.ProjectName)) { projectConfigurationName = solutionContext.ConfigurationName; projectPlatformName = solutionContext.PlatformName; } } } } if (projectConfigurationName.Length == 0 || projectPlatformName.Length == 0) { Logging.Logging.LogWarning("No project configuration found for solution configuration, trying to use solution configuration on project."); projectConfigurationName = solutionConfigurationName; projectPlatformName = solutionPlatformName; } IVCConfigurationWrapper vcProjectConfiguration = vcProject.getConfiguration(projectConfigurationName, projectPlatformName); if (vcProjectConfiguration != null && vcProjectConfiguration.isValid()) { SetCompatibilityVersionFlag(vcProject, vcProjectConfiguration); string commandFlags = ""; { // gather include paths and preprocessor definitions of the project List <string> projectIncludeDirectories = ProjectUtility.GetProjectIncludeDirectories(vcProject, vcProjectConfiguration, _pathResolver); List <string> systemIncludeDirectories = ProjectUtility.GetSystemIncludeDirectories(vcProject, vcProjectConfiguration, _pathResolver); List <string> preprocessorDefinitions = ProjectUtility.GetPreprocessorDefinitions(vcProject, vcProjectConfiguration); List <string> forcedIncludeFiles = ProjectUtility.GetForcedIncludeFiles(vcProject, vcProjectConfiguration, _pathResolver); foreach (string flag in _compatibilityFlags) { commandFlags += flag + " "; } commandFlags += _compatibilityVersionFlag + " "; if (!string.IsNullOrWhiteSpace(additionalClangOptions)) { commandFlags += additionalClangOptions; } if (nonSystemIncludesUseAngleBrackets) { systemIncludeDirectories.InsertRange(0, projectIncludeDirectories); projectIncludeDirectories.Clear(); } foreach (string dir in projectIncludeDirectories) { commandFlags += " -I \"" + dir + "\" "; } foreach (string dir in systemIncludeDirectories) { commandFlags += " -isystem \"" + dir + "\" "; } foreach (string prepDef in preprocessorDefinitions) { commandFlags += " -D " + prepDef + " "; } foreach (string file in forcedIncludeFiles) { commandFlags += " -include \"" + file + "\" "; } } string cppStandard = Utility.ProjectUtility.GetCppStandardForProject(vcProject); Logging.Logging.LogInfo("Found C++ standard " + cppStandard + "."); bool isMakefileProject = vcProjectConfiguration.isMakefileConfiguration(); // create command objects for all applicable project items { foreach (ProjectItem item in Utility.ProjectUtility.GetProjectItems(project)) { CompileCommand command = CreateCompileCommand(item, commandFlags, cppStandard, cStandard, isMakefileProject); if (command == null) { continue; } lambda(command); } } if (projectGuid != Guid.Empty) { Utility.ProjectUtility.UnloadProject(projectGuid, dte); } } else { Logging.Logging.LogError("No project configuration found. Skipping this project"); } }