Skip to content

Commit

Permalink
enforced component selection using extended component identifier #774 (
Browse files Browse the repository at this point in the history
…#516) (#850)

* enforced component selection using extended component identifier #774

Co-authored-by: Evgueni Driouk <evgueni.driouk@arm.com>
  • Loading branch information
grasci-arm and Evgueni Driouk committed Apr 20, 2023
1 parent 886ee78 commit 6330bd1
Show file tree
Hide file tree
Showing 24 changed files with 485 additions and 179 deletions.
68 changes: 41 additions & 27 deletions libs/rtemodel/include/RteItem.h
Expand Up @@ -520,45 +520,59 @@ class RteItem : public XmlTreeItem<RteItem>
virtual bool MatchesHost() const;

/**
* @brief check if item provides data matching supplied host type
* @param hostType host type to match, empty to match current host
* @return true if item data matches host platform
*/
* @brief check if item provides data matching supplied host type
* @param hostType host type to match, empty to match current host
* @return true if item data matches host platform
*/
virtual bool MatchesHost(const std::string& hostType) const;

/**
* @brief collect components matching supplied attributes
* @param item reference to RteItem containing component attributes to match
* @param components container for components
* @return pointer to first component found if any, null otherwise
*/
virtual RteComponent* FindComponents(const RteItem& item, std::list<RteComponent*>& components) const;

/**
* @brief checks if the item contains all attributes matching those in the supplied map
* @param attributes map of key-value pairs to match against component attributes
* @return true if the item has all attributes found in the supplied map
*/
/**
* @brief checks if the item contains all attributes matching those in the supplied map
* @param item reference to an RteItem containing component attributes to match
* @return true if the item has all attributes found in the supplied map
*/
virtual bool MatchComponent(const RteItem& item) const;

/**
* @brief checks if the item contains all attributes matching those in the supplied map
* @param attributes map of key-value pairs to match against component attributes
* @return true if the item has all attributes found in the supplied map
*/
virtual bool MatchComponentAttributes(const std::map<std::string, std::string>& attributes) const;

/**
* @brief check if the item matches supplied API attributes
* @param attributes collection of 'C' (API) attributes
* @return true if the item matches supplied API attributes
*/
/**
* @brief check if the item matches supplied API attributes
* @param attributes collection of 'C' (API) attributes
* @return true if the item matches supplied API attributes
*/
virtual bool MatchApiAttributes(const std::map<std::string, std::string>& attributes) const;

/**
* @brief check if given collection of attributes contains the same values for "Dname", "Pname" and "Dvendor"
* @param attributes collection of attributes
* @return true if collection of attributes contains the same values for "Dname", "Pname" and "Dvendor"
*/
/**
* @brief check if given collection of attributes contains the same values for "Dname", "Pname" and "Dvendor"
* @param attributes collection of attributes
* @return true if collection of attributes contains the same values for "Dname", "Pname" and "Dvendor"
*/
virtual bool MatchDevice(const std::map<std::string, std::string>& attributes) const;

/**
* @brief check if the item matches all supplied 'D' attributes stored in the instance
* @param attributes collection of 'D' device attributes
* @return true if given list contains all device attributes stored in the instance
*/
/**
* @brief check if the item matches all supplied 'D' attributes stored in the instance
* @param attributes collection of 'D' device attributes
* @return true if given list contains all device attributes stored in the instance
*/
virtual bool MatchDeviceAttributes(const std::map<std::string, std::string>& attributes) const;

/**
* @brief check if attribute "maxInstances" is not empty
* @return true if attribute "maxInstances" is not empty
*/
* @brief check if attribute "maxInstances" is not empty
* @return true if attribute "maxInstances" is not empty
*/
virtual bool HasMaxInstances() const;
/**
* @brief determine value of attribute "maxInstances" as integer, default value is 1
Expand Down
8 changes: 8 additions & 0 deletions libs/rtemodel/include/RteModel.h
Expand Up @@ -190,6 +190,14 @@ class RteModel : public RteItem
*/
RteBoard* FindCompatibleBoard(const std::string& displayName, RteDeviceItem* device, bool bOnlyMounted = false) const;

/**
* @brief collect components matching supplied attributes
* @param item reference to RteItem containing component attributes to match
* @param components container for components
* @return pointer to first component found if any, null otherwise
*/
RteComponent* FindComponents(const RteItem& item, std::list<RteComponent*>& components) const override;

/**
* @brief check if this object has no children
* @return true if this object has no children
Expand Down
8 changes: 8 additions & 0 deletions libs/rtemodel/include/RtePackage.h
Expand Up @@ -223,6 +223,14 @@ class RtePackage : public RteRootItem
*/
RteItem* GetComponents() const { return m_components; }

/**
* @brief collect components matching supplied attributes
* @param item reference to RteItem containing component attributes to match
* @param components container for components
* @return pointer to first component found if any, null otherwise
*/
RteComponent* FindComponents(const RteItem& item, std::list<RteComponent*>& components) const override;

/**
* @brief get <apis> element
* @return pointer to RteItem representing container for APIs
Expand Down
46 changes: 22 additions & 24 deletions libs/rtemodel/src/RteComponent.cpp
Expand Up @@ -176,27 +176,6 @@ const string& RteComponent::GetCbundleName() const

string RteComponent::ConstructID()
{
RtePackage* pack = GetPackage();
if (pack && pack->IsGenerated()) {
SetAttribute("generated", "1");
}

// inherit attributes from bundle
if (GetAttribute("Cclass").empty()) {
AddAttribute("Cclass", GetCclassName());
}
// ensure Cvendor Cversion and Cbundle for components, not for apis
if (!IsApi()) {
if (m_parent && GetAttribute("Cbundle").empty()) {
AddAttribute("Cbundle", m_parent->GetCbundleName(), false); // insert bundle ID if not empty
}
if (GetAttribute("Cvendor").empty()) {
AddAttribute("Cvendor", GetVendorString());
}
if (GetAttribute("Cversion").empty()) {
AddAttribute("Cversion", GetVersionString(), false);
}
}
return GetComponentUniqueID(true);
};

Expand Down Expand Up @@ -265,10 +244,29 @@ RteItem* RteComponent::CreateItem(const std::string& tag)

void RteComponent::Construct()
{
RteItem::Construct();
if (!HasAttribute("generator")) {
AddAttribute("generator", GetGeneratorName(), false);
RtePackage* pack = GetPackage();
if (pack && pack->IsGenerated()) {
SetAttribute("generated", "1");
}

// inherit attributes from bundle
if (GetAttribute("Cclass").empty()) {
AddAttribute("Cclass", GetCclassName());
}
// ensure Cvendor Cversion and Cbundle for components, not for apis
if (!IsApi()) {
if (m_parent && GetAttribute("Cbundle").empty()) {
AddAttribute("Cbundle", m_parent->GetCbundleName(), false); // insert bundle ID if not empty
}
if (GetAttribute("Cvendor").empty()) {
AddAttribute("Cvendor", GetVendorString());
}
if (GetAttribute("Cversion").empty()) {
AddAttribute("Cversion", GetVersionString(), false);
}
}

RteItem::Construct();
}


Expand Down
2 changes: 1 addition & 1 deletion libs/rtemodel/src/RteCprjProject.cpp
Expand Up @@ -220,8 +220,8 @@ void RteCprjProject::ApplySelectedComponentsToCprjFile() {
item->AddAttributes(ci->GetAttributes(), true); // take over attributes
if (ci->GetVersionMatchMode(GetActiveTargetName()) != VersionCmp::MatchMode::FIXED_VERSION) {
item->RemoveAttribute("Cversion"); // specify version only if fixed
item->RemoveAttribute("condition"); // remove generally attribute "condition"
}
item->RemoveAttribute("condition"); // remove generally attribute "condition"
// TODO: add build flags to component
ApplyComponentFilesToCprjFile(ci, item); // add files to component
cprjComponents->AddItem(item); // add component to cprj file
Expand Down
31 changes: 25 additions & 6 deletions libs/rtemodel/src/RteItem.cpp
Expand Up @@ -197,7 +197,6 @@ string RteItem::ConstructComponentID(const string& prefix, bool bVariant, bool b
string id = prefix;
id += "::";
id += ConcatenateCclassCgroupCsub(delimiter);

if (bCondition && !GetConditionID().empty())
{
id += "(";
Expand Down Expand Up @@ -461,12 +460,10 @@ string RteItem::GetTaxonomyDescriptionID(const XmlItem& attributes)
string RteItem::GetPackageID(bool withVersion) const
{
RtePackage* package = GetPackage();
if (package == this) {
if (!package || package == this) {
return RtePackage::GetPackageIDfromAttributes(*this, withVersion);
} else if (package) {
return package->GetPackageID(withVersion);
}
return EMPTY_STRING;
return package->GetPackageID(withVersion);
}

string RteItem::GetPackagePath(bool withVersion) const
Expand Down Expand Up @@ -506,6 +503,28 @@ bool RteItem::MatchesHost(const string& hostType) const
host == (hostType.empty() ? CrossPlatformUtils::GetHostType() : hostType));
}

RteComponent* RteItem::FindComponents(const RteItem& item, list<RteComponent*>& components) const
{
for (auto child : GetChildren()) {
if (child->GetTag() == "bundle" && item.GetCbundleName() == child->GetCbundleName()) {
return child->FindComponents(item, components);
}
RteComponent* c = dynamic_cast<RteComponent*>(child);
if (c && c->MatchComponent(item)) {
components.push_back(c);
}
}
return components.empty() ? nullptr : *(components.begin());
}

bool RteItem::MatchComponent(const RteItem& item) const
{
if (!item.GetConditionID().empty() && item.GetConditionID() != GetConditionID()) {
return false;
}
return MatchComponentAttributes(item.GetAttributes());
}


bool RteItem::MatchComponentAttributes(const map<string, string>& attributes) const
{
Expand Down Expand Up @@ -868,7 +887,7 @@ bool RteItem::Validate()
m_bValid = true; // assume valid
const string& conditionId = GetConditionID();
if (!conditionId.empty()) {
if (!GetCondition(conditionId)) {
if (!GetCondition(conditionId) && GetPackage()) {
string msg = " condition '";
msg += conditionId;
msg += "' not found";
Expand Down
13 changes: 13 additions & 0 deletions libs/rtemodel/src/RteModel.cpp
Expand Up @@ -202,6 +202,19 @@ RteBoard* RteModel::FindCompatibleBoard(const string& displayName, RteDeviceItem
return nullptr;
}

RteComponent* RteModel::FindComponents(const RteItem& item, std::list<RteComponent*>& components) const
{
const string packId = item.GetPackageID(true);
if (!packId.empty()) {
RtePackage* pack = GetAvailablePackage(item.GetPackageID(true));
return pack ? pack->FindComponents(item, components) : nullptr;
}
for (auto [key, pack] : m_packages) {
pack->FindComponents(item, components);
}
return components.empty()? nullptr : *(components.begin());
}

RteComponent* RteModel::GetComponent(const string& uniqueID) const
{
// look in the APIs
Expand Down
7 changes: 7 additions & 0 deletions libs/rtemodel/src/RtePackage.cpp
Expand Up @@ -481,6 +481,13 @@ string RtePackage::GetDownloadUrl(bool withVersion, const char* extension) const
return url;
}

RteComponent* RtePackage::FindComponents(const RteItem& item, list<RteComponent*>& components) const
{
if (item.IsApi()) {
return m_apis ? m_apis->FindComponents(item, components) : nullptr;
}
return m_components ? m_components->FindComponents(item, components) : nullptr;
}

RteApi* RtePackage::GetApi(const map<string, string>& componentAttributes) const
{
Expand Down
2 changes: 1 addition & 1 deletion libs/rtemodel/src/RteProject.cpp
Expand Up @@ -286,6 +286,7 @@ void RteProject::AddCprjComponents(const list<RteItem*>& selItems, RteTarget* ta
RteComponentInstance* ci = AddCprjComponent(item, target);
RteComponent* component = ci->GetResolvedComponent(target->GetName());
int instances = item->GetAttributeAsInt("instances", 1);
target->SetComponentUsed(ci, instances);
if (component) {
target->SelectComponent(component, instances, false, true);
const list<RteItem*>& files = item->GetChildren();
Expand All @@ -302,7 +303,6 @@ void RteProject::AddCprjComponents(const list<RteItem*>& selItems, RteTarget* ta
configFileVersions[name] = version;
}
} else {
target->SetComponentUsed(ci, instances);
unresolvedComponents.insert(ci);
}
}
Expand Down
6 changes: 4 additions & 2 deletions libs/rtemodel/src/RteTarget.cpp
Expand Up @@ -254,8 +254,6 @@ bool RteTarget::SelectComponent(RteComponent* c, int count, bool bUpdateDependen
int maxInst = c->GetMaxInstances();
if (count > maxInst)
count = maxInst;
if (!IsComponentFiltered(c))
count = 0;

RteComponentAggregate* a = GetComponentAggregate(c);
if (!a)
Expand Down Expand Up @@ -1554,6 +1552,10 @@ RteComponent* RteTarget::ResolveComponent(RteComponentInstance* ci) const
RteComponent* c = NULL;
if (mode == VersionCmp::MatchMode::FIXED_VERSION) {
c = GetComponent(ci->GetComponentID(true));
if (!c && ci->HasAttribute("condition")) { // enforced component is specified
RteComponentList lst;
c = GetFilteredModel()->FindComponents(*ci, lst);
}
} else {
c = GetLatestComponent(ci);
}
Expand Down

0 comments on commit 6330bd1

Please sign in to comment.