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);
        }
Example #2
0
        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);
        }
Example #4
0
        /// <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);
            }
        }