Exemple #1
0
        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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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);
        }