async Task <bool> ConjureXamarinCecilAndRemapRef(Context context, bool haveManagedRuntime, string managedRuntime) { StatusStep(context, "Building remap-assembly-ref"); bool result = await Utilities.BuildRemapRef(context, haveManagedRuntime, managedRuntime, quiet : true); if (!result) { return(false); } var msbuild = new MSBuildRunner(context); StatusStep(context, "Building conjure-xamarin-android-cecil"); string projectPath = Path.Combine(Configurables.Paths.BuildToolsDir, "conjure-xamarin-android-cecil", "conjure-xamarin-android-cecil.csproj"); result = await msbuild.Run( projectPath : projectPath, logTag : "conjure-xamarin-android-cecil", binlogName : "build-conjure-xamarin-android-cecil" ); if (!result) { Log.ErrorLine("Failed to build conjure-xamarin-android-cecil"); return(false); } StatusStep(context, "Conjuring Xamarin.Android.Cecil and Xamari.Android.Cecil.Mdb"); string conjurer = Path.Combine(Configurables.Paths.BuildBinDir, "conjure-xamarin-android-cecil.exe"); string conjurerSourceDir = Configurables.Paths.MonoProfileToolsDir; string conjurerDestDir = Configurables.Paths.BuildBinDir; result = Utilities.RunCommand( haveManagedRuntime ? managedRuntime : conjurer, // command BuildPaths.XamarinAndroidSourceRoot, // workingDirectory true, // ignoreEmptyArguments // arguments haveManagedRuntime ? conjurer : String.Empty, Configurables.Paths.MonoProfileToolsDir, // source dir Configurables.Paths.BuildBinDir // destination dir ); StatusStep(context, "Re-signing Xamarin.Android.Cecil.dll"); var sn = new SnRunner(context); string snkPath = Path.Combine(BuildPaths.XamarinAndroidSourceRoot, "mono.snk"); string assemblyPath = Path.Combine(Configurables.Paths.BuildBinDir, "Xamarin.Android.Cecil.dll"); result = await sn.ReSign(snkPath, assemblyPath, $"sign-xamarin-android-cecil"); if (!result) { Log.ErrorLine("Failed to re-sign Xamarin.Android.Cecil.dll"); return(false); } Utilities.CreateDirectory(Configurables.Paths.NetCoreBinDir); Utilities.CopyFile(assemblyPath, Path.Combine(Configurables.Paths.NetCoreBinDir, "Xamarin.Android.Cecil.dll")); StatusStep(context, "Re-signing Xamarin.Android.Cecil.Mdb.dll"); assemblyPath = Path.Combine(Configurables.Paths.BuildBinDir, "Xamarin.Android.Cecil.Mdb.dll"); result = await sn.ReSign(snkPath, assemblyPath, $"sign-xamarin-android-cecil-mdb"); if (!result) { Log.ErrorLine("Failed to re-sign Xamarin.Android.Cecil.Mdb.dll"); return(false); } Utilities.CopyFile(assemblyPath, Path.Combine(Configurables.Paths.NetCoreBinDir, "Xamarin.Android.Cecil.Mdb.dll")); return(true); }
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 (File.Exists(localPackagePath)) { Log.StatusLine("Xamarin.Android Bundle archive already downloaded"); } 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); } }
async Task <bool> InstallRuntimes(Context context, List <Runtime> enabledRuntimes) { StatusStep(context, "Installing tests"); EnsureAllRuntimes(); foreach (TestAssembly tasm in allRuntimes !.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.Length > 0) { 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 || src.Length == 0 || dst.Length == 0) { 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 disabled, bool success)> ConfigureBuildAndInstall(Context context, string abiName) { if (!context.IsHostJitAbiEnabled(abiName)) { Log.DebugLine($"Windows target {abiName} disabled, not building libzip"); return(true, true); } bool sixtyFourBit = context.Is64BitMingwHostAbi(abiName); string sourceDir = context.Properties.GetRequiredValue(KnownProperties.LibZipSourceFullPath); string buildDir = Path.Combine(Configurables.Paths.BuildBinDir, $"libzip-windows-{abiName}"); string stampFile = Path.Combine(buildDir, $".build-{context.BuildInfo.FullLibZipHash}"); string outputPath; if (sixtyFourBit) { outputPath = Path.Combine("x64", LibZipName); } else { outputPath = LibZipName; } string sourceFile = Path.Combine(buildDir, "lib", LibZipName); string destFile = Path.Combine(Configurables.Paths.LibZipOutputPath, outputPath); bool needBuild; if (Utilities.FileExists(stampFile) && Utilities.FileExists(sourceFile)) { Log.DebugLine($"LibZip-Windows build stamp file exists: {stampFile}"); Log.StatusLine($"LibZip for {abiName} already built, skipping compilation"); needBuild = false; } else { needBuild = true; } if (needBuild) { Utilities.DeleteDirectorySilent(buildDir); Utilities.CreateDirectory(buildDir); List <string> arguments = GetCmakeArguments(context, buildDir, sixtyFourBit); string logTag = $"libzip-windows-{abiName}"; var cmake = new CMakeRunner(context); bool result = await cmake.Run( logTag : logTag, sourceDirectory : sourceDir, workingDirectory : buildDir, arguments : arguments ); if (!result) { return(false, false); } var ninja = new NinjaRunner(context); result = await ninja.Run( logTag : logTag, workingDirectory : buildDir ); if (!result) { return(false, false); } } Utilities.CopyFile(sourceFile, destFile); if (!File.Exists(destFile)) { Log.ErrorLine($"Failed to copy {sourceFile} to {destFile}"); return(false, false); } TouchStampFile(stampFile); return(false, true); }