From 5aaa0a035139eff4cffaf7891fa9e2f728e2675d Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sun, 27 Aug 2017 11:54:44 +0300 Subject: [PATCH] Fixed a crash when trying to use a VS version missing from the system. Fixes https://github.com/mono/CppSharp/issues/922. Signed-off-by: Dimitar Dobrev --- src/Core/Toolchains/MSVCToolchain.cs | 51 +++++++++++++++++----------- src/Parser/ParserOptions.cs | 11 +++--- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/Core/Toolchains/MSVCToolchain.cs b/src/Core/Toolchains/MSVCToolchain.cs index 83500db8..8092b6df 100644 --- a/src/Core/Toolchains/MSVCToolchain.cs +++ b/src/Core/Toolchains/MSVCToolchain.cs @@ -32,6 +32,8 @@ namespace CppSharp /// Extra data value associated with the toolchain. public string Value; + public bool IsValid => Version > 0 && !string.IsNullOrEmpty(Directory); + public override string ToString() { return string.Format("{0} (version: {1})", Directory, Version); @@ -83,13 +85,14 @@ namespace CppSharp } /// Dumps include directories for selected toolchain. + /// The version of Visual Studio to dump the SDK-s of. public static void DumpSdkIncludes(VisualStudioVersion vsVersion = VisualStudioVersion.Latest) { Console.WriteLine("\nInclude search path (VS: {0}):", vsVersion); - var includes = GetSystemIncludes(vsVersion); - foreach (var include in includes) - Console.WriteLine("\t{0}", include); + VisualStudioVersion foundVsVersion; + foreach (var include in GetSystemIncludes(vsVersion, out foundVsVersion)) + Console.WriteLine($"\t{include}"); } public static Version GetCLVersion(VisualStudioVersion vsVersion) @@ -143,12 +146,10 @@ namespace CppSharp if (vsSdks.Count == 0) throw new Exception("Could not find a valid Visual Studio toolchain"); - var vsSdk = (vsVersion == VisualStudioVersion.Latest) + return (vsVersion == VisualStudioVersion.Latest) ? vsSdks.Last() : vsSdks.Find(version => - (int)version.Version == GetVisualStudioVersion(vsVersion)); - - return vsSdk; + (int) version.Version == GetVisualStudioVersion(vsVersion)); } public static ToolchainVersion GetWindowsKitsToolchain(VisualStudioVersion vsVersion, @@ -188,27 +189,39 @@ namespace CppSharp windowsKitSdk = windowsKitsSdks.Last(); return windowsKitSdk; } - /// Gets the system include folders for the given Visual Studio version. - public static List GetSystemIncludes(VisualStudioVersion vsVersion) - { - var vsSdk = GetVSToolchain(vsVersion); - var vsDir = vsSdk.Directory; - vsDir = vsDir.Substring(0, vsDir.LastIndexOf(@"\Common7\IDE", - StringComparison.Ordinal)); + /// Gets the system include folders for the given Visual Studio version. + /// The version of Visual Studio to get + /// system includes from. + /// The found version of Visual Studio + /// system includes are actually got from. + public static List GetSystemIncludes(VisualStudioVersion wantedVsVersion, + out VisualStudioVersion foundVsVersion) + { + if (wantedVsVersion != VisualStudioVersion.Latest) + { + var vsSdk = GetVSToolchain(wantedVsVersion); + if (vsSdk.IsValid) + { + var vsDir = vsSdk.Directory; + vsDir = vsDir.Substring(0, vsDir.LastIndexOf(@"\Common7\IDE", + StringComparison.Ordinal)); - if (vsVersion != VisualStudioVersion.Latest) - return GetSystemIncludes(vsVersion, vsDir); + foundVsVersion = wantedVsVersion; + return GetSystemIncludes(wantedVsVersion, vsDir); + } + } // we don't know what "latest" is on a given machine - // because we do not (yet) pass a parameter from the build scripts // so start from the latest specified version and loop until a match is found for (var i = VisualStudioVersion.Latest - 1; i >= VisualStudioVersion.VS2012; i--) { - var includes = GetSystemIncludes(i, vsDir); - if (includes.Any()) + var includes = GetSystemIncludes(i, out foundVsVersion); + if (includes.Count > 0) return includes; } + + foundVsVersion = VisualStudioVersion.Latest; return new List(); } diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index e081f66b..413c09a1 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -52,16 +52,17 @@ namespace CppSharp.Parser NoBuiltinIncludes = true; NoStandardIncludes = true; Abi = CppAbi.Microsoft; - var clVersion = MSVCToolchain.GetCLVersion(vsVersion); + + VisualStudioVersion foundVsVersion; + var includes = MSVCToolchain.GetSystemIncludes(vsVersion, out foundVsVersion); + foreach (var include in includes) + AddSystemIncludeDirs(include); + var clVersion = MSVCToolchain.GetCLVersion(foundVsVersion); ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000; AddArguments("-fms-extensions"); AddArguments("-fms-compatibility"); AddArguments("-fdelayed-template-parsing"); - - var includes = MSVCToolchain.GetSystemIncludes(vsVersion); - foreach (var include in includes) - AddSystemIncludeDirs(include); } public void SetupXcode()