public void Can_add_argument() { ////Arrange var builder = new CommandLineBuilder(); ////Act var result = builder.Build(new Example {Argument = "tester"}); ////Assert Assert.That(result, Is.EqualTo(" -Des.index.gateway.type=tester")); }
protected override void AppendAdditionalArguments(CommandLineBuilder builder) { if (MaxCpuCount.HasValue) builder.Append("maxcpucount", MaxCpuCount); if (ToolsVersion.HasValue) builder.Append("toolsversion", PickToolsVersion()); if (NodeReuse.HasValue) builder.Append("nodeReuse", NodeReuse); }
/// <summary> /// Generates the command-line using the template specified. /// </summary> private void GenerateTemplatedCommandLine(CommandLineBuilder builder) { // Match all instances of [asdf], where "asdf" can be any combination of any // characters *except* a [ or an ]. i.e., if "[ [ sdf ]" is passed, then we will // match "[ sdf ]" string matchString = @"\[[^\[\]]+\]"; Regex regex = new Regex(matchString, RegexOptions.ECMAScript); MatchCollection matches = regex.Matches(CommandLineTemplate); int indexOfEndOfLastSubstitution = 0; foreach (Match match in matches) { if (match.Length == 0) { continue; } // Because we match non-greedily, in the case where we have input such as "[[[[[foo]", the match will // be "[foo]". However, if there are multiple '[' in a row, we need to do some escaping logic, so we // want to know what the first *consecutive* square bracket was. int indexOfFirstBracketInMatch = match.Index; // Indexing using "indexOfFirstBracketInMatch - 1" is safe here because it will always be // greater than indexOfEndOfLastSubstitution, which will always be 0 or greater. while (indexOfFirstBracketInMatch > indexOfEndOfLastSubstitution && CommandLineTemplate[indexOfFirstBracketInMatch - 1].Equals('[')) { indexOfFirstBracketInMatch--; } // Append everything we know we want to add -- everything between where the last substitution ended and // this match (including previous '[' that were not initially technically part of the match) begins. if (indexOfFirstBracketInMatch != indexOfEndOfLastSubstitution) { builder.AppendTextUnquoted(CommandLineTemplate.Substring(indexOfEndOfLastSubstitution, indexOfFirstBracketInMatch - indexOfEndOfLastSubstitution)); } // Now replace every "[[" with a literal '['. We can do this by simply counting the number of '[' between // the first one and the start of the match, since by definition everything in between is an '['. // + 1 because match.Index is also a bracket. int openBracketsInARow = match.Index - indexOfFirstBracketInMatch + 1; if (openBracketsInARow % 2 == 0) { // even number -- they all go away and the rest of the match is appended literally. for (int i = 0; i < openBracketsInARow / 2; i++) { builder.AppendTextUnquoted("["); } builder.AppendTextUnquoted(match.Value.Substring(1, match.Value.Length - 1)); } else { // odd number -- all but one get merged two at a time, and the rest of the match is substituted. for (int i = 0; i < (openBracketsInARow - 1) / 2; i++) { builder.AppendTextUnquoted("["); } // Determine which property the user has specified in the template. string propertyName = match.Value.Substring(1, match.Value.Length - 2); if (String.Equals(propertyName, "AllOptions", StringComparison.OrdinalIgnoreCase)) { // When [AllOptions] is specified, we append all switch-type options. CommandLineBuilder tempBuilder = new CommandLineBuilder(true); GenerateStandardCommandLine(tempBuilder, true); builder.AppendTextUnquoted(tempBuilder.ToString()); } else if (String.Equals(propertyName, "AdditionalOptions", StringComparison.OrdinalIgnoreCase)) { BuildAdditionalArgs(builder); } else if (IsPropertySet(propertyName)) { CommandLineToolSwitch property = _activeCommandLineToolSwitches[propertyName]; // verify the dependencies if (VerifyDependenciesArePresent(property) && VerifyRequiredArgumentsArePresent(property, false)) { CommandLineBuilder tempBuilder = new CommandLineBuilder(true); GenerateCommandsAccordingToType(tempBuilder, property, false); builder.AppendTextUnquoted(tempBuilder.ToString()); } } else if (!PropertyExists(propertyName)) { // If the thing enclosed in square brackets is not in fact a property, we // don't want to replace it. builder.AppendTextUnquoted('[' + propertyName + ']'); } } indexOfEndOfLastSubstitution = match.Index + match.Length; } builder.AppendTextUnquoted(CommandLineTemplate.Substring(indexOfEndOfLastSubstitution, CommandLineTemplate.Length - indexOfEndOfLastSubstitution)); }
private static StringBuilder GetCommandLine(CommandLineBuilder commandLine) { return((StringBuilder)commandLine.GetType() .GetProperty("CommandLine", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(commandLine, null)); }
public InteropMessage <WasmCodeRunnerResponse> ExecuteRunRequest(WasmCodeRunnerRequest runRequest, int sequence) { var output = new List <string>(); string runnerException = null; var bytes = Convert.FromBase64String(runRequest.Base64Assembly); var stdOut = new StringWriter(); var stdError = new StringWriter(); using (var consoleState = new PreserveConsoleState()) { MethodInfo main; try { var assembly = Assembly.Load(bytes); Console.SetOut(stdOut); Console.SetError(stdError); main = EntryPointDiscoverer.FindStaticEntryMethod(assembly); } catch (InvalidProgramException) { var result = new WasmCodeRunnerResponse(succeeded: false, exception: null, output: new[] { "error CS5001: Program does not contain a static 'Main' method suitable for an entry point" }, diagnostics: Array.Empty <SerializableDiagnostic>(), runnerException: null); return(new InteropMessage <WasmCodeRunnerResponse>(sequence, result)); } try { var args = runRequest.RunArgs; var builder = new CommandLineBuilder() .ConfigureRootCommandFromMethod(main); var parser = builder.Build(); parser.InvokeAsync(args).GetAwaiter().GetResult(); } catch (Exception e) { if ((e.InnerException ?? e) is TypeLoadException t) { runnerException = $"Missing type `{t.TypeName}`"; } if ((e.InnerException ?? e) is MissingMethodException m) { runnerException = $"Missing method `{m.Message}`"; } if ((e.InnerException ?? e) is FileNotFoundException f) { runnerException = $"Missing file: `{f.FileName}`"; } output.AddRange(SplitOnNewlines(e.ToString())); } var errors = stdError.ToString(); if (!string.IsNullOrWhiteSpace(errors)) { runnerException = errors; output.AddRange(SplitOnNewlines(errors)); } output.AddRange(SplitOnNewlines(stdOut.ToString())); var rb = new WasmCodeRunnerResponse( succeeded: true, exception: null, output: output.ToArray(), diagnostics: null, runnerException: runnerException); return(new InteropMessage <WasmCodeRunnerResponse>(sequence, rb)); } }
private void BuildCommands(CommandLineBuilder rootBuilder, Type type) { Command command = null; var baseAttributes = (BaseAttribute[])type.GetCustomAttributes(typeof(BaseAttribute), inherit: false); foreach (BaseAttribute baseAttribute in baseAttributes) { if (baseAttribute is CommandAttribute commandAttribute && IsValidPlatform(commandAttribute)) { command = new Command(commandAttribute.Name, commandAttribute.Help); var properties = new List <(PropertyInfo, Option)>(); var arguments = new List <(PropertyInfo, Argument)>(); foreach (PropertyInfo property in type.GetProperties().Where(p => p.CanWrite)) { var argumentAttribute = (ArgumentAttribute)property.GetCustomAttributes(typeof(ArgumentAttribute), inherit: false).SingleOrDefault(); if (argumentAttribute != null) { IArgumentArity arity = property.PropertyType.IsArray ? ArgumentArity.ZeroOrMore : ArgumentArity.ZeroOrOne; var argument = new Argument { Name = argumentAttribute.Name ?? property.Name.ToLowerInvariant(), Description = argumentAttribute.Help, ArgumentType = property.PropertyType, Arity = arity }; command.AddArgument(argument); arguments.Add((property, argument)); } else { var optionAttribute = (OptionAttribute)property.GetCustomAttributes(typeof(OptionAttribute), inherit: false).SingleOrDefault(); if (optionAttribute != null) { var option = new Option(optionAttribute.Name ?? BuildAlias(property.Name), optionAttribute.Help) { Argument = new Argument { ArgumentType = property.PropertyType } }; command.AddOption(option); properties.Add((property, option)); foreach (var optionAliasAttribute in (OptionAliasAttribute[])property.GetCustomAttributes(typeof(OptionAliasAttribute), inherit: false)) { option.AddAlias(optionAliasAttribute.Name); } } else { // If not an option, add as just a settable properties properties.Add((property, null)); } } } var handler = new Handler(this, commandAttribute.AliasExpansion, arguments, properties, type); _commandHandlers.Add(command.Name, handler); command.Handler = handler; rootBuilder.AddCommand(command); } if (baseAttribute is CommandAliasAttribute commandAliasAttribute && IsValidPlatform(commandAliasAttribute)) { if (command == null) { throw new ArgumentException($"No previous CommandAttribute for this CommandAliasAttribute: {type.Name}"); } command.AddAlias(commandAliasAttribute.Name); } } }
private static CommandLineBuilder DisablePosixBinding(this CommandLineBuilder builder) { builder.EnablePosixBundling(false); return(builder); }
protected override string GetArguments() { var builder = new CommandLineBuilder(); if (Targets.Any()) builder.Append("target", string.Join(";", Targets.ToArray())); foreach (var property in Properties) builder.Append("property", string.Format("{0}={1}", property.Key, property.Value)); if(Verbosity.HasValue) builder.Append("verbosity", Verbosity.ToString().ToLowerInvariant()); builder.Append(ProjectFile ?? GetFirstSolutionInCurrentDir()); AppendAdditionalArguments(builder); return builder.ToString(); }
string GenerateCommandLineCommands(string ManifestFile, string currentAbi, string currentResourceOutputFile) { var cmd = new CommandLineBuilder(); cmd.AppendSwitch("link"); if (MonoAndroidHelper.LogInternalExceptions) { cmd.AppendSwitch("-v"); } string manifestDir = Path.Combine(Path.GetDirectoryName(ManifestFile), currentAbi != null ? currentAbi : "manifest"); Directory.CreateDirectory(manifestDir); string manifestFile = Path.Combine(manifestDir, Path.GetFileName(ManifestFile)); ManifestDocument manifest = new ManifestDocument(ManifestFile, this.Log); manifest.SdkVersion = AndroidSdkPlatform; if (!string.IsNullOrEmpty(VersionCodePattern)) { try { manifest.CalculateVersionCode(currentAbi, VersionCodePattern, VersionCodeProperties); } catch (ArgumentOutOfRangeException ex) { Log.LogCodedError("XA0003", ManifestFile, 0, ex.Message); return(string.Empty); } } if (currentAbi != null && string.IsNullOrEmpty(VersionCodePattern)) { manifest.SetAbi(currentAbi); } if (!manifest.ValidateVersionCode(out string error, out string errorCode)) { Log.LogCodedError(errorCode, ManifestFile, 0, error); return(string.Empty); } manifest.ApplicationName = ApplicationName; manifest.Save(manifestFile); cmd.AppendSwitchIfNotNull("--manifest ", manifestFile); if (!string.IsNullOrEmpty(JavaDesignerOutputDirectory)) { var designerDirectory = Path.IsPathRooted(JavaDesignerOutputDirectory) ? JavaDesignerOutputDirectory : Path.Combine(WorkingDirectory, JavaDesignerOutputDirectory); Directory.CreateDirectory(designerDirectory); cmd.AppendSwitchIfNotNull("--java ", JavaDesignerOutputDirectory); } if (PackageName != null) { cmd.AppendSwitchIfNotNull("--custom-package ", PackageName.ToLowerInvariant()); } if (AdditionalResourceArchives != null) { foreach (var item in AdditionalResourceArchives) { var flata = Path.Combine(WorkingDirectory, item.ItemSpec); if (File.Exists(flata)) { cmd.AppendSwitchIfNotNull("-R ", flata); } else { Log.LogDebugMessage("Archive does not exist: " + flata); } } } if (CompiledResourceFlatArchive != null) { var flata = Path.Combine(WorkingDirectory, CompiledResourceFlatArchive.ItemSpec); if (File.Exists(flata)) { cmd.AppendSwitchIfNotNull("-R ", flata); } else { Log.LogDebugMessage("Archive does not exist: " + flata); } } cmd.AppendSwitch("--auto-add-overlay"); if (!string.IsNullOrWhiteSpace(UncompressedFileExtensions)) { foreach (var ext in UncompressedFileExtensions.Split(new char [] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries)) { cmd.AppendSwitchIfNotNull("-0 ", ext); } } if (!string.IsNullOrEmpty(ExtraPackages)) { cmd.AppendSwitchIfNotNull("--extra-packages ", ExtraPackages); } cmd.AppendSwitchIfNotNull("-I ", JavaPlatformJarPath); if (!string.IsNullOrEmpty(ResourceSymbolsTextFile)) { cmd.AppendSwitchIfNotNull("--output-text-symbols ", ResourceSymbolsTextFile); } if (ProtobufFormat) { cmd.AppendSwitch("--proto-format"); } var extraArgsExpanded = ExpandString(ExtraArgs); if (extraArgsExpanded != ExtraArgs) { Log.LogDebugMessage(" ExtraArgs expanded: {0}", extraArgsExpanded); } if (!string.IsNullOrWhiteSpace(extraArgsExpanded)) { cmd.AppendSwitch(extraArgsExpanded); } if (!string.IsNullOrWhiteSpace(AssetsDirectory)) { var assetDir = AssetsDirectory.TrimEnd('\\'); if (!Path.IsPathRooted(assetDir)) { assetDir = Path.Combine(WorkingDirectory, assetDir); } if (!string.IsNullOrWhiteSpace(assetDir) && Directory.Exists(assetDir)) { cmd.AppendSwitchIfNotNull("-A ", assetDir); } } cmd.AppendSwitchIfNotNull("-o ", currentResourceOutputFile); return(cmd.ToString()); }
private static unsafe CommandLineBuilder Init_MakeConEmuCommandLine([NotNull] ConEmuStartInfo startinfo, [NotNull] HostContext hostcontext, [CanBeNull] AnsiLog ansilog, [NotNull] DirectoryInfo dirLocalTempRoot) { if (startinfo == null) { throw new ArgumentNullException(nameof(startinfo)); } if (hostcontext == null) { throw new ArgumentNullException(nameof(hostcontext)); } var cmdl = new CommandLineBuilder(); // This sets up hosting of ConEmu in our control cmdl.AppendSwitch("-InsideWnd"); cmdl.AppendFileNameIfNotNull("0x" + ((ulong)hostcontext.HWndParent).ToString("X")); // Don't use keyboard hooks in ConEmu when embedded cmdl.AppendSwitch("-NoKeyHooks"); switch (startinfo.LogLevel) { case ConEmuStartInfo.LogLevels.Basic: cmdl.AppendSwitch("-Log"); break; case ConEmuStartInfo.LogLevels.Detailed: cmdl.AppendSwitch("-Log2"); break; case ConEmuStartInfo.LogLevels.Advanced: cmdl.AppendSwitch("-Log3"); break; case ConEmuStartInfo.LogLevels.Full: cmdl.AppendSwitch("-Log4"); break; } // Basic settings, like fonts and hidden tab bar // Plus some of the properties on this class cmdl.AppendSwitch("-LoadCfgFile"); cmdl.AppendFileNameIfNotNull(Init_MakeConEmuCommandLine_EmitConfigFile(dirLocalTempRoot, startinfo, hostcontext)); if (!string.IsNullOrEmpty(startinfo.StartupDirectory)) { cmdl.AppendSwitch("-Dir"); cmdl.AppendFileNameIfNotNull(startinfo.StartupDirectory); } if (dirLocalTempRoot == null) { throw new ArgumentNullException(nameof(dirLocalTempRoot)); } // This one MUST be the last switch cmdl.AppendSwitch("-cmd"); // Console mode command // NOTE: if placed AFTER the payload command line, otherwise somehow conemu hooks won't fetch the switch out of the cmdline, e.g. with some complicated git fetch/push cmdline syntax which has a lot of colons inside on itself string sConsoleExitMode; switch (startinfo.WhenConsoleProcessExits) { case WhenConsoleProcessExits.CloseConsoleEmulator: sConsoleExitMode = "n"; break; case WhenConsoleProcessExits.KeepConsoleEmulator: sConsoleExitMode = "c0"; break; case WhenConsoleProcessExits.KeepConsoleEmulatorAndShowMessage: sConsoleExitMode = "c"; break; default: throw new ArgumentOutOfRangeException("ConEmuStartInfo" + "::" + "WhenConsoleProcessExits", startinfo.WhenConsoleProcessExits, "This is not a valid enum value."); } cmdl.AppendSwitchIfNotNull("-cur_console:", $"{(startinfo.IsElevated ? "a" : "")}{sConsoleExitMode}"); // ANSI Log file if (ansilog != null) { cmdl.AppendSwitchIfNotNull("-cur_console:L:", ansilog.Directory.FullName); } if (!string.IsNullOrEmpty(startinfo.ConsoleProcessExtraArgs)) { cmdl.AppendSwitch(startinfo.ConsoleProcessExtraArgs); } // And the shell command line itself cmdl.AppendSwitch(startinfo.ConsoleProcessCommandLine); return(cmdl); }
private Process Init_StartConEmu([NotNull] ConEmuStartInfo startinfo, [NotNull] CommandLineBuilder cmdl) { if (startinfo == null) { throw new ArgumentNullException(nameof(startinfo)); } if (cmdl == null) { throw new ArgumentNullException(nameof(cmdl)); } try { if (string.IsNullOrEmpty(startinfo.ConEmuExecutablePath)) { throw new InvalidOperationException("Could not run the console emulator. The path to ConEmu.exe could not be detected."); } if (!File.Exists(startinfo.ConEmuExecutablePath)) { throw new InvalidOperationException($"Missing ConEmu executable at location “{startinfo.ConEmuExecutablePath}”."); } var processNew = new Process() { StartInfo = new ProcessStartInfo(startinfo.ConEmuExecutablePath, cmdl.ToString()) { UseShellExecute = false } }; // Bind process termination processNew.EnableRaisingEvents = true; processNew.Exited += delegate { // Ensure STA _joinableTaskFactory.RunAsync(async() => { await _joinableTaskFactory.SwitchToMainThreadAsync(); // Tear down all objects TerminateLifetime(); // If we haven't separately caught an exit of the payload process TryFireConsoleProcessExited(_process.ExitCode /* We haven't caught the exit of the payload process, so we haven't gotten a message with its errorlevel as well. Assume ConEmu propagates its exit code, as there ain't other way for getting it now */); // Fire client total exited event ConsoleEmulatorClosed?.Invoke(this, EventArgs.Empty); }); }; if (!processNew.Start()) { throw new Win32Exception("The process did not start."); } return(processNew); } catch (Win32Exception ex) { TerminateLifetime(); throw new InvalidOperationException("Could not run the console emulator. " + ex.Message + $" ({ex.NativeErrorCode:X8})" + Environment.NewLine + Environment.NewLine + "Command:" + Environment.NewLine + startinfo.ConEmuExecutablePath + Environment.NewLine + Environment.NewLine + "Arguments:" + Environment.NewLine + cmdl, ex); } }
bool DoExecute() { var abis = SupportedAbis.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); var results = new List <ITaskItem> (); string bundlepath = Path.Combine(TempOutputPath, "bundles"); if (!Directory.Exists(bundlepath)) { Directory.CreateDirectory(bundlepath); } else { Directory.Delete(bundlepath, true); } foreach (var abi in abis) { AndroidTargetArch arch = AndroidTargetArch.Other; switch (abi) { case "arm64": case "arm64-v8a": case "aarch64": arch = AndroidTargetArch.Arm64; break; case "armeabi": case "armeabi-v7a": arch = AndroidTargetArch.Arm; break; case "x86": arch = AndroidTargetArch.X86; break; case "x86_64": arch = AndroidTargetArch.X86_64; break; case "mips": arch = AndroidTargetArch.Mips; break; } if (!NdkUtil.ValidateNdkPlatform(Log, AndroidNdkDirectory, arch, enableLLVM: false)) { return(false); } int level = NdkUtil.GetMinimumApiLevelFor(arch, AndroidNdkDirectory); var outpath = Path.Combine(bundlepath, abi); if (!Directory.Exists(outpath)) { Directory.CreateDirectory(outpath); } var clb = new CommandLineBuilder(); clb.AppendSwitch("--dos2unix=false"); clb.AppendSwitch("--nomain"); clb.AppendSwitch("--i18n none"); clb.AppendSwitch("--bundled-header"); clb.AppendSwitch("--style"); clb.AppendSwitch("linux"); clb.AppendSwitch("-c"); clb.AppendSwitch("-o"); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "temp.c")); clb.AppendSwitch("-oo"); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "assemblies.o")); if (AutoDeps) { clb.AppendSwitch("--autodeps"); } if (KeepTemp) { clb.AppendSwitch("--keeptemp"); } clb.AppendSwitch("-z"); // Compress clb.AppendFileNamesIfNotNull(Assemblies, " "); var psi = new ProcessStartInfo() { FileName = MkbundlePath, Arguments = clb.ToString(), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, }; var gccNoQuotes = NdkUtil.GetNdkTool(AndroidNdkDirectory, arch, "gcc"); var gcc = '"' + gccNoQuotes + '"'; var gas = '"' + NdkUtil.GetNdkTool(AndroidNdkDirectory, arch, "as") + '"'; psi.EnvironmentVariables ["CC"] = gcc; psi.EnvironmentVariables ["AS"] = gas; Log.LogDebugMessage("CC=" + gcc); Log.LogDebugMessage("AS=" + gas); //psi.EnvironmentVariables ["PKG_CONFIG_PATH"] = Path.Combine (Path.GetDirectoryName (MonoDroidSdk.MandroidTool), "lib", abi); Log.LogDebugMessage("[mkbundle] " + psi.FileName + " " + clb); var proc = new Process(); proc.OutputDataReceived += OnMkbundleOutputData; proc.ErrorDataReceived += OnMkbundleErrorData; proc.StartInfo = psi; proc.Start(); proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.WaitForExit(); if (proc.ExitCode != 0) { Log.LogCodedError("XA5102", "Conversion from assembly to native code failed. Exit code {0}", proc.ExitCode); return(false); } // make some changes in the mkbundle output so that it does not require libmonodroid.so var mkbundleOutput = File.ReadAllText(Path.Combine(outpath, "temp.c")); mkbundleOutput = mkbundleOutput.Replace("void mono_mkbundle_init ()", "void mono_mkbundle_init (void (register_bundled_assemblies_func)(const MonoBundledAssembly **), void (register_config_for_assembly_func)(const char *, const char *))") .Replace("mono_register_config_for_assembly (\"", "register_config_for_assembly_func (\"") .Replace("install_dll_config_files (void)", "install_dll_config_files (void (register_config_for_assembly_func)(const char *, const char *))") .Replace("install_dll_config_files ()", "install_dll_config_files (register_config_for_assembly_func)") .Replace("mono_register_bundled_assemblies(", "register_bundled_assemblies_func("); File.WriteAllText(Path.Combine(outpath, "temp.c"), mkbundleOutput); // then compile temp.c into temp.o and ... clb = new CommandLineBuilder(); clb.AppendSwitch("-c"); clb.AppendSwitch("-o"); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "temp.o")); if (!string.IsNullOrWhiteSpace(IncludePath)) { clb.AppendSwitch("-I"); clb.AppendFileNameIfNotNull(IncludePath); } clb.AppendSwitch("-I"); clb.AppendFileNameIfNotNull(NdkUtil.GetNdkPlatformIncludePath(AndroidNdkDirectory, arch, level)); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "temp.c")); Log.LogDebugMessage("[CC] " + gcc + " " + clb); if (MonoAndroidHelper.RunProcess(gccNoQuotes, clb.ToString(), OnCcOutputData, OnCcErrorData) != 0) { Log.LogCodedError("XA5103", "NDK C compiler resulted in an error. Exit code {0}", proc.ExitCode); return(false); } // ... link temp.o and assemblies.o into app.so clb = new CommandLineBuilder(); clb.AppendSwitch("--shared"); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "temp.o")); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "assemblies.o")); clb.AppendSwitch("-o"); clb.AppendFileNameIfNotNull(Path.Combine(outpath, "libmonodroid_bundle_app.so")); clb.AppendSwitch("-L"); clb.AppendFileNameIfNotNull(NdkUtil.GetNdkPlatformLibPath(AndroidNdkDirectory, arch, level)); clb.AppendSwitch("-lc"); clb.AppendSwitch("-lm"); clb.AppendSwitch("-ldl"); clb.AppendSwitch("-llog"); clb.AppendSwitch("-lz"); // Compress string ld = NdkUtil.GetNdkTool(AndroidNdkDirectory, arch, "ld"); Log.LogMessage(MessageImportance.Normal, "[LD] " + ld + " " + clb); if (MonoAndroidHelper.RunProcess(ld, clb.ToString(), OnLdOutputData, OnLdErrorData) != 0) { Log.LogCodedError("XA5201", "NDK Linker resulted in an error. Exit code {0}", proc.ExitCode); return(false); } results.Add(new TaskItem(Path.Combine(outpath, "libmonodroid_bundle_app.so"))); } OutputNativeLibraries = results.ToArray(); return(true); }
protected override string GenerateCommandLineCommands() { var cmd = new CommandLineBuilder(); if (!UseProguard) { // Add the JavaOptions if they are not null // These could be any of the additional options if (!string.IsNullOrEmpty(JavaOptions)) { cmd.AppendSwitch(JavaOptions); } // Add the specific -XmxN to override the default heap size for the JVM // N can be in the form of Nm or NGB (e.g 100m or 1GB ) cmd.AppendSwitchIfNotNull("-Xmx", JavaMaximumHeapSize); cmd.AppendSwitchIfNotNull("-jar ", Path.Combine(ProguardJarPath)); } if (!ClassesOutputDirectory.EndsWith(Path.DirectorySeparatorChar.ToString())) { ClassesOutputDirectory += Path.DirectorySeparatorChar; } var classesFullPath = Path.GetFullPath(ClassesOutputDirectory); if (File.Exists(ProguardJarInput)) { File.Delete(ProguardJarInput); } using (var zip = ZipArchive.Open(ProguardJarInput, FileMode.Create)) { foreach (var file in Directory.GetFiles(classesFullPath, "*", SearchOption.AllDirectories)) { zip.AddFile(file, Path.Combine(Path.GetDirectoryName(file.Substring(classesFullPath.Length)), Path.GetFileName(file))); } } var acwLines = File.ReadAllLines(AcwMapFile); using (var appcfg = File.CreateText(ProguardGeneratedApplicationConfiguration)) for (int i = 0; i + 3 < acwLines.Length; i += 4) { try { var java = acwLines [i + 3].Substring(acwLines [i + 3].IndexOf(';') + 1); appcfg.WriteLine("-keep class " + java + " { *; }"); } catch { // skip invalid lines } } var injars = new List <string> (); var libjars = new List <string> (); injars.Add(ProguardJarInput); if (JavaLibrariesToEmbed != null) { foreach (var jarfile in JavaLibrariesToEmbed) { injars.Add(jarfile.ItemSpec); } } using (var xamcfg = File.Create(ProguardCommonXamarinConfiguration)) GetType().Assembly.GetManifestResourceStream("proguard_xamarin.cfg").CopyTo(xamcfg); var configs = ProguardConfigurationFiles .Replace("{sdk.dir}", AndroidSdkDirectory + Path.DirectorySeparatorChar) .Replace("{intermediate.common.xamarin}", ProguardCommonXamarinConfiguration) .Replace("{intermediate.references}", ProguardGeneratedReferenceConfiguration) .Replace("{intermediate.application}", ProguardGeneratedApplicationConfiguration) .Replace("{project}", string.Empty) // current directory anyways. .Split(';') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)); var enclosingChar = OS.IsWindows ? "\"" : string.Empty; foreach (var file in configs) { if (File.Exists(file)) { cmd.AppendSwitchUnquotedIfNotNull("-include ", $"{enclosingChar}'{file}'{enclosingChar}"); } else { Log.LogWarning("Proguard configuration file '{0}' was not found.", file); } } libjars.Add(JavaPlatformJarPath); if (ExternalJavaLibraries != null) { foreach (var jarfile in ExternalJavaLibraries.Select(p => p.ItemSpec)) { libjars.Add(jarfile); } } cmd.AppendSwitchUnquotedIfNotNull("-injars ", $"{enclosingChar}'" + string.Join($"'{Path.PathSeparator}'", injars.Distinct()) + $"'{enclosingChar}"); cmd.AppendSwitchUnquotedIfNotNull("-libraryjars ", $"{enclosingChar}'" + string.Join($"'{Path.PathSeparator}'", libjars.Distinct()) + $"'{enclosingChar}"); cmd.AppendSwitchIfNotNull("-outjars ", ProguardJarOutput); if (EnableLogging) { cmd.AppendSwitchIfNotNull("-dump ", DumpOutput); cmd.AppendSwitchIfNotNull("-printseeds ", PrintSeedsOutput); cmd.AppendSwitchIfNotNull("-printusage ", PrintUsageOutput); cmd.AppendSwitchIfNotNull("-printmapping ", PrintMappingOutput); } // http://stackoverflow.com/questions/5701126/compile-with-proguard-gives-exception-local-variable-type-mismatch#7587680 cmd.AppendSwitch("-optimizations !code/allocation/variable"); return(cmd.ToString()); }
public static CommandLineBuilder Build() { var parser = new CommandLineBuilder() .AddCommand(CompileFolder()) .AddCommand(CompileSubtree()) .AddCommand(CompileNugetPackages()); return(parser); Command CompileFolder() => new Command("compile-directory", "Compile all assemblies in directory", new Option[] { InputDirectory(), OutputDirectory(), CoreRootDirectory(), CpaotDirectory(), Crossgen(), NoJit(), NoExe(), NoEtw(), NoCleanup(), Sequential(), Framework(), UseFramework(), Release(), LargeBubble(), ReferencePath(), IssuesPath(), }, handler: CommandHandler.Create <BuildOptions>(CompileDirectoryCommand.CompileDirectory)); Command CompileSubtree() => new Command("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app", new Option[] { InputDirectory(), OutputDirectory(), CoreRootDirectory(), CpaotDirectory(), Crossgen(), NoJit(), NoExe(), NoEtw(), NoCleanup(), Sequential(), Framework(), UseFramework(), Release(), LargeBubble(), ReferencePath(), IssuesPath(), }, handler: CommandHandler.Create <BuildOptions>(CompileSubtreeCommand.CompileSubtree)); Command CompileNugetPackages() => new Command("compile-nuget", "Restore a list of Nuget packages into an empty console app, publish, and optimize with Crossgen / CPAOT", new Option[] { OutputDirectory(), PackageList(), CoreRootDirectory(), Crossgen(), CpaotDirectory(), NoCleanup() }, handler: CommandHandler.Create <BuildOptions>(CompileNugetCommand.CompileNuget)); // Todo: Input / Output directories should be required arguments to the command when they're made available to handlers // https://github.com/dotnet/command-line-api/issues/297 Option InputDirectory() => new Option(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize", new Argument <DirectoryInfo>().ExistingOnly()); Option OutputDirectory() => new Option(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies", new Argument <DirectoryInfo>().LegalFilePathsOnly()); Option CoreRootDirectory() => new Option(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder", new Argument <DirectoryInfo>().ExistingOnly()); Option CpaotDirectory() => new Option(new[] { "--cpaot-directory", "-cpaot" }, "Folder containing the CPAOT compiler", new Argument <DirectoryInfo>().ExistingOnly()); Option ReferencePath() => new Option(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation", new Argument <DirectoryInfo[]>() { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly()); Option Crossgen() => new Option(new[] { "--crossgen" }, "Compile the apps using Crossgen in the CORE_ROOT folder", new Argument <bool>()); Option NoJit() => new Option(new[] { "--nojit" }, "Don't run tests in JITted mode", new Argument <bool>()); Option NoEtw() => new Option(new[] { "--noetw" }, "Don't capture jitted methods using ETW", new Argument <bool>()); Option NoExe() => new Option(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)", new Argument <bool>()); Option NoCleanup() => new Option(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs", new Argument <bool>()); Option Sequential() => new Option(new[] { "--sequential" }, "Run tests sequentially", new Argument <bool>()); Option Framework() => new Option(new[] { "--framework" }, "Precompile and use native framework", new Argument <bool>()); Option UseFramework() => new Option(new[] { "--use-framework" }, "Use native framework (don't precompile, assume previously compiled)", new Argument <bool>()); Option Release() => new Option(new[] { "--release" }, "Build the tests in release mode", new Argument <bool>()); Option LargeBubble() => new Option(new[] { "--large-bubble" }, "Assume all input files as part of one version bubble", new Argument <bool>()); Option IssuesPath() => new Option(new[] { "--issues-path", "-ip" }, "Path to issues.targets", new Argument <FileInfo[]>() { Arity = ArgumentArity.ZeroOrMore }); // // compile-nuget specific options // Option PackageList() => new Option(new[] { "--package-list", "-pl" }, "Text file containing a package name on each line", new Argument <FileInfo>().ExistingOnly()); }
public static CommandLineBuilder Build() { var parser = new CommandLineBuilder() .AddCommand(CompileFolder()) .AddCommand(CompileSubtree()) .AddCommand(CompileFramework()) .AddCommand(CompileNugetPackages()) .AddCommand(CompileSerp()); return(parser); Command CreateCommand(string name, string description, Option[] options, Func <BuildOptions, int> action) { Command command = new Command(name, description); foreach (var option in GetCommonOptions()) { command.AddOption(option); } foreach (var option in options) { command.AddOption(option); } command.Handler = CommandHandler.Create <BuildOptions>(action); return(command); } Option[] GetCommonOptions() => new[] { CoreRootDirectory(), DotNetCli() }; Command CompileFolder() => CreateCommand("compile-directory", "Compile all assemblies in directory", new Option[] { InputDirectory(), OutputDirectory(), Crossgen(), CrossgenPath(), Crossgen2Path(), TargetArch(), VerifyTypeAndFieldLayout(), NoJit(), NoCrossgen2(), Exe(), NoExe(), NoEtw(), NoCleanup(), Map(), Pdb(), DegreeOfParallelism(), Sequential(), Framework(), UseFramework(), Release(), LargeBubble(), Composite(), Crossgen2Parallelism(), Crossgen2JitPath(), ReferencePath(), IssuesPath(), CompilationTimeoutMinutes(), ExecutionTimeoutMinutes(), R2RDumpPath(), MeasurePerf(), InputFileSearchString(), }, CompileDirectoryCommand.CompileDirectory); Command CompileSubtree() => CreateCommand("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app", new Option[] { InputDirectory(), OutputDirectory(), Crossgen(), CrossgenPath(), Crossgen2Path(), TargetArch(), VerifyTypeAndFieldLayout(), NoJit(), NoCrossgen2(), Exe(), NoExe(), NoEtw(), NoCleanup(), Map(), Pdb(), DegreeOfParallelism(), Sequential(), Framework(), UseFramework(), Release(), LargeBubble(), Composite(), Crossgen2Parallelism(), Crossgen2JitPath(), ReferencePath(), IssuesPath(), CompilationTimeoutMinutes(), ExecutionTimeoutMinutes(), R2RDumpPath(), GCStress(), }, CompileSubtreeCommand.CompileSubtree); Command CompileFramework() => CreateCommand("compile-framework", "Compile managed framework assemblies in Core_Root", new Option[] { Crossgen(), CrossgenPath(), Crossgen2Path(), TargetArch(), VerifyTypeAndFieldLayout(), NoCrossgen2(), NoCleanup(), Map(), Pdb(), Crossgen2Parallelism(), Crossgen2JitPath(), DegreeOfParallelism(), Sequential(), Release(), LargeBubble(), Composite(), ReferencePath(), IssuesPath(), CompilationTimeoutMinutes(), R2RDumpPath(), MeasurePerf(), InputFileSearchString(), OutputDirectory(), }, CompileFrameworkCommand.CompileFramework); Command CompileNugetPackages() => CreateCommand("compile-nuget", "Restore a list of Nuget packages into an empty console app, publish, and optimize with Crossgen / CPAOT", new Option[] { R2RDumpPath(), InputDirectory(), OutputDirectory(), PackageList(), Crossgen(), NoCleanup(), Map(), Pdb(), DegreeOfParallelism(), CompilationTimeoutMinutes(), ExecutionTimeoutMinutes(), }, CompileNugetCommand.CompileNuget); Command CompileSerp() => CreateCommand("compile-serp", "Compile existing application", new Option[] { InputDirectory(), DegreeOfParallelism(), AspNetPath(), Composite(), Map(), Pdb(), CompilationTimeoutMinutes(), Crossgen2Path(), }, options => { var compileSerp = new CompileSerpCommand(options); return(compileSerp.CompileSerpAssemblies()); }); // Todo: Input / Output directories should be required arguments to the command when they're made available to handlers // https://github.com/dotnet/command-line-api/issues/297 Option InputDirectory() => new Option <DirectoryInfo>(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize").ExistingOnly(); Option OutputDirectory() => new Option <DirectoryInfo>(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies").LegalFilePathsOnly(); Option CoreRootDirectory() => new Option <DirectoryInfo>(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder") { Required = true }.ExistingOnly(); Option ReferencePath() => new Option <DirectoryInfo[]>(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation") { Argument = new Argument <DirectoryInfo[]>() { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly() }; Option Crossgen() => new Option <bool>(new[] { "--crossgen" }, "Compile the apps using Crossgen in the CORE_ROOT folder"); Option CrossgenPath() => new Option <FileInfo>(new[] { "--crossgen-path", "-cp" }, "Explicit Crossgen path (useful for cross-targeting)").ExistingOnly(); Option Crossgen2Path() => new Option <FileInfo>(new[] { "--crossgen2-path", "-c2p" }, "Explicit Crossgen2 path (useful for cross-targeting)").ExistingOnly(); Option VerifyTypeAndFieldLayout() => new Option <bool>(new[] { "--verify-type-and-field-layout" }, "Verify that struct type layout and field offsets match between compile time and runtime. Use only for diagnostic purposes."); Option NoJit() => new Option <bool>(new[] { "--nojit" }, "Don't run tests in JITted mode"); Option NoCrossgen2() => new Option <bool>(new[] { "--nocrossgen2" }, "Don't run tests in Crossgen2 mode"); Option Exe() => new Option <bool>(new[] { "--exe" }, "Don't compile tests, just execute them"); Option NoExe() => new Option <bool>(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)"); Option NoEtw() => new Option <bool>(new[] { "--noetw" }, "Don't capture jitted methods using ETW"); Option NoCleanup() => new Option <bool>(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs"); Option Map() => new Option <bool>(new[] { "--map" }, "Generate a map file (Crossgen2)"); Option Pdb() => new Option <bool>(new[] { "--pdb" }, "Generate PDB symbol information (Crossgen2 / Windows only)"); Option DegreeOfParallelism() => new Option <int>(new[] { "--degree-of-parallelism", "-dop" }, "Override default compilation / execution DOP (default = logical processor count)"); Option Sequential() => new Option <bool>(new[] { "--sequential" }, "Run tests sequentially"); Option Framework() => new Option <bool>(new[] { "--framework" }, "Precompile and use native framework"); Option UseFramework() => new Option <bool>(new[] { "--use-framework" }, "Use native framework (don't precompile, assume previously compiled)"); Option Release() => new Option <bool>(new[] { "--release" }, "Build the tests in release mode"); Option LargeBubble() => new Option <bool>(new[] { "--large-bubble" }, "Assume all input files as part of one version bubble"); Option Composite() => new Option <bool>(new[] { "--composite" }, "Compile tests in composite R2R mode"); Option Crossgen2Parallelism() => new Option <int>(new[] { "--crossgen2-parallelism" }, "Max number of threads to use in Crossgen2 (default = logical processor count)"); Option Crossgen2JitPath() => new Option <FileInfo>(new[] { "--crossgen2-jitpath" }, "Jit path to use for crossgen2"); Option IssuesPath() => new Option <FileInfo[]>(new[] { "--issues-path", "-ip" }, "Path to issues.targets") { Argument = new Argument <FileInfo[]>() { Arity = ArgumentArity.ZeroOrMore } }; Option CompilationTimeoutMinutes() => new Option <int>(new[] { "--compilation-timeout-minutes", "-ct" }, "Compilation timeout (minutes)"); Option ExecutionTimeoutMinutes() => new Option <int>(new[] { "--execution-timeout-minutes", "-et" }, "Execution timeout (minutes)"); Option R2RDumpPath() => new Option <FileInfo>(new[] { "--r2r-dump-path", "-r2r" }, "Path to R2RDump.exe/dll").ExistingOnly();; Option MeasurePerf() => new Option <bool>(new[] { "--measure-perf" }, "Print out compilation time"); Option InputFileSearchString() => new Option <string>(new[] { "--input-file-search-string", "-input-file" }, "Search string for input files in the input directory"); Option GCStress() => new Option <string>(new[] { "--gcstress" }, "Run tests with the specified GC stress level enabled (the argument value is in hex)"); Option DotNetCli() => new Option <string>(new [] { "--dotnet-cli", "-cli" }, "For dev box testing, point at .NET 5 dotnet.exe or <repo>/dotnet.cmd."); Option TargetArch() => new Option <string>(new[] { "--target-arch" }, "Target architecture for crossgen2"); // // compile-nuget specific options // Option PackageList() => new Option <FileInfo>(new[] { "--package-list", "-pl" }, "Text file containing a package name on each line").ExistingOnly();; // // compile-serp specific options // Option AspNetPath() => new Option <DirectoryInfo>(new[] { "--asp-net-path", "-asp" }, "Path to SERP's ASP.NET Core folder").ExistingOnly(); }
public static void ShouldBe(this CommandLineBuilder commandLineBuilder, string expected) { commandLineBuilder.ToString().ShouldBe(expected); }
protected override string GenerateCommandLineCommands() { var cmd = new CommandLineBuilder(); if (!UseProguard) { // Add the JavaOptions if they are not null // These could be any of the additional options if (!string.IsNullOrEmpty(JavaOptions)) { cmd.AppendSwitch(JavaOptions); } // Add the specific -XmxN to override the default heap size for the JVM // N can be in the form of Nm or NGB (e.g 100m or 1GB ) cmd.AppendSwitchIfNotNull("-Xmx", JavaMaximumHeapSize); cmd.AppendSwitchIfNotNull("-jar ", Path.Combine(ProguardJarPath)); } if (!ClassesOutputDirectory.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase)) { ClassesOutputDirectory += Path.DirectorySeparatorChar; } var classesZip = Path.Combine(ClassesOutputDirectory, "..", "classes.zip"); var acwLines = File.ReadAllLines(AcwMapFile); using (var appcfg = File.CreateText(ProguardGeneratedApplicationConfiguration)) for (int i = 0; i + 2 < acwLines.Length; i += 3) { try { var line = acwLines [i + 2]; var java = line.Substring(line.IndexOf(';') + 1); appcfg.WriteLine("-keep class " + java + " { *; }"); } catch { // skip invalid lines } } if (!string.IsNullOrWhiteSpace(ProguardCommonXamarinConfiguration)) { using (var xamcfg = File.Create(ProguardCommonXamarinConfiguration)) GetType().Assembly.GetManifestResourceStream("proguard_xamarin.cfg").CopyTo(xamcfg); } var enclosingChar = OS.IsWindows ? "\"" : string.Empty; foreach (var file in ProguardConfigurationFiles) { if (File.Exists(file)) { cmd.AppendSwitchUnquotedIfNotNull("-include ", $"{enclosingChar}'{file}'{enclosingChar}"); } else { Log.LogCodedWarning("XA4304", file, 0, Properties.Resources.XA4304, file); } } var injars = new List <string> (); var libjars = new List <string> (); injars.Add(classesZip); if (JavaLibrariesToEmbed != null) { foreach (var jarfile in JavaLibrariesToEmbed) { injars.Add(jarfile.ItemSpec); } } libjars.Add(JavaPlatformJarPath); if (JavaLibrariesToReference != null) { foreach (var jarfile in JavaLibrariesToReference.Select(p => p.ItemSpec)) { libjars.Add(jarfile); } } cmd.AppendSwitchUnquotedIfNotNull("-injars ", "\"'" + string.Join($"'{ProguardInputJarFilter}{Path.PathSeparator}'", injars.Distinct()) + $"'{ProguardInputJarFilter}\""); cmd.AppendSwitchUnquotedIfNotNull("-libraryjars ", $"{enclosingChar}'" + string.Join($"'{Path.PathSeparator}'", libjars.Distinct()) + $"'{enclosingChar}"); cmd.AppendSwitchIfNotNull("-outjars ", ProguardJarOutput); if (EnableLogging) { cmd.AppendSwitchIfNotNull("-dump ", DumpOutput); cmd.AppendSwitchIfNotNull("-printseeds ", PrintSeedsOutput); cmd.AppendSwitchIfNotNull("-printusage ", PrintUsageOutput); cmd.AppendSwitchIfNotNull("-printmapping ", PrintMappingOutput); } // http://stackoverflow.com/questions/5701126/compile-with-proguard-gives-exception-local-variable-type-mismatch#7587680 cmd.AppendSwitch("-optimizations !code/allocation/variable"); return(cmd.ToString()); }
public static CommandLineBuilder UseHost(this CommandLineBuilder builder, Func <string[], IHostBuilder> hostBuilderFactory, Action <IHostBuilder> configureHost = null) => builder.AddMiddleware(async(invocation, next) =>
/// <summary> /// Generates the arguments. /// </summary> /// <param name="builder">The builder.</param> protected override void GenerateArguments(CommandLineBuilder builder) { base.GenerateArguments(builder); }
bool DoExecute () { var results = new List<ITaskItem> (); string bundlepath = Path.Combine (TempOutputPath, "bundles"); if (!Directory.Exists (bundlepath)) Directory.CreateDirectory (bundlepath); else Directory.Delete (bundlepath, true); foreach (var abi in SupportedAbis) { AndroidTargetArch arch = AndroidTargetArch.Other; switch (abi) { case "arm64": case "arm64-v8a": case "aarch64": arch = AndroidTargetArch.Arm64; break; case "armeabi-v7a": arch = AndroidTargetArch.Arm; break; case "x86": arch = AndroidTargetArch.X86; break; case "x86_64": arch = AndroidTargetArch.X86_64; break; case "mips": arch = AndroidTargetArch.Mips; break; } if (!NdkUtil.ValidateNdkPlatform (Log, AndroidNdkDirectory, arch, enableLLVM: false)) { return false; } int level = NdkUtil.GetMinimumApiLevelFor (arch, AndroidNdkDirectory); var outpath = Path.Combine (bundlepath, abi); if (!Directory.Exists (outpath)) Directory.CreateDirectory (outpath); var clb = new CommandLineBuilder (); clb.AppendSwitch ("--dos2unix=false"); clb.AppendSwitch ("--nomain"); clb.AppendSwitch ("--i18n none"); clb.AppendSwitch ("--bundled-header"); clb.AppendSwitch ("--mono-api-struct-path"); clb.AppendFileNameIfNotNull (BundleApiPath); clb.AppendSwitch ("--style"); clb.AppendSwitch ("linux"); clb.AppendSwitch ("-c"); clb.AppendSwitch ("-o"); clb.AppendFileNameIfNotNull (Path.Combine (outpath, "temp.c")); clb.AppendSwitch ("-oo"); clb.AppendFileNameIfNotNull (Path.Combine (outpath, "assemblies.o")); if (AutoDeps) clb.AppendSwitch ("--autodeps"); if (KeepTemp) clb.AppendSwitch ("--keeptemp"); clb.AppendSwitch ("-z"); // Compress clb.AppendFileNamesIfNotNull (Assemblies, " "); var psi = new ProcessStartInfo () { FileName = MkbundlePath, Arguments = clb.ToString (), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, }; string windowsCompilerSwitches = NdkUtil.GetCompilerTargetParameters (AndroidNdkDirectory, arch, level); var compilerNoQuotes = NdkUtil.GetNdkTool (AndroidNdkDirectory, arch, "gcc", level); var compiler = $"\"{compilerNoQuotes}\" {windowsCompilerSwitches}".Trim (); var gas = '"' + NdkUtil.GetNdkTool (AndroidNdkDirectory, arch, "as", level) + '"'; psi.EnvironmentVariables ["CC"] = compiler; psi.EnvironmentVariables ["AS"] = gas; Log.LogDebugMessage ("CC=" + compiler); Log.LogDebugMessage ("AS=" + gas); //psi.EnvironmentVariables ["PKG_CONFIG_PATH"] = Path.Combine (Path.GetDirectoryName (MonoDroidSdk.MandroidTool), "lib", abi); Log.LogDebugMessage ("[mkbundle] " + psi.FileName + " " + clb); var proc = new Process (); proc.OutputDataReceived += OnMkbundleOutputData; proc.ErrorDataReceived += OnMkbundleErrorData; proc.StartInfo = psi; proc.Start (); proc.BeginOutputReadLine (); proc.BeginErrorReadLine (); proc.WaitForExit (); if (proc.ExitCode != 0) { Log.LogCodedError ("XA5102", Properties.Resources.XA5102, proc.ExitCode); return false; } // then compile temp.c into temp.o and ... clb = new CommandLineBuilder (); // See NdkUtils.GetNdkTool for reasons why if (!String.IsNullOrEmpty (windowsCompilerSwitches)) clb.AppendTextUnquoted (windowsCompilerSwitches); clb.AppendSwitch ("-c"); // This is necessary only when unified headers are in use but it won't hurt to have it // defined even if we don't use them clb.AppendSwitch ($"-D__ANDROID_API__={level}"); // This is necessary because of the injected code, which is reused between libmonodroid // and the bundle clb.AppendSwitch ("-DANDROID"); clb.AppendSwitch ("-o"); clb.AppendFileNameIfNotNull (Path.Combine (outpath, "temp.o")); if (!string.IsNullOrWhiteSpace (IncludePath)) { clb.AppendSwitch ("-I"); clb.AppendFileNameIfNotNull (IncludePath); } string asmIncludePath = NdkUtil.GetNdkAsmIncludePath (AndroidNdkDirectory, arch, level); if (!String.IsNullOrEmpty (asmIncludePath)) { clb.AppendSwitch ("-I"); clb.AppendFileNameIfNotNull (asmIncludePath); } clb.AppendSwitch ("-I"); clb.AppendFileNameIfNotNull (NdkUtil.GetNdkPlatformIncludePath (AndroidNdkDirectory, arch, level)); clb.AppendFileNameIfNotNull (Path.Combine (outpath, "temp.c")); Log.LogDebugMessage ("[CC] " + compiler + " " + clb); if (MonoAndroidHelper.RunProcess (compilerNoQuotes, clb.ToString (), OnCcOutputData, OnCcErrorData) != 0) { Log.LogCodedError ("XA5103", Properties.Resources.XA5103, proc.ExitCode); return false; } // ... link temp.o and assemblies.o into app.so clb = new CommandLineBuilder (); clb.AppendSwitch ("--shared"); clb.AppendFileNameIfNotNull (Path.Combine (outpath, "temp.o")); clb.AppendFileNameIfNotNull (Path.Combine (outpath, "assemblies.o")); // API23+ requires that the shared library has its soname set or it won't load clb.AppendSwitch ("-soname"); clb.AppendSwitch (BundleSharedLibraryName); clb.AppendSwitch ("-o"); clb.AppendFileNameIfNotNull (Path.Combine (outpath, BundleSharedLibraryName)); clb.AppendSwitch ("-L"); clb.AppendFileNameIfNotNull (NdkUtil.GetNdkPlatformLibPath (AndroidNdkDirectory, arch, level)); clb.AppendSwitch ("-lc"); clb.AppendSwitch ("-lm"); clb.AppendSwitch ("-ldl"); clb.AppendSwitch ("-llog"); clb.AppendSwitch ("-lz"); // Compress string ld = NdkUtil.GetNdkTool (AndroidNdkDirectory, arch, "ld", level); Log.LogMessage (MessageImportance.Normal, "[LD] " + ld + " " + clb); if (MonoAndroidHelper.RunProcess (ld, clb.ToString (), OnLdOutputData, OnLdErrorData) != 0) { Log.LogCodedError ("XA5201", Properties.Resources.XA5201, proc.ExitCode); return false; } results.Add (new TaskItem (Path.Combine (outpath, "libmonodroid_bundle_app.so"))); } OutputNativeLibraries = results.ToArray (); return true; }
/// <summary> /// Generates the command line arguments. /// </summary> /// <returns> /// Returns a string value containing the command line arguments to pass directly to the executable file. /// </returns> protected override void AppendCommand(CommandLineBuilder commandLine) { base.AppendCommand(commandLine); commandLine.AppendFileNameIfNotNull(BackupPath); }
/// <summary> /// Launches Visual Studio. /// </summary> /// <param name="arguments">The current <see cref="ProgramArguments" />.</param> /// <param name="visualStudioInstance">A <see cref="VisualStudioInstance" /> object representing which instance of Visual Studio to launch.</param> /// <param name="solutionFileFullPath">The full path to the solution file.</param> /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param> /// <returns>true if Visual Studio was launched, otherwise false.</returns> public static bool TryLaunch(ProgramArguments arguments, VisualStudioInstance visualStudioInstance, string solutionFileFullPath, ISlnGenLogger logger) { if (!arguments.ShouldLaunchVisualStudio()) { return(true); } if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { logger.LogWarning("Launching Visual Studio is not currently supported on your operating system."); return(true); } bool loadProjectsInVisualStudio = arguments.ShouldLoadProjectsInVisualStudio(); bool enableShellExecute = arguments.EnableShellExecute(); string devEnvFullPath = arguments.DevEnvFullPath?.LastOrDefault(); if (!enableShellExecute || !loadProjectsInVisualStudio || Program.CurrentDevelopmentEnvironment.IsCorext) { if (devEnvFullPath.IsNullOrWhiteSpace()) { if (visualStudioInstance == null) { logger.LogError( Program.CurrentDevelopmentEnvironment.IsCorext ? $"Could not find a Visual Studio {Environment.GetEnvironmentVariable("VisualStudioVersion")} installation. Please do one of the following:\n a) Specify a full path to devenv.exe via the -vs command-line argument\n b) Update your corext.config to specify a version of MSBuild.Corext that matches a Visual Studio version you have installed\n c) Install a version of Visual Studio that matches the version of MSBuild.Corext in your corext.config" : "Could not find a Visual Studio installation. Please specify the full path to devenv.exe via the -vs command-line argument"); return(false); } if (visualStudioInstance.IsBuildTools) { logger.LogError("Cannot use a BuildTools instance of Visual Studio."); return(false); } devEnvFullPath = Path.Combine(visualStudioInstance.InstallationPath, "Common7", "IDE", "devenv.exe"); } } if (solutionFileFullPath.IsNullOrWhiteSpace()) { throw new ArgumentNullException(nameof(solutionFileFullPath)); } CommandLineBuilder commandLineBuilder = new CommandLineBuilder(); ProcessStartInfo processStartInfo; if (!devEnvFullPath.IsNullOrWhiteSpace()) { if (!File.Exists(devEnvFullPath)) { logger.LogError($"The specified path to Visual Studio ({devEnvFullPath}) does not exist or is inaccessible."); return(false); } processStartInfo = new ProcessStartInfo { FileName = devEnvFullPath !, UseShellExecute = false, }; commandLineBuilder.AppendFileNameIfNotNull(solutionFileFullPath); if (!arguments.ShouldLoadProjectsInVisualStudio()) { commandLineBuilder.AppendSwitch(DoNotLoadProjectsCommandLineArgument); } } else { processStartInfo = new ProcessStartInfo { FileName = solutionFileFullPath, UseShellExecute = true, }; } try { processStartInfo.Arguments = commandLineBuilder.ToString(); Process process = new Process { StartInfo = processStartInfo, }; logger.LogMessageHigh("Launching Visual Studio..."); logger.LogMessageLow(" FileName = {0}", processStartInfo.FileName); logger.LogMessageLow(" Arguments = {0}", processStartInfo.Arguments); logger.LogMessageLow(" UseShellExecute = {0}", processStartInfo.UseShellExecute); logger.LogMessageLow(" WindowStyle = {0}", processStartInfo.WindowStyle); if (!process.Start()) { logger.LogError("Failed to launch Visual Studio."); } } catch (Exception e) { logger.LogError($"Failed to launch Visual Studio. {e.Message}"); } return(true); }
protected virtual CommandLineBuilder GetCommandLineBuilder() { var cmd = new CommandLineBuilder(); if (!string.IsNullOrEmpty(JavaOptions)) { cmd.AppendSwitch(JavaOptions); } cmd.AppendSwitchIfNotNull("-Xmx", JavaMaximumHeapSize); cmd.AppendSwitchIfNotNull("-classpath ", JarPath); cmd.AppendSwitch(MainClass); if (!string.IsNullOrEmpty(ExtraArguments)) { cmd.AppendSwitch(ExtraArguments); // it should contain "--dex". } if (Debug) { cmd.AppendSwitch("--debug"); } else { cmd.AppendSwitch("--release"); } //NOTE: if this is blank, we can omit --min-api in this call if (!string.IsNullOrEmpty(AndroidManifestFile)) { var doc = AndroidAppManifest.Load(AndroidManifestFile, MonoAndroidHelper.SupportedVersions); if (doc.MinSdkVersion.HasValue) { MinSdkVersion = doc.MinSdkVersion.Value; cmd.AppendSwitchIfNotNull("--min-api ", MinSdkVersion.ToString()); } } if (!EnableDesugar) { cmd.AppendSwitch("--no-desugaring"); } var injars = new List <string> (); var libjars = new List <string> (); if (AlternativeJarLibrariesToEmbed?.Length > 0) { Log.LogDebugMessage(" processing AlternativeJarLibrariesToEmbed..."); foreach (var jar in AlternativeJarLibrariesToEmbed) { injars.Add(jar.ItemSpec); } } else if (JavaLibrariesToEmbed != null) { Log.LogDebugMessage(" processing ClassesZip, JavaLibrariesToEmbed..."); if (!string.IsNullOrEmpty(ClassesZip) && File.Exists(ClassesZip)) { injars.Add(ClassesZip); } foreach (var jar in JavaLibrariesToEmbed) { injars.Add(jar.ItemSpec); } } libjars.Add(JavaPlatformJarPath); if (JavaLibrariesToReference != null) { foreach (var jar in JavaLibrariesToReference) { libjars.Add(jar.ItemSpec); } } cmd.AppendSwitchIfNotNull("--output ", OutputDirectory); foreach (var jar in libjars) { cmd.AppendSwitchIfNotNull("--lib ", jar); } foreach (var jar in injars) { cmd.AppendFileNameIfNotNull(jar); } return(cmd); }
public static CommandLineBuilder Build() { var parser = new CommandLineBuilder() .AddCommand(CompileFolder()) .AddCommand(CompileSubtree()); return(parser); Command CompileFolder() => new Command("compile-directory", "Compile all assemblies in directory", new Option[] { InputDirectory(), OutputDirectory(), CoreRootDirectory(), CpaotDirectory(), Crossgen(), NoJit(), NoExe(), NoEtw(), NoCleanup(), Sequential(), ReferencePath() }, handler: CommandHandler.Create <BuildOptions>(CompileDirectoryCommand.CompileDirectory)); Command CompileSubtree() => new Command("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app", new Option[] { InputDirectory(), OutputDirectory(), CoreRootDirectory(), CpaotDirectory(), Crossgen(), NoJit(), NoExe(), NoEtw(), NoCleanup(), Sequential(), ReferencePath() }, handler: CommandHandler.Create <BuildOptions>(CompileSubtreeCommand.CompileSubtree)); // Todo: Input / Output directories should be required arguments to the command when they're made available to handlers // https://github.com/dotnet/command-line-api/issues/297 Option InputDirectory() => new Option(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize", new Argument <DirectoryInfo>().ExistingOnly()); Option OutputDirectory() => new Option(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies", new Argument <DirectoryInfo>().LegalFilePathsOnly()); Option CoreRootDirectory() => new Option(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder", new Argument <DirectoryInfo>().ExistingOnly()); Option CpaotDirectory() => new Option(new[] { "--cpaot-directory", "-cpaot" }, "Folder containing the CPAOT compiler", new Argument <DirectoryInfo>().ExistingOnly()); Option ReferencePath() => new Option(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation", new Argument <DirectoryInfo[]>() { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly()); Option Crossgen() => new Option(new[] { "--crossgen" }, "Compile the apps using Crossgen in the CORE_ROOT folder", new Argument <bool>()); Option NoJit() => new Option(new[] { "--nojit" }, "Don't run tests in JITted mode", new Argument <bool>()); Option NoEtw() => new Option(new[] { "--noetw" }, "Don't capture jitted methods using ETW", new Argument <bool>()); Option NoExe() => new Option(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)", new Argument <bool>()); Option NoCleanup() => new Option(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs", new Argument <bool>()); Option Sequential() => new Option(new[] { "--sequential" }, "Run tests sequentially", new Argument <bool>()); }
private void BuildCommands(CommandLineBuilder rootBuilder, IEnumerable <Assembly> assemblies) { BuildCommands(rootBuilder, assemblies.SelectMany((assembly) => assembly.GetExportedTypes())); }
/// <summary> /// Generates the SvnAdmin arguments. /// </summary> /// <returns></returns> protected virtual void AppendArguments(CommandLineBuilder commandLine) { commandLine.AppendSwitchIfTrue("--quiet", Quiet); // raw arguments commandLine.AppendSwitchIfNotNull("", Arguments); }
public static void Append(this CommandLineBuilder commandLine, string text) { GetCommandLine(commandLine).Append(text); }
/// <summary> /// Generates the command line arguments. /// </summary> /// <returns> /// Returns a string value containing the command line arguments to pass directly to the executable file. /// </returns> protected override string GenerateCommandLineCommands() { var commandLine = new CommandLineBuilder(); AppendCommand(commandLine); AppendArguments(commandLine); return commandLine.ToString(); }
private static void AppendTextWithQuoting(CommandLineBuilder commandLine, string text) { commandLine.GetType() .GetMethod("AppendTextWithQuoting", BindingFlags.Instance | BindingFlags.NonPublic) .Invoke(commandLine, new [] { text }); }
/// <summary> /// Generates the SvnAdmin command. /// </summary> /// <returns></returns> protected virtual void AppendCommand(CommandLineBuilder commandLine) { commandLine.AppendSwitch(Command); commandLine.AppendFileNameIfNotNull(RepositoryPath); }
protected string GenerateCommandLineCommands(string ManifestFile, string currentAbi, string currentResourceOutputFile) { // For creating Resource.Designer.cs: // Running command: C:\Program Files (x86)\Android\android-sdk-windows\platform-tools\aapt // "package" // "-M" "C:\Users\Jonathan\AppData\Local\Temp\ryob4gaw.way\AndroidManifest.xml" // "-J" "C:\Users\Jonathan\AppData\Local\Temp\ryob4gaw.way" // "-F" "C:\Users\Jonathan\AppData\Local\Temp\ryob4gaw.way\resources.apk" // "-S" "c:\users\jonathan\documents\visual studio 2010\Projects\MonoAndroidApplication4\MonoAndroidApplication4\obj\Debug\res" // "-I" "C:\Program Files (x86)\Android\android-sdk-windows\platforms\android-8\android.jar" // "--max-res-version" "10" // For packaging: // Running command: C:\Program Files (x86)\Android\android-sdk-windows\platform-tools\aapt // "package" // "-f" // "-m" // "-M" "AndroidManifest.xml" // "-J" "src" // "--custom-package" "androidmsbuildtest.androidmsbuildtest" // "-F" "bin\packaged_resources" // "-S" "C:\Users\Jonathan\Documents\Visual Studio 2010\Projects\AndroidMSBuildTest\AndroidMSBuildTest\obj\Debug\res" // "-I" "C:\Program Files (x86)\Android\android-sdk-windows\platforms\android-8\android.jar" // "--extra-packages" "com.facebook.android:my.another.library" var cmd = new CommandLineBuilder(); cmd.AppendSwitch("package"); if (MonoAndroidHelper.LogInternalExceptions) { cmd.AppendSwitch("-v"); } if (NonConstantId) { cmd.AppendSwitch("--non-constant-id"); } cmd.AppendSwitch("-f"); cmd.AppendSwitch("-m"); string manifestFile; string manifestDir = Path.Combine(Path.GetDirectoryName(ManifestFile), currentAbi != null ? currentAbi : "manifest"); Directory.CreateDirectory(manifestDir); manifestFile = Path.Combine(manifestDir, Path.GetFileName(ManifestFile)); ManifestDocument manifest = new ManifestDocument(ManifestFile, this.Log); if (currentAbi != null) { manifest.SetAbi(currentAbi); } manifest.ApplicationName = ApplicationName; manifest.Save(manifestFile); cmd.AppendSwitchIfNotNull("-M ", manifestFile); Directory.CreateDirectory(JavaDesignerOutputDirectory); cmd.AppendSwitchIfNotNull("-J ", JavaDesignerOutputDirectory); if (PackageName != null) { cmd.AppendSwitchIfNotNull("--custom-package ", PackageName.ToLowerInvariant()); } if (!string.IsNullOrEmpty(currentResourceOutputFile)) { cmd.AppendSwitchIfNotNull("-F ", currentResourceOutputFile + ".bk"); } // The order of -S arguments is *important*, always make sure this one comes FIRST cmd.AppendSwitchIfNotNull("-S ", ResourceDirectory.TrimEnd('\\')); if (AdditionalResourceDirectories != null) { foreach (var resdir in AdditionalResourceDirectories) { cmd.AppendSwitchIfNotNull("-S ", resdir.ItemSpec.TrimEnd('\\')); } } if (AdditionalAndroidResourcePaths != null) { foreach (var dir in AdditionalAndroidResourcePaths) { cmd.AppendSwitchIfNotNull("-S ", Path.Combine(dir.ItemSpec.TrimEnd(System.IO.Path.DirectorySeparatorChar), "res")); } } if (LibraryProjectJars != null) { foreach (var jar in LibraryProjectJars) { cmd.AppendSwitchIfNotNull("-j ", jar); } } cmd.AppendSwitchIfNotNull("-I ", JavaPlatformJarPath); // Add asset directory if it exists if (!string.IsNullOrWhiteSpace(AssetDirectory) && Directory.Exists(AssetDirectory)) { cmd.AppendSwitchIfNotNull("-A ", AssetDirectory.TrimEnd('\\')); } if (!string.IsNullOrWhiteSpace(UncompressedFileExtensions)) { foreach (var ext in UncompressedFileExtensions.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries)) { cmd.AppendSwitchIfNotNull("-0 ", ext); } } if (!string.IsNullOrEmpty(ExtraPackages)) { cmd.AppendSwitchIfNotNull("--extra-packages ", ExtraPackages); } // TODO: handle resource names if (ExplicitCrunch) { cmd.AppendSwitch("--no-crunch"); } cmd.AppendSwitch("--auto-add-overlay"); var extraArgsExpanded = ExpandString(ExtraArgs); if (extraArgsExpanded != ExtraArgs) { Log.LogDebugMessage(" ExtraArgs expanded: {0}", extraArgsExpanded); } if (!string.IsNullOrWhiteSpace(extraArgsExpanded)) { cmd.AppendSwitch(extraArgsExpanded); } if (!AndroidUseLatestPlatformSdk) { cmd.AppendSwitchIfNotNull("--max-res-version ", ApiLevel); } return(cmd.ToString()); }
protected abstract void AppendCommandLineArguments(IDictionary <string, string> environment, CommandLineBuilder args, ITaskItem input, ITaskItem output);
protected void AppendIntegerSwitch(CommandLineBuilder commandLine, string @switch, int value) { commandLine.AppendSwitchUnquotedIfNotNull(@switch, value.ToString(NumberFormatInfo.InvariantInfo)); }
public static CommandLineBuilder Build() { var parser = new CommandLineBuilder() .AddCommand(CompileFolder()) .AddCommand(CompileSubtree()) .AddCommand(CompileFramework()) .AddCommand(CompileNugetPackages()) .AddCommand(CompileCrossgenRsp()); return(parser); Command CompileFolder() => new Command("compile-directory", "Compile all assemblies in directory", new Option[] { InputDirectory(), OutputDirectory(), CoreRootDirectory(), Crossgen(), CrossgenPath(), NoJit(), NoCrossgen2(), Exe(), NoExe(), NoEtw(), NoCleanup(), GenerateMapFile(), DegreeOfParallelism(), Sequential(), Framework(), UseFramework(), Release(), LargeBubble(), Crossgen2Parallelism(), ReferencePath(), IssuesPath(), CompilationTimeoutMinutes(), ExecutionTimeoutMinutes(), R2RDumpPath(), MeasurePerf(), InputFileSearchString(), }, handler: CommandHandler.Create <BuildOptions>(CompileDirectoryCommand.CompileDirectory)); Command CompileSubtree() => new Command("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app", new Option[] { InputDirectory(), OutputDirectory(), CoreRootDirectory(), Crossgen(), CrossgenPath(), NoJit(), NoCrossgen2(), Exe(), NoExe(), NoEtw(), NoCleanup(), GenerateMapFile(), DegreeOfParallelism(), Sequential(), Framework(), UseFramework(), Release(), LargeBubble(), Crossgen2Parallelism(), ReferencePath(), IssuesPath(), CompilationTimeoutMinutes(), ExecutionTimeoutMinutes(), R2RDumpPath(), }, handler: CommandHandler.Create <BuildOptions>(CompileSubtreeCommand.CompileSubtree)); Command CompileFramework() => new Command("compile-framework", "Compile managed framework assemblies in Core_Root", new Option[] { CoreRootDirectory(), Crossgen(), CrossgenPath(), NoCrossgen2(), NoCleanup(), DegreeOfParallelism(), Sequential(), Release(), LargeBubble(), ReferencePath(), IssuesPath(), CompilationTimeoutMinutes(), R2RDumpPath(), MeasurePerf(), InputFileSearchString(), }, handler: CommandHandler.Create <BuildOptions>(CompileFrameworkCommand.CompileFramework)); Command CompileNugetPackages() => new Command("compile-nuget", "Restore a list of Nuget packages into an empty console app, publish, and optimize with Crossgen / CPAOT", new Option[] { R2RDumpPath(), InputDirectory(), OutputDirectory(), PackageList(), CoreRootDirectory(), Crossgen(), NoCleanup(), DegreeOfParallelism(), CompilationTimeoutMinutes(), ExecutionTimeoutMinutes(), }, handler: CommandHandler.Create <BuildOptions>(CompileNugetCommand.CompileNuget)); Command CompileCrossgenRsp() => new Command("compile-crossgen-rsp", "Use existing Crossgen .rsp file(s) to build assemblies, optionally rewriting base paths", new Option[] { InputDirectory(), CrossgenResponseFile(), OutputDirectory(), CoreRootDirectory(), Crossgen(), NoCleanup(), DegreeOfParallelism(), CompilationTimeoutMinutes(), RewriteOldPath(), RewriteNewPath(), }, handler: CommandHandler.Create <BuildOptions>(CompileFromCrossgenRspCommand.CompileFromCrossgenRsp)); // Todo: Input / Output directories should be required arguments to the command when they're made available to handlers // https://github.com/dotnet/command-line-api/issues/297 Option InputDirectory() => new Option(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize", new Argument <DirectoryInfo>().ExistingOnly()); Option OutputDirectory() => new Option(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies", new Argument <DirectoryInfo>().LegalFilePathsOnly()); Option CoreRootDirectory() => new Option(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder", new Argument <DirectoryInfo>().ExistingOnly()); Option ReferencePath() => new Option(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation", new Argument <DirectoryInfo[]>() { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly()); Option Crossgen() => new Option(new[] { "--crossgen" }, "Compile the apps using Crossgen in the CORE_ROOT folder", new Argument <bool>()); Option CrossgenPath() => new Option(new[] { "--crossgen-path", "-cp" }, "Explicit Crossgen path (useful for cross-targeting)", new Argument <FileInfo>().ExistingOnly()); Option NoJit() => new Option(new[] { "--nojit" }, "Don't run tests in JITted mode", new Argument <bool>()); Option NoCrossgen2() => new Option(new[] { "--nocrossgen2" }, "Don't run tests in Crossgen2 mode", new Argument <bool>()); Option Exe() => new Option(new[] { "--exe" }, "Don't compile tests, just execute them", new Argument <bool>()); Option NoExe() => new Option(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)", new Argument <bool>()); Option NoEtw() => new Option(new[] { "--noetw" }, "Don't capture jitted methods using ETW", new Argument <bool>()); Option NoCleanup() => new Option(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs", new Argument <bool>()); Option GenerateMapFile() => new Option(new[] { "--map" }, "Generate a map file (Crossgen2)", new Argument <bool>()); Option DegreeOfParallelism() => new Option(new[] { "--degree-of-parallelism", "-dop" }, "Override default compilation / execution DOP (default = logical processor count)", new Argument <int>()); Option Sequential() => new Option(new[] { "--sequential" }, "Run tests sequentially", new Argument <bool>()); Option Framework() => new Option(new[] { "--framework" }, "Precompile and use native framework", new Argument <bool>()); Option UseFramework() => new Option(new[] { "--use-framework" }, "Use native framework (don't precompile, assume previously compiled)", new Argument <bool>()); Option Release() => new Option(new[] { "--release" }, "Build the tests in release mode", new Argument <bool>()); Option LargeBubble() => new Option(new[] { "--large-bubble" }, "Assume all input files as part of one version bubble", new Argument <bool>()); Option Crossgen2Parallelism() => new Option(new[] { "--crossgen2-parallelism" }, "Max number of threads to use in Crossgen2 (default = logical processor count)", new Argument <int>()); Option IssuesPath() => new Option(new[] { "--issues-path", "-ip" }, "Path to issues.targets", new Argument <FileInfo[]>() { Arity = ArgumentArity.ZeroOrMore }); Option CompilationTimeoutMinutes() => new Option(new[] { "--compilation-timeout-minutes", "-ct" }, "Compilation timeout (minutes)", new Argument <int>()); Option ExecutionTimeoutMinutes() => new Option(new[] { "--execution-timeout-minutes", "-et" }, "Execution timeout (minutes)", new Argument <int>()); Option R2RDumpPath() => new Option(new[] { "--r2r-dump-path", "-r2r" }, "Path to R2RDump.exe/dll", new Argument <FileInfo>().ExistingOnly()); Option CrossgenResponseFile() => new Option(new [] { "--crossgen-response-file", "-rsp" }, "Response file to transpose", new Argument <FileInfo>().ExistingOnly()); Option RewriteOldPath() => new Option(new [] { "--rewrite-old-path" }, "Path substring to replace", new Argument <DirectoryInfo[]>() { Arity = ArgumentArity.ZeroOrMore }); Option RewriteNewPath() => new Option(new [] { "--rewrite-new-path" }, "Path substring to use instead", new Argument <DirectoryInfo[]>() { Arity = ArgumentArity.ZeroOrMore }); Option MeasurePerf() => new Option(new[] { "--measure-perf" }, "Print out compilation time", new Argument <bool>()); Option InputFileSearchString() => new Option(new[] { "--input-file-search-string", "-input-file" }, "Search string for input files in the input directory", new Argument <string>()); // // compile-nuget specific options // Option PackageList() => new Option(new[] { "--package-list", "-pl" }, "Text file containing a package name on each line", new Argument <FileInfo>().ExistingOnly()); }
private void GenerateArgumentInt(CommandLineBuilder builder, BaseProperty property, string value) { // Currently we only have one Int property and it doesn't correspond to a // command line arguemnt (ProcessorNumber) so we ignore it here. }
/// <summary> /// Generates the svn command. /// </summary> /// <returns></returns> protected virtual void AppendCommand(CommandLineBuilder commandLine) { commandLine.AppendSwitch(Command); // import has paths in diff order if (Command == Commands.Import) { commandLine.AppendFileNameIfNotNull(LocalPath); commandLine.AppendFileNameIfNotNull(RepositoryPath); } else { commandLine.AppendFileNameIfNotNull(RepositoryPath); commandLine.AppendFileNameIfNotNull(LocalPath); } }
protected virtual void AppendAdditionalArguments(CommandLineBuilder builder) { }
protected virtual void AddCommandLineCommands(CommandLineBuilder commandLine) { commandLine.AppendWhenTrue("/noconfig", NoConfig); }
protected override string GenerateCommandLineCommands() { var cmd = new CommandLineBuilder(); #if DEBUG cmd.AppendSwitch("/v"); #endif if (NoStdLib) { cmd.AppendSwitch("/nostdlib"); } cmd.AppendSwitchIfNotNull("/compiler:", CompilerPath); cmd.AppendSwitchIfNotNull("/baselib:", BaseLibDll); cmd.AppendSwitchIfNotNull("/out:", OutputAssembly); if (NoStdLib) { string dir; if (!string.IsNullOrEmpty(BaseLibDll)) { dir = Path.GetDirectoryName(BaseLibDll); } else { dir = null; } cmd.AppendSwitchIfNotNull("/lib:", dir); cmd.AppendSwitchIfNotNull("/r:", Path.Combine(dir, "mscorlib.dll")); } if (EmitDebugInformation) { cmd.AppendSwitch("/debug"); } if (AllowUnsafeBlocks) { cmd.AppendSwitch("/unsafe"); } cmd.AppendSwitchIfNotNull("/ns:", Namespace); if (!string.IsNullOrEmpty(DefineConstants)) { var strv = DefineConstants.Split(new [] { ';' }); var sanitized = new List <string> (); foreach (var str in strv) { if (str != string.Empty) { sanitized.Add(str); } } if (sanitized.Count > 0) { cmd.AppendSwitchIfNotNull("/d:", string.Join(";", sanitized.ToArray())); } } //cmd.AppendSwitch ("/e"); foreach (var item in ApiDefinitions) { cmd.AppendFileNameIfNotNull(Path.GetFullPath(item.ItemSpec)); } if (CoreSources != null) { foreach (var item in CoreSources) { cmd.AppendSwitchIfNotNull("/s:", Path.GetFullPath(item.ItemSpec)); } } if (Sources != null) { foreach (var item in Sources) { cmd.AppendSwitchIfNotNull("/x:", Path.GetFullPath(item.ItemSpec)); } } if (AdditionalLibPaths != null) { foreach (var item in AdditionalLibPaths) { cmd.AppendSwitchIfNotNull("/lib:", Path.GetFullPath(item.ItemSpec)); } } HandleReferences(cmd); if (Resources != null) { foreach (var item in Resources) { var args = new List <string> (); string id; args.Add(item.ToString()); id = item.GetMetadata("LogicalName"); if (!string.IsNullOrEmpty(id)) { args.Add(id); } cmd.AppendSwitchIfNotNull("/res:", args.ToArray(), ","); } } if (NativeLibraries != null) { foreach (var item in NativeLibraries) { var args = new List <string> (); string id; args.Add(item.ToString()); id = item.GetMetadata("LogicalName"); if (string.IsNullOrEmpty(id)) { id = Path.GetFileName(args[0]); } args.Add(id); cmd.AppendSwitchIfNotNull("/link-with:", args.ToArray(), ","); } } if (GeneratedSourcesDir != null) { cmd.AppendSwitchIfNotNull("/tmpdir:", Path.GetFullPath(GeneratedSourcesDir)); } if (GeneratedSourcesFileList != null) { cmd.AppendSwitchIfNotNull("/sourceonly:", Path.GetFullPath(GeneratedSourcesFileList)); } return(cmd.ToString()); }
/// <summary> /// Generates the svn arguments. /// </summary> /// <returns></returns> protected virtual void AppendArguments(CommandLineBuilder commandLine) { commandLine.AppendSwitchIfNotNull("--username ", Username); commandLine.AppendSwitchIfNotNull("--password ", Password); commandLine.AppendSwitchIfNotNull("--message ", Message); commandLine.AppendSwitchIfTrue("--force", Force); commandLine.AppendSwitchIfTrue("--verbose", Verbose); commandLine.AppendSwitchIfTrue("--xml", Xml); commandLine.AppendSwitchIfTrue("--non-interactive", NonInteractive); commandLine.AppendSwitchIfTrue("--no-auth-cache", NoAuthCache); // raw arguments if (!string.IsNullOrEmpty(Arguments)) commandLine.AppendSwitch(Arguments); }