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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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
                       ));
        }