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"));
        }
Example #2
0
        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);
        }
Example #3
0
        /// <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));
        }
Example #4
0
 private static StringBuilder GetCommandLine(CommandLineBuilder commandLine)
 {
     return((StringBuilder)commandLine.GetType()
            .GetProperty("CommandLine", BindingFlags.Instance | BindingFlags.NonPublic)
            .GetValue(commandLine, null));
 }
Example #5
0
        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);
                }
            }
        }
Example #7
0
File: Parser.cs Project: nohwnd/sdk
 private static CommandLineBuilder DisablePosixBinding(this CommandLineBuilder builder)
 {
     builder.EnablePosixBundling(false);
     return(builder);
 }
Example #8
0
        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();
        }
Example #9
0
        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());
        }
Example #10
0
        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);
        }
Example #11
0
        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);
            }
        }
Example #12
0
        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);
        }
Example #13
0
        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());
        }
Example #14
0
        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());
        }
Example #15
0
        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);
 }
Example #17
0
        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());
        }
Example #18
0
 public static CommandLineBuilder UseHost(this CommandLineBuilder builder,
                                          Func <string[], IHostBuilder> hostBuilderFactory,
                                          Action <IHostBuilder> configureHost = null) =>
 builder.AddMiddleware(async(invocation, next) =>
Example #19
0
 /// <summary>
 /// Generates the arguments.
 /// </summary>
 /// <param name="builder">The builder.</param>
 protected override void GenerateArguments(CommandLineBuilder builder)
 {
     base.GenerateArguments(builder);
 }
Example #20
0
		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;
		}
Example #21
0
 /// <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);
 }
Example #22
0
        /// <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);
        }
Example #23
0
        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);
        }
Example #24
0
        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>());
        }
Example #25
0
 private void BuildCommands(CommandLineBuilder rootBuilder, IEnumerable <Assembly> assemblies)
 {
     BuildCommands(rootBuilder, assemblies.SelectMany((assembly) => assembly.GetExportedTypes()));
 }
Example #26
0
        /// <summary>
        /// Generates the SvnAdmin arguments.
        /// </summary>
        /// <returns></returns>
        protected virtual void AppendArguments(CommandLineBuilder commandLine)
        {
            commandLine.AppendSwitchIfTrue("--quiet", Quiet);

            // raw arguments
            commandLine.AppendSwitchIfNotNull("", Arguments);
        }
Example #27
0
 public static void Append(this CommandLineBuilder commandLine, string text)
 {
     GetCommandLine(commandLine).Append(text);
 }
Example #28
0
 /// <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();
 }
Example #29
0
 private static void AppendTextWithQuoting(CommandLineBuilder commandLine, string text)
 {
     commandLine.GetType()
     .GetMethod("AppendTextWithQuoting", BindingFlags.Instance | BindingFlags.NonPublic)
     .Invoke(commandLine, new [] { text });
 }
Example #30
0
 /// <summary>
 /// Generates the SvnAdmin command.
 /// </summary>
 /// <returns></returns>
 protected virtual void AppendCommand(CommandLineBuilder commandLine)
 {
     commandLine.AppendSwitch(Command);
     commandLine.AppendFileNameIfNotNull(RepositoryPath);
 }
Example #31
0
        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);
Example #33
0
 protected void AppendIntegerSwitch(CommandLineBuilder commandLine, string @switch, int value)
 {
     commandLine.AppendSwitchUnquotedIfNotNull(@switch, value.ToString(NumberFormatInfo.InvariantInfo));
 }
Example #34
0
        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());
        }
Example #35
0
 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.
 }
Example #36
0
 /// <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);                
     }
     
 }
Example #37
0
 protected virtual void AppendAdditionalArguments(CommandLineBuilder builder)
 {
 }
Example #38
0
 protected virtual void AddCommandLineCommands(CommandLineBuilder commandLine)
 {
     commandLine.AppendWhenTrue("/noconfig", NoConfig);
 }
Example #39
0
        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());
        }
Example #40
0
        /// <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);
        }