void CleanupBeforeInstall() { foreach (string dir in allRuntimes.OutputDirectories) { Utilities.DeleteDirectorySilent(dir); } }
async Task <bool> DownloadAndUpackIfNeeded(Context context, string name, string customUrl, string localPath, string archiveFileName, string destinationDirectory) { if (File.Exists(localPath)) { Log.StatusLine($"{name} archive already downloaded"); } else { Utilities.DeleteFileSilent(localPath); var url = string.IsNullOrEmpty(customUrl) ? new Uri(Configurables.Urls.MonoArchive_BaseUri, archiveFileName) : new Uri(customUrl); Log.StatusLine($"Downloading {name} archive from {url}"); (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus(url); if (!success) { if (status == HttpStatusCode.NotFound) { Log.Info($"{name} archive URL not found"); } else { Log.Info($"Failed to obtain {name} archive size. HTTP status code: {status} ({(int)status})"); } Log.InfoLine(". Mono runtimes will be rebuilt"); return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {url}", ConsoleColor.White); await Download(context, url, localPath, $"{name} Archive", archiveFileName, downloadStatus); if (!File.Exists(localPath)) { Log.InfoLine($"Download of {name} archive from {url} failed, Mono will be rebuilt"); return(false); } } string tempDir = $"{destinationDirectory}.tmp"; if (!await Utilities.Unpack(localPath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Utilities.DeleteDirectorySilent(destinationDirectory); Log.WarningLine($"Failed to unpack {name} archive {localPath}, Mono will be rebuilt"); return(false); } Log.DebugLine($"Moving unpacked Mono archive from {tempDir} to {destinationDirectory}"); try { Utilities.MoveDirectoryContentsRecursively(tempDir, destinationDirectory, resetFileTimestamp: true); } finally { Utilities.DeleteDirectorySilent(tempDir); } return(true); }
bool InstallBCL(Context context) { string redistListDir = MonoRuntimesHelpers.BCLRedistListDestinationDir; foreach (KeyValuePair <BclFileTarget, string> kvp in MonoRuntimesHelpers.BCLDestinationDirs) { Utilities.CreateDirectory(kvp.Value); } foreach (KeyValuePair <BclFileTarget, string> kvp in MonoRuntimesHelpers.BCLFacadesDestinationDirs) { Utilities.CreateDirectory(kvp.Value); } Utilities.CreateDirectory(redistListDir); StatusStep(context, "Installing Android BCL assemblies"); InstallBCLFiles(allRuntimes.BclFilesToInstall); StatusStep(context, "Installing Designer Host BCL assemblies"); InstallBCLFiles(allRuntimes.DesignerHostBclFilesToInstall); StatusStep(context, "Installing Designer Windows BCL assemblies"); InstallBCLFiles(allRuntimes.DesignerWindowsBclFilesToInstall); Utilities.DeleteDirectorySilent(Configurables.Paths.BCLWindowsOutputDir); return(GenerateFrameworkList( context, MonoRuntimesHelpers.FrameworkListPath, MonoRuntimesHelpers.BCLDestinationDirs [BclFileTarget.Android], MonoRuntimesHelpers.BCLFacadesDestinationDirs [BclFileTarget.Android] )); }
protected override async Task <bool> Execute(Context context) { string corettoInstallDir = Configurables.Paths.CorrettoInstallDir; if (CorrettoExistsAndIsValid(corettoInstallDir, out string installedVersion)) { Log.Status("Corretto version "); Log.Status(installedVersion, ConsoleColor.Yellow); Log.StatusLine(" already installed in: ", corettoInstallDir, tailColor: ConsoleColor.Cyan); return(true); } Log.StatusLine($"Corretto JDK {Configurables.Defaults.CorrettoVersion} will be installed"); Uri correttoURL = Configurables.Urls.Corretto; if (correttoURL == null) { throw new InvalidOperationException("Corretto URL must not be null"); } string packageName = Path.GetFileName(correttoURL.LocalPath); string localPackagePath = Path.Combine(Configurables.Paths.CorrettoCacheDir, packageName); if (!await DownloadCorretto(context, localPackagePath, correttoURL)) { return(false); } string tempDir = $"{corettoInstallDir}.temp"; try { if (!await Utilities.Unpack(localPackagePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Log.ErrorLine("Failed to install Corretto"); return(false); } string rootDirName = GetArchiveRootDirectoryName(); string rootDir = Path.Combine(tempDir, rootDirName); Log.DebugLine($"{context.OS.Type} root directory name of Corretto OpenJDK package is: {rootDirName}"); if (!Directory.Exists(rootDir)) { Log.ErrorLine($"Corretto root directory not found after unpacking: {rootDirName}"); return(false); } Utilities.MoveDirectoryContentsRecursively(rootDir, corettoInstallDir); } finally { Utilities.DeleteDirectorySilent(tempDir); // Clean up zip after extraction if running on a hosted azure pipelines agent. if (context.IsRunningOnHostedAzureAgent) { Utilities.DeleteFileSilent(localPackagePath); } } return(true); }
protected override async Task <bool> Execute(Context context) { string hostDestinationDirectory = Configurables.Paths.HostBinutilsInstallDir; string windowsDestinationDirectory = Configurables.Paths.WindowsBinutilsInstallDir; bool hostHaveAll = HaveAllBinutils(hostDestinationDirectory); bool windowsHaveAll = HaveAllBinutils(windowsDestinationDirectory, ".exe"); if (hostHaveAll && windowsHaveAll) { Log.StatusLine("All Binutils are already installed"); return(true); } string packageName = Path.GetFileName(Configurables.Urls.BinutilsArchive.LocalPath); string localArchivePath = Path.Combine(Configurables.Paths.BinutilsCacheDir, packageName); if (!await DownloadBinutils(context, localArchivePath, Configurables.Urls.BinutilsArchive)) { return(false); } string tempDir = Path.Combine(Path.GetTempPath(), "xaprepare-binutils"); Utilities.DeleteDirectorySilent(tempDir); Utilities.CreateDirectory(tempDir); Log.DebugLine($"Unpacking {ProductName} archive {localArchivePath} into {tempDir}"); if (!await Utilities.Unpack(localArchivePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { return(false); } if (!hostHaveAll) { CopyToDestination(context, "Host", tempDir, hostDestinationDirectory, executableExtension: ExecutableExtension); } if (!windowsHaveAll) { CopyToDestination(context, "Windows", tempDir, windowsDestinationDirectory, "windows", ".exe"); } return(true); }
async Task <bool> Unpack(string fullArchivePath, string destinationDirectory, bool cleanDestinationBeforeUnpacking = false) { // https://bintray.com/jetbrains/intellij-jdk/download_file?file_path=jbrsdk-8u202-windows-x64-b1483.37.tar.gz // doesn't contain a single root directory! This causes the // "JetBrains root directory not found after unpacking" check to fail on Windows. // "Fix" things by setting destinationDirectory to contain RootDirName, allowing // the check to succeed. if (JdkVersion == Configurables.Defaults.JetBrainsOpenJDK8Version) { destinationDirectory = Path.Combine(destinationDirectory, RootDirName); } // On Windows we don't have Tar available and the Windows package is a .tar.gz // 7zip can unpack tar.gz but it's a two-stage process - first it decompresses the package, then it can be // invoked again to extract the actual tar contents. if (cleanDestinationBeforeUnpacking) { Utilities.DeleteDirectorySilent(destinationDirectory); } Utilities.CreateDirectory(destinationDirectory); var sevenZip = new SevenZipRunner(Context.Instance); Log.DebugLine($"Uncompressing {fullArchivePath} to {destinationDirectory}"); if (!await sevenZip.Extract(fullArchivePath, destinationDirectory)) { Log.DebugLine($"Failed to decompress {fullArchivePath}"); return(false); } string tarPath = Path.Combine(destinationDirectory, Path.GetFileNameWithoutExtension(fullArchivePath)); bool ret = await sevenZip.Extract(tarPath, destinationDirectory); Utilities.DeleteFileSilent(tarPath); if (!ret) { Log.DebugLine($"Failed to extract TAR contents from {tarPath}"); return(false); } return(true); }
async Task <bool> Unpack(string fullArchivePath, string destinationDirectory, bool cleanDestinationBeforeUnpacking = false) { if (cleanDestinationBeforeUnpacking) { Utilities.DeleteDirectorySilent(destinationDirectory); } Utilities.CreateDirectory(destinationDirectory); var sevenZip = new SevenZipRunner(Context.Instance); Log.DebugLine($"Uncompressing {fullArchivePath} to {destinationDirectory}"); if (!await sevenZip.Extract(fullArchivePath, destinationDirectory)) { Log.DebugLine($"Failed to decompress {fullArchivePath}"); return(false); } if (fullArchivePath.EndsWith("tar.gz", StringComparison.OrdinalIgnoreCase)) { // On Windows we don't have Tar available and the Windows package is a .tar.gz // 7zip can unpack tar.gz but it's a two-stage process - first it decompresses the package, then it can be // invoked again to extract the actual tar contents. string tarPath = Path.Combine(destinationDirectory, Path.GetFileNameWithoutExtension(fullArchivePath)); bool ret = await sevenZip.Extract(tarPath, destinationDirectory); Utilities.DeleteFileSilent(tarPath); if (!ret) { Log.DebugLine($"Failed to extract TAR contents from {tarPath}"); return(false); } } 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 (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) { string localPackagePath = Configurables.Paths.AntArchivePath; if (await Utilities.VerifyArchive(localPackagePath)) { Log.StatusLine("Ant archive already downloaded and valid"); } else { Uri antUrl = new Uri(Configurables.Urls.AntBaseUri, Configurables.Paths.AntArchiveName); Log.StatusLine("Ant URL: ", $"{antUrl}", tailColor: ConsoleColor.Cyan); HttpStatusCode status; bool success; ulong size; (success, size, status) = await Utilities.GetDownloadSizeWithStatus(antUrl); if (!success) { Log.ErrorLine($"Failed to access Ant at {antUrl} (HTTP status: {status})"); return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {antUrl}", ConsoleColor.White); await Download(context, antUrl, localPackagePath, "Apache Ant", Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of Xamarin.Android Bundle from {antUrl} failed."); return(false); } } Log.StatusLine($"Unpacking Ant to {Configurables.Paths.AntInstallDir}"); string tempDir = $"{Configurables.Paths.AntInstallDir}-ant.temp"; try { if (!await Utilities.Unpack(localPackagePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Log.ErrorLine("Failed to unpack Ant"); return(false); } Log.DebugLine($"Moving unpacked Ant from {tempDir} to {Configurables.Paths.AntInstallDir}"); // There should be just a single subdirectory List <string> subdirs = Directory.EnumerateDirectories(tempDir).ToList(); if (subdirs.Count > 1) { throw new InvalidOperationException($"Unexpected contents layout of the Ant archive - expected a single subdirectory, instead found {subdirs.Count}"); } Utilities.MoveDirectoryContentsRecursively(subdirs [0], Configurables.Paths.AntInstallDir); } finally { Utilities.DeleteDirectorySilent(tempDir); } return(true); }
protected override async Task <bool> Execute(Context context) { if (Directory.Exists(Configurables.Paths.OldOpenJDKInstallDir)) { Log.DebugLine($"Found old OpenJDK directory at {Configurables.Paths.OldOpenJDKInstallDir}, removing"); Utilities.DeleteDirectorySilent(Configurables.Paths.OldOpenJDKInstallDir); } string jdkInstallDir = JdkInstallDir; if (OpenJDKExistsAndIsValid(jdkInstallDir, out string installedVersion)) { Log.Status($"{ProductName} version "); Log.Status(installedVersion, ConsoleColor.Yellow); Log.StatusLine(" already installed in: ", jdkInstallDir, tailColor: ConsoleColor.Cyan); return(true); } Log.StatusLine($"{ProductName} {JdkVersion} r{JdkRelease} will be installed"); Uri jdkURL = JdkUrl; if (jdkURL == null) { throw new InvalidOperationException($"{ProductName} URL must not be null"); } string?packageName = GetPackageName(jdkURL); if (String.IsNullOrEmpty(packageName)) { Log.ErrorLine($"Unable to extract file name from {ProductName} URL"); return(false); } string localPackagePath = Path.Combine(JdkCacheDir, packageName); if (!await DownloadOpenJDK(context, localPackagePath, jdkURL)) { return(false); } string tempDir = $"{jdkInstallDir}.temp"; try { if (!await Unpack(localPackagePath, tempDir, cleanDestinationBeforeUnpacking: true)) { Log.ErrorLine($"Failed to install {ProductName}"); return(false); } string rootDir = Path.Combine(tempDir, RootDirName); if (!Directory.Exists(rootDir)) { Log.ErrorLine($"${ProductName} root directory not found after unpacking: {RootDirName}"); return(false); } MoveContents(rootDir, jdkInstallDir); File.WriteAllText(Path.Combine(jdkInstallDir, XAVersionInfoFile), $"{JdkRelease}{Environment.NewLine}"); } finally { Utilities.DeleteDirectorySilent(tempDir); // Clean up zip after extraction if running on a hosted azure pipelines agent. if (context.IsRunningOnHostedAzureAgent) { Utilities.DeleteFileSilent(localPackagePath); } } return(true); }
protected override async Task <bool> Execute(Context context) { string sdkRoot = context.Properties.GetRequiredValue(KnownProperties.AndroidSdkDirectory); string ndkRoot = context.Properties.GetRequiredValue(KnownProperties.AndroidNdkDirectory); string packageCacheDir = context.Properties.GetRequiredValue(KnownProperties.AndroidToolchainCacheDirectory); RefreshSdk = context.ComponentsToRefresh.HasFlag(RefreshableComponent.AndroidSDK); RefreshNdk = context.ComponentsToRefresh.HasFlag(RefreshableComponent.AndroidNDK); Log.StatusLine("Android SDK location: ", sdkRoot, tailColor: Log.DestinationColor); Log.StatusLine("Android NDK location: ", ndkRoot, tailColor: Log.DestinationColor); Log.DebugLine($"Toolchain cache directory: {packageCacheDir}"); var toolchain = new AndroidToolchain(); var toInstall = new List <AndroidPackage> (); toolchain.Components.ForEach(c => Check(context, packageCacheDir, sdkRoot, c, toInstall, 4)); if (toInstall.Count == 0) { return(GatherNDKInfo(context, ndkRoot)); } Log.MessageLine(); toInstall.ForEach(p => Log.DebugLine($"Missing Android component: {p.Component.Name}")); string tempDir = Path.Combine(context.Properties.GetRequiredValue(KnownProperties.AndroidToolchainDirectory), "temp"); Log.DebugLine($"Toolchain temporary directory: {tempDir}"); if (Directory.Exists(tempDir)) { Log.DebugLine("Temporary directory exists, cleaning it up"); Utilities.DeleteDirectorySilent(tempDir); } Directory.CreateDirectory(tempDir); Log.MessageLine("Installing missing components"); var toDownload = new List <AndroidPackage> (); toInstall.ForEach(c => CheckPackageStatus(context, packageCacheDir, c, toDownload)); if (toDownload.Count > 0) { ulong totalDownloadSize = 0; foreach (AndroidPackage pkg in toDownload) { Log.DebugLine($"Android component '{pkg.Component.Name}' will be downloaded from {pkg.Url}"); (bool success, ulong size) = await Utilities.GetDownloadSize(pkg.Url); if (!success) { continue; } totalDownloadSize += size; } toDownload.ForEach(p => Log.StatusLine($" {context.Characters.Link} {p.Url}", ConsoleColor.White)); DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, totalDownloadSize, context.InteractiveSession); await Task.WhenAll(toDownload.Select(p => Download(context, p.Url, p.LocalPackagePath, p.Component.Name, p.PackageName, downloadStatus))); } foreach (AndroidPackage p in toInstall) { await Unpack(context, tempDir, p); } if (!AcceptLicenses(context, sdkRoot)) { Log.ErrorLine("Failed to accept Android SDK licenses"); return(false); } return(GatherNDKInfo(context, ndkRoot)); }
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 = Path.Combine(Configurables.Paths.BundleArchivePath); 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. 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.Bundle_InstallDir}"); Utilities.MoveDirectoryContentsRecursively(tempDir, Configurables.Paths.BundleInstallDir, resetFileTimestamp: true); } finally { Utilities.DeleteDirectorySilent(tempDir); } return(true); }
protected override async Task <bool> Execute(Context context) { if (Directory.Exists(Configurables.Paths.OldOpenJDKInstallDir)) { Log.DebugLine($"Found old OpenJDK directory at {Configurables.Paths.OldOpenJDKInstallDir}, removing"); Utilities.DeleteDirectorySilent(Configurables.Paths.OldOpenJDKInstallDir); } string jdkInstallDir = JdkInstallDir; if (OpenJDKExistsAndIsValid(jdkInstallDir, out string installedVersion)) { Log.Status($"{ProductName} version "); Log.Status(installedVersion, ConsoleColor.Yellow); Log.StatusLine(" already installed in: ", jdkInstallDir, tailColor: ConsoleColor.Cyan); return(true); } Log.StatusLine($"JetBrains JDK {JdkVersion} r{JdkRelease} will be installed"); Uri jdkURL = JdkUrl; if (jdkURL == null) { throw new InvalidOperationException($"{ProductName} URL must not be null"); } string[] queryParams = jdkURL.Query.TrimStart('?').Split(QuerySeparator, StringSplitOptions.RemoveEmptyEntries); if (queryParams.Length == 0) { Log.ErrorLine($"Unable to extract file name from {ProductName} URL as it contains no query component"); return(false); } string?packageName = null; foreach (string p in queryParams) { if (!p.StartsWith(URLQueryFilePathField, StringComparison.Ordinal)) { continue; } int idx = p.IndexOf('='); if (idx < 0) { Log.DebugLine($"{ProductName} URL query field '{URLQueryFilePathField}' has no value, unable to detect file name"); break; } packageName = p.Substring(idx + 1).Trim(); } if (String.IsNullOrEmpty(packageName)) { Log.ErrorLine($"Unable to extract file name from {ProductName} URL"); return(false); } string localPackagePath = Path.Combine(JdkCacheDir, packageName); if (!await DownloadOpenJDK(context, localPackagePath, jdkURL)) { return(false); } string tempDir = $"{jdkInstallDir}.temp"; try { if (!await Unpack(localPackagePath, tempDir, cleanDestinationBeforeUnpacking: true)) { Log.ErrorLine($"Failed to install {ProductName}"); return(false); } string rootDir = Path.Combine(tempDir, RootDirName); if (!Directory.Exists(rootDir)) { Log.ErrorLine($"JetBrains root directory not found after unpacking: {RootDirName}"); return(false); } MoveContents(rootDir, jdkInstallDir); File.WriteAllText(Path.Combine(jdkInstallDir, XAVersionInfoFile), $"{JdkRelease}{Environment.NewLine}"); } finally { Utilities.DeleteDirectorySilent(tempDir); // Clean up zip after extraction if running on a hosted azure pipelines agent. if (context.IsRunningOnHostedAzureAgent) { Utilities.DeleteFileSilent(localPackagePath); } } return(true); }
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); }