Skip to contentSkip to conversation

br2-external: support multiple trees at once

PATCH Superseded Yann E. MORIN 2 participants 12 messages Oct 2, 2016 – Oct 14, 2016 Kbuild

v6 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v6 cover br2-external: support multiple trees at once

Hello All!

This series introduces support for using multiple br2-external trees.

Currently, Buildroot can use what we call a br2-external tree, that is a location where one can store customisations outside of the Buildroot tree:

- defconfig files;
- packages;
- custom make rules and logic;
- company-, project- and board-related configurations files, like a

    kernel config file, a rootfs overlay;

- any other content that does not belong to the Buildroot tree...

This is very nice and very handy!

However, it is not possible to use more than one such br2-external tree at a time; Buildroot only supports using at most one br2-external tree.

Having support for using more than one br2-external tree at the same time would allow more flexibility organising those out-of-tree customisations. One could use a br2-external tree to store FLOSS packages not yet in Buildroot and a second br2-external tree for proprietary packages; such a separation would make compliance with FLOSS licenses easier (by allowing distributing only the br2-external tree with FLOSS packages, keeping the proprietary bits private).

It could also be used to commonalise br2-external trees from different internal projects, where each would provide a set of extensions (new packages, new boards defconfigs...) that a project could cherry-pick.

And countless other possibilities.

This series is an attempt at making it possible to use such setups.

Here's a brief overview of all the patches:

- patch 1 moves the hard-coded sourcing of BR2_EXTERNAL/Config.in from the main Config.in into the generated Kconfig snippet.

- patch 2 gets rid of our dummy br2-external tree, since we now can include the br2-external only if specified by the user.

- patch 3 moves the handling of BR2_EXTERNAL out of the main Makefile into the generated $(BASE_DIR)/.br-external.mk Makefile fragment. So far, this fragment was already generated, but it only memorised the value of BR2_EXTERNAL so that it need not be specified at each call; it now also defines a new internal variable, BR2_EXTERNAL_MK, that contains the path to the BR2_EXTERNAL/external.mk makefile fragment.

This allows us to offload all the logic about handling a br2-external tree to a helper script, whether it be about the Kconfig snippet or the Makefile fragment.

- patch 4 adds more validation of a br2-external tree than we previously had.

- patch 5 introduces a layout change in the br2-external tree: a br2-external tree must now declare its name. This name is used to construct a set of variables unique to that br2-external tree.

This change is the foundation for using multiple br2-external trees at once, as their paths will now be in different variables; see below for more explanations.

As we now generate the Kconfig snippet and Makefile fragment, we can easily (pre-)compute the variables from the helper script.

This change renders existing br2-external trees incompatible with the new layout, as the BR2_EXTERNAL variable is now no longer to be used by br2-external trees, and is no longer available in Kconfig (although it still is available in Makefile, but we can't remove it as we need it for the infra).

- patch 6 is the documentation for the br2-external name.

- patch 7 adds a blurb in the manual about how to easily convert an old br2-external tree. This is referenced from the helper script and displayed in case of error.

- patch 8 is the core of the change, that adds suport for using multiple br2-external trees at once.

Again, because we generate the Kconfig snippet and Makefile fragment, it is very easy to (pre-)compute the per-br2-external tree variables.

Each tree is now identified with its name, which is displayed both in the Kconfig menu for that tree, as well as in the comment listing the defconfig files from that tree.

- patch 9 is the documentation for mutliple br2-external trees.

- patch 10 makes it possible for a br2-external tree to override defcongis present in Buildroot, as well as override defconfigs in other br2-external trees (by the order they are listed in BR2_EXTERNAL).

The pivotal change in this series is implemented in patch 5, and aims at providing br2-external trees with a way to find their own files, given that their locations at runtime is completely unkown, and can not even be deduced relative to Buildroot's own TOPDIR; this is explained below.

Unlike Makefiles, Kconfig does not allow us to redefine a variable at various moments of the parsing, because the values are only valid and acted upon when the complete Kconfig code has been parsed. So, we need a way to provide Config.in files from each br2-external with their actual location. For that, we need different variables, one for each br2-external tree.

So, we need a way to uniquely identify each br2-external tree, and we need a stable scheme. We can't use indexes (because they would not be stable across various runs or various ordering of the br2-external trees); we can't use path-based hashing (because paths are not stable accross users/machines/time); we can't use content-based hashing (external.mk and/or Config.in may all be empty, giving the same hash); we can't use hashes altogether because they are not human-friendly.

The solution is to require br2-external trees to provide a unique name that is used as a kind of 'name-space' for that tree: we eventually provide, for each br2-external tree, a variable, BR2_EXTERNAL_$(NAME)_PATH, that points to the location of that tree; because $(NAME) is known to the br2-external tree, it also knows BR2_EXTERNAL_$(NAME)_PATH exists, so it can use it, and we export it both in Config.in and external.mk .

Therefore, br2-external trees must now use $(BR2_EXTERNAL_$(MY_NAME)_PATH) to refer to their own files. It also prevents them from (accidentally) including files from other br2-external trees.

Note: unlike old iterations, it is now mandatory that a br2-external tree defines its name, the rationale being that it is relatively trivial to upgrade an existing br2-external tree to the new layout.

And that's about all for this time. ;-)

Changes v5 -> v6:
- the helper script is first run in Makefile context, so change the error function to emit Makefile code

Changes v4 -> v5:
- introduce br2-external conversion earlier in the series (Julien)
- fix intermediate-state br2-external helper script (Julien)
- misc typoes

Regards,
Yann E. MORIN.

The following changes since commit 9a1d2729ec9c594d7690e5ae444a18317dca5813

efivar: bump to version 28 (2016-10-02 00:11:12 +0200)

are available in the git repository at:

git://git.buildroot.org/~ymorin/git/buildroot.git

for you to fetch changes up to fbe34e72c7fbf6637344ccaa13b80a93e0336c77

core: allow a br2-external tree to override a defconfig (2016-10-02 10:06:00 +0200)

----------------------------------------------------------------
Yann E. MORIN (10):
core: do not hard-code inclusion of br2-external in Kconfig
core: get rid of our dummy br2-external tree
core: offload handling of BR2_EXTERNAL into the script core/br2-external: validate even more
core: introduce per br2-external NAME docs/manual: document the br2-external NAME docs/manual: add appendix to convert old br2-external trees
core: add support for multiple br2-external trees docs/manual: document multi br2-external
core: allow a br2-external tree to override a defconfig

 Config.in                                     |  11 --
 Makefile                                      |  86 ++++++-----
 boot/barebox/barebox-aux/Config.in            |   3 +-
 boot/barebox/barebox/Config.in                |   3 +-
 docs/manual/adding-packages-asciidoc.txt      |   6 +-
 docs/manual/adding-packages-perl.txt          |   2 +-
 docs/manual/adding-packages-python.txt        |   2 +-
 docs/manual/appendix.txt                      |   1 +
 docs/manual/br2-external-converting.txt       |  39 +++++
 docs/manual/customize-directory-structure.txt |  13 +-
 docs/manual/customize-outside-br.txt          | 171 +++++++++++++-------
 docs/manual/customize-packages.txt            |  25 +--
 package/Makefile.in                           |   3 +-
 package/pkg-generic.mk                        |   4 +-
 support/dummy-external/Config.in              |   0
 support/dummy-external/external.mk            |   0
 support/misc/utils.mk                         |   4 +
 support/scripts/br2-external                  | 214 ++++++++++++++++++++++++++
 18 files changed, 449 insertions(+), 138 deletions(-)
 create mode 100644 docs/manual/br2-external-converting.txt
 delete mode 100644 support/dummy-external/Config.in
 delete mode 100644 support/dummy-external/external.mk
 create mode 100755 support/scripts/br2-external
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.  |
'------------------------------^-------^------------------^--------------------'
#1 lore raw

PATCH v6 1/10 core: do not hard-code inclusion of br2-external in Kconfig

Move the inclusion of br2-external's Config.in to the generated kconfig snippet.

This will ultimately allow us to use more than one br2-external tree.

Offload the "User-provided options" menu to the generated Kconfig snippet. We can also move the definition of the Kconfig-version of BR2_EXTERNAL into this snippet.

We introduce an extra check that was not present in the previous code, to check that we do have permission on that directory. Prevciously, it was handled as a side effect of not being able to cd into there, but it is cleaner to check it expressly.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Romain Naour <[email protected]>
---
 Config.in                    | 11 ------
 Makefile                     |  2 +-
 support/scripts/br2-external | 88 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 12 deletions(-)
 create mode 100755 support/scripts/br2-external
Config.in +0 -11
index 8d37c93..985c412 100644
@@ -14,10 +14,6 @@ config BR2_HOSTARCH
 	string
 	option env="HOSTARCH"
 
-config BR2_EXTERNAL
-	string
-	option env="BR2_EXTERNAL"
-
 config BR2_BUILD_DIR
 	string
 	option env="BUILD_DIR"
@@ -759,11 +755,4 @@ source "package/Config.in.host"
 
 source "Config.in.legacy"
 
-menu "User-provided options"
-	depends on BR2_EXTERNAL != "support/dummy-external"
-
-source "$BR2_EXTERNAL/Config.in"
-
-endmenu
-
 source "$BR2_BUILD_DIR/.br2-external.in"
Makefile +1 -1
index 5e4daef..f44e509 100644
@@ -883,7 +883,7 @@ endif
 # value of BR2_EXTERNAL is changed.
 .PHONY: $(BUILD_DIR)/.br2-external.in
 $(BUILD_DIR)/.br2-external.in: $(BUILD_DIR)
-	@touch $@
+	$(Q)support/scripts/br2-external -o "$(@)" $(BR2_EXTERNAL)
 
 # printvars prints all the variables currently defined in our
 # Makefiles. Alternatively, if a non-empty VARS variable is passed,
support/scripts/br2-external new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.7.4
#2 lore raw

PATCH v6 2/10 core: get rid of our dummy br2-external tree

In reply to Yann E. MORIN

Now that we generate a kconfig snippet, we can conditionally include the BR2_EXTERNAL's Config.in only when BR2_EXTERNAL is supplied by the user, which means our empty/dummy Config.in is no longer useful to us.

As for external.mk, we can also include it only when BR2_EXTERNAL is supplied by the user, which means our empty/dummy external.mk is no longer of any use to us.

Ditch both of those files, and:

- only generate actual content in the Kconfig snippet when we actually do have a BR2_EXTERNAL provided by the user (i.e. BR2_EXTERNAL is not empty);

- add a variable that contains the path to the external.mk provided by the user, or empty if none, and include the path set in that variable (make can 'include' nothing without any problem! ;-) )

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Romain Naour <[email protected]>
Cc Julien CORJON <[email protected]>
---
 Makefile                           | 11 ++++-------
 support/dummy-external/Config.in   |  0
 support/dummy-external/external.mk |  0
 support/scripts/br2-external       | 18 +++++++++++++++---
 4 files changed, 19 insertions(+), 10 deletions(-)
 delete mode 100644 support/dummy-external/Config.in
 delete mode 100644 support/dummy-external/external.mk
Makefile +4 -7
index f44e509..10afcda 100644
@@ -147,16 +147,11 @@ $(if $(BASE_DIR),, $(error output directory "$(O)" does not exist))
 # on the command line, therefore the file is re-created every time make is run.
 #
 # When BR2_EXTERNAL is set to an empty value (e.g. explicitly in command
-# line), the .br-external file is removed and we point to
-# support/dummy-external. This makes sure we can unconditionally include the
-# Config.in and external.mk from the BR2_EXTERNAL directory. In this case,
-# override is necessary so the user can clear BR2_EXTERNAL from the command
-# line, but the dummy path is still used internally.
+# line), the .br-external file is removed.
 
 BR2_EXTERNAL_FILE = $(BASE_DIR)/.br-external
 -include $(BR2_EXTERNAL_FILE)
 ifeq ($(BR2_EXTERNAL),)
-  override BR2_EXTERNAL = support/dummy-external
   $(shell rm -f $(BR2_EXTERNAL_FILE))
 else
   _BR2_EXTERNAL = $(shell cd $(BR2_EXTERNAL) >/dev/null 2>&1 && pwd)
@@ -165,6 +160,7 @@ else
   endif
   override BR2_EXTERNAL := $(_BR2_EXTERNAL)
   $(shell echo BR2_EXTERNAL ?= $(BR2_EXTERNAL) > $(BR2_EXTERNAL_FILE))
+  BR2_EXTERNAL_MK = $(BR2_EXTERNAL)/external.mk
 endif
 
 # To make sure that the environment variable overrides the .config option,
@@ -461,7 +457,8 @@ include boot/common.mk
 include linux/linux.mk
 include fs/common.mk
 
-include $(BR2_EXTERNAL)/external.mk
+# Nothing to include if no BR2_EXTERNAL tree in use
+include $(BR2_EXTERNAL_MK)
 
 # Now we are sure we have all the packages scanned and defined. We now
 # check for each package in the list of enabled packages, that all its
support/dummy-external/Config.in deleted +0 -0
deleted file mode 100644
index e69de29..0000000
support/dummy-external/external.mk deleted +0 -0
deleted file mode 100644
index e69de29..0000000
support/scripts/br2-external +15 -3
index 6c2b85b..1c42ffa 100755
@@ -19,9 +19,11 @@ main() {
     # Forget options; keep only positional args
     shift $((OPTIND-1))
 
-    if [ ${#} -ne 1 ]; then
-        error "need exactly one br2-external tree to be specified\n"
+    # Accept 0 or 1 br2-external tree.
+    if [ ${#} -gt 1 ]; then
+        error "only zero or one br2-external tree allowed.\n"
     fi
+
     br2_ext="${1}"
 
     if [ -z "${ofile}" ]; then
@@ -38,6 +40,11 @@ main() {
 do_validate() {
     local br2_ext="${1}"
 
+    # No br2-external tree is valid
+    if [ -z "${br2_ext}" ]; then
+        return
+    fi
+
     if [ ! -d "${br2_ext}" ]; then
         error "'%s': no such file or directory\n" "${br2_ext}"
     fi
@@ -52,12 +59,17 @@ do_validate() {
 do_kconfig() {
     printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
     printf '\n'
+
+    if [ -z "${BR2_EXT}" ]; then
+        printf '# No br2-external tree defined.\n'
+        return
+    fi
+
     printf 'config BR2_EXTERNAL\n'
     printf '\tstring\n'
     printf '\tdefault "%s"\n' "${BR2_EXT}"
     printf '\n'
     printf 'menu "User-provided options"\n'
-    printf '\tdepends on BR2_EXTERNAL != "support/dummy-external"\n'
     printf '\n'
     printf 'source "%s/Config.in"\n' "${BR2_EXT}"
     printf '\n'
Signature · 1 line
2.7.4
#3 lore raw

PATCH v6 3/10 core: offload handling of BR2_EXTERNAL into the script

In reply to Yann E. MORIN

Currently, we treat the case where we have no br2-external tree (BR2_EXTERNAL is empty) differently from the case where we do have one (BR2_EXTERNAL is not empty).

There is now no reason to treat those two cases differently:

- the kconfig snippet is always generated appropriately (i.e. it would

    include the br2-external tree if set, or include nothing otherwise);

- we no longer have a dummy br-external tree either.

Also, the Makefile code to handle BR2_EXTERNAL is currently quite readable if at least a little bit tricky.

However, when we're going to add support for using multiple br2-external trees simultaneously, this code would need to get much, much more complex.

To keep the Makefile (rather) simple, offload all of the handling of BR2_EXTERNAL to the recently added br2-external helper script.

However, because of Makefiles idiosyncracies, we can't use a rule to generate that Makefile fragment.

Instead, we use $(shell ...) to call the helper script, and include the fragment twice: once before the $(shell ...) so we can grab a previously defined BR2_EXTERNAL value, a second time to use the one passed on the command line, if any.

Furthermore, we can't error out (e.g. on non-existent br2-external tree) directly from the fragment or we'd get that error on subsequent calls, with no chance to override it even from command line.

Instead, we use a variable in which we store the error, set it to empty before the second inclusion, so that only the one newly generated, if any, is taken into account.

Since we know the script will always be called from Makefile context first, we know validation will occur in Makefile context first. So we can assume that, if there is an error, it will be detected in Makefile context. Consequently, if the script is called to generate the kconfig fragment, validation has already occured, and there should be no error. So we change the error function to generate Makefile code, so that errors are caught as explained above.

Lastly, when the value of BR2_EXTERNAL changes, we want to 'forget' about the previous value of the BR2_EXTERNAL_MK variable, especially in the case where BR2_EXTERNAL is now set to empty, so that we do not try to include it later. That's why we first generate empty version of BR2_EXTERNAL_MK, and then assign it the new value, if any.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Romain Naour <[email protected]>
---
 Makefile                     | 31 ++++++++++-----------
 support/scripts/br2-external | 64 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 70 insertions(+), 25 deletions(-)
Makefile +14 -17
index 10afcda..5c3673b 100644
@@ -143,24 +143,21 @@ $(if $(BASE_DIR),, $(error output directory "$(O)" does not exist))
 # Handling of BR2_EXTERNAL.
 #
 # The value of BR2_EXTERNAL is stored in .br-external in the output directory.
-# On subsequent invocations of make, it is read in. It can still be overridden
-# on the command line, therefore the file is re-created every time make is run.
-#
-# When BR2_EXTERNAL is set to an empty value (e.g. explicitly in command
-# line), the .br-external file is removed.
+# The location of the external.mk makefile fragment is computed in that file.
+# On subsequent invocations of make, this file is read in. BR2_EXTERNAL can
+# still be overridden on the command line, therefore the file is re-created
+# every time make is run.
 
-BR2_EXTERNAL_FILE = $(BASE_DIR)/.br-external
+BR2_EXTERNAL_FILE = $(BASE_DIR)/.br-external.mk
 -include $(BR2_EXTERNAL_FILE)
-ifeq ($(BR2_EXTERNAL),)
-  $(shell rm -f $(BR2_EXTERNAL_FILE))
-else
-  _BR2_EXTERNAL = $(shell cd $(BR2_EXTERNAL) >/dev/null 2>&1 && pwd)
-  ifeq ($(_BR2_EXTERNAL),)
-    $(error BR2_EXTERNAL='$(BR2_EXTERNAL)' does not exist, relative to $(TOPDIR))
-  endif
-  override BR2_EXTERNAL := $(_BR2_EXTERNAL)
-  $(shell echo BR2_EXTERNAL ?= $(BR2_EXTERNAL) > $(BR2_EXTERNAL_FILE))
-  BR2_EXTERNAL_MK = $(BR2_EXTERNAL)/external.mk
+$(shell support/scripts/br2-external \
+	-m \
+	-o '${BR2_EXTERNAL_FILE}' \
+	$(BR2_EXTERNAL))
+BR2_EXTERNAL_ERROR =
+include $(BR2_EXTERNAL_FILE)
+ifneq ($(BR2_EXTERNAL_ERROR),)
+$(error $(BR2_EXTERNAL_ERROR))
 endif
 
 # To make sure that the environment variable overrides the .config option,
@@ -880,7 +877,7 @@ endif
 # value of BR2_EXTERNAL is changed.
 .PHONY: $(BUILD_DIR)/.br2-external.in
 $(BUILD_DIR)/.br2-external.in: $(BUILD_DIR)
-	$(Q)support/scripts/br2-external -o "$(@)" $(BR2_EXTERNAL)
+	$(Q)support/scripts/br2-external -k -o "$(@)" $(BR2_EXTERNAL)
 
 # printvars prints all the variables currently defined in our
 # Makefiles. Alternatively, if a non-empty VARS variable is passed,
support/scripts/br2-external +56 -8

112 lines not on this page · raw message

Signature · 1 line
2.7.4
#4 lore raw

PATCH 3/10 core: offload handling of BR2_EXTERNAL into the script

Hello,

Makefile $(if $(BASE_DIR),, $(error output directory "$(O)" does not exist)) · line 156

Quoted 4 lines · Yann E. MORIN

+$(shell support/scripts/br2-external \

Makefile +3 -0
+	-m \
+	-o '${BR2_EXTERNAL_FILE}' \
+	$(BR2_EXTERNAL))

Excessive newline usage here. Also, why ${} instead of $() ?

Makefile $(if $(BASE_DIR),, $(error output directory "$(O)" does not exist)) · line 161

Quoted 5 lines
Makefile +4 -0
+BR2_EXTERNAL_ERROR =
+include $(BR2_EXTERNAL_FILE)
+ifneq ($(BR2_EXTERNAL_ERROR),)
+$(error $(BR2_EXTERNAL_ERROR))
 endif

I don't really like this BR2_EXTERNAL_ERROR variable that gets written in the .mk file by the br2-external script if it fails, and then re-used here. But I'm not sure I have a better proposal.

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#5 lore raw

PATCH v6 4/10 core/br2-external: validate even more

In reply to Yann E. MORIN

A br2-external tree must provide external.mk and Config.in.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Romain Naour <[email protected]>
---
 support/scripts/br2-external | 6 ++++++
 1 file changed, 6 insertions(+)
support/scripts/br2-external +6 -0
index b2bff64..1a0c743 100755
@@ -67,6 +67,12 @@ do_validate() {
     if [ ! -r "${br2_ext}" -o ! -x "${br2_ext}" ]; then
         error "'%s': permission denied\n" "${br2_ext}"
     fi
+    if [ ! -f "${br2_ext}/external.mk" ]; then
+        error "'%s/external.mk': no such file or directory\n" "${br2_ext}"
+    fi
+    if [ ! -f "${br2_ext}/Config.in" ]; then
+        error "'%s/Config.in': no such file or directory\n" "${br2_ext}"
+    fi
 
     BR2_EXT="$(cd "${br2_ext}"; pwd -P )"
 }
Signature · 1 line
2.7.4
#6 lore raw

PATCH v6 5/10 core: introduce per br2-external NAME

In reply to Yann E. MORIN

This unique NAME is used to construct a per br2-external tree variable, BR2_EXTERNAL_$(NAME)_PATH, which contains the path to the br2-external tree.

This variable is available both from Kconfig (set in the Kconfig snippet) and from the .mk files.

Also, display the NAME and its path as a comment in the menuconfig.

This will ultimately allow us to support multiple br2-external trees at once, with that NAME (and thus BR2_EXTERNAL_$(NAME)) uniquely defining which br2-external tree is being used.

The obvious outcome is that BR2_EXTERNAL should now no longer be used to refer to the files in the br2-external tree; that location is now known from the BR2_EXTERNAL_$(NAME)_PATH variable instead. This means we no longer need to expose, and must stop from from exposing BR2_EXTERNAL as a Kconfig variable.

Finally, this also fixes a latent bug in the pkg-generic infra, where we would so far always refer to BR2_EXTERNAL (even if not set) to filter the names of packages (to decide whether they are a bootloader, a toolchain or a simple package).

Note: since the variables in the Makefile and in Kconfig are named the same, the one we computed early on in the Makefile will be overridden by the one in .config when we have it. Thus, even though they are set to the same raw value, the one from .config is quoted and, being included later in the Makefile, will take precedence, so we just re-include the generated Makefile fragment a third time before includeing the br2-external's Makefiles. That's unfortunate, but there is no easy way around that as we do want the two variables to be named the same in Makefile and Kconfig (and we can't ask the user to un-quote that variable himself either), hence this little dirty triple-inclusion trick.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Romain Naour <[email protected]>
---
 Makefile                           | 19 ++++++++++++++-----
 boot/barebox/barebox-aux/Config.in |  3 +--
 boot/barebox/barebox/Config.in     |  3 +--
 package/Makefile.in                |  3 +--
 package/pkg-generic.mk             |  4 ++--
 support/scripts/br2-external       | 38 +++++++++++++++++++++++++++++---------
 6 files changed, 48 insertions(+), 22 deletions(-)
Makefile +14 -5
index 5c3673b..b4bcca2 100644
@@ -454,6 +454,14 @@ include boot/common.mk
 include linux/linux.mk
 include fs/common.mk
 
+# If using a br2-external tree, the BR2_EXTERNAL_$(NAME)_PATH variable
+# is also present in the .config file. Since .config is included after
+# we defined BR2_EXTERNAL_$(NAME)_PATH in the Makefile, the value in
+# that variable is quoted. We just include the generated Makefile fragment
+# .br2-external.mk a third time, which will set that variable to the
+# un-quoted value.
+include $(BR2_EXTERNAL_FILE)
+
 # Nothing to include if no BR2_EXTERNAL tree in use
 include $(BR2_EXTERNAL_MK)
 
@@ -769,7 +777,6 @@ COMMON_CONFIG_ENV = \
 	KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \
 	KCONFIG_TRISTATE=$(BUILD_DIR)/buildroot-config/tristate.config \
 	BR2_CONFIG=$(BR2_CONFIG) \
-	BR2_EXTERNAL=$(BR2_EXTERNAL) \
 	HOST_GCC_VERSION="$(HOSTCC_VERSION)" \
 	BUILD_DIR=$(BUILD_DIR) \
 	SKIP_LEGACY=
@@ -848,7 +855,7 @@ define percent_defconfig
 	@$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@ \
 		$$< --defconfig=$(1)/configs/$$@ $$(CONFIG_CONFIG_IN)
 endef
-$(eval $(foreach d,$(TOPDIR) $(BR2_EXTERNAL),$(call percent_defconfig,$(d))$(sep)))
+$(eval $(foreach d,$(TOPDIR) $(if $(BR2_EXTERNAL_NAME),$(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)),$(call percent_defconfig,$(d))$(sep)))
 
 savedefconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig
 	@$(COMMON_CONFIG_ENV) $< \
@@ -975,12 +982,14 @@ list-defconfigs:
 	@echo 'Built-in configs:'
 	@$(foreach b, $(sort $(notdir $(wildcard $(TOPDIR)/configs/*_defconfig))), \
 	  printf "  %-35s - Build for %s\\n" $(b) $(b:_defconfig=);)
-ifneq ($(wildcard $(BR2_EXTERNAL)/configs/*_defconfig),)
+ifneq ($(BR2_EXTERNAL_NAME),)
+ifneq ($(wildcard $(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)/configs/*_defconfig),)
 	@echo
 	@echo 'User-provided configs:'
-	@$(foreach b, $(sort $(notdir $(wildcard $(BR2_EXTERNAL)/configs/*_defconfig))), \
+	@$(foreach b, $(sort $(notdir $(wildcard $(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)/configs/*_defconfig))), \
 	  printf "  %-35s - Build for %s\\n" $(b) $(b:_defconfig=);)
 endif
+endif
 	@echo
 
 release: OUT = buildroot-$(BR2_VERSION)
@@ -1000,7 +1009,7 @@ print-version:
 	@echo $(BR2_VERSION_FULL)
 
 include docs/manual/manual.mk
--include $(BR2_EXTERNAL)/docs/*/*.mk
+-include $(if $(BR2_EXTERNAL_NAME),$(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)/docs/*/*.mk)
 
 .PHONY: $(noconfig_targets)
 
boot/barebox/barebox-aux/Config.in +1 -2
index 315e1a3..ec3b97c 100644
@@ -67,8 +67,7 @@ config BR2_TARGET_BAREBOX_AUX_CUSTOM_EMBEDDED_ENV_PATH
 	  invalid. This option sets the barebox Kconfig option
 	  CONFIG_DEFAULT_ENVIRONMENT_PATH to the specified path. This
 	  way it is possible to use Buildroot variables like
-	  BR2_EXTERNAL, TOPDIR etc. to refer to the custom
-	  environment.
+	  TOPDIR etc. to refer to the custom environment.
 
 	  Depending on your setup, the custom embedded environment
 	  will probably be based on either the content of the
boot/barebox/barebox/Config.in +1 -2
index f5e3bae..3d8d014 100644
@@ -73,8 +73,7 @@ config BR2_TARGET_BAREBOX_CUSTOM_EMBEDDED_ENV_PATH
 	  invalid. This option sets the barebox Kconfig option
 	  CONFIG_DEFAULT_ENVIRONMENT_PATH to the specified path. This
 	  way it is possible to use Buildroot variables like
-	  BR2_EXTERNAL, TOPDIR etc. to refer to the custom
-	  environment.
+	  TOPDIR etc. to refer to the custom environment.
 
 	  Depending on your setup, the custom embedded environment
 	  will probably be based on either the content of the
package/Makefile.in +1 -2
index b4a4c60..8249359 100644
@@ -314,8 +314,7 @@ HOST_MAKE_ENV = \
 EXTRA_ENV = \
 	PATH=$(BR_PATH) \
 	BR2_DL_DIR=$(BR2_DL_DIR) \
-	BUILD_DIR=$(BUILD_DIR) \
-	BR2_EXTERNAL=$(BR2_EXTERNAL)
+	BUILD_DIR=$(BUILD_DIR)
 
 ################################################################################
 # settings we need to pass to configure
package/pkg-generic.mk +2 -2
index 68ead3d..946244e 100644
@@ -767,9 +767,9 @@ $$($(2)_TARGET_DIRCLEAN):		PKG=$(2)
 # kernel case, the bootloaders case, and the normal packages case.
 ifeq ($(1),linux)
 $(2)_KCONFIG_VAR = BR2_LINUX_KERNEL
-else ifneq ($$(filter boot/% $(BR2_EXTERNAL)/boot/%,$(pkgdir)),)
+else ifneq ($$(filter boot/% $$(if $$(BR2_EXTERNAL_NAME),$$(BR2_EXTERNAL_$$(BR2_EXTERNAL_NAME)_PATH)/boot/%),$(pkgdir)),)
 $(2)_KCONFIG_VAR = BR2_TARGET_$(2)
-else ifneq ($$(filter toolchain/% $(BR2_EXTERNAL)/toolchain/%,$(pkgdir)),)
+else ifneq ($$(filter toolchain/% $$(if $$(BR2_EXTERNAL_NAME),$$(BR2_EXTERNAL_$$(BR2_EXTERNAL_NAME)_PATH)/toolchain/%),$(pkgdir)),)
 $(2)_KCONFIG_VAR = BR2_$(2)
 else
 $(2)_KCONFIG_VAR = BR2_PACKAGE_$(2)
support/scripts/br2-external +29 -9
index 1a0c743..21d7351 100755
@@ -1,7 +1,8 @@
 #!/bin/bash
 set -e
 
-# The location of the br2-external tree, once validated.
+# The name and location of the br2-external tree, once validated.
+declare BR2_NAME
 declare BR2_EXT
 
 main() {
@@ -55,6 +56,7 @@ main() {
 #
 do_validate() {
     local br2_ext="${1}"
+    local br2_name n
 
     # No br2-external tree is valid
     if [ -z "${br2_ext}" ]; then
@@ -67,6 +69,20 @@ do_validate() {
     if [ ! -r "${br2_ext}" -o ! -x "${br2_ext}" ]; then
         error "'%s': permission denied\n" "${br2_ext}"
     fi
+    if [ ! -f "${br2_ext}/external.desc" ]; then
+        error "'%s': does not have a name (in 'external.desc')\n" "${br2_ext}"
+    fi
+    br2_name="$(sed -r -e '/^name: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
+    if [ -z "${br2_name}" ]; then
+        error "'%s/external.desc': does not define the name\n" "${br2_ext}"
+    fi
+    # Only ASCII chars in [A-Za-z0-9_] are permitted
+    n="$(sed -r -e 's/[A-Za-z0-9_]//g' <<<"${br2_name}" )"
+    if [ -n "${n}" ]; then
+        # Escape '$' so that it gets printed
+        error "'%s': name '%s' contains invalid chars: '%s'\n" \
+            "${br2_ext}" "${br2_name//\$/\$\$}" "${n//\$/\$\$}"
+    fi
     if [ ! -f "${br2_ext}/external.mk" ]; then
         error "'%s/external.mk': no such file or directory\n" "${br2_ext}"
     fi
@@ -74,27 +90,29 @@ do_validate() {
         error "'%s/Config.in': no such file or directory\n" "${br2_ext}"
     fi
 
+    BR2_NAME="${br2_name}"
     BR2_EXT="$(cd "${br2_ext}"; pwd -P )"
 }
 
 # Generate the .mk snippet that defines makefile variables
 # for the br2-external tree
 do_mk() {
-    local BR2_EXT="${1}"
-
     printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
     printf '\n'
 
     printf 'BR2_EXTERNAL ?= %s\n' "${BR2_EXT}"
+    printf 'BR2_EXTERNAL_NAME = \n'
     printf 'BR2_EXTERNAL_MK =\n'
     printf '\n'
 
-    if [ -z "${BR2_EXT}" ]; then
+    if [ -z "${BR2_NAME}" ]; then
         printf '# No br2-external tree defined.\n'
         return
     fi
 
+    printf 'BR2_EXTERNAL_NAME = %s\n' "${BR2_NAME}"
     printf 'BR2_EXTERNAL_MK = %s/external.mk\n' "${BR2_EXT}"
+    printf 'BR2_EXTERNAL_%s_PATH = %s\n' "${BR2_NAME}" "${BR2_EXT}"
 }
 
 # Generate the kconfig snippet for the br2-external tree.
@@ -102,18 +120,20 @@ do_kconfig() {
     printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
     printf '\n'
 
-    if [ -z "${BR2_EXT}" ]; then
+    if [ -z "${BR2_NAME}" ]; then
         printf '# No br2-external tree defined.\n'
         return
     fi
 
-    printf 'config BR2_EXTERNAL\n'
+    printf 'menu "User-provided options"\n'
+    printf '\n'
+    printf 'comment "%s (in %s)"\n' "${BR2_NAME}" "${BR2_EXT}"
+    printf '\n'
+    printf 'config BR2_EXTERNAL_%s_PATH\n' "${BR2_NAME}"
     printf '\tstring\n'
     printf '\tdefault "%s"\n' "${BR2_EXT}"
     printf '\n'
-    printf 'menu "User-provided options"\n'
-    printf '\n'
-    printf 'source "%s/Config.in"\n' "${BR2_EXT}"
+    printf 'source "$BR2_EXTERNAL_%s_PATH/Config.in"\n' "${BR2_NAME}"
     printf '\n'
     printf "endmenu # User-provided options\n"
 }
Signature · 1 line
2.7.4
#7 lore raw

PATCH v6 6/10 docs/manual: document the br2-external NAME

In reply to Yann E. MORIN

Update the manual with the new external.desc mandatory file.

Take the opportunity to add a section listing all mandatory files, Config.in, external.mk and the new external.desc, instead of just hinting about them in the external package recipes section.

Change the examples to use the NAME-suffixed variable instead of the raw BR2_EXTERNAL variable.

Change all references to BR2_EXTERNAL elsewhere in the manual to now use the 'br2-external tree' terminology.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Samuel Martin <[email protected]>
Cc Romain Naour <[email protected]>
Cc Julien CORJON <[email protected]>
---
 docs/manual/adding-packages-asciidoc.txt      |   6 +-
 docs/manual/adding-packages-perl.txt          |   2 +-
 docs/manual/adding-packages-python.txt        |   2 +-
 docs/manual/customize-directory-structure.txt |  13 +--
 docs/manual/customize-outside-br.txt          | 134 ++++++++++++++++----------
 docs/manual/customize-packages.txt            |  25 +----
 6 files changed, 102 insertions(+), 80 deletions(-)
docs/manual/adding-packages-asciidoc.txt +3 -3
index a278d44..d870c51 100644
@@ -19,9 +19,9 @@ Although Buildroot only contains one document written in AsciiDoc, there
 is, as for packages, an infrastructure for rendering documents using the
 AsciiDoc syntax.
 
-Also as for packages, the AsciiDoc infrastructure is available from
-xref:outside-br-custom[BR2_EXTERNAL]. This allows documentation for a
-BR2_EXTERNAL tree to match the Buildroot documentation, as it will be
+Also as for packages, the AsciiDoc infrastructure is available from a
+xref:outside-br-custom[br2-external tree]. This allows documentation for
+a br2-external tree to match the Buildroot documentation, as it will be
 rendered to the same formats and use the same layout and theme.
 
 ==== +asciidoc-document+ tutorial
docs/manual/adding-packages-perl.txt +1 -1
index 63fafe6..4f5a6a4 100644
@@ -47,7 +47,7 @@ built.
 Most of these data can be retrieved from https://metacpan.org/.
 So, this file and the Config.in can be generated by running
 the script +supports/scripts/scancpan Foo-Bar+ in the Buildroot directory
-(or in the +BR2_EXTERNAL+ directory).
+(or in a br2-external tree).
 This script creates a Config.in file and foo-bar.mk file for the
 requested package, and also recursively for all dependencies specified by
 CPAN. You should still manually edit the result. In particular, the
docs/manual/adding-packages-python.txt +1 -1
index 94ac809..abcd4ca 100644
@@ -195,7 +195,7 @@ license and license files are guessed and must be checked. You also
 need to manually add the package to the +package/Config.in+ file.
 
 If your Buildroot package is not in the official Buildroot tree but in
-a +BR2_EXTERNAL+ tree, use the -o flag as follows:
+a br2-external tree, use the -o flag as follows:
 
 -----------------------
 ./support/script/scanpypi foo bar -o other_package_dir
docs/manual/customize-directory-structure.txt +7 -6
index 0be3f77..b177319 100644
@@ -13,7 +13,8 @@ section.
 
 Orthogonal to this directory structure, you can choose _where_ you place
 this structure itself: either inside the Buildroot tree, or outside of
-it using +BR2_EXTERNAL+. Both options are valid, the choice is up to you.
+it using a br2-external tree. Both options are valid, the choice is up
+to you.
 
 -----
 +-- board/
@@ -38,8 +39,8 @@ it using +BR2_EXTERNAL+. Both options are valid, the choice is up to you.
 |
 +-- package/
 |   +-- <company>/
-|       +-- Config.in (if not using BR2_EXTERNAL)
-|       +-- <company>.mk (if not using BR2_EXTERNAL)
+|       +-- Config.in (if not using a br2-external tree)
+|       +-- <company>.mk (if not using a br2-external tree)
 |       +-- package1/
 |       |    +-- Config.in
 |       |    +-- package1.mk
@@ -47,14 +48,14 @@ it using +BR2_EXTERNAL+. Both options are valid, the choice is up to you.
 |           +-- Config.in
 |           +-- package2.mk
 |
-+-- Config.in (if using BR2_EXTERNAL)
-+-- external.mk (if using BR2_EXTERNAL)
++-- Config.in (if using a br2-external tree)
++-- external.mk (if using a br2-external tree)
 ------
 
 Details on the files shown above are given further in this chapter.
 
 Note: if you choose to place this structure outside of the Buildroot
-tree using +BR2_EXTERNAL+, the <company> and possibly <boardname>
+tree but in a br2-external tree, the <company> and possibly <boardname>
 components may be superfluous and can be left out.
 
 ==== Implementing layered customizations
docs/manual/customize-outside-br.txt +85 -49

183 lines not on this page · raw message

docs/manual/customize-packages.txt +5 -20
index 9a5e8c5..b57280e 100644
@@ -14,8 +14,9 @@ packages in a project-specific directory.
 
 As shown in xref:customize-dir-structure[], the recommended location for
 project-specific packages is +package/<company>/+. If you are using the
-+BR2_EXTERNAL+ feature (see xref:outside-br-custom[]) the recommended
-location is +$(BR2_EXTERNAL)/package/+.
+br2-external tree feature (see xref:outside-br-custom[]) the recommended
+location is to put them in a sub-directory named +package/+ in your
+br2-external tree.
 
 However, Buildroot will not be aware of the packages in this location,
 unless we perform some additional steps. As explained in
@@ -37,14 +38,6 @@ have only one extra directory level below +package/<company>/+):
 include $(sort $(wildcard package/<company>/*/*.mk))
 -----
 
-If you are using +BR2_EXTERNAL+, create a file
-+$(BR2_EXTERNAL)/external.mk+ with following contents (again assuming only
-one extra level):
-
------
-include $(sort $(wildcard $(BR2_EXTERNAL)/package/*/*.mk))
------
-
 For the +Config.in+ files, create a file +package/<company>/Config.in+
 that includes the +Config.in+ files of all your packages. An exhaustive
 list has to be provided since wildcards are not supported in the source command of kconfig.
@@ -59,13 +52,5 @@ Include this new file +package/<company>/Config.in+ from
 +package/Config.in+, preferably in a company-specific menu to make
 merges with future Buildroot versions easier.
 
-If you are using +BR2_EXTERNAL+, create a file
-+$(BR2_EXTERNAL)/Config.in+ with similar contents:
-
------
-source "$BR2_EXTERNAL/package/package1/Config.in"
-source "$BR2_EXTERNAL/package/package2/Config.in"
------
-
-You do not have to add an include for this +$(BR2_EXTERNAL)/Config.in+
-file as it is included automatically.
+If using a br2-external tree, refer to xref:outside-br-custom[] for how
+to fill in those files.
Signature · 1 line
2.7.4
#8 lore raw

PATCH v6 7/10 docs/manual: add appendix to convert old br2-external trees

In reply to Yann E. MORIN
Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Samuel Martin <[email protected]>
Cc Romain Naour <[email protected]>
Cc Julien CORJON <[email protected]>
---
 docs/manual/appendix.txt                |  1 +
 docs/manual/br2-external-converting.txt | 36 +++++++++++++++++++++++++++++++++
 docs/manual/customize-outside-br.txt    |  5 +++++
 support/scripts/br2-external            |  7 ++++++-
 4 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 docs/manual/br2-external-converting.txt
docs/manual/appendix.txt +1 -0
index 03dbbd1..4d4bbec 100644
@@ -3,3 +3,4 @@
 
 include::makedev-syntax.txt[]
 include::makeusers-syntax.txt[]
+include::br2-external-converting.txt[]
docs/manual/br2-external-converting.txt new file +36 -0
new file mode 100644
index 0000000..b207601
@@ -0,0 +1,36 @@
+// -*- mode:doc; -*-
+// vim: set syntax=asciidoc:
+
+[[br2-external-converting]]
+== Converting old br2-external trees
+
+Buildroot 2016.11 introduced a backward-incompatible change in the way
+br2-external trees are handled. A minor change has to be made: adding
+a name to your br2-external tree, see xref:outside-br-custom[].
+
+This can be done very easily in just a few steps:
+
+ * First, create a new file named +external.desc+, at the root of your
+   br2-external tree, with a single line defining the name of your
+   br2-external tree:
++
+----
+$ echo 'name: NAME_OF_YOUR_TREE' >external.desc
+----
++
+.Note
+Be careful when choosing a name: it has to be relatively unique, be made
+with only ASCII characters from the set +[A-Za-z0-9_]+.
+
+ * Then, change every occurence of +BR2_EXTERNAL+ in your br2-external
+   tree with the new variable:
++
+----
+$ find . -type f | xargs sed -i 's/BR2_EXTERNAL/BR2_EXTERNAL_NAME_OF_YOUR_TREE_PATH/g'
+----
+
+Now, your br2-external tree can be used with Buildroot 2016.11 onward.
+
+.Note:
+This change makes your br2-external tree incompatible with Buildroot
+before 2016.11.
docs/manual/customize-outside-br.txt +5 -0
index f2a83a6..3ad0bc0 100644
@@ -33,6 +33,11 @@ If it is passed as a relative path, it is important to note that it is
 interpreted relative to the main Buildroot source directory, *not* to
 the Buildroot output directory.
 
+.Note:
+If using an br2-external tree from before Buildroot 2016.11, you need to
+convert it before you can use it with Buildroot 2016.11 onward. See
+xref:br2-external-converting[] for help on doing so.
+
 Some examples:
 
 -----
support/scripts/br2-external +6 -1
index 21d7351..281a084 100755
@@ -5,6 +5,10 @@ set -e
 declare BR2_NAME
 declare BR2_EXT
 
+# URL to manual for help in converting old br2-external trees.
+# Escape '#' so that make does not consider it a comment.
+MANUAL_URL='https://buildroot.org/manual/manual.html\#br2-external-converting'
+
 main() {
     local OPT OPTARG
     local br2_ext ofile ofmt
@@ -70,7 +74,8 @@ do_validate() {
         error "'%s': permission denied\n" "${br2_ext}"
     fi
     if [ ! -f "${br2_ext}/external.desc" ]; then
-        error "'%s': does not have a name (in 'external.desc')\n" "${br2_ext}"
+        error "'%s': does not have a name (in 'external.desc'). See %s\n" \
+            "${br2_ext}" "${MANUAL_URL}"
     fi
     br2_name="$(sed -r -e '/^name: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
     if [ -z "${br2_name}" ]; then
Signature · 1 line
2.7.4
#9 lore raw

PATCH v6 8/10 core: add support for multiple br2-external trees

In reply to Yann E. MORIN

Currently, we only support at most one br2-external tree. Being able to use more than one br2-external tree can be very useful.

A use-case would be for having a br2-external to contain the basic packages, basic board defconfigs and board files, provided by one team responsible for the "board-bringup", while other teams consume that br2-external as a base, and complements it each with their own set of packages, defconfigs and extra board files.

Another use-case would be for third-parties to provide their own Buildroot packaging in a br2-external tree, along-side the archives for their stuff.

Finally, another use-case is to be able to add FLOSS packages in a br2-external tree, and proprietary packages in another. This allows to not touch the Buildroot tree at all, and still be able to get in compliance by providing only that br2-external tree(s) that contains FLOSS packages, leaving aside the br2-external tree(s) with the proprietary bits.

What we do is to treat BR2_EXTERNAL as a colon-separated (space- separated also work, and we use that internally) list of paths, on which we iterate to construct:

- the list of all br2-external names, BR2_EXTERNAL_NAMES,

- the per-br2-external tree BR2_EXTERNAL_$(NAME) variables, which point each to the actual location of the corresponding tree,

- the list of paths to all the external.mk files, BR2_EXTERNAL_MKS,

- the space-separated list of absolute paths to the external trees, BR2_EXTERNAL_DIRS.

Once we have all those variables, we replace references to BR2_EXTERNAL with either one of those.

This cascades into how we display the list of defconfigs, so that it is easy to see what br2-external tree provides what defconfigs. As suggested by Arnout, tweak the comment from "User-provided configs" to "External configs", on the assumption that some br2-external trees could be provided by vendors, so not necessarily user-provided. Ditto the menu in Kconfig, changed from "User-provided options" to "External options".

Now, when more than one br2-external tree is used, each gets its own sub-menu in the "User-provided options" menu. The sub-menu is labelled with that br2-external tree's name and the sub-menu's first item is a comment with the path to that br2-external tree.

If there's only one br2-external tree, then there is no sub-menu; there is a single comment that contains the name and path to the br2-external tree.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Romain Naour <[email protected]>
Cc Julien CORJON <[email protected]>
---
 Makefile                     |  57 +++++++++++++--------
 package/pkg-generic.mk       |   4 +-
 support/scripts/br2-external | 117 ++++++++++++++++++++++++++++---------------
 3 files changed, 113 insertions(+), 65 deletions(-)
Makefile +35 -22
index b4bcca2..40e6b74 100644
@@ -143,7 +143,7 @@ $(if $(BASE_DIR),, $(error output directory "$(O)" does not exist))
 # Handling of BR2_EXTERNAL.
 #
 # The value of BR2_EXTERNAL is stored in .br-external in the output directory.
-# The location of the external.mk makefile fragment is computed in that file.
+# The location of the external.mk makefile fragments is computed in that file.
 # On subsequent invocations of make, this file is read in. BR2_EXTERNAL can
 # still be overridden on the command line, therefore the file is re-created
 # every time make is run.
@@ -454,16 +454,15 @@ include boot/common.mk
 include linux/linux.mk
 include fs/common.mk
 
-# If using a br2-external tree, the BR2_EXTERNAL_$(NAME)_PATH variable
-# is also present in the .config file. Since .config is included after
-# we defined BR2_EXTERNAL_$(NAME)_PATH in the Makefile, the value in
-# that variable is quoted. We just include the generated Makefile fragment
-# .br2-external.mk a third time, which will set that variable to the
-# un-quoted value.
+# If using a br2-external tree, the BR2_EXTERNAL_$(NAME)_PATH variables
+# are also present in the .config file. Since .config is included after
+# we defined them in the Makefile, the values for those variables are
+# quoted. We just include the generated Makefile fragment .br2-external.mk
+# a third time, which will set those variables to the un-quoted values.
 include $(BR2_EXTERNAL_FILE)
 
 # Nothing to include if no BR2_EXTERNAL tree in use
-include $(BR2_EXTERNAL_MK)
+include $(BR2_EXTERNAL_MKS)
 
 # Now we are sure we have all the packages scanned and defined. We now
 # check for each package in the list of enabled packages, that all its
@@ -855,7 +854,7 @@ define percent_defconfig
 	@$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@ \
 		$$< --defconfig=$(1)/configs/$$@ $$(CONFIG_CONFIG_IN)
 endef
-$(eval $(foreach d,$(TOPDIR) $(if $(BR2_EXTERNAL_NAME),$(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)),$(call percent_defconfig,$(d))$(sep)))
+$(eval $(foreach d,$(TOPDIR) $(BR2_EXTERNAL_DIRS),$(call percent_defconfig,$(d))$(sep)))
 
 savedefconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig
 	@$(COMMON_CONFIG_ENV) $< \
@@ -978,19 +977,33 @@ help:
 	@echo 'it on-line@http://buildroot.org/docs.html'
 	@echo
 
+# List the defconfig files
+# $(1): base directory
+# $(2): br2-external name, empty for bundled
+define list-defconfigs
+	@first=true; \
+	for defconfig in $(1)/configs/*_defconfig; do \
+		[ -f "$${defconfig}" ] || continue; \
+		if $${first}; then \
+			if [ "$(2)" ]; then \
+				printf "External configs in $(2):\n"; \
+			else \
+				printf "Built-in configs:\n"; \
+			fi; \
+			first=false; \
+		fi; \
+		defconfig="$${defconfig##*/}"; \
+		printf "  %-35s - Build for %s\n" "$${defconfig}" "$${defconfig%_defconfig}"; \
+	done; \
+	$${first} || printf "\n"
+endef
+
+# We iterate over BR2_EXTERNAL_NAMES rather than BR2_EXTERNAL_DIRS,
+# because we want to display the name of the br2-external tree.
 list-defconfigs:
-	@echo 'Built-in configs:'
-	@$(foreach b, $(sort $(notdir $(wildcard $(TOPDIR)/configs/*_defconfig))), \
-	  printf "  %-35s - Build for %s\\n" $(b) $(b:_defconfig=);)
-ifneq ($(BR2_EXTERNAL_NAME),)
-ifneq ($(wildcard $(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)/configs/*_defconfig),)
-	@echo
-	@echo 'User-provided configs:'
-	@$(foreach b, $(sort $(notdir $(wildcard $(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)/configs/*_defconfig))), \
-	  printf "  %-35s - Build for %s\\n" $(b) $(b:_defconfig=);)
-endif
-endif
-	@echo
+	$(call list-defconfigs,$(TOPDIR))
+	$(foreach name,$(BR2_EXTERNAL_NAMES),\
+		$(call list-defconfigs,$(BR2_EXTERNAL_$(name)_PATH),$(name))$(sep))
 
 release: OUT = buildroot-$(BR2_VERSION)
 
@@ -1009,7 +1022,7 @@ print-version:
 	@echo $(BR2_VERSION_FULL)
 
 include docs/manual/manual.mk
--include $(if $(BR2_EXTERNAL_NAME),$(BR2_EXTERNAL_$(BR2_EXTERNAL_NAME)_PATH)/docs/*/*.mk)
+-include $(foreach dir,$(BR2_EXTERNAL_DIRS),$(dir)/docs/*/*.mk)
 
 .PHONY: $(noconfig_targets)
 
package/pkg-generic.mk +2 -2
index 946244e..0737fa1 100644
@@ -767,9 +767,9 @@ $$($(2)_TARGET_DIRCLEAN):		PKG=$(2)
 # kernel case, the bootloaders case, and the normal packages case.
 ifeq ($(1),linux)
 $(2)_KCONFIG_VAR = BR2_LINUX_KERNEL
-else ifneq ($$(filter boot/% $$(if $$(BR2_EXTERNAL_NAME),$$(BR2_EXTERNAL_$$(BR2_EXTERNAL_NAME)_PATH)/boot/%),$(pkgdir)),)
+else ifneq ($$(filter boot/% $$(foreach dir,$$(BR2_EXTERNAL_DIRS),$$(dir)/boot/%),$(pkgdir)),)
 $(2)_KCONFIG_VAR = BR2_TARGET_$(2)
-else ifneq ($$(filter toolchain/% $$(if $$(BR2_EXTERNAL_NAME),$$(BR2_EXTERNAL_$$(BR2_EXTERNAL_NAME)_PATH)/toolchain/%),$(pkgdir)),)
+else ifneq ($$(filter toolchain/% $$(foreach dir,$$(BR2_EXTERNAL_DIRS),$$(dir)/toolchain/%),$(pkgdir)),)
 $(2)_KCONFIG_VAR = BR2_$(2)
 else
 $(2)_KCONFIG_VAR = BR2_PACKAGE_$(2)
support/scripts/br2-external +76 -41

194 lines not on this page · raw message

Signature · 1 line
2.7.4
#10 lore raw

PATCH v6 9/10 docs/manual: document multi br2-external

In reply to Yann E. MORIN
Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Samuel Martin <[email protected]>
Cc Romain Naour <[email protected]>
Cc Julien CORJON <[email protected]>
---
 docs/manual/br2-external-converting.txt |  9 ++++--
 docs/manual/customize-outside-br.txt    | 49 ++++++++++++++++++++++++---------
 2 files changed, 42 insertions(+), 16 deletions(-)
docs/manual/br2-external-converting.txt +6 -3
index b207601..9c7a168 100644
@@ -4,9 +4,12 @@
 [[br2-external-converting]]
 == Converting old br2-external trees
 
-Buildroot 2016.11 introduced a backward-incompatible change in the way
-br2-external trees are handled. A minor change has to be made: adding
-a name to your br2-external tree, see xref:outside-br-custom[].
+Before Buildroot 2016.11, it was possible to use only one br2-external
+tree at once. With Buildroot 2016.11 came the possibility to use more
+than one simultaneously (for details, see xref:outside-br-custom[]).
+
+This however means that older br2-external trees are not usable as-is.
+A minor change has to be made: adding a name to your br2-external tree.
 
 This can be done very easily in just a few steps:
 
docs/manual/customize-outside-br.txt +36 -13

92 lines not on this page · raw message

Signature · 1 line
2.7.4
#11 lore raw

PATCH v6 10/10 core: allow a br2-external tree to override a defconfig

In reply to Yann E. MORIN

Currently, it is not possible for a br2-external tree to override a defconfig bundled in Buildroot, nor is it possible to override one from a previous br2-external tree in the stack.

However, it is interesting that a latter br2-external tree be able to override a defconfig:

- the ones bundled in Buildroot are minimalist, and almost always build a toolchain, so a br2-external tree may want to provide a "better" defconfig (better, in the sense "suited for the project");

- similarly for a defconfig from a previous br2-external tree.

But we can't do that, as the rules for the defconfigs are generated in the order the br2-external trees are specified, all after the bundled defconfigs. Those rule are patten-matching rules, which means that the first one to match is used, and the following ones are ignored.

Add a new utility macro, 'reverse', inspired from GMSL, that does what it says: reverse a list of words.

Use that macro to reverse the list of br2-external trees, so that the latters win over the formers, and even over bundled ones.

Cc Thomas Petazzoni <[email protected]>
Cc Arnout Vandecappelle <[email protected]>
Cc Samuel Martin <[email protected]>
Cc Romain Naour <[email protected]>
Cc Julien CORJON <[email protected]>
---
 Makefile                             | 2 +-
 docs/manual/customize-outside-br.txt | 5 +++--
 support/misc/utils.mk                | 4 ++++
 3 files changed, 8 insertions(+), 3 deletions(-)
Makefile +1 -1
index 40e6b74..67a0b5c 100644
@@ -854,7 +854,7 @@ define percent_defconfig
 	@$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@ \
 		$$< --defconfig=$(1)/configs/$$@ $$(CONFIG_CONFIG_IN)
 endef
-$(eval $(foreach d,$(TOPDIR) $(BR2_EXTERNAL_DIRS),$(call percent_defconfig,$(d))$(sep)))
+$(eval $(foreach d,$(call reverse,$(TOPDIR) $(BR2_EXTERNAL_DIRS)),$(call percent_defconfig,$(d))$(sep)))
 
 savedefconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig
 	@$(COMMON_CONFIG_ENV) $< \
docs/manual/customize-outside-br.txt +3 -2
index 09977e0..4c0f568 100644
@@ -169,5 +169,6 @@ And then in +$(BR2_EXTERNAL_FOO_42_PATH)/package/package1+ and
 +
 .Note:
 If a defconfig file is present in more than one br2-external tree, then
-   the first one is used. It is not possible to override a defconfig
-   bundled in Buildroot.
+   the one from the last br2-external tree is used. It is thus possible
+   to override a defconfig bundled in Buildroot or another br2-external
+   tree.
support/misc/utils.mk +4 -0
index 990a3d1..c443193 100644
@@ -46,6 +46,10 @@ endef
 $(eval $(call caseconvert-helper,UPPERCASE,$(join $(addsuffix :,$([FROM])),$([TO]))))
 $(eval $(call caseconvert-helper,LOWERCASE,$(join $(addsuffix :,$([TO])),$([FROM]))))
 
+# Reverse the orders of words in a list. Again, inspired by the gmsl
+# 'reverse' macro.
+reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1))) $(firstword $(1)))
+
 # Sanitize macro cleans up generic strings so it can be used as a filename
 # and in rules. Particularly useful for VCS version strings, that can contain
 # slashes, colons (OK in filenames but not in rules), and spaces.
Signature · 1 line
2.7.4