public override bool Execute() { Log.LogMessage($"Emitting winmd..."); string dllPath = Path.Combine(this.ToolsBinDir, "ClangSharpSourceToWinmd.dll"); string interopPath = Path.Combine(this.Win32WinmdBinDir, "Windows.Win32.Interop.dll"); string win32WinmdPath = Path.Combine(this.Win32WinmdBinDir, "Windows.Win32.winmd"); string outputWinmd = this.OutputWinmd; if (!Path.IsPathRooted(outputWinmd)) { outputWinmd = Path.Combine(this.MSBuildProjectDirectory, outputWinmd); } var args = new StringBuilder($"{dllPath} --sourceDir \"{this.EmitterSourceDir}\" --arch x64 --interopFileName \"{interopPath}\" --ref \"{win32WinmdPath}\" --version {this.WinmdVersion} --outputFileName \"{outputWinmd}\""); int exitCode = TaskUtils.ExecuteCmd("dotnet", args.ToString(), out var output, this.Log); if (exitCode < 0) { Log.LogError($"ClangSharpSourceToWinmd.dll failed: {output}"); return(false); } Log.LogMessage(MessageImportance.High, $"Winmd emitted at: {outputWinmd}"); this.FileWrites = new ITaskItem[] { new TaskItem(outputWinmd) }; return(true); }
public override bool Execute() { #if DEBUG if (System.Environment.GetEnvironmentVariable("DEBUG_TASKS") == "1") { System.Diagnostics.Debugger.Launch(); } #endif Log.LogMessage($"Scanning libs..."); string[] libFiles = GetLibs(); string dumpBinPath = Path.Combine(this.LibToolsBinDir, "dumpbin.exe"); StringBuilder libLines = new StringBuilder(); Regex libRegex = new Regex(@"DLL name : (\S+)\s+Symbol name : (\S+)"); HashSet <string> functionNames = new HashSet <string>(System.StringComparer.OrdinalIgnoreCase); foreach (var lib in libFiles) { string dbinArgs = $"/headers \"{lib}\""; TaskUtils.ExecuteCmd(dumpBinPath, dbinArgs, out var dbinOutput, this.Log); foreach (Match match in libRegex.Matches(dbinOutput)) { var dllName = Path.GetFileNameWithoutExtension(match.Groups[1].Value); var functionName = match.Groups[2].Value; if (!functionNames.Contains(functionName)) { if (libLines.Length == 0) { libLines.AppendLine("--with-librarypath"); } libLines.AppendLine($"{functionName}={dllName}"); functionNames.Add(functionName); } } } if (libLines.Length != 0) { var objDir = Path.Combine(this.MSBuildProjectDirectory, "obj"); Directory.CreateDirectory(objDir); string rspFile = Path.Combine(objDir, $"withLibs.generated.rsp"); File.WriteAllText(rspFile, libLines.ToString()); this.OutputLibRsp = new TaskItem(rspFile); } return(true); }
public static string GetVcDirPath(string scriptsDir, TaskLoggingHelper log) { string scriptPath = Path.Combine(scriptsDir, "GetVcDirPath.ps1"); string scriptArgs = $"-File \"{scriptPath}\" x86 x86"; int ret = TaskUtils.ExecuteCmd("powershell.exe", scriptArgs, out var scriptOutput, log); if (ret != 0) { log.LogError($"GetVcDirPath.ps1 failed: {scriptOutput}"); return(null); } return(scriptOutput); }
private bool ScrapeConstants() { Log.LogMessage($"Scraping constants..."); string constantsScraperDll = Path.Combine(this.ToolsBinDir, "ConstantsScraper.dll"); string constantsHeaderTxt = Path.Combine(this.Win32MetadataScraperAssetsDir, "ConstantsHeader.txt"); var args = new StringBuilder($"{constantsScraperDll} --repoRoot {this.objDir} --arch x64 --headerTextFile {constantsHeaderTxt}"); int exitCode = TaskUtils.ExecuteCmd("dotnet", args.ToString(), out var output, this.Log); if (exitCode < 0) { Log.LogError($"ConstantsScraper.dll failed: {output}"); return(false); } return(true); }
public override bool Execute() { #if DEBUG if (System.Environment.GetEnvironmentVariable("DEBUG_COMPILE_IDLS_TASK") == "1") { System.Diagnostics.Debugger.Launch(); } #endif string[] idls = this.GetIdls(); if (idls.Length == 0) { return(true); } Directory.CreateDirectory(this.ObjDir); Directory.CreateDirectory(this.CompiledHeadersDir); string vcPath = TaskUtils.GetVcDirPath(this.ScriptsDir, this.Log); if (string.IsNullOrEmpty(vcPath)) { return(false); } vcPath = vcPath.Trim(); string scriptPath = Path.Combine(this.ScriptsDir, "ConvertMidlAttributesToSalAnnotations.ps1"); string midlPath = Path.Combine(this.SdkBinDir, "x86", "midl.exe"); string umDir = Path.Combine(this.SdkIncRoot, "um"); string sharedDir = Path.Combine(this.SdkIncRoot, "shared"); string winrtDir = Path.Combine(this.SdkIncRoot, "winrt"); string commonMidlArgs = $"/out \"{this.ObjDir}\" /no_warn /DUNICODE /D_UNICODE /DWINVER=0x0A00 -D_APISET_MINWIN_VERSION=0x010F /DNTDDI_VERSION=0x0A00000B /DBUILD_UMS_ENABLED=0 /DBUILD_WOW64_ENABLED=0 /DBUILD_ARM64X_ENABLED=0 /DEXECUTABLE_WRITES_SUPPORT=0 -D_USE_DECLSPECS_FOR_SAL=1 -D_CONTROL_FLOW_GUARD_SVCTAB=1 /Di386 /D_X86_ /D_WCHAR_T_DEFINED /no_stamp /nologo /no_settings_comment /lcid 1033 -sal /win32 -target NT100 /Zp8 /I\"{umDir}\" /I\"{sharedDir}\" /I\"{winrtDir}\""; if (!string.IsNullOrEmpty(this.AdditionalIncludes)) { commonMidlArgs += $" /I\"{this.AdditionalIncludes}\""; } foreach (var idl in idls) { string fixedIdlFile = Path.Combine(this.ObjDir, Path.GetFileName(idl)); string scriptArgs = $"-File \"{scriptPath}\" -inputFileName \"{idl}\" -outputFileName \"{fixedIdlFile}\""; if (File.Exists(fixedIdlFile)) { File.Delete(fixedIdlFile); } int ret = TaskUtils.ExecuteCmd("powershell.exe", scriptArgs, out var scriptOutput, this.Log); if (ret != 0) { this.Log.LogError($"powershell.exe {scriptArgs} failed: {scriptOutput}"); return(false); } string compiledHeader = Path.Combine(this.CompiledHeadersDir, Path.ChangeExtension(Path.GetFileName(idl), ".h")); string midlArgs = $"\"{fixedIdlFile}\" /header \"{compiledHeader}\" {commonMidlArgs}"; ret = TaskUtils.ExecuteCmd(midlPath, midlArgs, out var midlOutput, this.Log, vcPath); if (ret != 0) { this.Log.LogError($"midl.exe failed: {midlOutput}"); return(false); } this.Log.LogMessage(midlOutput); } return(true); }
private bool ProcessPartitionItem(ITaskItem partitionItem) { // TODO: Do we want to do this for all architectures? string arch = "x64"; string[] traverseFiles = GetTraverseFiles(partitionItem); string ns = partitionItem.GetMetadata("Namespace"); string name = partitionItem.GetMetadata("Name"); if (string.IsNullOrEmpty(name)) { name = ns.Split('.').Last(); } Log.LogMessage($"Scanning partition {name}..."); string partitionDir = Path.Combine(this.partitionsDir, name); if (!Directory.Exists(partitionDir)) { Directory.CreateDirectory(partitionDir); } string file = partitionItem.ItemSpec; string settingsRsp = Path.Combine(partitionDir, "settings.rsp"); string currentGeneratedDir = Path.Combine(this.generatedDir, arch); if (!Directory.Exists(currentGeneratedDir)) { Directory.CreateDirectory(currentGeneratedDir); } string outputFile = Path.Combine(currentGeneratedDir, $"{name}.cs"); if (File.Exists(outputFile)) { File.Delete(outputFile); } HashSet <string> includeDirHash = new HashSet <string>(); List <string> includeDirs = new List <string>(); // For sal.h, etc. includeDirs.Add(this.Win32MetadataScraperAssetsDir); foreach (var traverseFile in traverseFiles) { string dir = Path.GetDirectoryName(traverseFile); if (!includeDirHash.Contains(dir)) { includeDirHash.Add(dir); includeDirs.Add(dir); } } includeDirs.Add($"{this.WinSDKIncludeRoot}/shared"); includeDirs.Add($"{this.WinSDKIncludeRoot}/um"); includeDirs.Add($"{this.WinSDKIncludeRoot}/winrt"); string headerTextFile = Path.Combine(this.Win32MetadataScraperAssetsDir, "header.txt"); using (StreamWriter rspWriter = new StreamWriter(settingsRsp)) { rspWriter.WriteLine( $@"--file {file} --output {outputFile} --namespace {ns} --headerFile {headerTextFile} --include-directory"); foreach (var include in includeDirs) { rspWriter.WriteLine(include); } rspWriter.WriteLine("--traverse"); foreach (var traverseFile in traverseFiles) { rspWriter.WriteLine(traverseFile); } var exclusions = this.GetExclusions(partitionItem); if (exclusions.Any()) { rspWriter.WriteLine("--exclude"); foreach (var exclude in exclusions) { rspWriter.WriteLine(exclude); } } } string currentScraperOutputDir = Path.Combine(this.scraperDir, $"obj\\{arch}"); if (!Directory.Exists(currentScraperOutputDir)) { Directory.CreateDirectory(currentScraperOutputDir); } string scrapeToolOutput = Path.Combine(currentScraperOutputDir, $"{name}.generation.output.txt"); StringBuilder args = new StringBuilder($"\"@{settingsRsp}\""); AddWin32Rsp(args, "baseRemap.rsp"); AddWin32Rsp(args, "baseSettings.64.rsp"); AddWin32Rsp(args, "baseSettings.rsp"); AddWin32GeneratedRsp(args, "autoTypes.generated.rsp"); AddWin32GeneratedRsp(args, "functionPointerFixups.generated.rsp"); foreach (var rspItem in this.Rsps) { var rspPath = rspItem.ItemSpec; if (!Path.IsPathRooted(rspPath)) { rspPath = Path.Combine(this.MSBuildProjectDirectory, rspPath); } args.Append($" \"@{rspPath}\""); } int exitCode = TaskUtils.ExecuteCmd("ClangSharpPInvokeGenerator", args.ToString(), out var output, this.Log); if (output == null) { output = string.Empty; } File.WriteAllText(scrapeToolOutput, output); if (exitCode < 0 || !File.Exists(outputFile)) { Log.LogError($"ClangSharpPInvokeGenerator.exe failed, full output at {scrapeToolOutput}."); return(false); // TODO: Output errors } return(true); }