コード例 #1
0
        private bool AddAotOrR2RRuntimePackage(AotPackageType packageType, Version normalizedTargetFrameworkVersion, List <ITaskItem> packagesToDownload)
        {
            var knownPacks = packageType == AotPackageType.Crossgen2 ? KnownCrossgen2Packs : KnownILCompilerPacks;
            var knownPack  = knownPacks.Where(pack =>
            {
                var packTargetFramework = NuGetFramework.Parse(pack.GetMetadata("TargetFramework"));
                return(packTargetFramework.Framework.Equals(TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) &&
                       NormalizeVersion(packTargetFramework.Version) == normalizedTargetFrameworkVersion);
            }).SingleOrDefault();

            if (knownPack == null)
            {
                return(false);
            }

            var packageName = packageType == AotPackageType.Crossgen2 ? "Crossgen2" : "ILCompiler";

            var packPattern = knownPack.GetMetadata(packageName + "PackNamePattern");
            var packVersion = knownPack.GetMetadata(packageName + "PackVersion");
            var packSupportedRuntimeIdentifiers = knownPack.GetMetadata(packageName + "RuntimeIdentifiers").Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            var runtimeGraph          = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(runtimeGraph, NETCoreSdkRuntimeIdentifier, packSupportedRuntimeIdentifiers, out bool wasInGraph);

            if (hostRuntimeIdentifier == null)
            {
                return(false);
            }

            var runtimePackName = packPattern.Replace("**RID**", hostRuntimeIdentifier);

            if (!string.IsNullOrEmpty(RuntimeFrameworkVersion))
            {
                packVersion = RuntimeFrameworkVersion;
            }

            // We need to download the runtime pack
            TaskItem runtimePackToDownload = new TaskItem(runtimePackName);

            runtimePackToDownload.SetMetadata(MetadataKeys.Version, packVersion);
            packagesToDownload.Add(runtimePackToDownload);

            var newItem = new TaskItem(runtimePackName);

            newItem.SetMetadata(MetadataKeys.NuGetPackageId, runtimePackName);
            newItem.SetMetadata(MetadataKeys.NuGetPackageVersion, packVersion);

            if (packageType == AotPackageType.Crossgen2)
            {
                Crossgen2Packs = new[] { newItem };
            }
            else
            {
                ILCompilerPacks = new[] { newItem };
            }

            return(true);
        }
コード例 #2
0
        private void ProcessRuntimeIdentifier(string runtimeIdentifier, KnownFrameworkReference knownFrameworkReference,
                                              string runtimeFrameworkVersion, HashSet <string> unrecognizedRuntimeIdentifiers,
                                              List <ITaskItem> unavailableRuntimePacks, List <ITaskItem> runtimePacks, List <ITaskItem> packagesToDownload, string isTrimmable)
        {
            var runtimeGraph = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var knownFrameworkReferenceRuntimePackRuntimeIdentifiers = knownFrameworkReference.RuntimePackRuntimeIdentifiers.Split(';');

            string runtimePackRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                runtimeIdentifier,
                knownFrameworkReferenceRuntimePackRuntimeIdentifiers,
                out bool wasInGraph);

            if (runtimePackRuntimeIdentifier == null)
            {
                if (wasInGraph)
                {
                    //  Report this as an error later, if necessary.  This is because we try to download
                    //  all available runtime packs in case there is a transitive reference to a shared
                    //  framework we don't directly reference.  But we don't want to immediately error out
                    //  here if a runtime pack that we might not need to reference isn't available for the
                    //  targeted RID (e.g. Microsoft.WindowsDesktop.App for a linux RID).
                    var unavailableRuntimePack = new TaskItem(knownFrameworkReference.Name);
                    unavailableRuntimePack.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimeIdentifier);
                    unavailableRuntimePacks.Add(unavailableRuntimePack);
                }
                else if (!unrecognizedRuntimeIdentifiers.Contains(runtimeIdentifier))
                {
                    //  NETSDK1083: The specified RuntimeIdentifier '{0}' is not recognized.
                    Log.LogError(Strings.RuntimeIdentifierNotRecognized, runtimeIdentifier);
                    unrecognizedRuntimeIdentifiers.Add(runtimeIdentifier);
                }
            }
            else
            {
                foreach (var runtimePackNamePattern in knownFrameworkReference.RuntimePackNamePatterns.Split(';'))
                {
                    string runtimePackName = runtimePackNamePattern.Replace("**RID**", runtimePackRuntimeIdentifier);

                    if (runtimePacks != null)
                    {
                        TaskItem runtimePackItem = new TaskItem(runtimePackName);
                        runtimePackItem.SetMetadata(MetadataKeys.PackageName, runtimePackName);
                        runtimePackItem.SetMetadata(MetadataKeys.PackageVersion, runtimeFrameworkVersion);
                        runtimePackItem.SetMetadata(MetadataKeys.FrameworkName, knownFrameworkReference.Name);
                        runtimePackItem.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimePackRuntimeIdentifier);
                        runtimePackItem.SetMetadata(MetadataKeys.IsTrimmable, isTrimmable);
                        runtimePackItem.SetMetadata(MetadataKeys.AvailableRuntimeIdentifiers, knownFrameworkReference.RuntimePackRuntimeIdentifiers);

                        runtimePacks.Add(runtimePackItem);
                    }

                    TaskItem packageToDownload = new TaskItem(runtimePackName);
                    packageToDownload.SetMetadata(MetadataKeys.Version, runtimeFrameworkVersion);

                    packagesToDownload.Add(packageToDownload);
                }
            }
        }
コード例 #3
0
        private string GetBestRuntimeIdentifier(string targetRuntimeIdentifier, string availableRuntimeIdentifiers, out bool wasInGraph)
        {
            var runtimeGraph          = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var bestRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(runtimeGraph,
                                                                      AppHostRuntimeIdentifier,
                                                                      availableRuntimeIdentifiers.Split(';'),
                                                                      out wasInGraph);

            return(bestRuntimeIdentifier);
        }
コード例 #4
0
        protected override void ExecuteCore()
        {
            // Get the list of runtime identifiers that we support and can target
            ITaskItem frameworkRef = KnownFrameworkReferences.Where(item => String.Compare(item.ItemSpec, "Microsoft.NETCore.App", true) == 0).SingleOrDefault();
            string    supportedRuntimeIdentifiers = frameworkRef == null ? null : frameworkRef.GetMetadata("RuntimePackRuntimeIdentifiers");

            // Get information on the runtime package used for the current target
            ITaskItem frameworkPack = RuntimePacks.Where(pack =>
                                                         pack.GetMetadata(MetadataKeys.FrameworkName).Equals("Microsoft.NETCore.App", StringComparison.OrdinalIgnoreCase))
                                      .SingleOrDefault();

            _runtimeIdentifier = frameworkPack == null ? null : frameworkPack.GetMetadata(MetadataKeys.RuntimeIdentifier);
            _packagePath       = frameworkPack == null ? null : frameworkPack.GetMetadata(MetadataKeys.PackageDirectory);

            var runtimeGraph      = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var supportedRIDsList = supportedRuntimeIdentifiers == null?Array.Empty <string>() : supportedRuntimeIdentifiers.Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            string hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                NETCoreSdkRuntimeIdentifier,
                supportedRIDsList,
                out bool wasInGraph);

            if (hostRuntimeIdentifier == null || _runtimeIdentifier == null || _packagePath == null)
            {
                Log.LogError(Strings.ReadyToRunNoValidRuntimePackageError);
                return;
            }

            if (!ExtractTargetPlatformAndArchitecture(_runtimeIdentifier, out string targetPlatform, out _targetArchitecture) ||
                !ExtractTargetPlatformAndArchitecture(hostRuntimeIdentifier, out string hostPlatform, out Architecture hostArchitecture) ||
                targetPlatform != hostPlatform)
            {
                Log.LogError(Strings.ReadyToRunTargetNotSupportedError);
                return;
            }

            if (!GetCrossgenComponentsPaths() || !File.Exists(_crossgenPath) || !File.Exists(_clrjitPath))
            {
                Log.LogError(Strings.ReadyToRunTargetNotSupportedError);
                return;
            }

            // Create tool task item
            CrossgenTool = new TaskItem(_crossgenPath);
            CrossgenTool.SetMetadata("JitPath", _clrjitPath);
            if (!String.IsNullOrEmpty(_diasymreaderPath))
            {
                CrossgenTool.SetMetadata("DiaSymReader", _diasymreaderPath);
            }

            // Process input lists of files
            ProcessInputFileList(FilesToPublish, _compileList, _symbolsCompileList, _r2rFiles);
        }
コード例 #5
0
        protected override void ExecuteCore()
        {
            _runtimePack             = GetNETCoreAppRuntimePack();
            _crossgen2Pack           = Crossgen2Packs?.FirstOrDefault();
            _targetRuntimeIdentifier = _runtimePack?.GetMetadata(MetadataKeys.RuntimeIdentifier);

            // Get the list of runtime identifiers that we support and can target
            ITaskItem targetingPack = GetNETCoreAppTargetingPack();
            string    supportedRuntimeIdentifiers = targetingPack?.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers);

            var runtimeGraph      = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var supportedRIDsList = supportedRuntimeIdentifiers == null?Array.Empty <string>() : supportedRuntimeIdentifiers.Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            _hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                NETCoreSdkRuntimeIdentifier,
                supportedRIDsList,
                out bool wasInGraph);

            if (_hostRuntimeIdentifier == null || _targetRuntimeIdentifier == null)
            {
                Log.LogError(Strings.ReadyToRunNoValidRuntimePackageError);
                return;
            }

            if (ReadyToRunUseCrossgen2)
            {
                if (!ValidateCrossgen2Support())
                {
                    return;
                }

                // NOTE: Crossgen2 does not yet currently support emitting native symbols, and until this feature
                // is implemented, we will use crossgen for it. This should go away in the future when crossgen2 supports the feature.
                if (EmitSymbols && !ValidateCrossgenSupport())
                {
                    return;
                }
            }
            else
            {
                if (!ValidateCrossgenSupport())
                {
                    return;
                }
            }

            // Future: check DiaSymReaderPath in the _crossgen2Tool info when crossgen2 starts supporting emitting native symbols
            bool hasValidDiaSymReaderLib = String.IsNullOrEmpty(_crossgenTool.DiaSymReaderPath) ? false : File.Exists(_crossgenTool.DiaSymReaderPath);

            // Process input lists of files
            ProcessInputFileList(Assemblies, _compileList, _symbolsCompileList, _r2rFiles, _r2rReferences, hasValidDiaSymReaderLib);
        }
コード例 #6
0
        protected override void ExecuteCore()
        {
            ITaskItem runtimePack = GetNETCoreAppRuntimePack();

            _runtimeIdentifier = runtimePack?.GetMetadata(MetadataKeys.RuntimeIdentifier);
            _packagePath       = runtimePack?.GetMetadata(MetadataKeys.PackageDirectory);

            // Get the list of runtime identifiers that we support and can target
            ITaskItem targetingPack = GetNETCoreAppTargetingPack();
            string    supportedRuntimeIdentifiers = targetingPack?.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers);

            var runtimeGraph      = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var supportedRIDsList = supportedRuntimeIdentifiers == null?Array.Empty <string>() : supportedRuntimeIdentifiers.Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            string hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                NETCoreSdkRuntimeIdentifier,
                supportedRIDsList,
                out bool wasInGraph);

            if (hostRuntimeIdentifier == null || _runtimeIdentifier == null || _packagePath == null)
            {
                Log.LogError(Strings.ReadyToRunNoValidRuntimePackageError);
                return;
            }

            if (!ExtractTargetPlatformAndArchitecture(_runtimeIdentifier, out string targetPlatform, out _targetArchitecture) ||
                !ExtractTargetPlatformAndArchitecture(hostRuntimeIdentifier, out string hostPlatform, out Architecture hostArchitecture) ||
                targetPlatform != hostPlatform)
            {
                Log.LogError(Strings.ReadyToRunTargetNotSupportedError);
                return;
            }

            if (!GetCrossgenComponentsPaths() || !File.Exists(_crossgenPath) || !File.Exists(_clrjitPath))
            {
                Log.LogError(Strings.ReadyToRunTargetNotSupportedError);
                return;
            }

            // Create tool task item
            CrossgenTool = new TaskItem(_crossgenPath);
            CrossgenTool.SetMetadata("JitPath", _clrjitPath);
            if (!String.IsNullOrEmpty(_diasymreaderPath))
            {
                CrossgenTool.SetMetadata("DiaSymReader", _diasymreaderPath);
            }

            // Process input lists of files
            ProcessInputFileList(Assemblies, _compileList, _symbolsCompileList, _r2rFiles, _r2rReferences);
        }
コード例 #7
0
        protected override void ExecuteCore()
        {
            _runtimePack             = GetNETCoreAppRuntimePack();
            _crossgen2Pack           = Crossgen2Packs?.FirstOrDefault();
            _targetRuntimeIdentifier = _runtimePack?.GetMetadata(MetadataKeys.RuntimeIdentifier);

            // Get the list of runtime identifiers that we support and can target
            ITaskItem targetingPack = GetNETCoreAppTargetingPack();
            string    supportedRuntimeIdentifiers = targetingPack?.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers);

            var runtimeGraph      = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var supportedRIDsList = supportedRuntimeIdentifiers == null?Array.Empty <string>() : supportedRuntimeIdentifiers.Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            _hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                NETCoreSdkRuntimeIdentifier,
                supportedRIDsList,
                out _);

            if (_hostRuntimeIdentifier == null || _targetRuntimeIdentifier == null)
            {
                Log.LogError(Strings.ReadyToRunNoValidRuntimePackageError);
                return;
            }

            if (ReadyToRunUseCrossgen2)
            {
                if (!ValidateCrossgen2Support())
                {
                    return;
                }

                // NOTE: Crossgen2 does not yet currently support emitting native symbols, and until this feature
                // is implemented, we will use crossgen for it. This should go away in the future when crossgen2 supports the feature.
                if (EmitSymbols && !ValidateCrossgenSupport())
                {
                    return;
                }
            }
            else
            {
                if (!ValidateCrossgenSupport())
                {
                    return;
                }
            }
        }
コード例 #8
0
        protected override void ExecuteCore()
        {
            _runtimePack             = GetNETCoreAppRuntimePack();
            _crossgen2Pack           = Crossgen2Packs?.FirstOrDefault();
            _targetRuntimeIdentifier = _runtimePack?.GetMetadata(MetadataKeys.RuntimeIdentifier);

            // Get the list of runtime identifiers that we support and can target
            ITaskItem targetingPack = GetNETCoreAppTargetingPack();
            string    supportedRuntimeIdentifiers = targetingPack?.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers);

            var runtimeGraph      = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var supportedRIDsList = supportedRuntimeIdentifiers == null?Array.Empty <string>() : supportedRuntimeIdentifiers.Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            _hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                NETCoreSdkRuntimeIdentifier,
                supportedRIDsList,
                out _);

            if (_hostRuntimeIdentifier == null || _targetRuntimeIdentifier == null)
            {
                Log.LogError(Strings.ReadyToRunNoValidRuntimePackageError);
                return;
            }

            if (ReadyToRunUseCrossgen2)
            {
                if (!ValidateCrossgen2Support())
                {
                    return;
                }

                // In .NET 5 Crossgen2 did not support emitting native symbols, so we use Crossgen to emit them
                if (_crossgen2IsVersion5 && EmitSymbols && !ValidateCrossgenSupport())
                {
                    return;
                }
            }
            else
            {
                if (!ValidateCrossgenSupport())
                {
                    return;
                }
            }
        }
コード例 #9
0
        private bool AddCrossgen2Package(Version normalizedTargetFrameworkVersion, List <ITaskItem> packagesToDownload)
        {
            var knownCrossgen2Pack = KnownCrossgen2Packs.Where(crossgen2Pack =>
            {
                var packTargetFramework = NuGetFramework.Parse(crossgen2Pack.GetMetadata("TargetFramework"));
                return(packTargetFramework.Framework.Equals(TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) &&
                       NormalizeVersion(packTargetFramework.Version) == normalizedTargetFrameworkVersion);
            }).SingleOrDefault();

            if (knownCrossgen2Pack == null)
            {
                return(false);
            }

            var crossgen2PackPattern = knownCrossgen2Pack.GetMetadata("Crossgen2PackNamePattern");
            var crossgen2PackVersion = knownCrossgen2Pack.GetMetadata("Crossgen2PackVersion");
            var crossgen2PackSupportedRuntimeIdentifiers = knownCrossgen2Pack.GetMetadata("Crossgen2RuntimeIdentifiers").Split(';');

            // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture
            var runtimeGraph          = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var hostRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(runtimeGraph, NETCoreSdkRuntimeIdentifier, crossgen2PackSupportedRuntimeIdentifiers, out bool wasInGraph);

            if (hostRuntimeIdentifier == null)
            {
                return(false);
            }

            var crossgen2PackName = crossgen2PackPattern.Replace("**RID**", hostRuntimeIdentifier);

            if (!string.IsNullOrEmpty(RuntimeFrameworkVersion))
            {
                crossgen2PackVersion = RuntimeFrameworkVersion;
            }

            TaskItem packageToDownload = new TaskItem(crossgen2PackName);

            packageToDownload.SetMetadata(MetadataKeys.Version, crossgen2PackVersion);
            packagesToDownload.Add(packageToDownload);

            Crossgen2Packs    = new ITaskItem[1];
            Crossgen2Packs[0] = new TaskItem(crossgen2PackName);
            Crossgen2Packs[0].SetMetadata(MetadataKeys.NuGetPackageId, crossgen2PackName);
            Crossgen2Packs[0].SetMetadata(MetadataKeys.NuGetPackageVersion, crossgen2PackVersion);

            return(true);
        }
コード例 #10
0
        private void ProcessRuntimeIdentifier(
            string runtimeIdentifier,
            KnownRuntimePack selectedRuntimePack,
            string runtimePackVersion,
            List <string> additionalFrameworkReferencesForRuntimePack,
            HashSet <string> unrecognizedRuntimeIdentifiers,
            List <ITaskItem> unavailableRuntimePacks,
            List <ITaskItem> runtimePacks,
            List <ITaskItem> packagesToDownload,
            string isTrimmable,
            bool addRuntimePackAndDownloadIfNecessary)
        {
            var runtimeGraph = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
            var knownFrameworkReferenceRuntimePackRuntimeIdentifiers = selectedRuntimePack.RuntimePackRuntimeIdentifiers.Split(';');

            string runtimePackRuntimeIdentifier = NuGetUtils.GetBestMatchingRid(
                runtimeGraph,
                runtimeIdentifier,
                knownFrameworkReferenceRuntimePackRuntimeIdentifiers,
                out bool wasInGraph);

            if (runtimePackRuntimeIdentifier == null)
            {
                if (wasInGraph)
                {
                    //  Report this as an error later, if necessary.  This is because we try to download
                    //  all available runtime packs in case there is a transitive reference to a shared
                    //  framework we don't directly reference.  But we don't want to immediately error out
                    //  here if a runtime pack that we might not need to reference isn't available for the
                    //  targeted RID (e.g. Microsoft.WindowsDesktop.App for a linux RID).
                    var unavailableRuntimePack = new TaskItem(selectedRuntimePack.Name);
                    unavailableRuntimePack.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimeIdentifier);
                    unavailableRuntimePacks.Add(unavailableRuntimePack);
                }
                else if (!unrecognizedRuntimeIdentifiers.Contains(runtimeIdentifier))
                {
                    //  NETSDK1083: The specified RuntimeIdentifier '{0}' is not recognized.
                    Log.LogError(Strings.RuntimeIdentifierNotRecognized, runtimeIdentifier);
                    unrecognizedRuntimeIdentifiers.Add(runtimeIdentifier);
                }
            }
            else if (addRuntimePackAndDownloadIfNecessary)
            {
                foreach (var runtimePackNamePattern in selectedRuntimePack.RuntimePackNamePatterns.Split(';'))
                {
                    string runtimePackName = runtimePackNamePattern.Replace("**RID**", runtimePackRuntimeIdentifier);

                    //  Look up runtimePackVersion from workload manifests if necessary
                    string resolvedRuntimePackVersion = GetResolvedPackVersion(runtimePackName, runtimePackVersion);

                    string runtimePackPath = GetPackPath(runtimePackName, resolvedRuntimePackVersion);

                    if (runtimePacks != null)
                    {
                        TaskItem runtimePackItem = new TaskItem(runtimePackName);
                        runtimePackItem.SetMetadata(MetadataKeys.NuGetPackageId, runtimePackName);
                        runtimePackItem.SetMetadata(MetadataKeys.NuGetPackageVersion, resolvedRuntimePackVersion);
                        runtimePackItem.SetMetadata(MetadataKeys.FrameworkName, selectedRuntimePack.Name);
                        runtimePackItem.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimePackRuntimeIdentifier);
                        runtimePackItem.SetMetadata(MetadataKeys.IsTrimmable, isTrimmable);

                        if (selectedRuntimePack.RuntimePackAlwaysCopyLocal)
                        {
                            runtimePackItem.SetMetadata(MetadataKeys.RuntimePackAlwaysCopyLocal, "true");
                        }

                        if (additionalFrameworkReferencesForRuntimePack != null)
                        {
                            runtimePackItem.SetMetadata(MetadataKeys.AdditionalFrameworkReferences, string.Join(";", additionalFrameworkReferencesForRuntimePack));
                        }

                        if (runtimePackPath != null)
                        {
                            runtimePackItem.SetMetadata(MetadataKeys.PackageDirectory, runtimePackPath);
                        }

                        runtimePacks.Add(runtimePackItem);
                    }

                    if (runtimePackPath == null)
                    {
                        TaskItem packageToDownload = new TaskItem(runtimePackName);
                        packageToDownload.SetMetadata(MetadataKeys.Version, resolvedRuntimePackVersion);

                        packagesToDownload.Add(packageToDownload);
                    }
                }
            }
        }