Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions libs/rtemodel/include/RteKernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
/******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -241,21 +241,6 @@ class RteKernel
*/
void GetInstalledPdscFiles(std::map<std::string, std::string, RtePackageComparator>& pdscMap) const;

/**
* @brief getter for pdsc file determined by pack ID, pack path and pack attributes
* @param attributes pack attributes
* @param packId pack ID
* @return pair of pack ID to pdsc file
*/
std::pair<std::string, std::string> GetInstalledPdscFile(const XmlItem& attributes) const;

/**
* @brief getter for pdsc file pointed by the local repository index and determined by pack attributes, pack path and pack ID.
* @param attributes pack attributes
* @return pair of pack ID to pdsc file
*/
std::pair<std::string, std::string> GetLocalPdscFile(const XmlItem& attributes) const;

/**
* @brief get local or installed pdsc file corresponding to supplied pack ID, pack path and pack attributes
* @param attributes pack attributes
Expand Down
24 changes: 23 additions & 1 deletion libs/rtemodel/include/RtePackage.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
/******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -1333,11 +1333,33 @@ class RtePackRegistry
*/
const std::map<std::string, RtePackage*>& GetLoadedPacks() const { return m_loadedPacks;}

/**
* @brief get collection of effective pdscs
* @return const map of effective pdscs
*/
const std::map<std::string, std::string, RtePackageComparator>& GetPdscMap() const { return m_pdscMap; }

/**
* @brief set collection of effective pdscs
* @param map of effective pdscs
*/
void SetPdscMap(const std::map<std::string, std::string, RtePackageComparator>& pdscMap) { m_pdscMap = pdscMap; }

/**
* @brief clear collection of effective pdscs
*/
void ClearPdscMap() { m_pdscMap.clear(); }

protected:
/**
* @brief collection of loaded packs: absolute pdsc filename -> RtePackage*
*/
std::map<std::string, RtePackage*> m_loadedPacks;

/**
* @brief collection of effective pdscs: lower-case pack id -> absolute pdsc filename
*/
std::map<std::string, std::string, RtePackageComparator> m_pdscMap;
};


Expand Down
91 changes: 51 additions & 40 deletions libs/rtemodel/src/RteKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
/******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -80,6 +80,7 @@ bool RteKernel::SetCmsisPackRoot(const string& cmsisPackRoot)
if (m_cmsisPackRoot == cmsisPackRoot)
return false;
m_cmsisPackRoot = cmsisPackRoot;
RteFsUtils::NormalizePath(m_cmsisPackRoot);
return true;
}

Expand Down Expand Up @@ -413,12 +414,19 @@ bool RteKernel::GetEffectivePdscFilesAsMap(map<string, string, RtePackageCompara
if(cmsisPackRoot.empty()) {
return false;
}
// Get all installed files
RteKernel::GetInstalledPdscFiles(pdscMap);

// Overwrite entries with local pdsc files if any
XmlItem emptyAttributes;
GetLocalPdscFiles(emptyAttributes, pdscMap);
// Get pdsc map
RtePackRegistry* packRegistry = GetPackRegistry();
pdscMap = packRegistry->GetPdscMap();
if (pdscMap.empty()) {
// Get all installed files
GetInstalledPdscFiles(pdscMap);
// Overwrite entries with local pdsc files if any
XmlItem emptyAttributes;
GetLocalPdscFiles(emptyAttributes, pdscMap);
// Store pdsc map
packRegistry->SetPdscMap(pdscMap);
}

// purge entries if only latest are required
if(latest) {
Expand Down Expand Up @@ -482,51 +490,54 @@ void RteKernel::GetInstalledPdscFiles(std::map<std::string, std::string, RtePack
{
list<string> allFiles;
RteFsUtils::GetPackageDescriptionFiles(allFiles, GetCmsisPackRoot(), 3);
for(auto& f : allFiles) {
string id = RtePackage::PackIdFromPath(f);
for (auto& f : allFiles) {
string id = RteUtils::ToLower(RtePackage::PackIdFromPath(f));
pdscMap[id] = f;
}
}

pair<string, string> RteKernel::GetInstalledPdscFile(const XmlItem& attributes) const
pair<string, string> RteKernel::GetEffectivePdscFile(const XmlItem& attributes) const
{
const string& name = attributes.GetAttribute("name");
const string& vendor = attributes.GetAttribute("vendor");
if(!name.empty() && !vendor.empty()) {
string path = GetCmsisPackRoot() + '/' + vendor + '/' + name;
const string& versionRange = attributes.GetAttribute("version");
string installedVersion = RteFsUtils::GetInstalledPackVersion(path, versionRange);
if(!installedVersion.empty()) {
string packId = RtePackage::ComposePackageID(vendor, name, installedVersion);
path += '/' + installedVersion + '/' + vendor + '.' + name + ".pdsc";
return make_pair(packId, path);
if (!name.empty() && !vendor.empty()) {
const string& packId = RteUtils::ToLower(vendor + RteConstants::SUFFIX_PACK_VENDOR + name);
// get map of effective pdscs with lower-case ids
map<string, string, RtePackageComparator> pdscMap;
GetEffectivePdscFilesAsMap(pdscMap, false);
StrPairVec pdscs;
// get subset of pdscs for the searched packId
for (const auto& pdsc : pdscMap) {
if (RtePackage::CommonIdFromId(pdsc.first) == packId) {
pdscs.push_back(pdsc);
}
}
if (!pdscs.empty()) {
const string& versionRange = attributes.GetAttribute("version");
StrPair effectivePdsc;
if (versionRange.empty()) {
// required version range is empty = get greatest effective version
effectivePdsc = *pdscs.begin();
} else {
for (const auto& pdsc : pdscs) {
// find the greatest effective version in the required version range
if (VersionCmp::RangeCompare(RtePackage::VersionFromId(pdsc.first), versionRange) == 0) {
effectivePdsc = pdsc;
break;
}
}
}
auto& id = effectivePdsc.first;
if (!id.empty()) {
// preserve name::vendor as given in input attributes
id = RtePackage::ComposePackageID(vendor, name, RtePackage::VersionFromId(id));
return effectivePdsc;
}
}
}
return make_pair(RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING);
}

pair<string, string> RteKernel::GetLocalPdscFile(const XmlItem& attributes) const
{
map<string, string, RtePackageComparator> pdscMap;
if(!attributes.IsEmpty() && GetLocalPdscFiles(attributes, pdscMap)) {
return *pdscMap.begin();
}
return make_pair(RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING);
}

pair<string, string> RteKernel::GetEffectivePdscFile(const XmlItem& attributes) const
{
auto localPdsc = GetLocalPdscFile(attributes);
auto installedPdsc = GetInstalledPdscFile(attributes);

string localVersion = RtePackage::VersionFromId(localPdsc.first);
string installedVersion = RtePackage::VersionFromId(installedPdsc.first);
if(!localVersion.empty() && VersionCmp::Compare(localVersion, installedVersion) >= 0) {
return localPdsc;
}
return installedPdsc;
}


pair<string, string> RteKernel::GetPdscFileFromPath(const XmlItem& attributes, const string& prjPath) const
{
Expand Down Expand Up @@ -579,7 +590,7 @@ bool RteKernel::GetLocalPdscFiles(const XmlItem& attr, std::map<std::string, std
if(pack) {
const string& version = pack->GetVersionString();
if(versionRange.empty() || VersionCmp::RangeCompare(version, versionRange) == 0) {
pdscMap[pack->GetID()] = localPdscFile;
pdscMap[RteUtils::ToLower(pack->GetID())] = localPdscFile;
found = true;
}
}
Expand Down
55 changes: 4 additions & 51 deletions libs/rtemodel/test/src/RteModelTest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -725,60 +725,13 @@ TEST_F(RteModelPrjTest, LoadCprjConfigVer) {

}

TEST_F(RteModelPrjTest, GetLocalPdscFile) {
RteKernelSlim rteKernel;
rteKernel.SetCmsisPackRoot(packsDir);

XmlItem attributes;
auto pdsc = rteKernel.GetLocalPdscFile(attributes);
EXPECT_TRUE(pdsc.first.empty());
EXPECT_TRUE(pdsc.second.empty());

attributes.AddAttribute("name", "LocalPack");
attributes.AddAttribute("vendor", "LocalVendor");
pdsc = rteKernel.GetLocalPdscFile(attributes);

// check returned packId
EXPECT_EQ(pdsc.first, "LocalVendor::LocalPack@1.0.1");

// check returned pdsc
const string expectedPdsc =
RteFsUtils::MakePathCanonical(RteFsUtils::AbsolutePath(localPacks + "/L/LocalVendor.LocalPack.pdsc").generic_string());
error_code ec;
EXPECT_TRUE(fs::equivalent(pdsc.second, expectedPdsc, ec));
}

TEST_F(RteModelPrjTest, GetInstalledPdscFile) {
RteKernelSlim rteKernel;
rteKernel.SetCmsisPackRoot(packsDir);

XmlItem attributes;
auto pdsc = rteKernel.GetInstalledPdscFile(attributes);
EXPECT_TRUE(pdsc.first.empty());
EXPECT_TRUE(pdsc.second.empty());

attributes.AddAttribute("name", "RteTestRequired");
attributes.AddAttribute("vendor", "ARM");
pdsc = rteKernel.GetInstalledPdscFile(attributes);

// check returned packId
EXPECT_EQ(pdsc.first, "ARM::RteTestRequired@1.0.0");

// check returned pdsc
const string expectedPdsc =
RteFsUtils::MakePathCanonical(RteFsUtils::AbsolutePath(packsDir +
"/ARM/RteTestRequired/1.0.0/ARM.RteTestRequired.pdsc").generic_string());
error_code ec;
EXPECT_TRUE(fs::equivalent(pdsc.second, expectedPdsc, ec));
}

TEST_F(RteModelPrjTest, GetEffectivePdscFile) {
RteKernelSlim rteKernel;
rteKernel.SetCmsisPackRoot(packsDir);
XmlItem attributes;

// nothing has found for empty attributes
auto pdsc = rteKernel.GetInstalledPdscFile(attributes);
auto pdsc = rteKernel.GetEffectivePdscFile(attributes);
EXPECT_TRUE(pdsc.first.empty());
EXPECT_TRUE(pdsc.second.empty());

Expand Down Expand Up @@ -821,14 +774,14 @@ TEST_F(RteModelPrjTest, GetEffectivePdscFile) {

// outside range
attributes.AddAttribute("version", "2.0.0");
pdsc = rteKernel.GetInstalledPdscFile(attributes);
pdsc = rteKernel.GetEffectivePdscFile(attributes);
EXPECT_TRUE(pdsc.first.empty());
EXPECT_TRUE(pdsc.second.empty());

// unknown name
attributes.RemoveAttribute("version");
attributes.AddAttribute("name", "Unknown");
pdsc = rteKernel.GetInstalledPdscFile(attributes);
pdsc = rteKernel.GetEffectivePdscFile(attributes);
EXPECT_TRUE(pdsc.first.empty());
EXPECT_TRUE(pdsc.second.empty());
}
Expand Down
1 change: 1 addition & 0 deletions tools/projmgr/include/ProjMgrWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,7 @@ class ProjMgrWorker {
bool HasCompatibleEnvironment(const Collection<RteItem*>& environments, const StrVec& filter);
template<class T> bool CheckFilter(const std::string& filter, const T& item);
void ResolvePackRequirement(ContextItem& context, const PackItem& packEntry);
void FormatResolvedPackIds();
};

#endif // PROJMGRWORKER_H
28 changes: 27 additions & 1 deletion tools/projmgr/src/ProjMgrWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,9 @@ string ProjMgrWorker::GetPackRoot() {

bool ProjMgrWorker::InitializeModel() {
if(m_kernel) {
return true; // already initialized
// kernel is already initialized, clear pdsc map
m_kernel->GetPackRegistry()->ClearPdscMap();
return true;
}
m_packRoot = GetPackRoot();
m_kernel = ProjMgrKernel::Get();
Expand Down Expand Up @@ -527,6 +529,8 @@ bool ProjMgrWorker::LoadAllRelevantPacks() {
ProjMgrLogger::Get().Error("failed to load and insert packs");
return CheckRteErrors();
}
// Required packs are loaded: update pack-ids in 'userInputToResolvedPackIdMap'
FormatResolvedPackIds();
if (!m_model->Validate()) {
RtePrintErrorVistior visitor(m_kernel->GetCallback());
m_model->AcceptVisitor(&visitor);
Expand Down Expand Up @@ -5949,3 +5953,25 @@ bool ProjMgrWorker::ElaborateVariablesConfigurations() {
}
return configurationFound;
}

void ProjMgrWorker::FormatResolvedPackIds() {
StrMap realPackIds;
for (const auto& loadedPack : m_loadedPacks) {
const auto& realPackId = loadedPack->GetPackageID();
realPackIds[RteUtils::ToLower(realPackId)] = realPackId;
}
for (auto& contextName : m_selectedContexts) {
auto& contextItem = m_contexts[contextName];
for (auto& [_, resolvedPackIds] : contextItem.userInputToResolvedPackIdMap) {
StrSet formattedPackIds;
for (auto& resolvedPackId : resolvedPackIds) {
const auto& lowerCasePackId = RteUtils::ToLower(resolvedPackId);
const auto& packId = realPackIds.find(lowerCasePackId) != realPackIds.end() ?
realPackIds.at(lowerCasePackId) : resolvedPackId;
formattedPackIds.insert(packId);
}
resolvedPackIds = formattedPackIds;
}
}
}

18 changes: 17 additions & 1 deletion tools/projmgr/test/src/ProjMgrTestEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ void ProjMgrTestEnv::SetUp() {
RteFsUtils::CreateDirectories(destInvalidPacks);
fs::copy(fs::path(srcInvalidPacks), fs::path(destInvalidPacks), fs::copy_options::recursive, ec);

// copy PDSCs for case insensitiveness check
string packsCaseInsensitive = testinput_folder + "/packs-case-insensitive";
if (RteFsUtils::Exists(packsCaseInsensitive)) {
RteFsUtils::RemoveDir(packsCaseInsensitive);
}
RteFsUtils::CopyFileExAutoRetry(testcmsispack_folder + "/ARM/RteTest_DFP/0.2.0/ARM.RteTest_DFP.pdsc",
packsCaseInsensitive + "/Arm/RteTest_dfp/0.2.0/arm.rtetest_DFP.pdsc");
RteFsUtils::CopyFileExAutoRetry(testcmsispack_folder + "/ARM/RteTest_DFP/0.1.1/ARM.RteTest_DFP.pdsc",
packsCaseInsensitive + "/ARM/RTETEST_DFP/0.1.1/Arm.RTETEST_DFP.pdsc");

CrossPlatformUtils::SetEnv("CMSIS_PACK_ROOT", testcmsispack_folder);

// create dummy cmsis compiler root
Expand Down Expand Up @@ -231,7 +241,13 @@ std::map<std::string, std::string, RtePackageComparator> ProjMgrTestEnv::GetEffe
std::map<std::string, std::string, RtePackageComparator> pdscMap;
RteKernelSlim rteKernel;
rteKernel.SetCmsisPackRoot(GetCmsisPackRoot());
rteKernel.GetEffectivePdscFilesAsMap(pdscMap, bLatestsOnly);
std::list<std::string> pdscFiles;
std::list<RtePackage*> packs;
rteKernel.GetEffectivePdscFiles(pdscFiles, bLatestsOnly);
rteKernel.LoadAndInsertPacks(packs, pdscFiles);
for (const auto& pack : packs) {
pdscMap[pack->GetID()] = pack->GetPackageFileName();
}
return pdscMap;
}

Expand Down
Loading
Loading