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); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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("\"", "\\\"")); } }
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); }
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); }
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("\"", "\\\"")); } }
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("\"", "\\\"")); } }