public static Version GetVisualStudioVCToolsVersion(this DevEnv visualVersion) { if (!visualVersion.IsVisualStudio()) { throw new Error($"{visualVersion} is not a visual studio version!"); } Version version = s_visualStudioVCToolsVersionCache.GetOrAdd(visualVersion, devEnv => { string versionString = visualVersion.GetDefaultCompilerVersion(); // default fallback try { string toolchainFile = Path.Combine(visualVersion.GetVisualStudioDir(), "VC", "Auxiliary", "Build", "Microsoft.VCToolsVersion.default.txt"); if (File.Exists(toolchainFile)) { using (StreamReader file = new StreamReader(toolchainFile)) versionString = file.ReadLine().Trim(); } } catch { } return(new Version(versionString)); }); return(version); }
public static string GetVCTargetsPath(this DevEnv visualVersion) { if (!visualVersion.IsVisualStudio()) { return(null); } switch (visualVersion) { case DevEnv.vs2010: return(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"MSBuild\Microsoft.Cpp\v4.0"))); case DevEnv.vs2012: case DevEnv.vs2013: case DevEnv.vs2015: string versionSubfolder = visualVersion.GetDefaultPlatformToolset().ToUpperInvariant(); // this is enough for now but we could make a specific method to retrieve this value return(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"MSBuild\Microsoft.Cpp\v4.0", versionSubfolder))); case DevEnv.vs2017: return(Path.Combine(visualVersion.GetVisualStudioDir(), @"Common7\IDE\VC\VCTargets")); case DevEnv.vs2019: return(Path.Combine(visualVersion.GetVisualStudioDir(), @"MSBuild\Microsoft\VC\v160")); default: throw new ArgumentOutOfRangeException(nameof(visualVersion), visualVersion, null); } }
public static string GetVisualStudioDir(this DevEnv visualVersion, bool ignoreVisualStudioPathOverride = false) { if (!visualVersion.IsVisualStudio()) { throw new Error($"{visualVersion} is not a visual studio version!"); } // TODO: Replace Tuple with ValueTuple once we support C# 8 because ValueTuple is // allocated on the stack. That should be faster here. string visualStudioDirectory = s_visualStudioDirectories.GetOrAdd(Tuple.Create(visualVersion, ignoreVisualStudioPathOverride), devEnv => { if (!ignoreVisualStudioPathOverride) { // First check if the visual studio path is overridden from default value. string pathOverride; if (s_visualStudioDirOverrides.TryGetValue(visualVersion, out pathOverride)) { return(pathOverride); } } string installDir = Util.GetVisualStudioInstallPathFromQuery(visualVersion); if (string.IsNullOrEmpty(installDir)) { // try again but this time including previews installDir = Util.GetVisualStudioInstallPathFromQuery(visualVersion, allowPrereleaseVersions: true); if (string.IsNullOrEmpty(installDir)) // arbitrary fallback { if (visualVersion > DevEnv.vs2015) { installDir = @"Microsoft Visual Studio\" + GetVSYear(visualVersion) + @"\Professional"; } else { installDir = string.Format(@"Microsoft Visual Studio {0}", visualVersion.GetVisualVersionString()); } string rootDir = Environment.GetFolderPath(visualVersion < DevEnv.vs2022 ? Environment.SpecialFolder.ProgramFilesX86 : Environment.SpecialFolder.ProgramFiles); installDir = Path.Combine(rootDir, installDir); } } return(Util.SimplifyPath(installDir)); }); return(visualStudioDirectory); }
/// <summary> /// Gets whether two <see cref="DevEnv"/> values generate ABI-compatible binaries with /// their respective C++ compiler. /// </summary> /// <param name="devEnv">The <see cref="DevEnv"/> to check for ABI-compatibility.</param> /// <param name="other">The other <see cref="DevEnv"/> to check for ABI-compatibility with.</param> /// <returns>`true` if ABI-compatible, `false` otherwise.</returns> /// <exception cref="ArgumentException"><paramref name="devEnv"/> is not a Visual Studio version.</exception> /// <remarks> /// Only works for Visual Studio versions because other DevEnvs (such as Eclipse) are not /// shipped with a compiler version. /// </remarks> public static bool IsAbiCompatibleWith(this DevEnv devEnv, DevEnv other) { if (!devEnv.IsVisualStudio()) { throw new ArgumentException($"{devEnv} is not a Visual Studio DevEnv."); } // a VS version is obviously compatible with itself (identity check) if (devEnv == other) { return(true); } // VS2017 and VS2019 are guaranteed by Microsoft to be ABI-compatible with VS2015 for C++. if (devEnv.IsAbiCompatibleWithVS2015() && other.IsAbiCompatibleWithVS2015()) { return(true); } return(false); }
public static string GetVisualStudioVCRootPath(this DevEnv visualVersion) { if (!visualVersion.IsVisualStudio()) { throw new Error($"{visualVersion} is not a visual studio version!"); } string visualStudioVCRootPath = s_visualStudioVCRootPathCache.GetOrAdd(visualVersion, devEnv => { string vsDir = visualVersion.GetVisualStudioDir(); if (visualVersion > DevEnv.vs2015) { return(Path.Combine(vsDir, @"VC\Tools\MSVC", visualVersion.GetVisualStudioVCToolsVersion().ToString())); } else { return(Path.Combine(vsDir, "VC")); } }); return(visualStudioVCRootPath); }
public static string GetWindowsLibraryPath(this DevEnv visualVersion, Platform platform, DotNetFramework?dotNetFramework = null) { string visualStudioVCDir = Util.EnsureTrailingSeparator(visualVersion.GetVisualStudioVCRootPath()); string subDir = platform == Platform.win64 ? @"\amd64" : ""; if (visualVersion.IsVisualStudio() && visualVersion >= DevEnv.vs2017) { subDir = platform == Platform.win64 ? @"\x64" : @"\x86"; } string visualStudioLib = string.Format(@"{0}lib{1};{0}atlmfc\lib{1};", visualStudioVCDir, subDir); KitsRootEnum useKitsRoot = KitsRootPaths.GetUseKitsRootForDevEnv(visualVersion); string targetPlatform = platform == Platform.win64 ? "x64" : "x86"; switch (useKitsRoot) { case KitsRootEnum.KitsRoot: { string kitsRoot = Util.EnsureTrailingSeparator(KitsRootPaths.GetRoot(KitsRootEnum.KitsRoot)); return(string.Format(@"{0};{1}lib\win8\um\{2};{1}References\CommonConfiguration\Neutral;", visualStudioLib, kitsRoot, targetPlatform)); } case KitsRootEnum.KitsRoot81: { string kitsRoot = Util.EnsureTrailingSeparator(KitsRootPaths.GetRoot(KitsRootEnum.KitsRoot81)); return(string.Format(@"{0};{1}lib\winv6.3\um\{2};{1}References\CommonConfiguration\Neutral;", visualStudioLib, kitsRoot, targetPlatform)); } case KitsRootEnum.KitsRoot10: { string netFxPath = string.Empty; if (dotNetFramework.HasValue && visualVersion >= DevEnv.vs2015) { string netFXKitsDir = Util.EnsureTrailingSeparator(KitsRootPaths.GetNETFXKitsDir(dotNetFramework.Value < DotNetFramework.v4_6 ? DotNetFramework.v4_6 : dotNetFramework.Value)); netFxPath = Path.Combine(netFXKitsDir, "Lib", "um", targetPlatform); } string kitsRoot10 = KitsRootPaths.GetRoot(KitsRootEnum.KitsRoot10); Options.Vc.General.WindowsTargetPlatformVersion windowsTargetPlatformVersion = KitsRootPaths.GetWindowsTargetPlatformVersionForDevEnv(visualVersion); string platformVersion = windowsTargetPlatformVersion.ToVersionString(); var paths = new[] { visualStudioLib, Path.Combine(kitsRoot10, "Lib", platformVersion, "ucrt", targetPlatform), // $(UniversalCRT_LibraryPath_x86) or $(UniversalCRT_LibraryPath_x64) Path.Combine(kitsRoot10, "Lib", platformVersion, "um", targetPlatform), // $(WindowsSDK_LibraryPath_x86) or $(WindowsSDK_LibraryPath_x64) netFxPath }.ToList(); if (windowsTargetPlatformVersion <= Options.Vc.General.WindowsTargetPlatformVersion.v10_0_10240_0) { string kitsRoot81 = KitsRootPaths.GetRoot(KitsRootEnum.KitsRoot81); paths.AddRange(new[] { Path.Combine(kitsRoot81, "lib", "winv6.3", "um", targetPlatform), Path.Combine(kitsRoot81, "References", "CommonConfiguration", "Neutral") }); } return(string.Join(";", paths)); } default: throw new NotImplementedException("No WindowsResourceCompiler associated with " + visualVersion); } }