public static void AddRange(this List <BundleItem> list, List <BclFile> bclFiles) { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (bclFiles == null) { throw new ArgumentNullException(nameof(bclFiles)); } foreach (BclFile bf in bclFiles) { if (bf == null) { continue; } // BCL file's *destination* location is our *source* path (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(bf); list.Add(destFilePath); if (bf.ExcludeDebugSymbols || !File.Exists(debugSymbolsDestPath)) { continue; } list.Add(debugSymbolsDestPath); } }
public static void AddRange(this List <BundleItem> list, List <MonoUtilityFile> muFiles) { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (muFiles == null) { throw new ArgumentNullException(nameof(muFiles)); } foreach (MonoUtilityFile muf in muFiles) { if (muf == null) { continue; } // MU file's *destination* location is our *source* path (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(muf); list.Add(destFilePath); if (muf.IgnoreDebugInfo || String.IsNullOrEmpty(debugSymbolsDestPath)) { continue; } list.Add(debugSymbolsDestPath); } }
public static void AddRange(this List <BundleItem> list, List <TestAssembly> testAssemblies) { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (testAssemblies == null) { throw new ArgumentNullException(nameof(testAssemblies)); } foreach (TestAssembly tasm in testAssemblies) { if (tasm == null) { continue; } // Test assembly's *destination* location is our *source* path (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(tasm); list.Add(destFilePath); if (String.IsNullOrEmpty(debugSymbolsDestPath)) { continue; } list.Add(debugSymbolsDestPath); } }
void InstallBCLFiles(List <BclFile> files) { foreach (BclFile bf in files) { (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(bf); Utilities.CopyFile(bf.SourcePath, destFilePath); if (bf.ExcludeDebugSymbols) { continue; } if (debugSymbolsDestPath == null) { Log.DebugLine($"Debug symbols not found for BCL file {bf.Name} ({bf.Type})"); continue; } if (!File.Exists(bf.DebugSymbolsPath)) { Log.DebugLine($"Debug symbols file does not exist: {bf.DebugSymbolsPath}"); continue; } Utilities.CopyFile(bf.DebugSymbolsPath, debugSymbolsDestPath); } }
bool InstallUtilities(Context context) { string destDir = MonoRuntimesHelpers.UtilitiesDestinationDir; Utilities.CreateDirectory(destDir); string managedRuntime = context.Properties.GetRequiredValue(KnownProperties.ManagedRuntime); bool haveManagedRuntime = !String.IsNullOrEmpty(managedRuntime); string remapper = Utilities.GetRelativePath(BuildPaths.XamarinAndroidSourceRoot, context.Properties.GetRequiredValue(KnownProperties.RemapAssemblyRefToolExecutable)); string targetCecil = Utilities.GetRelativePath(BuildPaths.XamarinAndroidSourceRoot, Path.Combine(Configurables.Paths.BuildBinDir, "Xamarin.Android.Cecil.dll")); StatusStep(context, "Installing runtime utilities"); foreach (MonoUtilityFile muf in allRuntimes.UtilityFilesToInstall) { (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(muf); Utilities.CopyFile(muf.SourcePath, destFilePath); if (!muf.IgnoreDebugInfo) { if (!String.IsNullOrEmpty(debugSymbolsDestPath)) { Utilities.CopyFile(muf.DebugSymbolsPath, debugSymbolsDestPath); } else { Log.DebugLine($"Debug symbols not found for utility file {Path.GetFileName (muf.SourcePath)}"); } } if (!muf.RemapCecil) { continue; } string relDestFilePath = Utilities.GetRelativePath(BuildPaths.XamarinAndroidSourceRoot, destFilePath); StatusSubStep(context, $"Remapping Cecil references for {relDestFilePath}"); bool result = Utilities.RunCommand( haveManagedRuntime ? managedRuntime : remapper, // command BuildPaths.XamarinAndroidSourceRoot, // workingDirectory true, // ignoreEmptyArguments // arguments haveManagedRuntime ? remapper : String.Empty, Utilities.GetRelativePath(BuildPaths.XamarinAndroidSourceRoot, muf.SourcePath), relDestFilePath, "Mono.Cecil", targetCecil); if (result) { continue; } Log.ErrorLine($"Failed to remap cecil reference for {destFilePath}"); return(false); } return(true); }
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); } }
protected override Task <bool> Execute(Context context) { List <Runtime> enabledRuntimes = MonoRuntimesHelpers.GetEnabledRuntimes(new Runtimes(), enableLogging: true); if (enabledRuntimes.Count == 0) { Log.StatusLine("No runtimes to build/install"); } return(Task.FromResult(true)); }
void InstallBCLFiles(List <BclFile> files) { foreach (BclFile bf in files) { (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(bf); Utilities.CopyFile(bf.SourcePath, destFilePath); if (!bf.ExcludeDebugSymbols && !String.IsNullOrEmpty(bf.DebugSymbolsPath) && debugSymbolsDestPath.Length > 0) { Utilities.CopyFile(bf.DebugSymbolsPath !, debugSymbolsDestPath); } } }
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 )); }
public static void AddRange(this List <BundleItem> list, List <RuntimeFile> runtimeFiles) { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (runtimeFiles == null) { throw new ArgumentNullException(nameof(runtimeFiles)); } var sharedFiles = new HashSet <string> (StringComparer.Ordinal); foreach (Runtime runtime in MonoRuntimesHelpers.GetEnabledRuntimes(new Runtimes(), false)) { foreach (RuntimeFile rtf in runtimeFiles) { if (rtf == null) { continue; } // Runtime file's *destination* location is our *source* path (bool skipFile, string _, string destFilePath) = MonoRuntimesHelpers.GetRuntimeFilePaths(runtime, rtf); if (rtf.Shared && sharedFiles.Contains(destFilePath)) { continue; } if (skipFile) { continue; } list.Add(destFilePath); if (rtf.Shared) { sharedFiles.Add(destFilePath); } } } }
static string GetAndroidInputLibDir(Runtime runtime) { return(Path.Combine(MonoRuntimesHelpers.GetRootDir(runtime), "lib")); }
async Task <bool> InstallRuntimes(Context context, List <Runtime> enabledRuntimes) { StatusStep(context, "Installing tests"); foreach (TestAssembly tasm in Runtimes.TestAssemblies) { string sourceBasePath; switch (tasm.TestType) { case TestAssemblyType.Reference: case TestAssemblyType.TestRunner: sourceBasePath = Path.Combine(Configurables.Paths.MonoProfileDir); break; case TestAssemblyType.XUnit: case TestAssemblyType.NUnit: case TestAssemblyType.Satellite: sourceBasePath = Configurables.Paths.BCLTestsSourceDir; break; default: throw new InvalidOperationException($"Unsupported test assembly type: {tasm.TestType}"); } (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(tasm); CopyFile(Path.Combine(sourceBasePath, tasm.Name), destFilePath); if (debugSymbolsDestPath != null) { CopyFile(Path.Combine(sourceBasePath, Utilities.GetDebugSymbolsPath(tasm.Name)), debugSymbolsDestPath); } } StatusSubStep(context, "Creating BCL tests archive"); Utilities.DeleteFileSilent(MonoRuntimesHelpers.BCLTestsArchivePath); var sevenZip = new SevenZipRunner(context); if (!await sevenZip.Zip(MonoRuntimesHelpers.BCLTestsArchivePath, MonoRuntimesHelpers.BCLTestsDestinationDir, new List <string> { "." })) { Log.ErrorLine("BCL tests archive creation failed, see the log files for details."); return(false); } StatusStep(context, "Installing runtimes"); foreach (Runtime runtime in enabledRuntimes) { StatusSubStep(context, $"Installing {runtime.Flavor} runtime {runtime.Name}"); string src, dst; bool skipFile; foreach (RuntimeFile rtf in allRuntimes.RuntimeFilesToInstall) { if (rtf.Shared && rtf.AlreadyCopied) { continue; } (skipFile, src, dst) = MonoRuntimesHelpers.GetRuntimeFilePaths(runtime, rtf); if (skipFile) { continue; } CopyFile(src, dst); if (!StripFile(runtime, rtf, dst)) { return(false); } if (rtf.Shared) { rtf.AlreadyCopied = true; } } } return(true); bool StripFile(Runtime runtime, RuntimeFile rtf, string filePath) { if (rtf.Type != RuntimeFileType.StrippableBinary) { return(true); } var monoRuntime = runtime.As <MonoRuntime> (); if (monoRuntime == null || !monoRuntime.CanStripNativeLibrary || !rtf.Strip) { return(true); } if (String.IsNullOrEmpty(monoRuntime.Strip)) { Log.WarningLine($"Binary stripping impossible, runtime {monoRuntime.Name} doesn't define the strip command"); return(true); } bool result; if (!String.IsNullOrEmpty(monoRuntime.StripFlags)) { result = Utilities.RunCommand(monoRuntime.Strip, monoRuntime.StripFlags, filePath); } else { result = Utilities.RunCommand(monoRuntime.Strip, filePath); } if (result) { return(true); } Log.ErrorLine($"Failed to strip the binary file {filePath}, see logs for error details"); return(false); } void CopyFile(string src, string dest) { if (!CheckFileExists(src, true)) { return; } Utilities.CopyFile(src, dest); } }
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); }
protected override async Task <bool> Execute(Context context) { if (context.ForceRuntimesBuild) { if (osSupportsMonoBuild) { Log.InfoLine("Rebuilding Mono runtimes as requested"); return(false); } Log.InfoLine($"Forced Mono runtimes rebuild requested but rebuilding on {context.OS.Type} is currently not supported."); } string localPackagePath = Configurables.Paths.BundleArchivePath; Log.DebugLine($"Local bundle path: {localPackagePath}"); if (await Utilities.VerifyArchive(localPackagePath)) { Log.StatusLine("Xamarin.Android Bundle archive already downloaded and valid"); } else { if (!String.IsNullOrEmpty(context.XABundlePath)) { // User indicated they wanted to use a specific bundle that's supposed to be on disk. It's not (or // it's invalid) and that means we have no way of getting it - we can't download the default one // since that was not the intention behind overriding the location. Thus, we error out. Log.DebugLine($"Bundle directory from command line: {context.XABundlePath}"); throw new InvalidOperationException($"Xamarin.Android bundle indicated on the command line does not exist ({context.XABundlePath})"); } var bundleUrl = new Uri(BundleUriPrefix, BundleFileName); Log.StatusLine("Bundle URL: ", $"{bundleUrl}", tailColor: ConsoleColor.Cyan); HttpStatusCode status; bool success; ulong size; (success, size, status) = await Utilities.GetDownloadSizeWithStatus(bundleUrl); if (!success) { if (status == HttpStatusCode.NotFound) { if (osSupportsMonoBuild) { Log.StatusLine(" not found, will need to rebuild"); } else { Log.ErrorLine($" not found, rebuilding on {context.OS.Type} is not currently supported"); } return(false); } if (String.IsNullOrEmpty(bundle404Message)) { throw new InvalidOperationException($"Failed to access bundle at {bundleUrl} (HTTP status: {status})"); } else { throw new InvalidOperationException(bundle404Message); } } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {bundleUrl}", ConsoleColor.White); await Download(context, bundleUrl, localPackagePath, "Xamarin.Android Bundle", Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of Xamarin.Android Bundle from {bundleUrl} failed."); return(false); } } Log.StatusLine($"Unpacking bundle to {Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, Configurables.Paths.BundleInstallDir)}"); string tempDir = $"{Configurables.Paths.BundleInstallDir}-bundle.temp"; try { if (!await Utilities.Unpack(localPackagePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Log.WarningLine("Failed to unpack bundle, will need to rebuild"); return(false); } Log.DebugLine($"Moving unpacked bundle from {tempDir} to {Configurables.Paths.BundleInstallDir}"); Utilities.MoveDirectoryContentsRecursively(tempDir, Configurables.Paths.BundleInstallDir, resetFileTimestamp: true, ignoreDeletionErrors: true); } finally { Utilities.DeleteDirectorySilent(tempDir); } string managedRuntime = context.Properties.GetRequiredValue(KnownProperties.ManagedRuntime); bool haveManagedRuntime = !String.IsNullOrEmpty(managedRuntime); if (!await Utilities.BuildRemapRef(context, haveManagedRuntime, managedRuntime)) { return(false); } Utilities.PropagateXamarinAndroidCecil(context); if (String.IsNullOrEmpty(context.XABundleCopyDir)) { return(HaveEverything()); } string destPackagePath = Path.Combine(context.XABundleCopyDir, Path.GetFileName(localPackagePath)); Log.DebugLine($"Copy of the XA bundle was requested to be created at {destPackagePath}"); if (Utilities.FileExists(destPackagePath)) { Log.DebugLine("Bundle copy already exists"); return(HaveEverything()); } // Utilities.FileExists above will return `false` for a dangling symlink at `destPackagePath`, doesn't hurt // to remove it here just in case Utilities.DeleteFileSilent(destPackagePath); Utilities.CopyFile(localPackagePath, destPackagePath); return(HaveEverything()); bool HaveEverything() { bool ret = MonoRuntimesHelpers.AllBundleItemsPresent(new Runtimes()); if (!ret) { Log.Instance.StatusLine($"Some bundle files are missing, download/rebuild/reinstall forced"); } return(ret); } }
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); }
static string GetCrossRuntimeOutputSourcePath(Runtime runtime) { var crossRuntime = EnsureRuntimeType <MonoCrossRuntime> (runtime, "cross compilation"); return(Path.Combine(MonoRuntimesHelpers.GetRootDir(runtime), "bin", $"{crossRuntime.ExePrefix}mono-sgen{crossRuntime.ExeSuffix}")); }