@@ -1675,6 +1675,7 @@ bool ProjMgrWorker::AddPackRequirements(ContextItem& context, const vector<PackI
16751675 }
16761676
16771677 // Process packages
1678+ map<VersionType, vector<PackItem>> packEntries;
16781679 for (const auto & packageEntry : packages) {
16791680 if (packageEntry.path .empty ()) {
16801681 // Store specified pack metadata
@@ -1696,28 +1697,11 @@ bool ProjMgrWorker::AddPackRequirements(ContextItem& context, const vector<PackI
16961697 } else {
16971698 // Not matching cbuild pack, add it unless a wildcard entry
16981699 PackageItem package;
1699- package.origin = packageEntry.origin ;
17001700 ProjMgrUtils::ConvertToPackInfo (packageEntry.pack , package.pack );
17011701
1702- // Resolve version range using installed/local packs
1702+ // Store pack entries in separated vectors for later resolution in the right order
17031703 if (!package.pack .name .empty () && !WildCards::IsWildcardPattern (package.pack .name )) {
1704- XmlItem attributes ({
1705- {" name" , package.pack .name },
1706- {" vendor" , package.pack .vendor },
1707- {" version" , ProjMgrUtils::ConvertToVersionRange (package.pack .version )},
1708- });
1709- auto pdsc = m_kernel->GetEffectivePdscFile (attributes);
1710- // Only remember the version of the pack if we had it installed or local
1711- // Will be used when serializing the cbuild-pack.yml file later
1712- if (!pdsc.first .empty ()) {
1713- context.userInputToResolvedPackIdMap [packageEntry.pack ].insert (pdsc.first );
1714- string installedVersion = RtePackage::VersionFromId (pdsc.first );
1715- package.pack .version = VersionCmp::RemoveVersionMeta (installedVersion);
1716- } else {
1717- // Remember that we had the user input, but it does not match any installed pack
1718- context.userInputToResolvedPackIdMap [packageEntry.pack ] = {};
1719- }
1720- context.packRequirements .push_back (package);
1704+ packEntries[ProjMgrUtils::GetVersionType (package.pack .version )].push_back (packageEntry);
17211705 }
17221706 }
17231707 } else {
@@ -1742,6 +1726,14 @@ bool ProjMgrWorker::AddPackRequirements(ContextItem& context, const vector<PackI
17421726 }
17431727 }
17441728
1729+ // Resolve pack entries in the order according to the version type: fixed, equivalent, compatible, minimum, any
1730+ for (const auto & versionType : { VersionType::FIXED, VersionType::EQUIVALENT, VersionType::COMPATIBLE,
1731+ VersionType::MINIMUM, VersionType::ANY }) {
1732+ for (const auto & packEntry : packEntries[versionType]) {
1733+ ResolvePackRequirement (context, packEntry);
1734+ }
1735+ }
1736+
17451737 // Add wildcard entries last so that they can be re-expanded if needed
17461738 for (const auto & packageEntry : packages) {
17471739 PackageItem package;
@@ -1766,6 +1758,44 @@ bool ProjMgrWorker::AddPackRequirements(ContextItem& context, const vector<PackI
17661758 return true ;
17671759}
17681760
1761+ void ProjMgrWorker::ResolvePackRequirement (ContextItem& context, const PackItem& packageEntry) {
1762+ // Resolve version range using installed/local packs
1763+ // Reuse already resolved pack when possible
1764+ PackageItem package;
1765+ ProjMgrUtils::ConvertToPackInfo (packageEntry.pack , package.pack );
1766+ string versionRange = ProjMgrUtils::ConvertToVersionRange (package.pack .version );
1767+ string bestMatch = RteUtils::EMPTY_STRING;
1768+ for (const auto & resolved : context.packRequirements ) {
1769+ if (resolved.pack .vendor == package.pack .vendor &&
1770+ resolved.pack .name == package.pack .name &&
1771+ VersionCmp::RangeCompare (resolved.pack .version , versionRange) == 0 &&
1772+ VersionCmp::Compare (resolved.pack .version , bestMatch) > 0 ) {
1773+ bestMatch = resolved.pack .version ;
1774+ }
1775+ }
1776+ if (!bestMatch.empty ()) {
1777+ versionRange = ProjMgrUtils::ConvertToVersionRange (bestMatch);
1778+ }
1779+ XmlItem attributes ({
1780+ {" name" , package.pack .name },
1781+ {" vendor" , package.pack .vendor },
1782+ {" version" , versionRange}
1783+ });
1784+ auto pdsc = m_kernel->GetEffectivePdscFile (attributes);
1785+ // Only remember the version of the pack if we had it installed or local
1786+ // Will be used when serializing the cbuild-pack.yml file later
1787+ if (!pdsc.first .empty ()) {
1788+ context.userInputToResolvedPackIdMap [packageEntry.pack ].insert (pdsc.first );
1789+ string installedVersion = RtePackage::VersionFromId (pdsc.first );
1790+ package.pack .version = VersionCmp::RemoveVersionMeta (installedVersion);
1791+ } else {
1792+ // Remember that we had the user input, but it does not match any installed pack
1793+ context.userInputToResolvedPackIdMap [packageEntry.pack ] = {};
1794+ }
1795+ package.origin = packageEntry.origin ;
1796+ context.packRequirements .push_back (package);
1797+ }
1798+
17691799bool ProjMgrWorker::ProcessToolchain (ContextItem& context) {
17701800 if (context.compiler .empty ()) {
17711801 // Use the default compiler if available
0 commit comments