コード例 #1
0
        public override bool RunTask()
        {
            Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode);

            if (string.IsNullOrEmpty(AndroidEmbedProfilers) && _Debug)
            {
                AndroidEmbedProfilers = "log";
            }

            var outputFiles = new List <string> ();

            uncompressedFileExtensions = UncompressedFileExtensions?.Split(new char [] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) ?? new string [0];

            existingEntries.Clear();
            ExecuteWithAbi(SupportedAbis, ApkInputPath, ApkOutputPath);
            outputFiles.Add(ApkOutputPath);
            if (CreatePackagePerAbi && SupportedAbis.Length > 1)
            {
                foreach (var abi in SupportedAbis)
                {
                    existingEntries.Clear();
                    var path = Path.GetDirectoryName(ApkOutputPath);
                    var apk  = Path.GetFileNameWithoutExtension(ApkOutputPath);
                    ExecuteWithAbi(new [] { abi }, String.Format("{0}-{1}", ApkInputPath, abi),
                                   Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                    outputFiles.Add(Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                }
            }

            OutputFiles = outputFiles.Select(a => new TaskItem(a)).ToArray();

            Log.LogDebugTaskItems("  [Output] OutputFiles :", OutputFiles);

            return(!Log.HasLoggedErrors);
        }
コード例 #2
0
ファイル: BuildApk.cs プロジェクト: Hanizam/xamarin-android
        public override bool Execute()
        {
            Log.LogDebugMessage("BuildApk Task");
            Log.LogDebugMessage("  ApkInputPath: {0}", ApkInputPath);
            Log.LogDebugMessage("  ApkOutputPath: {0}", ApkOutputPath);
            Log.LogDebugMessage("  BundleAssemblies: {0}", BundleAssemblies);
            Log.LogDebugTaskItems("  DalvikClasses:", DalvikClasses);
            Log.LogDebugMessage("  SupportedAbis: {0}", SupportedAbis);
            Log.LogDebugMessage("  UseSharedRuntime: {0}", UseSharedRuntime);
            Log.LogDebugMessage("  Debug: {0}", Debug ?? "no");
            Log.LogDebugMessage("  PreferNativeLibrariesWithDebugSymbols: {0}", PreferNativeLibrariesWithDebugSymbols);
            Log.LogDebugMessage("  EmbedAssemblies: {0}", EmbedAssemblies);
            Log.LogDebugMessage("  AndroidSequencePointsMode: {0}", AndroidSequencePointsMode);
            Log.LogDebugMessage("  CreatePackagePerAbi: {0}", CreatePackagePerAbi);
            Log.LogDebugMessage("  UncompressedFileExtensions: {0}", UncompressedFileExtensions);
            Log.LogDebugTaskItems("  ResolvedUserAssemblies:", ResolvedUserAssemblies);
            Log.LogDebugTaskItems("  ResolvedFrameworkAssemblies:", ResolvedFrameworkAssemblies);
            Log.LogDebugTaskItems("  NativeLibraries:", NativeLibraries);
            Log.LogDebugTaskItems("  AdditionalNativeLibraryReferences:", AdditionalNativeLibraryReferences);
            Log.LogDebugTaskItems("  BundleNativeLibraries:", BundleNativeLibraries);
            Log.LogDebugTaskItems("  JavaSourceFiles:", JavaSourceFiles);
            Log.LogDebugTaskItems("  JavaLibraries:", JavaLibraries);
            Log.LogDebugTaskItems("  LibraryProjectJars:", LibraryProjectJars);
            Log.LogDebugTaskItems("  AdditionalNativeLibraryReferences:", AdditionalNativeLibraryReferences);

            Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode);

            if (string.IsNullOrEmpty(AndroidEmbedProfilers) && _Debug)
            {
                AndroidEmbedProfilers = "log";
            }

            var outputFiles = new List <string> ();

            uncompressedFileExtensions = UncompressedFileExtensions?.Split(new char [] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) ?? new string [0];

            ExecuteWithAbi(SupportedAbis, ApkInputPath, ApkOutputPath);
            outputFiles.Add(ApkOutputPath);
            if (CreatePackagePerAbi)
            {
                var abis = SupportedAbis.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
                if (abis.Length > 1)
                {
                    foreach (var abi in abis)
                    {
                        var path = Path.GetDirectoryName(ApkOutputPath);
                        var apk  = Path.GetFileNameWithoutExtension(ApkOutputPath);
                        ExecuteWithAbi(abi, String.Format("{0}-{1}", ApkInputPath, abi),
                                       Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                        outputFiles.Add(Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                    }
                }
            }

            OutputFiles = outputFiles.Select(a => new TaskItem(a)).ToArray();

            Log.LogDebugTaskItems("  [Output] OutputFiles :", OutputFiles);

            return(!Log.HasLoggedErrors);
        }
コード例 #3
0
ファイル: CilStrip.cs プロジェクト: AntiqOnliner1983/hhhhh
        bool DoExecute()
        {
            Log.LogDebugTaskItems("  Targets:", ResolvedAssemblies);

            AotMode aotMode;
            bool    hasValidAotMode = Aot.GetAndroidAotMode(AndroidAotMode, out aotMode);

            if (!hasValidAotMode)
            {
                Log.LogCodedError("XA3002", Properties.Resources.XA3002, AndroidAotMode);
                return(false);
            }

            // Create a directory to move the original non IL-stripped assemblies.
            string assembliesDir = Path.GetDirectoryName(ResolvedAssemblies.First().ItemSpec);
            string nonstripDir   = Path.Combine(assembliesDir, "non-stripped");

            if (!Directory.Exists(nonstripDir))
            {
                Directory.CreateDirectory(nonstripDir);
            }

            var timestampFileDate = File.GetLastWriteTimeUtc(ApkOutputPath.ItemSpec);

            foreach (var assembly in ResolvedAssemblies)
            {
                string assemblyPath = Path.GetFullPath(assembly.ItemSpec);
                string nonstripPath = Path.Combine(nonstripDir, Path.GetFileName(assemblyPath));

                Log.LogDebugMessage($"Moving {assemblyPath} to {nonstripPath}");

                var srcmodifiedDate = File.GetLastWriteTimeUtc(assemblyPath);

                if (srcmodifiedDate < timestampFileDate)
                {
                    Log.LogDebugMessage($"Skipping strip of IL for {assembly.ItemSpec}. Assembly has already been stripped.");
                    continue;
                }

                File.Copy(assemblyPath, nonstripPath, overwrite: true);

                if (!RunCilStrip(nonstripPath, assemblyPath))
                {
                    Log.LogCodedError("XA3003", Properties.Resources.XA3003, assembly.ItemSpec);
                    return(false);
                }
            }

            return(true);
        }
コード例 #4
0
        public override bool RunTask()
        {
            Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode);

            var outputFiles = new List <string> ();

            uncompressedFileExtensions = UncompressedFileExtensions?.Split(new char [] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) ?? new string [0];

            existingEntries.Clear();

            bool debug    = _Debug;
            bool compress = !debug && EnableCompression;
            IDictionary <string, CompressedAssemblyInfo> compressedAssembliesInfo = null;

            if (compress)
            {
                string key = CompressedAssemblyInfo.GetKey(ProjectFullPath);
                Log.LogDebugMessage($"Retrieving assembly compression info with key '{key}'");
                compressedAssembliesInfo = BuildEngine4.UnregisterTaskObjectAssemblyLocal <IDictionary <string, CompressedAssemblyInfo> > (key, RegisteredTaskObjectLifetime.Build);
                if (compressedAssembliesInfo == null)
                {
                    throw new InvalidOperationException($"Assembly compression info not found for key '{key}'. Compression will not be performed.");
                }
            }

            ExecuteWithAbi(SupportedAbis, ApkInputPath, ApkOutputPath, debug, compress, compressedAssembliesInfo);
            outputFiles.Add(ApkOutputPath);
            if (CreatePackagePerAbi && SupportedAbis.Length > 1)
            {
                foreach (var abi in SupportedAbis)
                {
                    existingEntries.Clear();
                    var path = Path.GetDirectoryName(ApkOutputPath);
                    var apk  = Path.GetFileNameWithoutExtension(ApkOutputPath);
                    ExecuteWithAbi(new [] { abi }, String.Format("{0}-{1}", ApkInputPath, abi),
                                   Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)),
                                   debug, compress, compressedAssembliesInfo);
                    outputFiles.Add(Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                }
            }

            OutputFiles = outputFiles.Select(a => new TaskItem(a)).ToArray();

            Log.LogDebugTaskItems("  [Output] OutputFiles :", OutputFiles);

            return(!Log.HasLoggedErrors);
        }
コード例 #5
0
ファイル: CilStrip.cs プロジェクト: yy520a/xamarin-android
        bool DoExecute()
        {
            Log.LogDebugTaskItems("  Targets:", ResolvedAssemblies);

            AotMode aotMode;
            bool    hasValidAotMode = Aot.GetAndroidAotMode(AndroidAotMode, out aotMode);

            if (!hasValidAotMode)
            {
                Log.LogCodedError("XA3001", "Invalid AOT mode: {0}", AndroidAotMode);
                return(false);
            }

            // Create a directory to move the original non IL-stripped assemblies.
            string assembliesDir = Path.GetDirectoryName(ResolvedAssemblies.First().ItemSpec);
            string nonstripDir   = Path.Combine(assembliesDir, "non-stripped");

            if (!Directory.Exists(nonstripDir))
            {
                Directory.CreateDirectory(nonstripDir);
            }

            foreach (var assembly in ResolvedAssemblies)
            {
                string assemblyPath = Path.GetFullPath(assembly.ItemSpec);
                string nonstripPath = Path.Combine(nonstripDir, Path.GetFileName(assemblyPath));

                File.Move(assemblyPath, nonstripPath);

                if (!RunCilStrip(nonstripPath, assemblyPath))
                {
                    Log.LogCodedError("XA3001", "Could not strip IL of assembly: {0}", assembly.ItemSpec);
                    return(false);
                }
            }

            return(true);
        }
コード例 #6
0
        public override bool RunTask()
        {
            string toolsZipAlignPath = Path.Combine(AndroidSdkPath, "tools", ZipAlign);
            bool   findZipAlign      = (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath)) && !File.Exists(toolsZipAlignPath);

            var commandLineToolsDir = MonoAndroidHelper.AndroidSdk.GetCommandLineToolsPaths(CommandLineToolsVersion)
                                      .FirstOrDefault() ?? "";

            var lintPaths = new string [] {
                LintToolPath ?? string.Empty,
                commandLineToolsDir,
                Path.Combine(commandLineToolsDir, "bin"),
                Path.Combine(AndroidSdkPath, "tools"),
                Path.Combine(AndroidSdkPath, "tools", "bin"),
            };

            LintToolPath = null;
            foreach (var path in lintPaths)
            {
                if (File.Exists(Path.Combine(path, Lint)))
                {
                    LintToolPath = path;
                    break;
                }
            }

            foreach (var dir in MonoAndroidHelper.AndroidSdk.GetBuildToolsPaths(AndroidSdkBuildToolsVersion))
            {
                Log.LogDebugMessage("Trying build-tools path: {0}", dir);
                if (dir == null || !Directory.Exists(dir))
                {
                    continue;
                }

                var toolsPaths = new string [] {
                    Path.Combine(dir),
                    Path.Combine(dir, "bin"),
                };

                string aapt = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, Aapt)));
                if (string.IsNullOrEmpty(aapt))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", Aapt,
                                        string.Join(Path.PathSeparator.ToString(), toolsPaths.Select(x => Path.Combine(x, Aapt))));
                    continue;
                }
                AndroidSdkBuildToolsPath    = Path.GetFullPath(dir);
                AndroidSdkBuildToolsBinPath = Path.GetFullPath(aapt);

                string zipalign = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, ZipAlign)));
                if (findZipAlign && string.IsNullOrEmpty(zipalign))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", ZipAlign,
                                        string.Join(Path.PathSeparator.ToString(), toolsPaths.Select(x => Path.Combine(x, ZipAlign))));
                    continue;
                }
                else
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(AndroidSdkBuildToolsPath))
            {
                Log.LogCodedError("XA5205", Properties.Resources.XA5205,
                                  Aapt, AndroidSdkPath, Path.DirectorySeparatorChar, Android);
                return(false);
            }

            ApkSignerJar        = Path.Combine(AndroidSdkBuildToolsBinPath, "lib", ApkSigner);
            AndroidUseApkSigner = File.Exists(ApkSignerJar);

            if (string.IsNullOrEmpty(Aapt2ToolPath))
            {
                var osBinPath = MonoAndroidHelper.GetOSBinPath();
                var aapt2     = Path.Combine(osBinPath, Aapt2);
                if (File.Exists(aapt2))
                {
                    Aapt2ToolPath = osBinPath;
                }
            }

            bool aapt2Installed = !string.IsNullOrEmpty(Aapt2ToolPath) && File.Exists(Path.Combine(Aapt2ToolPath, Aapt2));

            if (aapt2Installed && AndroidUseAapt2)
            {
                if (!GetAapt2Version())
                {
                    AndroidUseAapt2 = false;
                    aapt2Installed  = false;
                    Log.LogCodedWarning("XA0111", Properties.Resources.XA0111);
                }
            }
            if (AndroidUseAapt2)
            {
                if (!aapt2Installed)
                {
                    AndroidUseAapt2 = false;
                    Log.LogCodedWarning("XA0112", Properties.Resources.XA0112);
                }
            }

            if (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath))
            {
                ZipAlignPath = new [] {
                    Path.Combine(AndroidSdkBuildToolsPath),
                    Path.Combine(AndroidSdkBuildToolsBinPath),
                    Path.Combine(AndroidSdkPath, "tools"),
                }
                .Where(p => File.Exists(Path.Combine(p, ZipAlign)))
                .FirstOrDefault();
            }
            if (string.IsNullOrEmpty(ZipAlignPath))
            {
                Log.LogCodedError("XA5205", Properties.Resources.XA5205,
                                  ZipAlign, AndroidSdkPath, Path.DirectorySeparatorChar, Android);
                return(false);
            }

            if (!Validate())
            {
                return(false);
            }

            SequencePointsMode mode;

            if (!Aot.TryGetSequencePointsMode(SequencePointsMode ?? "None", out mode))
            {
                Log.LogCodedError("XA0104", Properties.Resources.XA0104, SequencePointsMode);
            }
            AndroidSequencePointsMode = mode.ToString();

            AndroidApiLevelName = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel(AndroidApiLevel);

            LogOutputs();

            return(!Log.HasLoggedErrors);
        }
コード例 #7
0
        public override bool RunTask()
        {
            string toolsZipAlignPath = Path.Combine(AndroidSdkPath, "tools", ZipAlign);
            bool   findZipAlign      = (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath)) && !File.Exists(toolsZipAlignPath);

            var lintPaths = new string [] {
                LintToolPath ?? string.Empty,
                Path.Combine(AndroidSdkPath, "tools"),
                Path.Combine(AndroidSdkPath, "tools", "bin"),
            };

            LintToolPath = null;
            foreach (var path in lintPaths)
            {
                if (File.Exists(Path.Combine(path, Lint)))
                {
                    LintToolPath = path;
                    break;
                }
            }

            foreach (var dir in MonoAndroidHelper.AndroidSdk.GetBuildToolsPaths(AndroidSdkBuildToolsVersion))
            {
                Log.LogDebugMessage("Trying build-tools path: {0}", dir);
                if (dir == null || !Directory.Exists(dir))
                {
                    continue;
                }

                var toolsPaths = new string [] {
                    Path.Combine(dir),
                    Path.Combine(dir, "bin"),
                };

                string aapt = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, Aapt)));
                if (string.IsNullOrEmpty(aapt))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", Aapt,
                                        string.Join(Path.PathSeparator.ToString(), toolsPaths.Select(x => Path.Combine(x, Aapt))));
                    continue;
                }
                AndroidSdkBuildToolsPath    = Path.GetFullPath(dir);
                AndroidSdkBuildToolsBinPath = Path.GetFullPath(aapt);

                string zipalign = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, ZipAlign)));
                if (findZipAlign && string.IsNullOrEmpty(zipalign))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", ZipAlign,
                                        string.Join(Path.PathSeparator.ToString(), toolsPaths.Select(x => Path.Combine(x, ZipAlign))));
                    continue;
                }
                else
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(AndroidSdkBuildToolsPath))
            {
                Log.LogCodedError("XA5205", Properties.Resources.XA5205,
                                  Aapt, AndroidSdkPath, Path.DirectorySeparatorChar, Android);
                return(false);
            }

            ApkSignerJar        = Path.Combine(AndroidSdkBuildToolsBinPath, "lib", ApkSigner);
            AndroidUseApkSigner = File.Exists(ApkSignerJar);

            if (string.IsNullOrEmpty(Aapt2ToolPath))
            {
                var osBinPath = MonoAndroidHelper.GetOSBinPath();
                var aapt2     = Path.Combine(osBinPath, Aapt2);
                if (File.Exists(aapt2))
                {
                    Aapt2ToolPath = osBinPath;
                }
            }

            bool aapt2Installed = !string.IsNullOrEmpty(Aapt2ToolPath) && File.Exists(Path.Combine(Aapt2ToolPath, Aapt2));

            if (aapt2Installed && AndroidUseAapt2)
            {
                if (!GetAapt2Version())
                {
                    AndroidUseAapt2 = false;
                    aapt2Installed  = false;
                    Log.LogCodedWarning("XA0111", Properties.Resources.XA0111);
                }
            }
            if (AndroidUseAapt2)
            {
                if (!aapt2Installed)
                {
                    AndroidUseAapt2 = false;
                    Log.LogCodedWarning("XA0112", Properties.Resources.XA0112);
                }
            }

            if (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath))
            {
                ZipAlignPath = new [] {
                    Path.Combine(AndroidSdkBuildToolsPath),
                    Path.Combine(AndroidSdkBuildToolsBinPath),
                    Path.Combine(AndroidSdkPath, "tools"),
                }
                .Where(p => File.Exists(Path.Combine(p, ZipAlign)))
                .FirstOrDefault();
            }
            if (string.IsNullOrEmpty(ZipAlignPath))
            {
                Log.LogCodedError("XA5205", Properties.Resources.XA5205,
                                  ZipAlign, AndroidSdkPath, Path.DirectorySeparatorChar, Android);
                return(false);
            }

            if (!ValidateApiLevels())
            {
                return(false);
            }

            if (!MonoAndroidHelper.SupportedVersions.FrameworkDirectories.Any(p => Directory.Exists(Path.Combine(p, TargetFrameworkVersion))))
            {
                Log.LogError(
                    subcategory: string.Empty,
                    errorCode: "XA0001",
                    helpKeyword: string.Empty,
                    file: ProjectFilePath,
                    lineNumber: 0,
                    columnNumber: 0,
                    endLineNumber: 0,
                    endColumnNumber: 0,
                    message: Properties.Resources.XA0001,
                    messageArgs: new [] {
                    TargetFrameworkVersion,
                }
                    );
                return(false);
            }

            int apiLevel;

            if (AndroidApplication && int.TryParse(AndroidApiLevel, out apiLevel))
            {
                if (apiLevel < 26)
                {
                    Log.LogCodedWarning("XA0113", Properties.Resources.XA0113, TargetFrameworkVersion, AndroidApiLevel);
                }
                if (apiLevel < 19)
                {
                    Log.LogCodedWarning("XA0117", Properties.Resources.XA0117, TargetFrameworkVersion);
                }
            }

            SequencePointsMode mode;

            if (!Aot.TryGetSequencePointsMode(SequencePointsMode ?? "None", out mode))
            {
                Log.LogCodedError("XA0104", Properties.Resources.XA0104, SequencePointsMode);
            }
            AndroidSequencePointsMode = mode.ToString();

            AndroidApiLevelName = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel(AndroidApiLevel);

            Log.LogDebugMessage($"{nameof (ResolveAndroidTooling)} Outputs:");
            Log.LogDebugMessage($"  {nameof (TargetFrameworkVersion)}: {TargetFrameworkVersion}");
            Log.LogDebugMessage($"  {nameof (AndroidApiLevel)}: {AndroidApiLevel}");
            Log.LogDebugMessage($"  {nameof (AndroidApiLevelName)}: {AndroidApiLevelName}");
            Log.LogDebugMessage($"  {nameof (AndroidSdkBuildToolsPath)}: {AndroidSdkBuildToolsPath}");
            Log.LogDebugMessage($"  {nameof (AndroidSdkBuildToolsBinPath)}: {AndroidSdkBuildToolsBinPath}");
            Log.LogDebugMessage($"  {nameof (ZipAlignPath)}: {ZipAlignPath}");
            Log.LogDebugMessage($"  {nameof (AndroidSequencePointsMode)}: {AndroidSequencePointsMode}");
            Log.LogDebugMessage($"  {nameof (LintToolPath)}: {LintToolPath}");
            Log.LogDebugMessage($"  {nameof (ApkSignerJar)}: {ApkSignerJar}");
            Log.LogDebugMessage($"  {nameof (AndroidUseApkSigner)}: {AndroidUseApkSigner}");
            Log.LogDebugMessage($"  {nameof (AndroidUseAapt2)}: {AndroidUseAapt2}");
            Log.LogDebugMessage($"  {nameof (Aapt2Version)}: {Aapt2Version}");

            return(!Log.HasLoggedErrors);
        }
コード例 #8
0
ファイル: BuildApk.cs プロジェクト: dora0825/xamarin-android
        void AddEnvironment(ZipArchive apk)
        {
            var environment = new StringWriter()
            {
                NewLine = "\n",
            };

            if (EnableLLVM)
            {
                environment.WriteLine("mono.llvm=true");
            }

            AotMode aotMode;

            if (AndroidAotMode != null && Aot.GetAndroidAotMode(AndroidAotMode, out aotMode))
            {
                environment.WriteLine("mono.aot={0}", aotMode.ToString().ToLowerInvariant());
            }

            const string defaultLogLevel           = "MONO_LOG_LEVEL=info";
            const string defaultMonoDebug          = "MONO_DEBUG=gen-compact-seq-points";
            const string defaultHttpMessageHandler = "XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler";
            string       xamarinBuildId            = string.Format("XAMARIN_BUILD_ID={0}", buildId);

            if (Environments == null)
            {
                if (_Debug)
                {
                    environment.WriteLine(defaultLogLevel);
                }
                if (sequencePointsMode != SequencePointsMode.None)
                {
                    environment.WriteLine(defaultMonoDebug);
                }
                environment.WriteLine(xamarinBuildId);
                apk.AddEntry("environment", environment.ToString(),
                             new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
                return;
            }

            bool haveLogLevel           = false;
            bool haveMonoDebug          = false;
            bool havebuildId            = false;
            bool haveHttpMessageHandler = false;

            foreach (ITaskItem env in Environments)
            {
                environment.WriteLine("## Source File: {0}", env.ItemSpec);
                foreach (string line in File.ReadLines(env.ItemSpec))
                {
                    var lineToWrite = line;
                    if (lineToWrite.StartsWith("MONO_LOG_LEVEL=", StringComparison.Ordinal))
                    {
                        haveLogLevel = true;
                    }
                    if (lineToWrite.StartsWith("XAMARIN_BUILD_ID=", StringComparison.Ordinal))
                    {
                        havebuildId = true;
                    }
                    if (lineToWrite.StartsWith("MONO_DEBUG=", StringComparison.Ordinal))
                    {
                        haveMonoDebug = true;
                        if (sequencePointsMode != SequencePointsMode.None && !lineToWrite.Contains("gen-compact-seq-points"))
                        {
                            lineToWrite = line + ",gen-compact-seq-points";
                        }
                    }
                    if (lineToWrite.StartsWith("XA_HTTP_CLIENT_HANDLER_TYPE=", StringComparison.Ordinal))
                    {
                        haveHttpMessageHandler = true;
                    }
                    environment.WriteLine(lineToWrite);
                }
            }

            if (_Debug && !haveLogLevel)
            {
                environment.WriteLine(defaultLogLevel);
            }

            if (sequencePointsMode != SequencePointsMode.None && !haveMonoDebug)
            {
                environment.WriteLine(defaultMonoDebug);
            }

            if (!havebuildId)
            {
                environment.WriteLine(xamarinBuildId);
            }

            if (!haveHttpMessageHandler)
            {
                environment.WriteLine(HttpClientHandlerType == null ? defaultHttpMessageHandler : $"XA_HTTP_CLIENT_HANDLER_TYPE={HttpClientHandlerType.Trim ()}");
            }

            apk.AddEntry("environment", environment.ToString(),
                         new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
        }
コード例 #9
0
ファイル: BuildApk.cs プロジェクト: dora0825/xamarin-android
        public override bool Execute()
        {
            Log.LogDebugMessage("BuildApk Task");
            Log.LogDebugMessage("  ApkInputPath: {0}", ApkInputPath);
            Log.LogDebugMessage("  ApkOutputPath: {0}", ApkOutputPath);
            Log.LogDebugMessage("  BundleAssemblies: {0}", BundleAssemblies);
            Log.LogDebugTaskItems("  DalvikClasses:", DalvikClasses);
            Log.LogDebugMessage("  SupportedAbis: {0}", SupportedAbis);
            Log.LogDebugMessage("  UseSharedRuntime: {0}", UseSharedRuntime);
            Log.LogDebugMessage("  Debug: {0}", Debug ?? "no");
            Log.LogDebugMessage("  EmbedAssemblies: {0}", EmbedAssemblies);
            Log.LogDebugMessage("  AndroidAotMode: {0}", AndroidAotMode);
            Log.LogDebugMessage("  AndroidSequencePointsMode: {0}", AndroidSequencePointsMode);
            Log.LogDebugMessage("  CreatePackagePerAbi: {0}", CreatePackagePerAbi);
            Log.LogDebugTaskItems("  Environments:", Environments);
            Log.LogDebugTaskItems("  ResolvedUserAssemblies:", ResolvedUserAssemblies);
            Log.LogDebugTaskItems("  ResolvedFrameworkAssemblies:", ResolvedFrameworkAssemblies);
            Log.LogDebugTaskItems("  NativeLibraries:", NativeLibraries);
            Log.LogDebugTaskItems("  AdditionalNativeLibraryReferences:", AdditionalNativeLibraryReferences);
            Log.LogDebugTaskItems("  BundleNativeLibraries:", BundleNativeLibraries);
            Log.LogDebugTaskItems("  JavaSourceFiles:", JavaSourceFiles);
            Log.LogDebugTaskItems("  JavaLibraries:", JavaLibraries);
            Log.LogDebugTaskItems("  LibraryProjectJars:", LibraryProjectJars);
            Log.LogDebugTaskItems("  AdditionalNativeLibraryReferences:", AdditionalNativeLibraryReferences);
            Log.LogDebugTaskItems("  HttpClientHandlerType:", HttpClientHandlerType);

            Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode);

            var androidDebugServer = GdbPaths.GetAndroidDebugServer(AndroidGdbDebugServer);

            if (!androidDebugServer.HasValue)
            {
                Log.LogError("Unable to determine debug server variant: {0}", AndroidGdbDebugServer);
                return(false);
            }
            debugServer = androidDebugServer.Value;

            if (string.IsNullOrEmpty(AndroidEmbedProfilers) && _Debug)
            {
                AndroidEmbedProfilers = "log";
            }

            var outputFiles = new List <string> ();

            ExecuteWithAbi(SupportedAbis, ApkInputPath, ApkOutputPath);
            outputFiles.Add(ApkOutputPath);
            if (CreatePackagePerAbi)
            {
                var abis = SupportedAbis.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
                if (abis.Length > 1)
                {
                    foreach (var abi in abis)
                    {
                        var path = Path.GetDirectoryName(ApkOutputPath);
                        var apk  = Path.GetFileNameWithoutExtension(ApkOutputPath);
                        ExecuteWithAbi(abi, String.Format("{0}-{1}", ApkInputPath, abi),
                                       Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                        outputFiles.Add(Path.Combine(path, String.Format("{0}-{1}.apk", apk, abi)));
                    }
                }
            }

            BuildId = buildId.ToString();

            Log.LogDebugMessage("  [Output] BuildId: {0}", BuildId);

            OutputFiles = outputFiles.Select(a => new TaskItem(a)).ToArray();

            Log.LogDebugTaskItems("  [Output] OutputFiles :", OutputFiles);

            return(!Log.HasLoggedErrors);
        }
コード例 #10
0
        public bool RunTask()
        {
            Log.LogDebugMessage("ResolveSdksTask:");
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  AndroidSdkBuildToolsVersion: {0}", AndroidSdkBuildToolsVersion);
            Log.LogDebugMessage($"  {nameof (AndroidSdkPath)}: {AndroidSdkPath}");
            Log.LogDebugMessage($"  {nameof (AndroidNdkPath)}: {AndroidNdkPath}");
            Log.LogDebugMessage($"  {nameof (JavaSdkPath)}: {JavaSdkPath}");
            Log.LogDebugTaskItems("  ReferenceAssemblyPaths: ", ReferenceAssemblyPaths);
            Log.LogDebugMessage("  TargetFrameworkVersion: {0}", TargetFrameworkVersion);
            Log.LogDebugMessage("  UseLatestAndroidPlatformSdk: {0}", UseLatestAndroidPlatformSdk);
            Log.LogDebugMessage("  SequencePointsMode: {0}", SequencePointsMode);
            Log.LogDebugMessage("  LintToolPath: {0}", LintToolPath);

            // OS X:    $prefix/lib/xamarin.android/xbuild/Xamarin/Android
            // Windows: %ProgramFiles(x86)%\MSBuild\Xamarin\Android
            if (string.IsNullOrEmpty(MonoAndroidToolsPath))
            {
                MonoAndroidToolsPath = Path.GetDirectoryName(typeof(ResolveSdks).Assembly.Location);
            }
            MonoAndroidBinPath = MonoAndroidHelper.GetOSBinPath() + Path.DirectorySeparatorChar;

            MonoAndroidHelper.RefreshSupportedVersions(ReferenceAssemblyPaths);
            MonoAndroidHelper.RefreshAndroidSdk(AndroidSdkPath, AndroidNdkPath, JavaSdkPath);

            this.AndroidNdkPath = MonoAndroidHelper.AndroidSdk.AndroidNdkPath;
            this.AndroidSdkPath = MonoAndroidHelper.AndroidSdk.AndroidSdkPath;
            this.JavaSdkPath    = MonoAndroidHelper.AndroidSdk.JavaSdkPath;

            if (!ValidateJavaVersion(TargetFrameworkVersion, AndroidSdkBuildToolsVersion))
            {
                return(false);
            }

            if (string.IsNullOrEmpty(AndroidSdkPath))
            {
                Log.LogCodedError("XA5205", "The Android SDK Directory could not be found. Please set via /p:AndroidSdkDirectory.");
                return(false);
            }

            string toolsZipAlignPath = Path.Combine(AndroidSdkPath, "tools", ZipAlign);
            bool   findZipAlign      = (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath)) && !File.Exists(toolsZipAlignPath);

            var lintPaths = new string [] {
                LintToolPath ?? string.Empty,
                Path.Combine(AndroidSdkPath, "tools"),
                Path.Combine(AndroidSdkPath, "tools", "bin"),
            };

            LintToolPath = null;
            foreach (var path in lintPaths)
            {
                if (File.Exists(Path.Combine(path, Lint)))
                {
                    LintToolPath = path;
                    break;
                }
            }

            foreach (var dir in MonoAndroidHelper.AndroidSdk.GetBuildToolsPaths(AndroidSdkBuildToolsVersion))
            {
                Log.LogDebugMessage("Trying build-tools path: {0}", dir);
                if (dir == null || !Directory.Exists(dir))
                {
                    continue;
                }

                var toolsPaths = new string[] {
                    Path.Combine(dir),
                    Path.Combine(dir, "bin"),
                };

                string aapt = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, Aapt)));
                if (string.IsNullOrEmpty(aapt))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", Aapt,
                                        string.Join(";", toolsPaths.Select(x => Path.Combine(x, Aapt))));
                    continue;
                }
                AndroidSdkBuildToolsPath    = Path.GetFullPath(dir);
                AndroidSdkBuildToolsBinPath = Path.GetFullPath(aapt);

                string zipalign = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, ZipAlign)));
                if (findZipAlign && string.IsNullOrEmpty(zipalign))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", ZipAlign,
                                        string.Join(";", toolsPaths.Select(x => Path.Combine(x, ZipAlign))));
                    continue;
                }
                else
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(AndroidSdkBuildToolsPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      Aapt, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            ApkSignerJar        = Path.Combine(AndroidSdkBuildToolsBinPath, "lib", ApkSigner);
            AndroidUseApkSigner = File.Exists(ApkSignerJar);

            if (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath))
            {
                ZipAlignPath = new[] {
                    Path.Combine(AndroidSdkBuildToolsPath),
                    Path.Combine(AndroidSdkBuildToolsBinPath),
                    Path.Combine(AndroidSdkPath, "tools"),
                }
                .Where(p => File.Exists(Path.Combine(p, ZipAlign)))
                .FirstOrDefault();
            }
            if (string.IsNullOrEmpty(ZipAlignPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      ZipAlign, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            if (!ValidateApiLevels())
            {
                return(false);
            }

            if (!MonoAndroidHelper.SupportedVersions.FrameworkDirectories.Any(p => Directory.Exists(Path.Combine(p, TargetFrameworkVersion))))
            {
                Log.LogError(
                    subcategory:      string.Empty,
                    errorCode:        "XA0001",
                    helpKeyword:      string.Empty,
                    file:             ProjectFilePath,
                    lineNumber:       0,
                    columnNumber:     0,
                    endLineNumber:    0,
                    endColumnNumber:  0,
                    message:          "Unsupported or invalid $(TargetFrameworkVersion) value of '{0}'. Please update your Project Options.",
                    messageArgs:      new[] {
                    TargetFrameworkVersion,
                }
                    );
                return(false);
            }

            SequencePointsMode mode;

            if (!Aot.TryGetSequencePointsMode(SequencePointsMode ?? "None", out mode))
            {
                Log.LogCodedError("XA0104", "Invalid Sequence Point mode: {0}", SequencePointsMode);
            }
            AndroidSequencePointsMode = mode.ToString();

            MonoAndroidHelper.TargetFrameworkDirectories = ReferenceAssemblyPaths;

            AndroidApiLevelName = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel(AndroidApiLevel);

            Log.LogDebugMessage("ResolveSdksTask Outputs:");
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  AndroidApiLevelName: {0}", AndroidApiLevelName);
            Log.LogDebugMessage("  AndroidNdkPath: {0}", AndroidNdkPath);
            Log.LogDebugMessage("  AndroidSdkBuildToolsPath: {0}", AndroidSdkBuildToolsPath);
            Log.LogDebugMessage("  AndroidSdkBuildToolsBinPath: {0}", AndroidSdkBuildToolsBinPath);
            Log.LogDebugMessage("  AndroidSdkPath: {0}", AndroidSdkPath);
            Log.LogDebugMessage("  JavaSdkPath: {0}", JavaSdkPath);
            Log.LogDebugMessage("  JdkVersion: {0}", JdkVersion);
            Log.LogDebugMessage("  MinimumRequiredJdkVersion: {0}", MinimumRequiredJdkVersion);
            Log.LogDebugMessage("  MonoAndroidBinPath: {0}", MonoAndroidBinPath);
            Log.LogDebugMessage("  MonoAndroidToolsPath: {0}", MonoAndroidToolsPath);
            Log.LogDebugMessage("  TargetFrameworkVersion: {0}", TargetFrameworkVersion);
            Log.LogDebugMessage("  ZipAlignPath: {0}", ZipAlignPath);
            Log.LogDebugMessage("  SupportedApiLevel: {0}", SupportedApiLevel);
            Log.LogDebugMessage("  AndroidSequencePointMode: {0}", AndroidSequencePointsMode);
            Log.LogDebugMessage("  LintToolPath: {0}", LintToolPath);

            if (!string.IsNullOrEmpty(CacheFile))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(CacheFile));

                var document = new XDocument(
                    new XDeclaration("1.0", "UTF-8", null),
                    new XElement("Sdk",
                                 new XElement("AndroidApiLevel", AndroidApiLevel),
                                 new XElement("AndroidApiLevelName", AndroidApiLevelName),
                                 new XElement("AndroidNdkPath", AndroidNdkPath),
                                 new XElement("AndroidSdkBuildToolsPath", AndroidSdkBuildToolsPath),
                                 new XElement("AndroidSdkBuildToolsBinPath", AndroidSdkBuildToolsBinPath),
                                 new XElement("AndroidSdkPath", AndroidSdkPath),
                                 new XElement("JavaSdkPath", JavaSdkPath),
                                 new XElement("MonoAndroidBinPath", MonoAndroidBinPath),
                                 new XElement("MonoAndroidToolsPath", MonoAndroidToolsPath),
                                 new XElement("ReferenceAssemblyPaths",
                                              (ReferenceAssemblyPaths ?? new string [0])
                                              .Select(e => new XElement("ReferenceAssemblyPath", e))),
                                 new XElement("TargetFrameworkVersion", TargetFrameworkVersion),
                                 new XElement("ZipAlignPath", ZipAlignPath),
                                 new XElement("MonoAndroidIncludePath", MonoAndroidIncludePath),
                                 new XElement("SupportedApiLevel", SupportedApiLevel),
                                 new XElement("AndroidSequencePointsMode", AndroidSequencePointsMode.ToString()),
                                 new XElement("LintToolPath", LintToolPath)
                                 ));
                document.Save(CacheFile);
            }

            //note: this task does not error out if it doesn't find all things. that's the job of the targets
            return(!Log.HasLoggedErrors);
        }
コード例 #11
0
        void AddEnvironment()
        {
            var environment = new StringWriter()
            {
                NewLine = "\n",
            };

            if (EnableLLVM)
            {
                WriteEnvironment("mono.llvm", "true");
            }

            AotMode aotMode;

            if (AndroidAotMode != null && Aot.GetAndroidAotMode(AndroidAotMode, out aotMode))
            {
                WriteEnvironment("mono.aot", aotMode.ToString().ToLowerInvariant());
            }

            bool haveLogLevel           = false;
            bool haveMonoDebug          = false;
            bool havebuildId            = false;
            bool haveHttpMessageHandler = false;
            bool haveTlsProvider        = false;
            bool haveMonoGCParams       = false;

            SequencePointsMode sequencePointsMode;

            if (!Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode))
            {
                sequencePointsMode = SequencePointsMode.None;
            }

            foreach (ITaskItem env in Environments ?? new TaskItem[0])
            {
                environment.WriteLine("\t\t// Source File: {0}", env.ItemSpec);
                foreach (string line in File.ReadLines(env.ItemSpec))
                {
                    var lineToWrite = line;
                    if (lineToWrite.StartsWith("MONO_LOG_LEVEL=", StringComparison.Ordinal))
                    {
                        haveLogLevel = true;
                    }
                    if (lineToWrite.StartsWith("MONO_GC_PARAMS=", StringComparison.Ordinal))
                    {
                        haveMonoGCParams = true;
                    }
                    if (lineToWrite.StartsWith("XAMARIN_BUILD_ID=", StringComparison.Ordinal))
                    {
                        havebuildId = true;
                    }
                    if (lineToWrite.StartsWith("MONO_DEBUG=", StringComparison.Ordinal))
                    {
                        haveMonoDebug = true;
                        if (sequencePointsMode != SequencePointsMode.None && !lineToWrite.Contains("gen-compact-seq-points"))
                        {
                            lineToWrite = line + ",gen-compact-seq-points";
                        }
                    }
                    if (lineToWrite.StartsWith("XA_HTTP_CLIENT_HANDLER_TYPE=", StringComparison.Ordinal))
                    {
                        haveHttpMessageHandler = true;
                    }
                    if (lineToWrite.StartsWith("XA_TLS_PROVIDER=", StringComparison.Ordinal))
                    {
                        haveTlsProvider = true;
                    }
                    WriteEnvironmentLine(lineToWrite);
                }
            }

            if (_Debug && !haveLogLevel)
            {
                WriteEnvironment(defaultLogLevel[0], defaultLogLevel[1]);
            }

            if (sequencePointsMode != SequencePointsMode.None && !haveMonoDebug)
            {
                WriteEnvironment(defaultMonoDebug[0], defaultMonoDebug[1]);
            }

            if (!havebuildId)
            {
                WriteEnvironment("XAMARIN_BUILD_ID", buildId.ToString());
            }

            if (!haveHttpMessageHandler)
            {
                if (HttpClientHandlerType == null)
                {
                    WriteEnvironment(defaultHttpMessageHandler[0], defaultHttpMessageHandler[1]);
                }
                else
                {
                    WriteEnvironment("XA_HTTP_CLIENT_HANDLER_TYPE", HttpClientHandlerType.Trim());
                }
            }

            if (!haveTlsProvider)
            {
                if (TlsProvider == null)
                {
                    WriteEnvironment(defaultTlsProvider[0], defaultTlsProvider[1]);
                }
                else
                {
                    WriteEnvironment("XA_TLS_PROVIDER", TlsProvider.Trim());
                }
            }

            if (!haveMonoGCParams)
            {
                if (EnableSGenConcurrent)
                {
                    WriteEnvironment("MONO_GC_PARAMS", "major=marksweep-conc");
                }
                else
                {
                    WriteEnvironment("MONO_GC_PARAMS", "major=marksweep");
                }
            }

            string environmentTemplate;

            using (var sr = new StreamReader(typeof(BuildApk).Assembly.GetManifestResourceStream(EnvironmentFileName))) {
                environmentTemplate = sr.ReadToEnd();
            }

            using (var ms = new MemoryStream()) {
                using (var sw = new StreamWriter(ms)) {
                    sw.Write(environmentTemplate.Replace("//@ENVVARS@", environment.ToString()));
                    sw.Flush();

                    string dest = Path.GetFullPath(Path.Combine(EnvironmentOutputDirectory, EnvironmentFileName));
                    MonoAndroidHelper.CopyIfStreamChanged(ms, dest);
                }
            }

            void WriteEnvironment(string name, string value)
            {
                environment.WriteLine($"\t\t\"{ValidJavaString (name)}\", \"{ValidJavaString (value)}\",");
            }

            void WriteEnvironmentLine(string line)
            {
                if (String.IsNullOrEmpty(line))
                {
                    return;
                }

                string[] nv = line.Split(new char[] { '=' }, 2);
                WriteEnvironment(nv[0].Trim(), nv.Length < 2 ? String.Empty : nv[1].Trim());
            }

            string ValidJavaString(string s)
            {
                return(s.Replace("\"", "\\\""));
            }
        }
コード例 #12
0
        public override bool Execute()
        {
            string toolsZipAlignPath = Path.Combine(AndroidSdkPath, "tools", ZipAlign);
            bool   findZipAlign      = (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath)) && !File.Exists(toolsZipAlignPath);

            var lintPaths = new string [] {
                LintToolPath ?? string.Empty,
                Path.Combine(AndroidSdkPath, "tools"),
                Path.Combine(AndroidSdkPath, "tools", "bin"),
            };

            LintToolPath = null;
            foreach (var path in lintPaths)
            {
                if (File.Exists(Path.Combine(path, Lint)))
                {
                    LintToolPath = path;
                    break;
                }
            }

            foreach (var dir in MonoAndroidHelper.AndroidSdk.GetBuildToolsPaths(AndroidSdkBuildToolsVersion))
            {
                Log.LogDebugMessage("Trying build-tools path: {0}", dir);
                if (dir == null || !Directory.Exists(dir))
                {
                    continue;
                }

                var toolsPaths = new string [] {
                    Path.Combine(dir),
                    Path.Combine(dir, "bin"),
                };

                string aapt = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, Aapt)));
                if (string.IsNullOrEmpty(aapt))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", Aapt,
                                        string.Join(Path.PathSeparator.ToString(), toolsPaths.Select(x => Path.Combine(x, Aapt))));
                    continue;
                }
                AndroidSdkBuildToolsPath    = Path.GetFullPath(dir);
                AndroidSdkBuildToolsBinPath = Path.GetFullPath(aapt);

                string zipalign = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, ZipAlign)));
                if (findZipAlign && string.IsNullOrEmpty(zipalign))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", ZipAlign,
                                        string.Join(Path.PathSeparator.ToString(), toolsPaths.Select(x => Path.Combine(x, ZipAlign))));
                    continue;
                }
                else
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(AndroidSdkBuildToolsPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      Aapt, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            ApkSignerJar        = Path.Combine(AndroidSdkBuildToolsBinPath, "lib", ApkSigner);
            AndroidUseApkSigner = File.Exists(ApkSignerJar);

            if (string.IsNullOrEmpty(Aapt2ToolPath))
            {
                var osBinPath = MonoAndroidHelper.GetOSBinPath();
                var aapt2     = Path.Combine(osBinPath, Aapt2);
                if (File.Exists(aapt2))
                {
                    Aapt2ToolPath = osBinPath;
                }
            }

            bool aapt2Installed = !string.IsNullOrEmpty(Aapt2ToolPath) && File.Exists(Path.Combine(Aapt2ToolPath, Aapt2));

            if (aapt2Installed && AndroidUseAapt2)
            {
                if (!GetAapt2Version())
                {
                    AndroidUseAapt2 = false;
                    aapt2Installed  = false;
                    Log.LogCodedWarning("XA0111", "Could not get the `aapt2` version. Disabling `aapt2` support. Please check it is installed correctly.");
                }
            }
            if (AndroidUseAapt2)
            {
                if (!aapt2Installed)
                {
                    AndroidUseAapt2 = false;
                    Log.LogCodedWarning("XA0112", "`aapt2` is not installed. Disabling `aapt2` support. Please check it is installed correctly.");
                }
            }

            if (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath))
            {
                ZipAlignPath = new [] {
                    Path.Combine(AndroidSdkBuildToolsPath),
                    Path.Combine(AndroidSdkBuildToolsBinPath),
                    Path.Combine(AndroidSdkPath, "tools"),
                }
                .Where(p => File.Exists(Path.Combine(p, ZipAlign)))
                .FirstOrDefault();
            }
            if (string.IsNullOrEmpty(ZipAlignPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      ZipAlign, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            if (!ValidateApiLevels())
            {
                return(false);
            }

            if (!MonoAndroidHelper.SupportedVersions.FrameworkDirectories.Any(p => Directory.Exists(Path.Combine(p, TargetFrameworkVersion))))
            {
                Log.LogError(
                    subcategory: string.Empty,
                    errorCode: "XA0001",
                    helpKeyword: string.Empty,
                    file: ProjectFilePath,
                    lineNumber: 0,
                    columnNumber: 0,
                    endLineNumber: 0,
                    endColumnNumber: 0,
                    message: "Unsupported or invalid $(TargetFrameworkVersion) value of '{0}'. Please update your Project Options.",
                    messageArgs: new [] {
                    TargetFrameworkVersion,
                }
                    );
                return(false);
            }

            int apiLevel;

            if (AndroidApplication && int.TryParse(AndroidApiLevel, out apiLevel))
            {
                if (apiLevel < 26)
                {
                    Log.LogCodedWarning("XA0113", $"Google Play requires that new applications and updates must use a TargetFrameworkVersion of v8.0 (API level 26) or above. You are currently targeting {TargetFrameworkVersion} (API level {AndroidApiLevel}).");
                }
                if (apiLevel < 19)
                {
                    Log.LogCodedWarning("XA0117", $"The TargetFrameworkVersion {TargetFrameworkVersion} is deprecated. Please update it to be v4.4 or higher.");
                }
            }

            SequencePointsMode mode;

            if (!Aot.TryGetSequencePointsMode(SequencePointsMode ?? "None", out mode))
            {
                Log.LogCodedError("XA0104", "Invalid Sequence Point mode: {0}", SequencePointsMode);
            }
            AndroidSequencePointsMode = mode.ToString();

            AndroidApiLevelName = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel(AndroidApiLevel);

            Log.LogDebugMessage($"{nameof (ResolveAndroidTooling)} Outputs:");
            Log.LogDebugMessage($"  {nameof (TargetFrameworkVersion)}: {TargetFrameworkVersion}");
            Log.LogDebugMessage($"  {nameof (AndroidApiLevel)}: {AndroidApiLevel}");
            Log.LogDebugMessage($"  {nameof (AndroidApiLevelName)}: {AndroidApiLevelName}");
            Log.LogDebugMessage($"  {nameof (AndroidSdkBuildToolsPath)}: {AndroidSdkBuildToolsPath}");
            Log.LogDebugMessage($"  {nameof (AndroidSdkBuildToolsBinPath)}: {AndroidSdkBuildToolsBinPath}");
            Log.LogDebugMessage($"  {nameof (ZipAlignPath)}: {ZipAlignPath}");
            Log.LogDebugMessage($"  {nameof (AndroidSequencePointsMode)}: {AndroidSequencePointsMode}");
            Log.LogDebugMessage($"  {nameof (LintToolPath)}: {LintToolPath}");
            Log.LogDebugMessage($"  {nameof (ApkSignerJar)}: {ApkSignerJar}");
            Log.LogDebugMessage($"  {nameof (AndroidUseApkSigner)}: {AndroidUseApkSigner}");
            Log.LogDebugMessage($"  {nameof (AndroidUseAapt2)}: {AndroidUseAapt2}");
            Log.LogDebugMessage($"  {nameof (Aapt2Version)}: {Aapt2Version}");

            return(!Log.HasLoggedErrors);
        }
コード例 #13
0
        public override bool Execute()
        {
            Log.LogDebugMessage("ResolveSdksTask:");
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  AndroidSdkBuildToolsVersion: {0}", AndroidSdkBuildToolsVersion);
            Log.LogDebugTaskItems("  ReferenceAssemblyPaths: ", ReferenceAssemblyPaths);
            Log.LogDebugMessage("  TargetFrameworkVersion: {0}", TargetFrameworkVersion);
            Log.LogDebugMessage("  UseLatestAndroidPlatformSdk: {0}", UseLatestAndroidPlatformSdk);
            Log.LogDebugMessage("  SequencePointsMode: {0}", SequencePointsMode);
            Log.LogDebugMessage("  MonoAndroidToolsPath: {0}", MonoAndroidToolsPath);
            Log.LogDebugMessage("  MonoAndroidBinPath: {0}", MonoAndroidBinPath);

            MonoAndroidHelper.InitializeAndroidLogger(Log);

            MonoAndroidHelper.RefreshAndroidSdk(AndroidSdkPath, AndroidNdkPath, JavaSdkPath);
            MonoAndroidHelper.RefreshMonoDroidSdk(MonoAndroidToolsPath, MonoAndroidBinPath, ReferenceAssemblyPaths);

            // OS X:    $prefix/lib/mandroid
            // Windows: %ProgramFiles(x86)%\MSBuild\Xamarin\Android
            this.MonoAndroidToolsPath = MonoDroidSdk.RuntimePath;

            // OS X:    $prefix/bin
            // Windows: %ProgramFiles(x86)%\MSBuild\Xamarin\Android
            this.MonoAndroidBinPath = MonoDroidSdk.BinPath;

            if (this.MonoAndroidBinPath == null)
            {
                Log.LogCodedError("XA0020", "Could not find mandroid!");
                return(false);
            }

            string include;

            if (MonoAndroidToolsPath != null &&
                Directory.Exists(include = Path.Combine(MonoAndroidToolsPath, "include")))
            {
                MonoAndroidIncludePath = include;
            }

            this.AndroidNdkPath = AndroidSdk.AndroidNdkPath;
            this.AndroidSdkPath = AndroidSdk.AndroidSdkPath;
            this.JavaSdkPath    = AndroidSdk.JavaSdkPath;

            if (string.IsNullOrEmpty(AndroidSdkPath))
            {
                Log.LogCodedError("XA5205", "The Android SDK Directory could not be found. Please set via /p:AndroidSdkDirectory.");
                return(false);
            }

            string toolsZipAlignPath = Path.Combine(AndroidSdkPath, "tools", ZipAlign);
            bool   findZipAlign      = (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath)) && !File.Exists(toolsZipAlignPath);

            foreach (var dir in AndroidSdk.GetBuildToolsPaths(AndroidSdkBuildToolsVersion))
            {
                Log.LogDebugMessage("Trying build-tools path: {0}", dir);
                if (dir == null || !Directory.Exists(dir))
                {
                    continue;
                }

                var toolsPaths = new string[] {
                    Path.Combine(dir),
                    Path.Combine(dir, "bin"),
                };

                string aapt = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, Aapt)));
                if (string.IsNullOrEmpty(aapt))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", Aapt,
                                        string.Join(";", toolsPaths.Select(x => Path.Combine(x, Aapt))));
                    continue;
                }
                AndroidSdkBuildToolsPath    = Path.GetFullPath(dir);
                AndroidSdkBuildToolsBinPath = Path.GetFullPath(aapt);

                string zipalign = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, ZipAlign)));
                if (findZipAlign && string.IsNullOrEmpty(zipalign))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", ZipAlign,
                                        string.Join(";", toolsPaths.Select(x => Path.Combine(x, ZipAlign))));
                    continue;
                }
                else
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(AndroidSdkBuildToolsPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      Aapt, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            if (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath))
            {
                ZipAlignPath = new[] {
                    Path.Combine(AndroidSdkBuildToolsPath),
                    Path.Combine(AndroidSdkBuildToolsBinPath),
                    Path.Combine(AndroidSdkPath, "tools"),
                }
                .Where(p => File.Exists(Path.Combine(p, ZipAlign)))
                .FirstOrDefault();
            }
            if (string.IsNullOrEmpty(ZipAlignPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      ZipAlign, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            if (!ValidateApiLevels())
            {
                return(false);
            }

            string frameworksPath = Path.GetDirectoryName(MonoDroidSdk.FrameworkPath);

            if (!Directory.Exists(Path.Combine(frameworksPath, TargetFrameworkVersion)))
            {
                Log.LogError(
                    subcategory:      string.Empty,
                    errorCode:        "XA0001",
                    helpKeyword:      string.Empty,
                    file:             ProjectFilePath,
                    lineNumber:       0,
                    columnNumber:     0,
                    endLineNumber:    0,
                    endColumnNumber:  0,
                    message:          "Unsupported or invalid $(TargetFrameworkVersion) value of '{0}'. Please update your Project Options.",
                    messageArgs:      new[] {
                    TargetFrameworkVersion,
                }
                    );
                return(false);
            }

            SequencePointsMode mode;

            if (!Aot.TryGetSequencePointsMode(SequencePointsMode ?? "None", out mode))
            {
                Log.LogCodedError("XA0104", "Invalid Sequence Point mode: {0}", SequencePointsMode);
            }
            AndroidSequencePointsMode = mode.ToString();


            AndroidApiLevelName = MonoAndroidHelper.GetPlatformApiLevelName(AndroidApiLevel);

            Log.LogDebugMessage("ResolveSdksTask Outputs:");
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  AndroidApiLevelName: {0}", AndroidApiLevelName);
            Log.LogDebugMessage("  AndroidNdkPath: {0}", AndroidNdkPath);
            Log.LogDebugMessage("  AndroidSdkBuildToolsPath: {0}", AndroidSdkBuildToolsPath);
            Log.LogDebugMessage("  AndroidSdkBuildToolsBinPath: {0}", AndroidSdkBuildToolsBinPath);
            Log.LogDebugMessage("  AndroidSdkPath: {0}", AndroidSdkPath);
            Log.LogDebugMessage("  JavaSdkPath: {0}", JavaSdkPath);
            Log.LogDebugMessage("  MonoAndroidBinPath: {0}", MonoAndroidBinPath);
            Log.LogDebugMessage("  MonoAndroidToolsPath: {0}", MonoAndroidToolsPath);
            Log.LogDebugMessage("  MonoAndroidIncludePath: {0}", MonoAndroidIncludePath);
            Log.LogDebugMessage("  TargetFrameworkVersion: {0}", TargetFrameworkVersion);
            Log.LogDebugMessage("  ZipAlignPath: {0}", ZipAlignPath);
            Log.LogDebugMessage("  SupportedApiLevel: {0}", SupportedApiLevel);
            Log.LogDebugMessage("  AndroidSequencePointMode: {0}", AndroidSequencePointsMode);

            if (!string.IsNullOrEmpty(CacheFile))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(CacheFile));

                var document = new XDocument(
                    new XDeclaration("1.0", "UTF-8", null),
                    new XElement("Sdk",
                                 new XElement("AndroidApiLevel", AndroidApiLevel),
                                 new XElement("AndroidApiLevelName", AndroidApiLevelName),
                                 new XElement("AndroidNdkPath", AndroidNdkPath),
                                 new XElement("AndroidSdkBuildToolsPath", AndroidSdkBuildToolsPath),
                                 new XElement("AndroidSdkBuildToolsBinPath", AndroidSdkBuildToolsBinPath),
                                 new XElement("AndroidSdkPath", AndroidSdkPath),
                                 new XElement("JavaSdkPath", JavaSdkPath),
                                 new XElement("MonoAndroidBinPath", MonoAndroidBinPath),
                                 new XElement("MonoAndroidToolsPath", MonoAndroidToolsPath),
                                 new XElement("ReferenceAssemblyPaths",
                                              (ReferenceAssemblyPaths ?? new string [0])
                                              .Select(e => new XElement("ReferenceAssemblyPath", e))),
                                 new XElement("TargetFrameworkVersion", TargetFrameworkVersion),
                                 new XElement("ZipAlignPath", ZipAlignPath),
                                 new XElement("MonoAndroidIncludePath", MonoAndroidIncludePath),
                                 new XElement("SupportedApiLevel", SupportedApiLevel),
                                 new XElement("AndroidSequencePointsMode", AndroidSequencePointsMode.ToString())
                                 ));
                document.Save(CacheFile);
            }

            //note: this task does not error out if it doesn't find all things. that's the job of the targets
            return(!Log.HasLoggedErrors);
        }
コード例 #14
0
        void AddEnvironment()
        {
            bool   usesMonoAOT          = false;
            bool   usesAssemblyPreload  = EnablePreloadAssembliesDefault;
            uint   monoAOTMode          = 0;
            string androidPackageName   = null;
            var    environmentVariables = new Dictionary <string, string> (StringComparer.Ordinal);
            var    systemProperties     = new Dictionary <string, string> (StringComparer.Ordinal);

            AotMode aotMode;

            if (AndroidAotMode != null && Aot.GetAndroidAotMode(AndroidAotMode, out aotMode))
            {
                usesMonoAOT = true;
                monoAOTMode = (uint)aotMode;
            }

            bool haveLogLevel           = false;
            bool haveMonoDebug          = false;
            bool havebuildId            = false;
            bool haveHttpMessageHandler = false;
            bool haveTlsProvider        = false;
            bool haveMonoGCParams       = false;

            SequencePointsMode sequencePointsMode;

            if (!Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode))
            {
                sequencePointsMode = SequencePointsMode.None;
            }

            foreach (ITaskItem env in Environments ?? new TaskItem[0])
            {
                foreach (string line in File.ReadLines(env.ItemSpec))
                {
                    var lineToWrite = line;
                    if (lineToWrite.StartsWith("MONO_LOG_LEVEL=", StringComparison.Ordinal))
                    {
                        haveLogLevel = true;
                    }
                    if (lineToWrite.StartsWith("MONO_GC_PARAMS=", StringComparison.Ordinal))
                    {
                        haveMonoGCParams = true;
                    }
                    if (lineToWrite.StartsWith("XAMARIN_BUILD_ID=", StringComparison.Ordinal))
                    {
                        havebuildId = true;
                    }
                    if (lineToWrite.StartsWith("MONO_DEBUG=", StringComparison.Ordinal))
                    {
                        haveMonoDebug = true;
                        if (sequencePointsMode != SequencePointsMode.None && !lineToWrite.Contains("gen-compact-seq-points"))
                        {
                            lineToWrite = line + ",gen-compact-seq-points";
                        }
                    }
                    if (lineToWrite.StartsWith("XA_HTTP_CLIENT_HANDLER_TYPE=", StringComparison.Ordinal))
                    {
                        haveHttpMessageHandler = true;
                    }
                    if (lineToWrite.StartsWith("XA_TLS_PROVIDER=", StringComparison.Ordinal))
                    {
                        haveTlsProvider = true;
                    }
                    if (lineToWrite.StartsWith("mono.enable_assembly_preload=", StringComparison.Ordinal))
                    {
                        int  idx = lineToWrite.IndexOf('=');
                        uint val;
                        if (idx < lineToWrite.Length - 1 && UInt32.TryParse(lineToWrite.Substring(idx + 1), out val))
                        {
                            usesAssemblyPreload = idx == 1;
                        }
                        continue;
                    }

                    AddEnvironmentVariableLine(lineToWrite);
                }
            }

            if (_Debug && !haveLogLevel)
            {
                AddEnvironmentVariable(defaultLogLevel[0], defaultLogLevel[1]);
            }

            if (sequencePointsMode != SequencePointsMode.None && !haveMonoDebug)
            {
                AddEnvironmentVariable(defaultMonoDebug[0], defaultMonoDebug[1]);
            }

            if (!havebuildId)
            {
                AddEnvironmentVariable("XAMARIN_BUILD_ID", BuildId);
            }

            if (!haveHttpMessageHandler)
            {
                if (HttpClientHandlerType == null)
                {
                    AddEnvironmentVariable(defaultHttpMessageHandler[0], defaultHttpMessageHandler[1]);
                }
                else
                {
                    AddEnvironmentVariable("XA_HTTP_CLIENT_HANDLER_TYPE", HttpClientHandlerType.Trim());
                }
            }

            if (!haveTlsProvider)
            {
                if (TlsProvider == null)
                {
                    AddEnvironmentVariable(defaultTlsProvider[0], defaultTlsProvider[1]);
                }
                else
                {
                    AddEnvironmentVariable("XA_TLS_PROVIDER", TlsProvider.Trim());
                }
            }

            if (!haveMonoGCParams)
            {
                if (EnableSGenConcurrent)
                {
                    AddEnvironmentVariable("MONO_GC_PARAMS", "major=marksweep-conc");
                }
                else
                {
                    AddEnvironmentVariable("MONO_GC_PARAMS", "major=marksweep");
                }
            }

            using (var ms = new MemoryStream()) {
                var utf8Encoding = new UTF8Encoding(false);
                foreach (string abi in SupportedAbis)
                {
                    ms.SetLength(0);
                    NativeAssemblerTargetProvider asmTargetProvider;
                    string asmFileName = Path.Combine(EnvironmentOutputDirectory, $"environment.{abi.ToLowerInvariant ()}.s");
                    switch (abi.Trim())
                    {
                    case "armeabi-v7a":
                        asmTargetProvider = new ARMNativeAssemblerTargetProvider(false);
                        break;

                    case "arm64-v8a":
                        asmTargetProvider = new ARMNativeAssemblerTargetProvider(true);
                        break;

                    case "x86":
                        asmTargetProvider = new X86NativeAssemblerTargetProvider(false);
                        break;

                    case "x86_64":
                        asmTargetProvider = new X86NativeAssemblerTargetProvider(true);
                        break;

                    default:
                        throw new InvalidOperationException($"Unknown ABI {abi}");
                    }

                    var asmgen = new ApplicationConfigNativeAssemblyGenerator(asmTargetProvider, environmentVariables, systemProperties)
                    {
                        IsBundledApp        = IsBundledApplication,
                        UsesMonoAOT         = usesMonoAOT,
                        UsesMonoLLVM        = EnableLLVM,
                        UsesAssemblyPreload = usesAssemblyPreload,
                        MonoAOTMode         = monoAOTMode.ToString().ToLowerInvariant(),
                        AndroidPackageName  = AndroidPackageName,
                    };

                    using (var sw = new StreamWriter(ms, utf8Encoding, bufferSize: 8192, leaveOpen: true)) {
                        asmgen.Write(sw, asmFileName);
                        MonoAndroidHelper.CopyIfStreamChanged(ms, asmFileName);
                    }
                }
            }

            void AddEnvironmentVariable(string name, string value)
            {
                if (Char.IsUpper(name [0]) || !Char.IsLetter(name [0]))
                {
                    environmentVariables [ValidAssemblerString(name)] = ValidAssemblerString(value);
                }
                else
                {
                    systemProperties [ValidAssemblerString(name)] = ValidAssemblerString(value);
                }
            }

            void AddEnvironmentVariableLine(string l)
            {
                string line = l?.Trim();

                if (String.IsNullOrEmpty(line) || line [0] == '#')
                {
                    return;
                }

                string[] nv = line.Split(new char[] { '=' }, 2);
                AddEnvironmentVariable(nv[0].Trim(), nv.Length < 2 ? String.Empty : nv[1].Trim());
            }

            string ValidAssemblerString(string s)
            {
                return(s.Replace("\"", "\\\""));
            }
        }
コード例 #15
0
        void AddEnvironment()
        {
            bool usesMonoAOT                = false;
            bool usesAssemblyPreload        = EnablePreloadAssembliesDefault;
            bool brokenExceptionTransitions = false;
            var  environmentVariables       = new Dictionary <string, string> (StringComparer.Ordinal);
            var  systemProperties           = new Dictionary <string, string> (StringComparer.Ordinal);

            if (!Enum.TryParse(PackageNamingPolicy, out PackageNamingPolicy pnp))
            {
                pnp = PackageNamingPolicyEnum.LowercaseCrc64;
            }

            AotMode aotMode = AotMode.None;

            if (!string.IsNullOrEmpty(AndroidAotMode) && Aot.GetAndroidAotMode(AndroidAotMode, out aotMode) && aotMode != AotMode.None)
            {
                usesMonoAOT = true;
            }

            bool haveLogLevel           = false;
            bool haveMonoDebug          = false;
            bool havebuildId            = false;
            bool haveHttpMessageHandler = false;
            bool haveTlsProvider        = false;
            bool haveMonoGCParams       = false;

            SequencePointsMode sequencePointsMode;

            if (!Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode))
            {
                sequencePointsMode = SequencePointsMode.None;
            }

            foreach (ITaskItem env in Environments ?? new TaskItem[0])
            {
                foreach (string line in File.ReadLines(env.ItemSpec))
                {
                    var lineToWrite = line;
                    if (lineToWrite.StartsWith("MONO_LOG_LEVEL=", StringComparison.Ordinal))
                    {
                        haveLogLevel = true;
                    }
                    if (lineToWrite.StartsWith("MONO_GC_PARAMS=", StringComparison.Ordinal))
                    {
                        haveMonoGCParams = true;
                    }
                    if (lineToWrite.StartsWith("XAMARIN_BUILD_ID=", StringComparison.Ordinal))
                    {
                        havebuildId = true;
                    }
                    if (lineToWrite.StartsWith("MONO_DEBUG=", StringComparison.Ordinal))
                    {
                        haveMonoDebug = true;
                        if (sequencePointsMode != SequencePointsMode.None && !lineToWrite.Contains("gen-compact-seq-points"))
                        {
                            lineToWrite = line + ",gen-compact-seq-points";
                        }
                    }
                    if (lineToWrite.StartsWith("XA_HTTP_CLIENT_HANDLER_TYPE=", StringComparison.Ordinal))
                    {
                        haveHttpMessageHandler = true;
                    }
                    if (lineToWrite.StartsWith("XA_TLS_PROVIDER=", StringComparison.Ordinal))
                    {
                        haveTlsProvider = true;
                    }
                    if (lineToWrite.StartsWith("mono.enable_assembly_preload=", StringComparison.Ordinal))
                    {
                        int  idx = lineToWrite.IndexOf('=');
                        uint val;
                        if (idx < lineToWrite.Length - 1 && UInt32.TryParse(lineToWrite.Substring(idx + 1), out val))
                        {
                            usesAssemblyPreload = idx == 1;
                        }
                        continue;
                    }
                    if (lineToWrite.StartsWith("XA_BROKEN_EXCEPTION_TRANSITIONS="))
                    {
                        brokenExceptionTransitions = true;
                        continue;
                    }

                    AddEnvironmentVariableLine(lineToWrite);
                }
            }

            if (_Debug && !haveLogLevel)
            {
                AddEnvironmentVariable(defaultLogLevel[0], defaultLogLevel[1]);
            }

            if (sequencePointsMode != SequencePointsMode.None && !haveMonoDebug)
            {
                AddEnvironmentVariable(defaultMonoDebug[0], defaultMonoDebug[1]);
            }

            if (!havebuildId)
            {
                AddEnvironmentVariable("XAMARIN_BUILD_ID", BuildId);
            }

            if (!haveHttpMessageHandler)
            {
                if (HttpClientHandlerType == null)
                {
                    AddEnvironmentVariable(defaultHttpMessageHandler[0], defaultHttpMessageHandler[1]);
                }
                else
                {
                    AddEnvironmentVariable("XA_HTTP_CLIENT_HANDLER_TYPE", HttpClientHandlerType.Trim());
                }
            }

            if (!haveTlsProvider)
            {
                if (TlsProvider == null)
                {
                    AddEnvironmentVariable(defaultTlsProvider[0], defaultTlsProvider[1]);
                }
                else
                {
                    AddEnvironmentVariable("XA_TLS_PROVIDER", TlsProvider.Trim());
                }
            }

            if (!haveMonoGCParams)
            {
                if (EnableSGenConcurrent)
                {
                    AddEnvironmentVariable("MONO_GC_PARAMS", "major=marksweep-conc");
                }
                else
                {
                    AddEnvironmentVariable("MONO_GC_PARAMS", "major=marksweep");
                }
            }

            global::Android.Runtime.BoundExceptionType boundExceptionType;
            if (String.IsNullOrEmpty(BoundExceptionType) || String.Compare(BoundExceptionType, "System", StringComparison.OrdinalIgnoreCase) == 0)
            {
                boundExceptionType = global::Android.Runtime.BoundExceptionType.System;
            }
            else if (String.Compare(BoundExceptionType, "Java", StringComparison.OrdinalIgnoreCase) == 0)
            {
                boundExceptionType = global::Android.Runtime.BoundExceptionType.Java;
            }
            else
            {
                throw new InvalidOperationException($"Unsupported BoundExceptionType value '{BoundExceptionType}'");
            }

            var appConfState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal <ApplicationConfigTaskState> (ApplicationConfigTaskState.RegisterTaskObjectKey, RegisteredTaskObjectLifetime.Build);

            foreach (string abi in SupportedAbis)
            {
                NativeAssemblerTargetProvider asmTargetProvider = GetAssemblyTargetProvider(abi);
                string baseAsmFilePath = Path.Combine(EnvironmentOutputDirectory, $"environment.{abi.ToLowerInvariant ()}");
                string asmFilePath     = $"{baseAsmFilePath}.s";

                var asmgen = new ApplicationConfigNativeAssemblyGenerator(asmTargetProvider, baseAsmFilePath, environmentVariables, systemProperties)
                {
                    IsBundledApp               = IsBundledApplication,
                    UsesMonoAOT                = usesMonoAOT,
                    UsesMonoLLVM               = EnableLLVM,
                    UsesAssemblyPreload        = usesAssemblyPreload,
                    MonoAOTMode                = aotMode.ToString().ToLowerInvariant(),
                    AndroidPackageName         = AndroidPackageName,
                    BrokenExceptionTransitions = brokenExceptionTransitions,
                    PackageNamingPolicy        = pnp,
                    BoundExceptionType         = boundExceptionType,
                    InstantRunEnabled          = InstantRunEnabled,
                    JniAddNativeMethodRegistrationAttributePresent = appConfState != null ? appConfState.JniAddNativeMethodRegistrationAttributePresent : false,
                };

                using (var sw = MemoryStreamPool.Shared.CreateStreamWriter()) {
                    asmgen.Write(sw);
                    sw.Flush();
                    Files.CopyIfStreamChanged(sw.BaseStream, asmFilePath);
                }
            }

            void AddEnvironmentVariable(string name, string value)
            {
                if (Char.IsUpper(name [0]) || !Char.IsLetter(name [0]))
                {
                    environmentVariables [ValidAssemblerString(name)] = ValidAssemblerString(value);
                }
                else
                {
                    systemProperties [ValidAssemblerString(name)] = ValidAssemblerString(value);
                }
            }

            void AddEnvironmentVariableLine(string l)
            {
                string line = l?.Trim();

                if (String.IsNullOrEmpty(line) || line [0] == '#')
                {
                    return;
                }

                string[] nv = line.Split(new char[] { '=' }, 2);
                AddEnvironmentVariable(nv[0].Trim(), nv.Length < 2 ? String.Empty : nv[1].Trim());
            }

            string ValidAssemblerString(string s)
            {
                return(s.Replace("\"", "\\\""));
            }
        }