Browse Source

Remove looking MSVC headers up with COM

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
cppsharp-net-standard-nuget
Dimitar Dobrev 4 years ago committed by João Matos
parent
commit
1e8bfb11e3
  1. 1
      Directory.Packages.props
  2. 1
      src/Core/CppSharp.csproj
  3. 335
      src/Core/Toolchains/MSVCToolchain.cs
  4. 1
      src/Package/CppSharp.Package.csproj
  5. 23
      src/Parser/ParserOptions.cs

1
Directory.Packages.props

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
<Project>
<ItemGroup>
<PackageVersion Include="Microsoft.Win32.Registry" Version="4.7.0" />
<PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="2.3.2262-g94fae01e" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
<PackageVersion Include="NUnit" Version="3.11.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="3.17.0" />

1
src/Core/CppSharp.csproj

@ -8,6 +8,5 @@ @@ -8,6 +8,5 @@
<ItemGroup>
<PackageReference Include="Microsoft.Win32.Registry" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Setup.Configuration.Interop" PrivateAssets="All" />
</ItemGroup>
</Project>

335
src/Core/Toolchains/MSVCToolchain.cs

@ -5,8 +5,6 @@ using System.IO; @@ -5,8 +5,6 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Win32;
using Microsoft.VisualStudio.Setup.Configuration;
using System.Runtime.InteropServices;
namespace CppSharp
{
@ -51,35 +49,6 @@ namespace CppSharp @@ -51,35 +49,6 @@ namespace CppSharp
public static class MSVCToolchain
{
/// <summary>Dumps the detected SDK versions.</summary>
public static void DumpSdks()
{
List<ToolchainVersion> vsSdks = GetVisualStudioSdks();
DumpSdks("Visual Studio", vsSdks);
List<ToolchainVersion> windowsSdks = GetWindowsSdks();
DumpSdks("Windows", windowsSdks);
List<ToolchainVersion> windowsKitsSdks = GetWindowsKitsSdks();
DumpSdks("Windows Kits", windowsKitsSdks);
List<ToolchainVersion> netFrameworkSdks = GetNetFrameworkSdks();
DumpSdks(".NET Framework", netFrameworkSdks);
List<ToolchainVersion> msbuildSdks = GetMSBuildSdks();
DumpSdks("MSBuild", msbuildSdks);
}
/// <summary>Dumps include directories for selected toolchain.</summary>
/// <param name="vsVersion">The version of Visual Studio to dump the SDK-s of.</param>
public static void DumpSdkIncludes(VisualStudioVersion vsVersion =
VisualStudioVersion.Latest)
{
Console.WriteLine("\nInclude search path (VS: {0}):", vsVersion);
foreach (var include in MSVCToolchain.GetSystemIncludes(vsVersion))
Console.WriteLine($"\t{include}");
}
public static Version GetCLVersion(VisualStudioVersion vsVersion)
{
Version clVersion;
@ -108,91 +77,6 @@ namespace CppSharp @@ -108,91 +77,6 @@ namespace CppSharp
return clVersion;
}
public static ToolchainVersion GetVSToolchain(VisualStudioVersion vsVersion)
{
if (VSSdks.Value.Count == 0)
throw new Exception("Could not find a valid Visual Studio toolchain");
return (vsVersion == VisualStudioVersion.Latest)
? VSSdks.Value.Last()
: VSSdks.Value.Find(version =>
(int) version.Version == GetVisualStudioVersion(vsVersion));
}
public static ToolchainVersion GetWindowsKitsToolchain(VisualStudioVersion vsVersion,
out int windowsSdkMajorVer)
{
var vsSdk = GetVSToolchain(vsVersion);
var vsDir = vsSdk.Directory;
vsDir = vsDir.Substring(0, vsDir.LastIndexOf(@"\Common7\IDE",
StringComparison.Ordinal));
// Check VCVarsQueryRegistry.bat to see which Windows SDK version
// is supposed to be used with this VS version.
var vcVarsPath = Path.Combine(vsDir, @"Common7\Tools\VCVarsQueryRegistry.bat");
windowsSdkMajorVer = 0;
string kitsRootKey = string.Empty;
var vcVarsFile = File.ReadAllText(vcVarsPath);
var match = Regex.Match(vcVarsFile, @"Windows\\v([1-9][0-9]*)\.?([0-9]*)");
if (match.Success)
windowsSdkMajorVer = int.Parse(match.Groups[1].Value);
match = Regex.Match(vcVarsFile, "KitsRoot([1-9][0-9]*)");
if (match.Success)
kitsRootKey = match.Groups[0].Value;
List<ToolchainVersion> windowsKitsSdks = GetWindowsKitsSdks();
var windowsKitSdk = (!string.IsNullOrWhiteSpace(kitsRootKey))
? windowsKitsSdks.Find(version => version.Value == kitsRootKey)
: windowsKitsSdks.Last();
// If for some reason we cannot find the SDK version reported by VS
// in the system, then fallback to the latest version found.
if (windowsKitSdk.Value == null)
windowsKitSdk = windowsKitsSdks.Last();
return windowsKitSdk;
}
public static VisualStudioVersion FindVSVersion(VisualStudioVersion vsVersion)
{
if (vsVersion != VisualStudioVersion.Latest)
{
var vsSdk = GetVSToolchain(vsVersion);
if (vsSdk.IsValid)
return vsVersion;
}
// we don't know what "latest" is on a given machine
// so start from the latest specified version and loop until a match is found
for (var i = VisualStudioVersion.Latest - 1; i >= VisualStudioVersion.VS2012; i--)
{
vsVersion = FindVSVersion(i);
if (vsVersion != VisualStudioVersion.Latest)
return vsVersion;
}
return VisualStudioVersion.Latest;
}
/// <summary>Gets the system include folders for the given Visual Studio version.</summary>
/// <param name="vsVersion">The version of Visual Studio to get
/// system includes from.</param>
public static List<string> GetSystemIncludes(VisualStudioVersion vsVersion)
{
var vsSdk = GetVSToolchain(vsVersion);
var vsDir = vsSdk.Directory;
if (Path.GetFileName(vsDir) == "IDE")
{
string secondToLastDirPath = Path.GetDirectoryName(vsDir);
if (Path.GetFileName(secondToLastDirPath) == "Common7")
vsDir = Path.GetDirectoryName(secondToLastDirPath);
}
return GetSystemIncludes(vsVersion, vsDir);
}
private static void DumpSdks(string sku, IEnumerable<ToolchainVersion> sdks)
{
Console.WriteLine("\n{0} SDKs:", sku);
@ -220,33 +104,6 @@ namespace CppSharp @@ -220,33 +104,6 @@ namespace CppSharp
}
}
private static List<string> GetSystemIncludes(VisualStudioVersion vsVersion, string vsDir)
{
if (vsVersion == VisualStudioVersion.VS2017)
return GetSystemIncludesVS2017(vsDir);
int windowsSdkMajorVer;
var windowsKitSdk = GetWindowsKitsToolchain(vsVersion, out windowsSdkMajorVer);
List<ToolchainVersion> windowsSdks = GetWindowsSdks();
var includes = new List<string> { Path.Combine(vsDir, @"VC\include") };
// Older Visual Studio versions provide their own Windows SDK.
if (windowsSdks.Count == 0)
{
includes.Add(Path.Combine(vsDir, @"\VC\PlatformSDK\Include"));
}
else
{
includes.AddRange(GetIncludeDirsFromWindowsSdks(windowsSdkMajorVer, windowsSdks));
}
includes.AddRange(
CollectUniversalCRuntimeIncludeDirs(vsDir, windowsKitSdk, windowsSdkMajorVer));
return includes;
}
private static IEnumerable<string> GetIncludeDirsFromWindowsSdks(
int windowsSdkMajorVer, List<ToolchainVersion> windowsSdks)
{
@ -412,38 +269,6 @@ namespace CppSharp @@ -412,38 +269,6 @@ namespace CppSharp
return versions;
}
/// <summary>
/// Gets Visual Studio installation directories.
/// </summary>
/// <param name="versions">Collection holding information about available Visual Studio instances</param>
/// <returns>Success of the operation</returns>
public static List<ToolchainVersion> GetVisualStudioSdks()
{
var versions = GetToolchainsFromSystemRegistry(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio",
"InstallDir", RegistryView.Registry32);
if (versions.Count == 0 && Environment.Is64BitProcess)
versions.AddRange(GetToolchainsFromSystemRegistry(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio",
"InstallDir", RegistryView.Registry64));
versions.AddRange(GetToolchainsFromSystemRegistry(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress",
"InstallDir", RegistryView.Registry32));
if (versions.Count == 0 && Environment.Is64BitProcess)
versions.AddRange(GetToolchainsFromSystemRegistry(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress",
"InstallDir", RegistryView.Registry64));
//Check for VS 2017
GetVs2017Instances(versions);
versions.Sort((v1, v2) => (int)(v1.Version - v2.Version));
return versions;
}
/// <summary>
/// Read registry strings looking for matching values.
/// </summary>
@ -597,165 +422,5 @@ namespace CppSharp @@ -597,165 +422,5 @@ namespace CppSharp
return hive;
}
private static Lazy<List<ToolchainVersion>> VSSdks =
new Lazy<List<ToolchainVersion>>(GetVisualStudioSdks, true);
#region VS2017
/// <summary>
/// Returns all system includes of the installed VS 2017 instance.
/// </summary>
/// <param name="vsDir">Path to the visual studio installation (for identifying the correct instance)</param>
/// <returns>The system includes</returns>
private static List<string> GetSystemIncludesVS2017(string vsDir)
{
List<string> includes = new List<string>();
//They includes are in a different folder
const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);
try
{
var query = new SetupConfiguration();
var query2 = (ISetupConfiguration2) query;
var e = query2.EnumAllInstances();
int fetched;
var instances = new ISetupInstance[1];
var regexWinSDK10Version = new Regex(@"Windows10SDK\.(\d+)\.?");
do
{
e.Next(1, instances, out fetched);
if (fetched > 0)
{
var instance = (ISetupInstance2) instances[0];
if (instance.GetInstallationPath() != vsDir) continue;
var packages = instance.GetPackages();
var vc_tools = from package in packages
where package.GetId().Contains("Microsoft.VisualStudio.Component.VC.Tools")
orderby package.GetId()
select package;
if (vc_tools.Any())
{ // Tools found, get path
var path = instance.GetInstallationPath();
var versionFilePath = path + @"\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt";
var version = System.IO.File.ReadLines(versionFilePath).ElementAt(0).Trim();
includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\include");
includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\atlmfc\include");
}
var sdks = from package in packages
where package.GetId().Contains("Windows10SDK") ||
package.GetId().Contains("Windows81SDK") ||
package.GetId().Contains("Win10SDK_10")
select package;
var win10sdks = from sdk in sdks
where regexWinSDK10Version.Match(sdk.GetId()).Success
orderby sdk.GetId()
select sdk;
var win8sdks = from sdk in sdks
where sdk.GetId().Contains("Windows81SDK")
select sdk;
if (win10sdks.Any())
{
var sdk = win10sdks.Last();
var matchVersion = regexWinSDK10Version.Match(sdk.GetId());
string path;
if (matchVersion.Success)
{
Environment.SpecialFolder specialFolder = Environment.Is64BitOperatingSystem ?
Environment.SpecialFolder.ProgramFilesX86 : Environment.SpecialFolder.ProgramFiles;
var programFiles = Environment.GetFolderPath(specialFolder);
path = Path.Combine(programFiles, "Windows Kits", "10", "include",
$"10.0.{matchVersion.Groups[1].Value}.0");
}
else
{
throw new Exception("Windows10SDK should not have been detected, something is terribly wrong");
}
var shared = Path.Combine(path, "shared");
var um = Path.Combine(path, "um");
var winrt = Path.Combine(path, "winrt");
var ucrt = Path.Combine(path, "ucrt");
if (Directory.Exists(shared) &&
Directory.Exists(um) &&
Directory.Exists(winrt) &&
Directory.Exists(ucrt))
{
includes.Add(shared);
includes.Add(um);
includes.Add(winrt);
includes.Add(ucrt);
}
}
else if (win8sdks.Any())
{
includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\shared");
includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\um");
includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\winrt");
}
return includes; //We've collected all information.
}
}
while (fetched > 0);
}
// a COM exception means the VS 2017 COM API (therefore VS itself) is not installed, ignore
catch (COMException ex) when (ex.HResult == REGDB_E_CLASSNOTREG)
{
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
}
return includes;
}
/// <summary>
/// Tries to get all vs 2017 instances.
/// </summary>
/// <param name="versions">Collection holding available visual studio instances</param>
/// <returns>Success of the operation</returns>
private static bool GetVs2017Instances(ICollection<ToolchainVersion> versions)
{
const int REGDB_E_CLASSNOTREG = unchecked((int) 0x80040154);
try
{
var query = new SetupConfiguration();
var query2 = (ISetupConfiguration2) query;
var e = query2.EnumAllInstances();
int fetched;
var instances = new ISetupInstance[1];
do
{
e.Next(1, instances, out fetched);
if (fetched > 0)
{
var instance = (ISetupInstance2) instances[0];
var toolchain = new ToolchainVersion
{
Directory = instance.GetInstallationPath() + @"\Common7\IDE",
Version = float.Parse(instance.GetInstallationVersion().Remove(2)),
Value = null // Not used currently
};
versions.Add(toolchain);
}
}
while (fetched > 0);
}
// a COM exception means the VS 2017 COM API (therefore VS itself) is not installed, ignore
catch (COMException ex) when (ex.HResult == REGDB_E_CLASSNOTREG)
{
return false;
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
return false;
}
return true;
}
#endregion
}
}

1
src/Package/CppSharp.Package.csproj

@ -15,7 +15,6 @@ It can also be used as a library to parse native code into a syntax tree with a @@ -15,7 +15,6 @@ It can also be used as a library to parse native code into a syntax tree with a
<ItemGroup>
<PackageReference Include="Microsoft.Win32.Registry" />
<PackageReference Include="Microsoft.VisualStudio.Setup.Configuration.Interop" />
<Content Include="$(PackageDir)runtimes\**" PackagePath="runtimes" />
<Content Include="$(PackageDir)ref\**" PackagePath="ref" />
<Content Include="$(PackageDir)contentFiles\**" PackagePath="contentFiles" PackageCopyToOutput="true" />

23
src/Parser/ParserOptions.cs

@ -74,14 +74,6 @@ namespace CppSharp.Parser @@ -74,14 +74,6 @@ namespace CppSharp.Parser
public bool EnableRTTI { get; set; }
public LanguageVersion? LanguageVersion { get; set; }
/// <summary>
/// This option forces the driver code to use Clang's toolchain code
/// to lookup the location of system headers and library locations.
/// At the moment, it only makes a difference for MSVC targets.
/// If its true, then we opt to use Clang's MSVC lookup logic.
/// </summary>
public bool ForceClangToolchainLookup = true;
public void BuildForSourceFile(
IEnumerable<CppSharp.AST.Module> modules, string file = null)
{
@ -151,21 +143,6 @@ namespace CppSharp.Parser @@ -151,21 +143,6 @@ namespace CppSharp.Parser
var clVersion = MSVCToolchain.GetCLVersion(vsVersion);
ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000;
if (!ForceClangToolchainLookup)
{
NoStandardIncludes = true;
NoBuiltinIncludes = true;
AddSystemIncludeDirs(BuiltinsDir);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
vsVersion = MSVCToolchain.FindVSVersion(vsVersion);
foreach (var include in MSVCToolchain.GetSystemIncludes(vsVersion))
AddSystemIncludeDirs(include);
}
}
// do not remove the CppSharp prefix becase the Mono C# compiler breaks
if (!LanguageVersion.HasValue)
LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU;

Loading…
Cancel
Save