public static bool AllBundleItemsPresent(Runtimes runtimes) { if (runtimes == null) { throw new ArgumentNullException(nameof(runtimes)); } bool runtimesFoundAndComplete = true; foreach (BundleItem item in runtimes.BundleItems) { if (item == null) { continue; } // BundleItem.SourcePath is the path *after* the file is installed into our tree if (File.Exists(item.SourcePath)) { continue; } runtimesFoundAndComplete = false; Log.Instance.DebugLine($"{item.SourcePath} missing, skipping the rest of bundle item file scan"); break; } return(runtimesFoundAndComplete); }
List <Runtime> GetEnabledRuntimes(bool enableLogging) { var enabledRuntimes = new List <Runtime> (); if (allRuntimes == null) { allRuntimes = new Runtimes(); } return(MonoRuntimesHelpers.GetEnabledRuntimes(allRuntimes, enableLogging)); }
void EnsureAllSDKHeadersAreIncluded(Context context, Runtimes allRuntimes) { string topDirTail = Configurables.Paths.MonoSDKRelativeIncludeSourceDir; if (!topDirTail.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) { topDirTail += Path.DirectorySeparatorChar; } // Find first enabled runtime - all headers are the same across all runtimes, so we don't care // where they come from. Runtime runtime = MonoRuntimesHelpers.GetEnabledRuntimes(allRuntimes, enableLogging: false)?.FirstOrDefault(); if (runtime == null) { Log.WarningLine("No enabled runtimes (?!)"); return; } string runtimeIncludeDirRoot = Path.Combine(Configurables.Paths.MonoSourceFullPath, MonoRuntimesHelpers.GetRootDir(runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir); IEnumerable <string> sourceIncludes = Directory.EnumerateFiles(runtimeIncludeDirRoot, "*", SearchOption.AllDirectories); var destinationIncludes = new List <string> (); foreach (RuntimeFile rf in allRuntimes.RuntimeFilesToInstall.Where(rf => rf.Type == RuntimeFileType.SdkHeader)) { destinationIncludes.Add(Path.Combine(Configurables.Paths.MonoSourceFullPath, rf.Source(runtime))); } bool haveDifference = false; haveDifference &= ReportDifference(sourceIncludes.Except(destinationIncludes).ToList(), "runtime", "bundle"); haveDifference &= ReportDifference(destinationIncludes.Except(sourceIncludes).ToList(), "bundle", "runtime"); if (haveDifference) { throw new InvalidOperationException("Differences found between the Mono SDK header files shipped in Mono archive and included in Xamarin.Android bundle"); } bool ReportDifference(List <string> diff, string foundIn, string notFoundIn) { if (diff.Count == 0) { return(false); } Log.ErrorLine($"There are files found in the {foundIn} but not in the {notFoundIn}:"); foreach (string f in diff) { Log.ErrorLine($" {context.Characters.Bullet} {Utilities.GetRelativePath (runtimeIncludeDirRoot, f)}"); } Log.ErrorLine(); return(true); } }
public override void Generate(Context context) { var runtimes = new Runtimes(); IEnumerable <BclFile> facadeAssemblies = runtimes.BclFilesToInstall.Where(f => f.Type == BclFileType.FacadeAssembly); IEnumerable <BclFile> profileAssemblies = runtimes.BclFilesToInstall.Where(f => f.Type == BclFileType.ProfileAssembly); IEnumerable <TestAssembly> testAssemblies = runtimes.TestAssemblies; EnsureNoDiscrepancies(facadeAssemblies, profileAssemblies, testAssemblies.Where(ta => ta.TestType != TestAssemblyType.Reference && ta.TestType != TestAssemblyType.TestRunner)); using (var fs = File.Open(OutputPath, FileMode.Create)) { using (var sw = new StreamWriter(fs)) { GenerateFile(sw, facadeAssemblies, profileAssemblies, testAssemblies); } } }
async Task <bool> DownloadMonoArchive(Context context) { if (context.ForceRuntimesBuild) { Log.StatusLine("Mono runtime rebuild forced, Mono Archive download skipped"); return(false); } Log.StatusLine("Checking if all runtime files are present"); var allRuntimes = new Runtimes(); if (MonoRuntimesHelpers.AllBundleItemsPresent(allRuntimes)) { // User might have changed the set of ABIs to build, we need to check and rebuild if necessary if (!Utilities.AbiChoiceChanged(context)) { Log.StatusLine("Mono runtimes already present and complete. No need to download or build."); return(true); } Log.StatusLine("Mono already present, but the choice of ABIs changed since previous build, runtime refresh is necessary"); } Log.Instance.StatusLine($" {Context.Instance.Characters.Bullet} some files are missing, download/rebuild/reinstall forced"); bool result = await DownloadAndUpackIfNeeded( context, "Mono", Configurables.Paths.MonoArchiveLocalPath, Configurables.Paths.MonoArchiveFileName, Configurables.Paths.MonoSDKSOutputDir ); if (!result) { return(false); } return(await DownloadAndUpackIfNeeded( context, "Windows Mono", Configurables.Paths.MonoArchiveWindowsLocalPath, Configurables.Paths.MonoArchiveWindowsFileName, Configurables.Paths.BCLWindowsOutputDir )); }
protected override async Task <bool> Execute(Context context) { var allRuntimes = new Runtimes(); string binRoot = Configurables.Paths.BinDir; string bundlePath = Path.Combine(binRoot, Configurables.Paths.XABundleFileName); Log.StatusLine("Generating bundle archive: ", Utilities.GetRelativePath(BuildPaths.XamarinAndroidSourceRoot, bundlePath), tailColor: ConsoleColor.White); Utilities.DeleteFileSilent(bundlePath); var sevenZip = new SevenZipRunner(context); CompressionFormat cf = context.CompressionFormat; Func <string, string, List <string>, Task <bool> > compressor; if (String.Compare(cf.Name, Configurables.Defaults.ZipCompressionFormatName, StringComparison.OrdinalIgnoreCase) == 0) { compressor = sevenZip.Zip; } else if (String.Compare(cf.Name, Configurables.Defaults.SevenZipCompressionFormatName, StringComparison.OrdinalIgnoreCase) == 0) { compressor = sevenZip.SevenZip; } else { throw new InvalidOperationException($"Unsupported compression type: {cf.Description}"); } EnsureAllSDKHeadersAreIncluded(context, allRuntimes); List <string> items = allRuntimes.BundleItems.Where(item => item.ShouldInclude == null || item.ShouldInclude(context)).Select( item => { string relPath = Utilities.GetRelativePath(binRoot, item.SourcePath); Log.DebugLine($"Bundle item: {item.SourcePath} (archive path: {relPath})"); return(relPath); } ).Distinct().ToList(); items.Sort(); if (!await compressor(bundlePath, binRoot, items)) { Log.ErrorLine("Bundle archive creation failed, see the log files for details."); return(false); } return(true); }
public static List <Runtime> GetEnabledRuntimes(Runtimes allRuntimes, bool enableLogging) { if (allRuntimes == null) { throw new ArgumentNullException(nameof(allRuntimes)); } var context = Context.Instance; var enabledRuntimes = new List <Runtime> (); if (enableLogging) { Log.Instance.StatusLine("Enabled Mono Android runtime ABIs:", ConsoleColor.White); } foreach (Runtime runtime in allRuntimes.Items.Where(r => r is MonoJitRuntime && r.Enabled)) { enabledRuntimes.Add(runtime); if (enableLogging) { Log.Instance.StatusLine($" {context.Characters.Bullet} {runtime.DisplayName}"); } } if (enableLogging) { Log.Instance.StatusLine(); Log.Instance.StatusLine("Enabled Mono host runtimes:", ConsoleColor.White); } foreach (Runtime runtime in allRuntimes.Items.Where(r => r is MonoHostRuntime && r.Enabled)) { enabledRuntimes.Add(runtime); if (enableLogging) { Log.Instance.StatusLine($" {context.Characters.Bullet} {runtime.DisplayName}"); } } bool anyCrossEnabled = false; if (enableLogging) { Log.Instance.StatusLine(); Log.Instance.StatusLine("Enabled Mono cross compilers:", ConsoleColor.White); } foreach (Runtime runtime in allRuntimes.Items.Where(r => r is MonoCrossRuntime && r.Enabled)) { anyCrossEnabled = true; enabledRuntimes.Add(runtime); if (enableLogging) { Log.Instance.StatusLine($" {context.Characters.Bullet} {runtime.DisplayName}"); } } if (enableLogging && !anyCrossEnabled) { Log.Instance.StatusLine($" NONE", ConsoleColor.DarkCyan); } anyCrossEnabled = false; if (enableLogging) { Log.Instance.StatusLine(); Log.Instance.StatusLine("Enabled LLVM cross compilers:", ConsoleColor.White); } foreach (Runtime runtime in allRuntimes.Items.Where(r => r is LlvmRuntime && r.Enabled)) { anyCrossEnabled = true; enabledRuntimes.Add(runtime); if (enableLogging) { Log.Instance.StatusLine($" {context.Characters.Bullet} {runtime.DisplayName}"); } } if (enableLogging && !anyCrossEnabled) { Log.Instance.StatusLine($" NONE", ConsoleColor.DarkCyan); } return(enabledRuntimes); }
public static bool AreRuntimeItemsInstalled(Context context, Runtimes runtimes) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (runtimes == null) { throw new ArgumentNullException(nameof(runtimes)); } if (!string.IsNullOrEmpty(context.MonoArchiveCustomUrl)) { context.Log.StatusLine("Skipping AreRuntimeItemsInstalled check, due to custom mono archive URL."); return(false); } foreach (var bclFile in runtimes.BclFilesToInstall) { (string destFilePath, string debugSymbolsDestPath) = GetDestinationPaths(bclFile); if (!DoesItemExist(destFilePath, bclFile.ExcludeDebugSymbols, debugSymbolsDestPath)) { return(false); } } foreach (var bclFile in runtimes.DesignerHostBclFilesToInstall) { (string destFilePath, string debugSymbolsDestPath) = GetDestinationPaths(bclFile); if (!DoesItemExist(destFilePath, bclFile.ExcludeDebugSymbols, debugSymbolsDestPath)) { return(false); } } foreach (var bclFile in runtimes.DesignerWindowsBclFilesToInstall) { (string destFilePath, string debugSymbolsDestPath) = GetDestinationPaths(bclFile); if (!DoesItemExist(destFilePath, bclFile.ExcludeDebugSymbols, debugSymbolsDestPath)) { return(false); } } foreach (var testFile in runtimes.TestAssemblies) { (string destFilePath, string debugSymbolsDestPath) = GetDestinationPaths(testFile); if (!DoesItemExist(destFilePath, true, debugSymbolsDestPath)) { return(false); } } foreach (var utilFile in runtimes.UtilityFilesToInstall) { (string destFilePath, string debugSymbolsDestPath) = GetDestinationPaths(utilFile); if (!DoesItemExist(destFilePath, utilFile.IgnoreDebugInfo, debugSymbolsDestPath)) { return(false); } } foreach (var runtime in GetEnabledRuntimes(runtimes, true)) { foreach (var runtimeFile in runtimes.RuntimeFilesToInstall) { (bool skipFile, string src, string dst) = GetRuntimeFilePaths(runtime, runtimeFile); if (!skipFile && (dst.Length == 0 || !File.Exists(dst))) { Log.Instance.WarningLine($"File '{dst}' missing, skipping the rest of runtime item file scan"); return(false); } } } return(true); bool DoesItemExist(string destFilePath, bool shouldExcludeSymbols, string debugSymbolsDestPath) { if (File.Exists(destFilePath) && shouldExcludeSymbols) { return(true); } if (File.Exists(destFilePath) && !shouldExcludeSymbols && !String.IsNullOrEmpty(debugSymbolsDestPath) && File.Exists(debugSymbolsDestPath)) { return(true); } Log.Instance.DebugLine($"File '{destFilePath}' or symbols '{debugSymbolsDestPath}' missing, skipping the rest of runtime item file scan"); return(false); } }
protected override async Task <bool> Execute(Context context) { List <Runtime> enabledRuntimes = GetEnabledRuntimes(enableLogging: false); if (enabledRuntimes.Count == 0) { Log.StatusLine("No runtimes to build/install"); return(true); } if (!context.MonoArchiveDownloaded) { // https://github.com/xamarin/xamarin-android/pull/3816 throw new NotImplementedException("Unable to build mono runtimes from sources."); } Log.StatusLine("Checking if all runtime files are present"); var allRuntimes = new Runtimes(); if (MonoRuntimesHelpers.AreRuntimeItemsInstalled(context, allRuntimes)) { // User might have changed the set of ABIs to build, we need to check and rebuild if necessary if (!Utilities.AbiChoiceChanged(context)) { Log.StatusLine("Mono runtimes already present and complete. No need to download or build."); return(true); } Log.StatusLine("Mono already present, but the choice of ABIs changed since previous build, runtime refresh is necessary"); } Log.Instance.StatusLine($" {Context.Instance.Characters.Bullet} some files are missing, rebuild/reinstall forced"); CleanupBeforeInstall(); Log.StatusLine(); string managedRuntime = context.Properties.GetRequiredValue(KnownProperties.ManagedRuntime); bool haveManagedRuntime = !String.IsNullOrEmpty(managedRuntime); if (!await ConjureXamarinCecilAndRemapRef(context, haveManagedRuntime, managedRuntime)) { return(false); } if (!await InstallRuntimes(context, enabledRuntimes)) { return(false); } if (!InstallBCL(context)) { return(false); } if (!InstallUtilities(context, haveManagedRuntime, managedRuntime)) { return(false); } Utilities.PropagateXamarinAndroidCecil(context); return(true); }
async Task <bool> DownloadMonoArchive(Context context) { if (context.ForceRuntimesBuild) { Log.StatusLine("Mono runtime rebuild forced, Mono Archive download skipped"); return(false); } Log.StatusLine("Checking if all runtime files are present"); var allRuntimes = new Runtimes(); if (MonoRuntimesHelpers.AreRuntimeItemsInstalled(context, allRuntimes)) { // User might have changed the set of ABIs to build, we need to check and rebuild if necessary if (!Utilities.AbiChoiceChanged(context)) { Log.StatusLine("Mono runtimes already present and complete. No need to download or build."); return(true); } Log.StatusLine("Mono already present, but the choice of ABIs changed since previous build, runtime refresh is necessary"); } Log.Instance.StatusLine($" {Context.Instance.Characters.Bullet} some files are missing, download and extraction required"); string localPath, archiveFileName; if (string.IsNullOrEmpty(context.MonoArchiveCustomUrl)) { localPath = Configurables.Paths.MonoArchiveLocalPath; archiveFileName = Configurables.Paths.MonoArchiveFileName; } else { var uri = new Uri(context.MonoArchiveCustomUrl); archiveFileName = Path.GetFileName(uri.LocalPath); localPath = Path.Combine(context.Properties.GetRequiredValue(KnownProperties.AndroidToolchainCacheDirectory), archiveFileName); } bool result = false; for (uint i = 0; i < 3; i++) { result = await DownloadAndUpackIfNeeded( context, "Mono", context.MonoArchiveCustomUrl, localPath, archiveFileName, Configurables.Paths.MonoSDKSOutputDir ); if (result) { break; } } if (!result) { return(false); } for (uint i = 0; i < 3; i++) { result = await DownloadAndUpackIfNeeded( context, "Windows Mono", customUrl : String.Empty, localPath : Configurables.Paths.MonoArchiveWindowsLocalPath, archiveFileName : Configurables.Paths.MonoArchiveWindowsFileName, destinationDirectory : Configurables.Paths.BCLWindowsOutputDir ); if (result) { break; } } return(result); }
async Task <bool> DownloadMonoArchive(Context context) { if (context.ForceRuntimesBuild) { Log.StatusLine("Mono runtime rebuild forced, Mono Archive download skipped"); return(false); } Log.StatusLine("Checking if all runtime files are present"); allRuntimes = new Runtimes(); bool runtimesFoundAndComplete = true; foreach (BundleItem item in allRuntimes.BundleItems) { if (item == null) { continue; } // BundleItem.SourcePath is the path *after* the file is installed into our tree if (File.Exists(item.SourcePath)) { continue; } runtimesFoundAndComplete = false; Log.DebugLine($"{item.SourcePath} missing, skipping the rest of file scan"); Log.StatusLine($" {context.Characters.Bullet} some Mono Runtime files are missing, download/rebuild forced"); break; } if (runtimesFoundAndComplete) { // User might have changed the set of ABIs to build, we need to check and rebuild if necessary if (!AbiChoiceChanged(context)) { Log.StatusLine("Mono runtimes already present and complete. No need to download or build."); return(true); } Log.StatusLine("Mono already present, but the choice of ABIs changed since previous build, runtime refresh is necessary"); } bool result = await DownloadAndUpackIfNeeded( context, "Mono", Configurables.Paths.MonoArchiveLocalPath, Configurables.Paths.MonoArchiveFileName, Configurables.Paths.MonoSDKSOutputDir ); if (!result) { return(false); } return(await DownloadAndUpackIfNeeded( context, "Windows Mono", Configurables.Paths.MonoArchiveWindowsLocalPath, Configurables.Paths.MonoArchiveWindowsFileName, Configurables.Paths.BCLWindowsOutputDir )); }