private static NativeCompileSettings ParseAndValidateArgs(ArgValues args) { var config = new NativeCompileSettings(); // Managed Input if (string.IsNullOrEmpty(args.InputManagedAssemblyPath) || !File.Exists(args.InputManagedAssemblyPath)) { //TODO make this message good throw new Exception("Invalid Managed Assembly Argument."); } config.InputManagedAssemblyPath = Path.GetFullPath(args.InputManagedAssemblyPath); // Architecture if(string.IsNullOrEmpty(args.Architecture)) { config.Architecture = RuntimeExtensions.GetCurrentArchitecture(); // CoreRT does not support x86 yet if (config.Architecture != ArchitectureMode.x64) { throw new Exception("Native Compilation currently only supported for x64."); } } else { try { config.Architecture = EnumExtensions.Parse<ArchitectureMode>(args.Architecture.ToLower()); } catch (Exception e) { throw new Exception("Invalid Architecture Option."); } } // BuildConfiguration if(string.IsNullOrEmpty(args.BuildConfiguration)) { config.BuildType = GetDefaultBuildType(); } else { try { config.BuildType = EnumExtensions.Parse<BuildConfiguration>(args.BuildConfiguration.ToLower()); } catch (Exception e) { throw new Exception("Invalid Configuration Option."); } } // Output if(string.IsNullOrEmpty(args.OutputDirectory)) { config.OutputDirectory = GetDefaultOutputDir(config); } else { config.OutputDirectory = args.OutputDirectory; } // Intermediate if(string.IsNullOrEmpty(args.IntermediateDirectory)) { config.IntermediateDirectory = GetDefaultIntermediateDir(config); } else { config.IntermediateDirectory = args.IntermediateDirectory; } // Mode if (string.IsNullOrEmpty(args.NativeMode)) { config.NativeMode = GetDefaultNativeMode(); } else { try { config.NativeMode = EnumExtensions.Parse<NativeIntermediateMode>(args.NativeMode.ToLower()); } catch (Exception e) { throw new Exception("Invalid Mode Option."); } } // AppDeps (TEMP) if(!string.IsNullOrEmpty(args.AppDepSDKPath)) { if (!Directory.Exists(args.AppDepSDKPath)) { throw new Exception("AppDepSDK Directory does not exist."); } config.AppDepSDKPath = args.AppDepSDKPath; var reference = Path.Combine(config.AppDepSDKPath, "*.dll"); config.ReferencePaths.Add(reference); } else { config.AppDepSDKPath = GetDefaultAppDepSDKPath(); var reference = Path.Combine(config.AppDepSDKPath, "*.dll"); config.ReferencePaths.Add(reference); } // IlcPath if (!string.IsNullOrEmpty(args.IlcPath)) { if (!Directory.Exists(args.IlcPath)) { throw new Exception("ILC Directory does not exist."); } config.IlcPath = args.IlcPath; } else { config.IlcPath = GetDefaultIlcPath(); } // logpath if (!string.IsNullOrEmpty(args.LogPath)) { config.LogPath = Path.GetFullPath(args.LogPath); } // CodeGenPath if (!string.IsNullOrEmpty(args.IlcArgs)) { config.IlcArgs = Path.GetFullPath(args.IlcArgs); } // Reference Paths foreach (var reference in args.ReferencePaths) { config.ReferencePaths.Add(Path.GetFullPath(reference)); } // Link Libs foreach (var lib in args.LinkLibPaths) { config.LinkLibPaths.Add(lib); } // OS config.OS = RuntimeInformationExtensions.GetCurrentOS(); return config; }
internal static ArgValues Parse(IEnumerable<string> args) { CommandLineApplication app = new CommandLineApplication(); app.HelpOption("-h|--help"); CommandOption output = app.Option("--output <arg>", "Output Directory for native executable.", CommandOptionType.SingleValue); CommandOption tempOutput = app.Option("--temp-output <arg>", "Directory for intermediate files.", CommandOptionType.SingleValue); CommandOption configuration = app.Option("--configuration <arg>", "debug/release build configuration. Defaults to debug.", CommandOptionType.SingleValue); CommandOption mode = app.Option("--mode <arg>", "Code Generation mode. Defaults to ryujit.", CommandOptionType.SingleValue); CommandOption reference = app.Option("--reference <arg>...", "Use to specify Managed DLL references of the app.", CommandOptionType.MultipleValue); // Custom Extensibility Points to support CoreRT workflow TODO better descriptions CommandOption ilcarg = app.Option("--ilcarg <arg>...", "Use to specify custom arguments for the IL Compiler.", CommandOptionType.MultipleValue); CommandOption ilcpath = app.Option("--ilcpath <arg>", "Use to specify a custom build of IL Compiler.", CommandOptionType.SingleValue); CommandOption ilcsdkpath = app.Option("ilcsdkpath <arg>", "Use to specify a custom build of IL Compiler SDK", CommandOptionType.SingleValue); CommandOption linklib = app.Option("--linklib <arg>...", "Use to link in additional static libs", CommandOptionType.MultipleValue); // TEMPORARY Hack until CoreRT compatible Framework Libs are available CommandOption appdepsdk = app.Option("--appdepsdk <arg>", "Use to plug in custom appdepsdk path", CommandOptionType.SingleValue); // Optional Log Path CommandOption logpath = app.Option("--logpath <arg>", "Use to dump Native Compilation Logs to a file.", CommandOptionType.SingleValue); // Optional flags to be passed to the native compiler CommandOption cppcompilerflags = app.Option("--cppcompilerflags <arg>", "Additional flags to be passed to the native compiler.", CommandOptionType.SingleValue); CommandArgument inputAssembly = app.Argument("INPUT_ASSEMBLY", "The managed input assembly to compile to native."); ArgValues argValues = new ArgValues(); app.OnExecute(() => { if (string.IsNullOrEmpty(inputAssembly.Value)) { Reporter.Error.WriteLine("Input Assembly is a required parameter."); return 1; } if (configuration.HasValue()) { try { argValues.BuildConfiguration = EnumExtensions.Parse<BuildConfiguration>(configuration.Value()); } catch (ArgumentException) { Reporter.Error.WriteLine($"Invalid Configuration Option: {configuration}"); return 1; } } if (mode.HasValue()) { try { argValues.NativeMode = EnumExtensions.Parse<NativeIntermediateMode>(mode.Value()); } catch (ArgumentException) { Reporter.Error.WriteLine($"Invalid Mode Option: {mode}"); return 1; } } argValues.InputManagedAssemblyPath = inputAssembly.Value; argValues.OutputDirectory = output.Value(); argValues.IntermediateDirectory = tempOutput.Value(); argValues.Architecture = ArchitectureMode.x64; argValues.ReferencePaths = reference.Values; argValues.IlcArgs = ilcarg.Values.Select(s => { if (!s.StartsWith("\"") || !s.EndsWith("\"")) { throw new ArgumentException("--ilcarg must be specified in double quotes", "ilcarg"); } return s.Substring(1, s.Length - 2); }); argValues.IlcPath = ilcpath.Value(); argValues.IlcSdkPath = ilcsdkpath.Value(); argValues.LinkLibPaths = linklib.Values; argValues.AppDepSDKPath = appdepsdk.Value(); argValues.LogPath = logpath.Value(); argValues.CppCompilerFlags = cppcompilerflags.Value(); Reporter.Output.WriteLine($"Input Assembly: {inputAssembly}"); return 0; }); try { argValues.ReturnCode = app.Execute(args.ToArray()); } catch (Exception ex) { #if DEBUG Console.Error.WriteLine(ex); #else Console.Error.WriteLine(ex.Message); #endif argValues.ReturnCode = 1; } if (argValues.ReturnCode != 0) { argValues.IsHelp = true; } return argValues; }
private static CommandLineApplication SetupApp() { var app = new CommandLineApplication { Name = "dotnet compile native", FullName = "IL to Native compiler", Description = "IL to Native compiler Compiler for the .NET Platform" }; app.HelpOption("-h|--help"); var managedInputArg = app.Argument("<INPUT_ASSEMBLY>", "The managed input assembly to compile to native."); var outputArg = app.Option("-o|--out <OUTPUT_DIR>", "Output Directory for native executable.", CommandOptionType.SingleValue); var intermediateArg = app.Option("-t|--temp-output <OUTPUT_DIR>", "Directory for intermediate files.", CommandOptionType.SingleValue); var buildConfigArg = app.Option("-c|--configuration <TYPE>", "debug/release build configuration. Defaults to debug.", CommandOptionType.SingleValue); var modeArg = app.Option("-m|--mode <MODE>", "Code Generation mode. Defaults to ryujit. ", CommandOptionType.SingleValue); var referencesArg = app.Option("-r|--reference <REF_PATH>", "Use to specify Managed DLL references of the app.", CommandOptionType.MultipleValue); // Custom Extensibility Points to support CoreRT workflow TODO better descriptions var ilcArgs = app.Option("--ilcargs <CODEGEN>", "Use to specify custom arguments for the IL Compiler.", CommandOptionType.SingleValue); var ilcPathArg = app.Option("--ilcpath <ILC_PATH>", "Use to plug in a custom built ilc.exe", CommandOptionType.SingleValue); var linklibArg = app.Option("--linklib <LINKLIB>", "Use to link in additional static libs", CommandOptionType.MultipleValue); // TEMPORARY Hack until CoreRT compatible Framework Libs are available var appdepSdkPathArg = app.Option("--appdepsdk <SDK>", "Use to plug in custom appdepsdk path", CommandOptionType.SingleValue); // Optional Log Path var logpathArg = app.Option("--logpath <LOG_PATH>", "Use to dump Native Compilation Logs to a file.", CommandOptionType.SingleValue); app.OnExecute(() => { var cmdLineArgs = new ArgValues() { InputManagedAssemblyPath = managedInputArg.Value, OutputDirectory = outputArg.Value(), IntermediateDirectory = intermediateArg.Value(), Architecture = "x64", BuildConfiguration = buildConfigArg.Value(), NativeMode = modeArg.Value(), ReferencePaths = referencesArg.Values, IlcArgs = ilcArgs.Value(), IlcPath = ilcPathArg.Value(), LinkLibPaths = linklibArg.Values, AppDepSDKPath = appdepSdkPathArg.Value(), LogPath = logpathArg.Value() }; var config = ParseAndValidateArgs(cmdLineArgs); DirectoryExtensions.CleanOrCreateDirectory(config.OutputDirectory); DirectoryExtensions.CleanOrCreateDirectory(config.IntermediateDirectory); var nativeCompiler = NativeCompiler.Create(config); var result = nativeCompiler.CompileToNative(config); return result ? 0 : 1; }); return app; }
internal static ArgValues Parse(IEnumerable <string> args) { CommandLineApplication app = new CommandLineApplication(); app.HelpOption("-h|--help"); CommandOption output = app.Option("--output <arg>", "Output Directory for native executable.", CommandOptionType.SingleValue); CommandOption tempOutput = app.Option("--temp-output <arg>", "Directory for intermediate files.", CommandOptionType.SingleValue); CommandOption configuration = app.Option("--configuration <arg>", "debug/release build configuration. Defaults to debug.", CommandOptionType.SingleValue); CommandOption mode = app.Option("--mode <arg>", "Code Generation mode. Defaults to ryujit.", CommandOptionType.SingleValue); CommandOption reference = app.Option("--reference <arg>...", "Use to specify Managed DLL references of the app.", CommandOptionType.MultipleValue); // Custom Extensibility Points to support CoreRT workflow TODO better descriptions CommandOption ilcarg = app.Option("--ilcarg <arg>...", "Use to specify custom arguments for the IL Compiler.", CommandOptionType.MultipleValue); CommandOption ilcpath = app.Option("--ilcpath <arg>", "Use to specify a custom build of IL Compiler.", CommandOptionType.SingleValue); CommandOption ilcsdkpath = app.Option("ilcsdkpath <arg>", "Use to specify a custom build of IL Compiler SDK", CommandOptionType.SingleValue); CommandOption linklib = app.Option("--linklib <arg>...", "Use to link in additional static libs", CommandOptionType.MultipleValue); // TEMPORARY Hack until CoreRT compatible Framework Libs are available CommandOption appdepsdk = app.Option("--appdepsdk <arg>", "Use to plug in custom appdepsdk path", CommandOptionType.SingleValue); // Optional Log Path CommandOption logpath = app.Option("--logpath <arg>", "Use to dump Native Compilation Logs to a file.", CommandOptionType.SingleValue); // Optional flags to be passed to the native compiler CommandOption cppcompilerflags = app.Option("--cppcompilerflags <arg>", "Additional flags to be passed to the native compiler.", CommandOptionType.SingleValue); CommandArgument inputAssembly = app.Argument("INPUT_ASSEMBLY", "The managed input assembly to compile to native."); ArgValues argValues = new ArgValues(); app.OnExecute(() => { if (string.IsNullOrEmpty(inputAssembly.Value)) { Reporter.Error.WriteLine("Input Assembly is a required parameter."); return(1); } if (configuration.HasValue()) { try { argValues.BuildConfiguration = EnumExtensions.Parse <BuildConfiguration>(configuration.Value()); } catch (ArgumentException) { Reporter.Error.WriteLine($"Invalid Configuration Option: {configuration}"); return(1); } } if (mode.HasValue()) { try { argValues.NativeMode = EnumExtensions.Parse <NativeIntermediateMode>(mode.Value()); } catch (ArgumentException) { Reporter.Error.WriteLine($"Invalid Mode Option: {mode}"); return(1); } } argValues.InputManagedAssemblyPath = inputAssembly.Value; argValues.OutputDirectory = output.Value(); argValues.IntermediateDirectory = tempOutput.Value(); argValues.Architecture = ArchitectureMode.x64; argValues.ReferencePaths = reference.Values; argValues.IlcArgs = ilcarg.Values.Select(s => { if (!s.StartsWith("\"") || !s.EndsWith("\"")) { throw new ArgumentException("--ilcarg must be specified in double quotes", "ilcarg"); } return(s.Substring(1, s.Length - 2)); }); argValues.IlcPath = ilcpath.Value(); argValues.IlcSdkPath = ilcsdkpath.Value(); argValues.LinkLibPaths = linklib.Values; argValues.AppDepSDKPath = appdepsdk.Value(); argValues.LogPath = logpath.Value(); argValues.CppCompilerFlags = cppcompilerflags.Value(); Reporter.Output.WriteLine($"Input Assembly: {inputAssembly}"); return(0); }); try { argValues.ReturnCode = app.Execute(args.ToArray()); } catch (Exception ex) { #if DEBUG Console.Error.WriteLine(ex); #else Console.Error.WriteLine(ex.Message); #endif argValues.ReturnCode = 1; } if (argValues.ReturnCode != 0) { argValues.IsHelp = true; } return(argValues); }