private StubbedModule(string moduleName, NativeInterface @interface, CompilerOptions options = null) { options = options ?? CompilerOptions.GetDefault(); if (moduleName.EndsWith(".dll")) { throw new AzureKinectStubGeneratorException("Module name should not include file extension"); } this.ModuleName = moduleName; this.CompilerOptions = options; this.NativeInterface = @interface; if (options.TempPath.Exists) { options.TempPath.Delete(true); options.TempPath.Refresh(); } if (options.BinaryPath.Exists) { options.BinaryPath.Delete(true); options.BinaryPath.Refresh(); } options.TempPath.Create(); options.TempPath.Refresh(); options.BinaryPath.Create(); options.BinaryPath.Refresh(); string executingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); string modulePath = Path.Combine(executingDirectory, moduleName + ".dll"); GenerateStub(modulePath, @interface, options); }
public static ModuleInfo Analyze(string path, CompilerOptions options = null) { options = options ?? CompilerOptions.GetDefault(); List <string> exports = new List <string>(); if (!File.Exists(path)) { throw new FileNotFoundException("Failed to analyze module, file not found.", path); } if (!options.TempPath.Exists) { options.TempPath.Create(); } Regex regex = new Regex(@"^\s+\d+\s+[\dA-Fa-f]+\s+[0-9A-Fa-f]{8}\s+([^\s]*).*?$", System.Text.RegularExpressions.RegexOptions.Multiline); // Start the compiler process ProcessStartInfo startInfo = new ProcessStartInfo(options.LinkerPath.FullName) { Arguments = $"/dump \"{path}\" /exports", WorkingDirectory = options.TempPath.FullName, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, }; try { using (Process link = Process.Start(startInfo)) { string output = link.StandardOutput.ReadToEnd().Replace("\r\n", "\n"); link.WaitForExit(); if (link.ExitCode != 0) { throw new AzureKinectStubGeneratorException("Link /dump failed"); } foreach (Match m in regex.Matches(output)) { string functionName = m.Groups[1].Value; exports.Add(functionName); } } } catch (Exception ex) { throw new AzureKinectStubGeneratorException("Failed to analyze module", ex); } return(new ModuleInfo(exports.ToArray())); }
/// <summary> /// Compiles a DLL /// </summary> /// <param name="sourceFiles">List of source files</param> /// <param name="outputBinary">Path of output DLL</param> /// <param name="impLib">Path of output import .lib</param> /// <param name="options">Compiler Options</param> public static void CompileModule(string[] sourceFiles, string outputBinary, string impLib, CompilerOptions options = null, string additionalFlags = null, string[] additionalLibraries = null, string[] additionalSources = null) { options = options ?? CompilerOptions.GetDefault(); string moduleName = outputBinary; // Set up compiler arguments StringBuilder compilerArguments = new StringBuilder(); compilerArguments.Append(options.CompilerFlags); if (additionalFlags != null) { compilerArguments.Append(" "); compilerArguments.Append(additionalFlags); } compilerArguments.Append(" /nologo"); compilerArguments.Append(" /LD"); // Create a .DLL foreach (string sourceFilePath in sourceFiles) { compilerArguments.Append($" \"{sourceFilePath}\""); } if (additionalSources != null) { foreach (string sourceFilePath in additionalSources) { compilerArguments.Append($" \"{sourceFilePath}\""); } } foreach (DirectoryInfo includePath in options.IncludePaths) { compilerArguments.Append($" \"/I{includePath.FullName.TrimEnd('\\')}\""); } // Linker options compilerArguments.Append(" /link"); foreach (DirectoryInfo libraryPath in options.LibraryPaths) { compilerArguments.Append($" \"/LIBPATH:{libraryPath.FullName.TrimEnd('\\')}\""); } compilerArguments.Append($" \"/OUT:{moduleName}\""); if (impLib != null) { compilerArguments.Append($" \"/IMPLIB:{impLib}\""); } foreach (string library in options.Libraries) { compilerArguments.Append(" " + library); } if (additionalLibraries != null) { foreach (string library in additionalLibraries) { compilerArguments.Append(" " + library); } } // Start the compiler process ProcessStartInfo startInfo = new ProcessStartInfo(options.CompilerPath.FullName) { Arguments = compilerArguments.ToString(), WorkingDirectory = options.TempPath.FullName, RedirectStandardOutput = true }; Debug.WriteLine(startInfo.Arguments); try { using (Process cl = Process.Start(startInfo)) { string output = cl.StandardOutput.ReadToEnd().Replace("\r\n", "\n"); cl.WaitForExit(); if (cl.ExitCode != 0) { throw new AzureKinectStubGeneratorException("Compilation failed: " + output); } } } catch (System.ComponentModel.Win32Exception ex) { if ((uint)ex.ErrorCode == 0x80004005) { throw new AzureKinectStubGeneratorException($"Could not find compiler \"{options.CompilerPath}\". Ensure you are running in a developer environment.", ex); } else { throw; } } }