depot_query: filter index by CPU architecture

This patch changes the depot_query tool to filter the returned index
data depending on the 'arch' as specified for the query. This way, one
index file can support multiple CPU architectures while allowing
individual entries to be architecture-specific.

Fixes #4295
This commit is contained in:
Norman Feske 2021-10-11 16:19:12 +02:00
parent 28a71f4a73
commit 440debfc39
2 changed files with 62 additions and 7 deletions

View File

@ -6,10 +6,10 @@
[init -> report_rom] report 'depot_query -> index'
[init -> report_rom] *<index>
[init -> report_rom] <index user="genodelabs" version="19.02">
[init -> report_rom] <index name="Demos">
[init -> report_rom] <pkg path="nano3d" info="simple software-rendering demo"/>
[init -> report_rom] </index>
[init -> report_rom] </index>
[init -> report_rom] <index name="Demos">
[init -> report_rom] <pkg path="nano3d" info="simple software-rendering demo"/>
[init -> report_rom] </index>
[init -> report_rom] </index>
[init -> report_rom] <missing user="genodelabs" version="19.03"/>
[init -> report_rom] </index>
</log>
@ -54,8 +54,10 @@
<dir name="depot"> <dir name="genodelabs"> <dir name="index">
<inline name="19.02">
<index>
<supports arch="x86_64"/>
<index name="Demos">
<pkg path="nano3d" info="simple software-rendering demo"/>
<pkg path="nano3d" info="simple software-rendering demo"/>
<pkg path="armored" info="ARM demo" arch="arm_v8a"/>
</index>
</index>
</inline>

View File

@ -415,6 +415,8 @@ struct Depot_query::Main : private Rom_query
void _collect_source_dependencies(Archive::Path const &, Dependencies &, Recursion_limit);
void _collect_binary_dependencies(Archive::Path const &, Dependencies &, Recursion_limit);
void _query_user(Archive::User const &, Xml_generator &);
void _gen_index_node_rec(Xml_generator &, Xml_node const &, unsigned) const;
void _gen_index_for_arch(Xml_generator &, Xml_node const &) const;
void _query_index(Archive::User const &, Archive::Version const &, bool, Xml_generator &);
void _handle_config()
@ -800,6 +802,58 @@ void Depot_query::Main::_query_user(Archive::User const &user, Xml_generator &xm
}
void Depot_query::Main::_gen_index_node_rec(Xml_generator &xml,
Xml_node const &node,
unsigned max_depth) const
{
if (max_depth == 0) {
warning("index has too many nesting levels");
return;
}
node.for_each_sub_node([&] (Xml_node const &node) {
/* check if single index entry is compatible with architecture */
bool const arch_compatible =
!node.has_attribute("arch") ||
(node.attribute_value("arch", Architecture()) == _architecture);
if (!arch_compatible)
return;
if (node.has_type("index")) {
xml.node("index", [&] () {
xml.attribute("name", node.attribute_value("name", String<100>()));
_gen_index_node_rec(xml, node, max_depth - 1);
});
}
if (node.has_type("pkg")) {
xml.node("pkg", [&] () {
xml.attribute("path", node.attribute_value("path", Archive::Path()));
xml.attribute("info", node.attribute_value("info", String<200>()));
});
}
});
};
void Depot_query::Main::_gen_index_for_arch(Xml_generator &xml,
Xml_node const &node) const
{
/* check of architecture is supported by the index */
bool supports_arch = false;
node.for_each_sub_node("supports", [&] (Xml_node const &supports) {
if (supports.attribute_value("arch", Architecture()) == _architecture)
supports_arch = true; });
if (!supports_arch)
return;
_gen_index_node_rec(xml, node, 10);
}
void Depot_query::Main::_query_index(Archive::User const &user,
Archive::Version const &version,
bool const content, Xml_generator &xml)
@ -823,8 +877,7 @@ void Depot_query::Main::_query_index(Archive::User const &user,
file(_heap, _root, index_path, File_content::Limit{16*1024});
file.xml([&] (Xml_node node) {
node.with_raw_content([&] (char const *start, size_t lenght) {
xml.append(start, lenght); }); });
_gen_index_for_arch(xml, node); });
} catch (Directory::Nonexistent_file) { }
}