Add list of virtual packages to manual (branch yem/manual)
v3 cover Add list of virtual packages to manual (branch yem/manual)
From: "Yann E. MORIN" <[email protected]>
Hello All!
This series intends to add the list of virtual packages to the manual, for three reasons:
- for users that are told (in a comment in the menuconfig) that a package they need depends on a virtual package, to know what provider to select,
- for people writing a new provider for an existing virtual package to have a reference of which symbol to select and which package to provide in their Config.in and .mk files,
- for people writing a new package that depends on features provided by a virtual package to know what symbol to depend on.
The series starts with some preparatory changes and cleanups, then introduces a way to generate different forms of tables, then goes on by removing virtual packages from the current lists, and finally adds a new list with the virtual packages.
Pre-rendered manual available here:
http://ymorin.is-a-geek.org/download/tmp/buildroot/virtual-packages/manual/manual.html
Special thanks to Samuel and Maxime for their pythonistic help! :-)
Changes v2 -> v3:
- drop remaining 'both' instances (Samuel)
Changes RFC -> v2:
- saner API to formatter-functions (Samuel)
- more classical Python constructs for dicts and lambdas (Samuel)
- more accurate python-doc (Samuel)
- lota typoes (Samuel)
Regards,
Yann E. MORIN.
The following changes since commit ed1182641812986f529b2150635f1e93c799a419:
xserver_xorg-server: add support for xtensa architecture (2014-06-08 15:51:00 +0200)
are available in the git repository at:
git://gitorious.org/buildroot/buildroot.git yem/manual
for you to fetch changes up to e5d675da25e21b9b647172b947977d45da55c3eb:
docs/manual: add the virtual packages list (2014-06-08 16:07:30 +0200)
----------------------------------------------------------------
Yann E. MORIN (11):
package/cryptodev: make it behave more like other virtual packages package/jpeg: make it behave more like other virtual packages package/mesa3d: rename the prompt
support/scripts: prepare expanding the packages lists support/scripts: document args to _is_package() in gen-manual-lists support/scripts: prepare handling virtual packages in generated lists support/scripts: do not display virtual packages in generated lists support/scripts: who's responsible to decide what is a package support/scripts: introduce a symbol formatter to generate package lists support/scripts: generate a list of virtual packages docs/manual: add the virtual packages list
docs/manual/adding-packages-directory.txt | 10 ++ docs/manual/adding-packages-virtual.txt | 6 + docs/manual/appendix.txt | 8 ++ package/cryptodev/Config.in | 4 +- package/jpeg/Config.in | 4 +- package/mesa3d/Config.in | 2 +- support/scripts/gen-manual-lists.py | 217 ++++++++++++++++++++++++------ 7 files changed, 209 insertions(+), 42 deletions(-)
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'
PATCH v3 1/11 package/cryptodev: make it behave more like other virtual packages
From: "Yann E. MORIN" <[email protected]>
Currently, the virtual package cryptodev is a special virtual package, as it offers a choice for its implementation, rather than letting the user enable them manually.
In so doing, it defines its _HAS option as a 'def_bool y' rather than letting each implementation 'select' it.
Since we are going to generate a list of virtual packages and their providers, this defeats the heuristic used to find providers.
Coming with an alternate heuristic that also matches the cryptodev package is quite complex, so better and easier to make it look more like any other virtual package.
--- package/cryptodev/Config.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
package/cryptodev/Config.in +3 -1
@@ -18,6 +18,7 @@ choice config BR2_PACKAGE_CRYPTODEV_LINUX bool "cryptodev-linux" depends on !BR2_microblaze + select BR2_PACKAGE_HAS_CRYPTODEV help Cryptodev-linux is a device that allows access to Linux kernel cryptographic drivers; thus allowing userspace applications
@@ -27,6 +28,7 @@ config BR2_PACKAGE_CRYPTODEV_LINUX config BR2_PACKAGE_OCF_LINUX bool "ocf-linux" + select BR2_PACKAGE_HAS_CRYPTODEV help OCF-Linux is a Linux port of the OpenBSD/FreeBSD Cryptographic Framework (OCF). This port aims to bring full asynchronous HW/SW
@@ -38,7 +40,7 @@ config BR2_PACKAGE_OCF_LINUX endchoice config BR2_PACKAGE_HAS_CRYPTODEV - def_bool y + bool config BR2_PACKAGE_PROVIDES_CRYPTODEV string
Signature · 1 line
1.8.3.2
PATCH v3 2/11 package/jpeg: make it behave more like other virtual packages
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Currently, the virtual package jpeg is a special virtual package, as it offers a choice for its implementation, rather than letting the user enable them manually.
In so doing, it defines its _HAS option as a 'def_bool y' rather than letting each implementation 'select' it.
Since we are going to generate a list of virtual packages and their providers, this defeats the heuristic used to find providers.
Coming with an alternate heuristic that also matches the jpeg package is quite complex, so better and easier to make it look more like any other virtual package.
--- package/jpeg/Config.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
package/jpeg/Config.in +3 -1
@@ -13,6 +13,7 @@ choice config BR2_PACKAGE_LIBJPEG bool "jpeg" + select BR2_PACKAGE_HAS_JPEG help The ubiquitous C library for manipulating JPEG images.
@@ -20,6 +21,7 @@ config BR2_PACKAGE_LIBJPEG config BR2_PACKAGE_JPEG_TURBO bool "jpeg-turbo" + select BR2_PACKAGE_HAS_JPEG help Libjpeg-turbo is a derivative of libjpeg that uses SIMD instructions (MMX, SSE2, NEON) to accelerate baseline JPEG
@@ -31,7 +33,7 @@ config BR2_PACKAGE_JPEG_TURBO endchoice config BR2_PACKAGE_HAS_JPEG - def_bool y + bool config BR2_PACKAGE_PROVIDES_JPEG string
Signature · 1 line
1.8.3.2
PATCH v3 3/11 package/mesa3d: rename the prompt
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Rename the prompt for mesa3d so that it matches what we usually do for prompts of packages: just name the package in lower case.
This will help generate nicer tables in the generated packages list, both in existing tables, and in the upcoming table of virtual packages.
--- package/mesa3d/Config.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
package/mesa3d/Config.in +1 -1
@@ -1,5 +1,5 @@ menuconfig BR2_PACKAGE_MESA3D - bool "Mesa 3D Graphics Library" + bool "mesa3d" select BR2_PACKAGE_LIBDRM select BR2_PACKAGE_EXPAT select BR2_PACKAGE_HOST_LIBXML2_PYTHON
Signature · 1 line
1.8.3.2
PATCH v3 4/11 support/scripts: prepare expanding the packages lists
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Move to a function the code generating the package name from a symbol's name, to avoid code duplication.
This is not used currently, but will be in a subsequent patch.
--- support/scripts/gen-manual-lists.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
support/scripts/gen-manual-lists.py +10 -1
@@ -245,7 +245,7 @@ class Buildroot: """ if not self.re_pkg_prefix.match(symbol.get_name()): return False - pkg_name = re.sub("BR2_PACKAGE_(HOST_)?(.*)", r"\2", symbol.get_name()) + pkg_name = self._get_pkg_name(symbol) pattern = "^(HOST_)?" + pkg_name + "$" pattern = re.sub("_", ".", pattern)
@@ -278,6 +278,15 @@ class Buildroot: return True return False + def _get_pkg_name(self, symbol): + """ Return the package name of the specified symbol. + + :param symbol: The symbol to get the package name of + + """ + + return re.sub("BR2_PACKAGE_(HOST_)?(.*)", r"\2", symbol.get_name()) + def _get_symbol_label(self, symbol, mark_deprecated=True): """ Return the label (a.k.a. prompt text) of the symbol.
Signature · 1 line
1.8.3.2
PATCH v3 5/11 support/scripts: document args to _is_package() in gen-manual-lists
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
--- support/scripts/gen-manual-lists.py | 2 ++ 1 file changed, 2 insertions(+)
support/scripts/gen-manual-lists.py +2 -0
@@ -242,6 +242,8 @@ class Buildroot: """ Return True if the symbol is a package or a host package, otherwise False. + :param symbol: The symbol to check + """ if not self.re_pkg_prefix.match(symbol.get_name()): return False
Signature · 1 line
1.8.3.2
PATCH v3 6/11 support/scripts: prepare handling virtual packages in generated lists
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Prepare to tell apart real packages from virtual packages.
Currently, the code implicitly recognises only real packages, and discards virtual packages, because of the heuristic used to recognise whether a symbol is a package:
- for real package:
- symbols : BR2_PACKAGE_FOO
- .mk files: foo.mk
- for virtual packages:
- symbols : BR2_PACKAGE_HAS_FOO
- .mk files: foo.mk
The current heuristic is to check for each symbol if a corresponding .mk file exists, by stripping 'BR2_PACKAGE_' from the beginning of the symbol, converting the result to lowercase, and checking if a .mk file exists.
So, as a side effect, it completely misses the virtual packages [*], which is pretty nice since we get a list with only real packages that the user can indeed select and see in the menuconfig.
[*] Except for 'cryptodev' and 'jpeg' which are both virtual packages and normal packages. Except they are not normal packages, they are used to display a choice of the implementation to use. This case will be fixed in follow-up patches.
Since we'll soon need to also output the table of virtual packages, we need to teach the _is_package() function to recognise them as well.
This patch is the first step into that direction: it introduces a new function _is_real_package() that is just a wrapper to _is_package(), which gains a new parameter, being the type of packages to filter on.
No behavioural change is made in this patch, it is just a preparatory patch.
---
Changes RFC -> v2
- remove useless 'both' semantic (Samuel)
- document default value (Samuel)
- fix typoes (Samuel)
--- support/scripts/gen-manual-lists.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
support/scripts/gen-manual-lists.py +9 -3
@@ -183,14 +183,14 @@ class Buildroot: 'target-packages': { 'filename': "package-list", 'root_menu': "Target packages", - 'filter': "_is_package", + 'filter': "_is_real_package", 'sorted': True, 'sub_menu': True, }, 'host-packages': { 'filename': "host-package-list", 'root_menu': "Host utilities", - 'filter': "_is_package", + 'filter': "_is_real_package", 'sorted': True, 'sub_menu': False, },
@@ -238,11 +238,14 @@ class Buildroot: return bool([ symbol for x in symbol.get_referenced_symbols() if x.get_name().startswith(self._deprecated.get_name()) ]) - def _is_package(self, symbol): + def _is_package(self, symbol, type='real'): """ Return True if the symbol is a package or a host package, otherwise False. :param symbol: The symbol to check + :param type: Limit to 'real' or 'virtual' types of packages, + with 'real' being the default. + Note: only 'real' is (implictly) handled for now """ if not self.re_pkg_prefix.match(symbol.get_name()):
@@ -280,6 +283,9 @@ class Buildroot: return True return False + def _is_real_package(self, symbol): + return self._is_package(symbol, 'real') + def _get_pkg_name(self, symbol): """ Return the package name of the specified symbol.
Signature · 1 line
1.8.3.2
PATCH v3 7/11 support/scripts: do not display virtual packages in generated lists
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
If a package has both a 'real' and a 'virtual' definition, consider it is a virtual package and do not display it in the generated package list.
This is the case for jpeg and cryptodev, that are virtual packages, but also real (but empty) packages used to provide a prompt to enable/disable a choice to select an implementation. In this case, we do not want to list the virtual packages, but only their implementations.
So, consider packages that are both real and virtual as virtual packages.
---
Changes v2 -> v3:
- drop remaining 'both' reference (Samuel)
Changes RFC -> v2:
- fix typoes (Samuel)
--- support/scripts/gen-manual-lists.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
support/scripts/gen-manual-lists.py +19 -2
@@ -279,13 +279,30 @@ class Buildroot: pkg_list.append(re.sub(r"(.*?)\.mk", r"\1", file_)) setattr(self, "_package_list", pkg_list) for pkg in getattr(self, "_package_list"): - if pattern.match(pkg): - return True + if type == 'real': + if pattern.match(pkg) and not self._exists_virt_symbol(pkg): + return True return False def _is_real_package(self, symbol): return self._is_package(symbol, 'real') + def _exists_virt_symbol(self, pkg_name): + """ Return True if a symbol exists that defines the package as + a virtual package, False otherwise + + :param pkg_name: The name of the package, for which to check if + a symbol exists defining it as a virtual package + + """ + virt_pattern = "BR2_PACKAGE_HAS_" + pkg_name + "$" + virt_pattern = re.sub("_", ".", virt_pattern) + virt_pattern = re.compile(virt_pattern, re.IGNORECASE) + for sym in self.config: + if virt_pattern.match(sym.get_name()): + return True + return False + def _get_pkg_name(self, symbol): """ Return the package name of the specified symbol.
Signature · 1 line
1.8.3.2
PATCH v3 8/11 support/scripts: who's responsible to decide what is a package
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
When generating the package lists, the responsibility to decide what is actually a package symbol is currently split between the _is_package(), the get_symbol_subset() and the format_asciidoc_table() functions.
The two latter functions check that an item is really a symbol, and that is has a prompt.
While this is currently correct for real packages, this will no longer be the case when we also generate a list of virtual packages, since they do not have a prompt.
Move the responsibility to verify that a symbol is indeed a package symbol to _is_package(), so it's all in one place, and makes it easier to change for virtual packages.
---
Changes RFC -> v2:
- fix typoes (samuel)
--- support/scripts/gen-manual-lists.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
support/scripts/gen-manual-lists.py +4 -4
@@ -75,8 +75,6 @@ def get_symbol_subset(root, filter_func): raise Exception(message) for item in get_items(): if item.is_symbol(): - if not item.prompts: - continue if not filter_func(item): continue yield item
@@ -134,8 +132,6 @@ def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True, return "| {0:<40}\n".format(item) lines = [] for item in get_symbol_subset(root, filter_func): - if not item.is_symbol() or not item.prompts: - continue loc = get_symbol_parents(item, root, enable_choice=enable_choice) lines.append(_format_entry(get_label_func(item), loc, sub_menu)) if sorted:
@@ -248,6 +244,10 @@ class Buildroot: Note: only 'real' is (implictly) handled for now """ + if not symbol.is_symbol(): + return False + if type == 'real' and not symbol.prompts: + return False if not self.re_pkg_prefix.match(symbol.get_name()): return False pkg_name = self._get_pkg_name(symbol)
Signature · 1 line
1.8.3.2
PATCH v3 9/11 support/scripts: introduce a symbol formatter to generate package lists
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Currently, we can generate two different tables of packages:
- a single-column table with the symbols' prompts,
- a two-column table with the symbols' prompts and locations in the menuconfig.
For virtual packages, this is not enough, since we will have to display more columns, with different content:
- the virtual package name (but such symbols do not have a prompt)
- the symbol name
- the providers for the virtual package
So, instead of having a single function that knows how to generate any table, introduce a formatter function that is passed as argument to, and called by format_asciidoc_table(). Such formatter functions are responsible for providing:
- the layout of the table (number of columns, column arrangement),
- the formatted header line,
- a formatted line for a symbol.
What the formatter should ouput depends on its arguments:
- if none are passed, the layout is returned,
- if the header label is passed, it returns the formatted header line,
- otherwise, it returns the formatted line for a symbol.
Two formatter functions are introduced in this changeset, to replace the current 'sub_menu' feature:
- _format_symbol_prompt() to display a one-column table with only the symbols' prompts,
- _format_symbol_prompt_location() to display a two-column table with the symbols' prompts and locations.
This will help us to later introduce a new formatter to generate a table for virtual packages.
[Thanks to Samuel for his pythonistic help!]
---
Changes v2 -> v3:
- drop redundant 'is None' test, enhance exception message (Samuel)
Changes RFC -> v2:
- add explicit parameter to formatters to decide what to do, instead of relying on argument being None or not (Samuel)
- use traditional 'lambda x: x' instead of custom ones (Samuel)
- fix typoes (samuel)
--- support/scripts/gen-manual-lists.py | 81 ++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 29 deletions(-)
support/scripts/gen-manual-lists.py +52 -29
@@ -109,50 +109,33 @@ def get_symbol_parents(item, root=None, enable_choice=False): def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True, - enable_choice=False, sorted=True, sub_menu=True, + format_func=lambda x: x, + enable_choice=False, sorted=True, item_label=None): """ Return the asciidoc formatted table of the items and their location. :param root: Root item of the item subset :param get_label_func: Item's label getter function :param filter_func: Filter function to apply on the item subset + :param format_func: Function to format a symbol and the table header :param enable_choice: Enable choices to appear as part of the item's location :param sorted: Flag to alphabetically sort the table - :param sub_menu: Output the column with the sub-menu path """ - def _format_entry(item, parents, sub_menu): - """ Format an asciidoc table entry. - """ - if sub_menu: - return "| {0:<40} <| {1}\n".format(item, " -> ".join(parents)) - else: - return "| {0:<40}\n".format(item) lines = [] for item in get_symbol_subset(root, filter_func): - loc = get_symbol_parents(item, root, enable_choice=enable_choice) - lines.append(_format_entry(get_label_func(item), loc, sub_menu)) + lines.append(format_func(what="symbol", symbol=item, root=root, + get_label_func=get_label_func, + enable_choice=enable_choice)) if sorted: lines.sort(key=lambda x: x.lower()) - if hasattr(root, "get_title"): - loc_label = get_symbol_parents(root, None, enable_choice=enable_choice) - loc_label += [root.get_title(), "..."] - else: - loc_label = ["Location"] - if not item_label: - item_label = "Items" table = ":halign: center\n\n" - if sub_menu: - width = "100%" - columns = "^1,4" - else: - width = "30%" - columns = "^1" + width, columns = format_func(what="layout") table = "[width=\"{0}\",cols=\"{1}\",options=\"header\"]\n".format(width, columns) table += "|===================================================\n" - table += _format_entry(item_label, loc_label, sub_menu) + table += format_func(what="header", header=item_label, root=root) table += "\n" + "".join(lines) + "\n" table += "|===================================================\n" return table
@@ -180,22 +163,22 @@ class Buildroot: 'filename': "package-list", 'root_menu': "Target packages", 'filter': "_is_real_package", + 'format': "_format_symbol_prompt_location", 'sorted': True, - 'sub_menu': True, }, 'host-packages': { 'filename': "host-package-list", 'root_menu': "Host utilities", 'filter': "_is_real_package", + 'format': "_format_symbol_prompt", 'sorted': True, - 'sub_menu': False, }, 'deprecated': { 'filename': "deprecated-list", 'root_menu': None, 'filter': "_is_deprecated", + 'format': "_format_symbol_prompt_location", 'sorted': False, - 'sub_menu': True, }, }
@@ -324,6 +307,45 @@ class Buildroot: label += " *(deprecated)*" return label + def _format_symbol_prompt(self, what=None, symbol=None, root=None, + enable_choice=False, header=None, + get_label_func=lambda x: x): + if what == "layout": + return ( "30%", "^1" ) + + if what == "header": + return "| {0:<40}\n".format(header) + + if what == "symbol": + return "| {0:<40}\n".format(get_label_func(symbol)) + + message = "Invalid argument 'what': '%s'\n" % str(what) + message += "Allowed values are: 'layout', 'header' and 'symbol'" + raise Exception(message) + + def _format_symbol_prompt_location(self, what=None, symbol=None, root=None, + enable_choice=False, header=None, + get_label_func=lambda x: x): + if what == "layout": + return ( "100%", "^1,4" ) + + if what == "header": + if hasattr(root, "get_title"): + loc_label = get_symbol_parents(root, None, enable_choice=enable_choice) + loc_label += [root.get_title(), "..."] + else: + loc_label = ["Location"] + return "| {0:<40} <| {1}\n".format(header, " -> ".join(loc_label)) + + if what == "symbol": + parents = get_symbol_parents(symbol, root, enable_choice) + return "| {0:<40} <| {1}\n".format(get_label_func(symbol), + " -> ".join(parents)) + + message = "Invalid argument 'what': '%s'\n" % str(what) + message += "Allowed values are: 'layout', 'header' and 'symbol'" + raise Exception(message) + def print_list(self, list_type, enable_choice=True, enable_deprecated=True, dry_run=False, output=None): """ Print the requested list. If not dry run, then the list is
@@ -356,6 +378,7 @@ class Buildroot: root_item = self.config filter_ = getattr(self, list_config.get('filter')) filter_func = lambda x: filter_(x) + format_func = getattr(self, list_config.get('format')) if not enable_deprecated and list_type != "deprecated": filter_func = lambda x: filter_(x) and not self._is_deprecated(x) mark_depr = list_type != "deprecated"
@@ -364,9 +387,9 @@ class Buildroot: table = format_asciidoc_table(root_item, get_label, filter_func=filter_func, + format_func=format_func, enable_choice=enable_choice, sorted=list_config.get('sorted'), - sub_menu=list_config.get('sub_menu'), item_label=item_label) content = self.list_in.format(table=table)
Signature · 1 line
1.8.3.2
PATCH v3 10/11 support/scripts: generate a list of virtual packages
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Generate an asciidoc table that can be included in the manual, that lists the existing virtual packages, the corresponding symbols, and their providers (and sub-options thereof).
The core of this change is the addition of a new formatter for virtual packages. This formatter is a bit tricky, as it has to catter for a bunch of corner cases:
- provider is not a package, but is sub-options of a package
- such a sub-option may be itself 'select'-ed by one or more other sub-options
- legacy packages should not be considered as a provider
Those cases are real:
- sub-options of mesa3d provide EGL or GLES
- selected sub-options of mesa3d provide GL
- udev is a legacy package, but it provides udev
---
Changes v2 -> v3:
- drop redundant 'is None' test, enhance exception message (Samuel)
Changes RFC -> v2:
- fix disctionnaries to use usual quoteation marks (Samuel)
- rewrite _is_legacy_symbol() in a more pythonic way (samuel)
- avoid passing the 'br' object since we're only ever calling the functions as class members anyway (Samuel)
- fix typoes (Samuel)
--- support/scripts/gen-manual-lists.py | 84 ++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
support/scripts/gen-manual-lists.py +83 -1
@@ -173,6 +173,13 @@ class Buildroot: 'format': "_format_symbol_prompt", 'sorted': True, }, + 'virtual-packages': { + 'filename': "virtual-package-list", + 'root_menu': "Target packages", + 'filter': "_is_virtual_package", + 'format': "_format_symbol_virtual", + 'sorted': True, + }, 'deprecated': { 'filename': "deprecated-list", 'root_menu': None,
@@ -231,6 +238,8 @@ class Buildroot: return False if type == 'real' and not symbol.prompts: return False + if type == 'virtual' and symbol.prompts: + return False if not self.re_pkg_prefix.match(symbol.get_name()): return False pkg_name = self._get_pkg_name(symbol)
@@ -265,11 +274,17 @@ class Buildroot: if type == 'real': if pattern.match(pkg) and not self._exists_virt_symbol(pkg): return True + if type == 'virtual': + if pattern.match('has_' + pkg): + return True return False def _is_real_package(self, symbol): return self._is_package(symbol, 'real') + def _is_virtual_package(self, symbol): + return self._is_package(symbol, 'virtual') + def _exists_virt_symbol(self, pkg_name): """ Return True if a symbol exists that defines the package as a virtual package, False otherwise
@@ -346,6 +361,71 @@ class Buildroot: message += "Allowed values are: 'layout', 'header' and 'symbol'" raise Exception(message) + def _format_symbol_virtual(self, what=None, symbol=None, root=None, + enable_choice=False, header=None, + get_label_func=lambda x: "?"): + def _symbol_is_legacy(symbol): + selects = [ s.get_name() for s in symbol.get_selected_symbols() ] + return ("BR2_LEGACY" in selects) + + def _get_parent_package(sym): + if self._is_real_package(sym): + return None + # Trim the symbol name from its last component (separated with + # underscores), until we either find a symbol which is a real + # package, or until we have no component (i.e. just 'BR2') + name = sym.get_name() + while name != "BR2": + name = name.rsplit("_", 1)[0] + s = self.config.get_symbol(name) + if s is None: + continue + if self._is_real_package(s): + return s + return None + + def _get_providers(config, symbol): + providers = list() + for sym in self.config: + if not sym.is_symbol(): + continue + selects = sym.get_selected_symbols() + if not selects: + continue + for s in selects: + if s == symbol: + if _symbol_is_legacy(sym): + continue + if sym.prompts: + l = self._get_symbol_label(sym,False) + parent_pkg = _get_parent_package(sym) + if parent_pkg is not None: + l = self._get_symbol_label(parent_pkg, False) \ + + " (w/ " + l + ")" + providers.append(l) + else: + providers.extend(_get_providers(config,sym)) + return providers + + if what == "layout": + return ( "100%", "^1,4,4" ) + + if what == "header": + return "| {0:<20} <| {1:<32} <| Providers\n".format("Virtual packages", "Symbols") + + if what == "symbol": + pkg = re.sub(r"^BR2_PACKAGE_HAS_(.+)$", r"\1", symbol.get_name()) + providers = _get_providers(self.config, symbol) + + return "| {0:<20} <| {1:<32} <| {2}\n".format(pkg.lower(), + '+' + symbol.get_name() + '+', + ", ".join(providers)) + + message = "Invalid argument 'what': '%s'\n" % str(what) + message += "Allowed values are: 'layout', 'header' and 'symbol'" + raise Exception(message) + + def print_list(self, list_type, enable_choice=True, enable_deprecated=True, dry_run=False, output=None): """ Print the requested list. If not dry run, then the list is
@@ -414,7 +494,7 @@ class Buildroot: if __name__ == '__main__': - list_types = ['target-packages', 'host-packages', 'deprecated'] + list_types = ['target-packages', 'host-packages', 'virtual-packages', 'deprecated'] parser = ArgumentParser() parser.add_argument("list_type", nargs="?", choices=list_types, help="""\
@@ -425,6 +505,8 @@ Generate the given list (generate all lists if unspecified)""") help="Output target package file") parser.add_argument("--output-host", dest="output_host", help="Output host package file") + parser.add_argument("--output-virtual", dest="output_virtual", + help="Output virtual package file") parser.add_argument("--output-deprecated", dest="output_deprecated", help="Output deprecated file") args = parser.parse_args()
Signature · 1 line
1.8.3.2
PATCH v3 11/11 docs/manual: add the virtual packages list
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
Add the list of virtual packages as an appendix to the manual.
Also reference this list from appropriate locations elsewhere in the manual:
- in section 7.2.2. "Config.in file", after the existing explanations on dependencies on target and toolchain options, on a linux kernel, and on udev /dev management,
- in section 7.2.10. "Infrastructure for virtual packages", in the provider Config.in and .mk explanations, to have the list of existing symbols to select (in Config.in) and packages to provide (in .mk).
---
Note: a pre-rendered version of the manual with these modifications is available at:
http://ymorin.is-a-geek.org/download/tmp/buildroot/virtual-pacakges/manual/manual.html
--- docs/manual/adding-packages-directory.txt | 10 ++++++++++ docs/manual/adding-packages-virtual.txt | 6 ++++++ docs/manual/appendix.txt | 8 ++++++++ 3 files changed, 24 insertions(+)
docs/manual/adding-packages-directory.txt +10 -0
@@ -298,6 +298,16 @@ management, use this format: foo needs udev /dev management and a toolchain w/ featA, featB, featC -------------------------- +==== Dependencies on features provided by virtual packages + +Some features can be provided by more than one package, such as the +openGL libraries. + +See xref:virtual-package-tutorial[] for more on the virtual packages. + +See xref:virtual-package-list[] for the symbols to depend on if your package +depends on a feature provided by a virtual package. + === The +.mk+ file [[adding-packages-mk]]
docs/manual/adding-packages-virtual.txt +6 -0
@@ -83,6 +83,9 @@ On line 3, we select +BR2_PACKAGE_HAS_SOMETHING_VIRTUAL+, and on line 11, we set the value of +BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL+ to the name of the provider, but only if it is selected. +See xref:virtual-package-list[] for the symbols to select if you implement +a new provider for an existing virtual package. + ==== Provider's +.mk+ file The +.mk+ file should also declare an additional variable
@@ -96,6 +99,9 @@ packages it is an implementation of: Of course, do not forget to add the proper build and runtime dependencies for this package! +See xref:virtual-package-list[] for the names of virtual packages to provide +if you implement a new provider for an existing virtual package. + ==== Notes on depending on a virtual package When adding a package that requires a certain +FEATURE+ provided by a virtual
docs/manual/appendix.txt +8 -0
@@ -14,6 +14,14 @@ include::makeusers-syntax.txt[] include::package-list.txt[] +[[virtual-package-list]] +== List of virtual packages + +These are the virtual packages known to +Buildroot+, with the +corresponding symbols and providers. + +include::virtual-package-list.txt[] + [[host-package-list]] == List of host utilities available in Buildroot
Signature · 1 line
1.8.3.2
v3 cover Add list of virtual packages to manual (branch yem/manual)
In reply to Yann E. MORINDear Yann E. MORIN,
Quoted 11 lines · Yann E. MORIN
This series intends to add the list of virtual packages to the manual, for three reasons:
- for users that are told (in a comment in the menuconfig) that a package they need depends on a virtual package, to know what provider to select,
- for people writing a new provider for an existing virtual package to have a reference of which symbol to select and which package to provide in their Config.in and .mk files,
Quoted 7 lines
- for people writing a new package that depends on features provided by a virtual package to know what symbol to depend on.
The series starts with some preparatory changes and cleanups, then introduces a way to generate different forms of tables, then goes on by removing virtual packages from the current lists, and finally adds a new list with the virtual packages.
Thanks, series applied!
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com