Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makefile.include: introduce 'BOARDSDIR' for boards directory #12183

Merged
merged 10 commits into from
Dec 16, 2019

Conversation

cladmi
Copy link
Contributor

@cladmi cladmi commented Sep 9, 2019

Contribution description

Introduce a new variable 'BOARDSDIR' to use when referencing the base
boards directory.

The goal is to replace using 'RIOTBOARD' by 'BOARDSDIR' to define external boards. With this, external boards could still use 'RIOTBOARD' to use, for example, 'RIOT/boards/common' files.

Help needed

Naming

Does the name fit? I tried something that was not prepended by RIOT directly to say it is not a RIOT/something directory, but ended up not being namespaced anymore.
I did not use 'external' either, as it should be the one used when refering to boards inside riot too.

I can replace it and update all the commit messages accordingly, it was easier to go with something and test than wait until I find the right name.

Documentation

Was there a documentation to say to use RIOTBOARD for external boards? a git grep finds nothing.

I can add a documentation in http://doc.riot-os.org/advanced-build-system-tricks.html

Does it fit your needs?

Does the wrapping works for you?

It did the choice to not overwrite the variable anymore even if set from the command line (make BOARDSDIR=lala) as it is not a normal make behavior.

The implementation also still does `BOARDSDIR := $(

Special for @bergzand

No currently I do not pass this variable to riotboot when building the bootloader as RIOTBOARD was not passed either.

Testing procedure

I added an example in tests/external_board_native/ that declares an external native board. Using native name will allow murdock to run the test.

make --no-print-directory -C tests/external_board_native/ flash test
make --no-print-directory -C tests/external_board_native/ flash test 
Building application "external_board" for "native" with MCU "native".

"make" -C /home/harter/work/git/RIOT/core
"make" -C /home/harter/work/git/RIOT/cpu/native
"make" -C /home/harter/work/git/RIOT/cpu/native/periph
"make" -C /home/harter/work/git/RIOT/cpu/native/vfs
"make" -C /home/harter/work/git/RIOT/drivers
"make" -C /home/harter/work/git/RIOT/drivers/periph_common
"make" -C /home/harter/work/git/RIOT/sys
"make" -C /home/harter/work/git/RIOT/sys/auto_init
"make" -C /home/harter/work/git/RIOT/tests/external_board_native/external_boards/native
"make" -C /home/harter/work/git/RIOT/boards/native
"make" -C /home/harter/work/git/RIOT/boards/native/drivers
   text    data     bss     dec     hex filename
  20410     572   47652   68634   10c1a /home/harter/work/git/RIOT/tests/external_board_native/bin/native/external_board.elf
true 
/home/harter/work/git/RIOT/tests/external_board_native/bin/native/external_board.elf  
RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2019.10-devel-693-g7b80d-pr/boardsdir)
Hello World!
You are running RIOT on a(n) native board.
THIS_BOARD_IS external_native
This board is 'An external extended native'
Test successful!!

Listing boards only lists the external boards. It is not a boards path search implementation.

make --no-print-directory -C tests/external_board_native/ info-boards
native

Building in docker is supported. I implemented it such as the BOARDSDIR is always set from the command line (when not RIOTBOARD), to allow overwriting any value that could be set in the makefile to an absolute path not depending on build path.

As I am building on an ubuntu:bionic, as our docker image, I can even run the native executable locally.

BUILD_IN_DOCKER=1 DOCKER="sudo docker" make --no-print-directory -C tests/external_board_native/ flash test
BUILD_IN_DOCKER=1 DOCKER="sudo docker" make --no-print-directory -C tests/external_board_native/ flash test 
Launching build container using image "riot/riotbuild:latest".
sudo docker run --rm -t -u "$(id -u)" \
    -v '/usr/share/zoneinfo/Europe/Berlin:/etc/localtime:ro' -v '/home/harter/work/git/RIOT:/data/riotbuild/riotbase' -e 'RIOTBASE=/data/riotbuild/riotbase' -e 'CCACHE_BASEDIR=/data/riotbuild/riotbase' -e 'BUILD_DIR=/data/riotbuild/riotbase/build' -e 'RIOTPROJECT=/data/riotbuild/riotbase' -e 'RIOTCPU=/data/riotbuild/riotbase/cpu' -e 'RIOTBOARD=/data/riotbuild/riotbase/boards' -e 'RIOTMAKE=/data/riotbuild/riotbase/makefiles' -v /home/harter/.gitcache:/data/riotbuild/gitcache -e GIT_CACHE_DIR=/data/riotbuild/gitcache    \
     \
    -w '/data/riotbuild/riotbase/tests/external_board_native/' \
    'riot/riotbuild:latest' make    'BOARDSDIR=/data/riotbuild/riotbase/tests/external_board_native/external_boards'
[sudo] password for harter: 
Building application "external_board" for "native" with MCU "native".

"make" -C /data/riotbuild/riotbase/core
"make" -C /data/riotbuild/riotbase/cpu/native
"make" -C /data/riotbuild/riotbase/cpu/native/periph
"make" -C /data/riotbuild/riotbase/cpu/native/vfs
"make" -C /data/riotbuild/riotbase/drivers
"make" -C /data/riotbuild/riotbase/drivers/periph_common
"make" -C /data/riotbuild/riotbase/sys
"make" -C /data/riotbuild/riotbase/sys/auto_init
"make" -C /data/riotbuild/riotbase/tests/external_board_native/external_boards/native
"make" -C /data/riotbuild/riotbase/boards/native
"make" -C /data/riotbuild/riotbase/boards/native/drivers
   text    data     bss     dec     hex filename
  20410     572   47652   68634   10c1a /data/riotbuild/riotbase/tests/external_board_native/bin/native/external_board.elf
true 
/home/harter/work/git/RIOT/tests/external_board_native/bin/native/external_board.elf  
RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2019.10-devel-693-g7b80d-pr/boardsdir)
Hello World!
You are running RIOT on a(n) native board.
THIS_BOARD_IS external_native
This board is 'An external extended native'
Test successful!!

When the directory is not in RIOT, the mounting is handled correctly:

Build in docker with out of tree `BOARDSDIR`
cp tests/external_board_native/external_boards/ /tmp -r
BUILD_IN_DOCKER=1 DOCKER="sudo docker" make --no-print-directory -C tests/external_board_native/ clean flash test  BOARDSDIR=/tmp/external_boards/
Launching build container using image "riot/riotbuild:latest".
sudo docker run --rm -t -u "$(id -u)" \
    -v '/usr/share/zoneinfo/Europe/Berlin:/etc/localtime:ro' -v '/home/harter/work/git/RIOT:/data/riotbuild/riotbase' -e 'RIOTBASE=/data/riotbuild/riotbase' -e 'CCACHE_BASEDIR=/data/riotbuild/riotbase' -e 'BUILD_DIR=/data/riotbuild/riotbase/build' -e 'RIOTPROJECT=/data/riotbuild/riotbase' -e 'RIOTCPU=/data/riotbuild/riotbase/cpu' -e 'RIOTBOARD=/data/riotbuild/riotbase/boards' -e 'RIOTMAKE=/data/riotbuild/riotbase/makefiles' -v /home/harter/.gitcache:/data/riotbuild/gitcache -e GIT_CACHE_DIR=/data/riotbuild/gitcache   -v '/tmp/external_boards:/data/riotbuild/boards'  \
     \
    -w '/data/riotbuild/riotbase/tests/external_board_native/' \
    'riot/riotbuild:latest' make    'BOARDSDIR=/data/riotbuild/boards'
Building application "external_board" for "native" with MCU "native".

"make" -C /data/riotbuild/boards/native
"make" -C /data/riotbuild/riotbase/boards/native
"make" -C /data/riotbuild/riotbase/boards/native/drivers
"make" -C /data/riotbuild/riotbase/core
"make" -C /data/riotbuild/riotbase/cpu/native
"make" -C /data/riotbuild/riotbase/cpu/native/periph
"make" -C /data/riotbuild/riotbase/cpu/native/vfs
"make" -C /data/riotbuild/riotbase/drivers
"make" -C /data/riotbuild/riotbase/drivers/periph_common
"make" -C /data/riotbuild/riotbase/sys
"make" -C /data/riotbuild/riotbase/sys/auto_init
   text    data     bss     dec     hex filename
  20410     572   47652   68634   10c1a /data/riotbuild/riotbase/tests/external_board_native/bin/native/external_board.elf
true
/home/harter/work/git/RIOT/tests/external_board_native/bin/native/external_board.elf
RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2019.10-devel-693-g7b80d-pr/boardsdir)
Hello World!
You are running RIOT on a(n) native board.
THIS_BOARD_IS external_native
This board is 'An external extended native'
Test successful!!

Building a normal example does not show any BOARDSDIR handling in docker as it should
BUILD_IN_DOCKER=1 DOCKER="sudo docker" make --no-print-directory -C examples/hello-world/ 
Launching build container using image "riot/riotbuild:latest".
sudo docker run --rm -t -u "$(id -u)" \
    -v '/usr/share/zoneinfo/Europe/Berlin:/etc/localtime:ro' -v '/home/harter/work/git/RIOT:/data/riotbuild/riotbase' -e 'RIOTBASE=/data/riotbuild/riotbase' -e 'CCACHE_BASEDIR=/data/riotbuild/riotbase' -e 'BUILD_DIR=/data/riotbuild/riotbase/build' -e 'RIOTPROJECT=/data/riotbuild/riotbase' -e 'RIOTCPU=/data/riotbuild/riotbase/cpu' -e 'RIOTBOARD=/data/riotbuild/riotbase/boards' -e 'RIOTMAKE=/data/riotbuild/riotbase/makefiles' -v /home/harter/.gitcache:/data/riotbuild/gitcache -e GIT_CACHE_DIR=/data/riotbuild/gitcache    \
     \
    -w '/data/riotbuild/riotbase/examples/hello-world/' \
    'riot/riotbuild:latest' make    
Building application "hello-world" for "native" with MCU "native".
...

Issues/PRs references

Was referenced as an issue in #11155
Also talked about it with different persons during the RIOT summit.

@cladmi
Copy link
Contributor Author

cladmi commented Sep 9, 2019

@bergzand Finally something for your issue :)

@vincent-d @javierfileiv @toonst I think you were all interested by this. Please complain if it does not work for your need, I want an implementation that can be used.

@miri64 miri64 requested review from smlng and kaspar030 September 10, 2019 13:15
@miri64 miri64 added Area: build system Area: Build system Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation labels Sep 10, 2019
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Sep 30, 2019
@benpicco
Copy link
Contributor

Travis is not happy:

	Invalid build system patterns found by ./dist/tools/buildsystem_sanity_check/check.sh:
	Applications Makefile should use "BOARD ?="
		tests/external_board_native/Makefile:BOARD = native

@cladmi
Copy link
Contributor Author

cladmi commented Oct 1, 2019

Travis is not happy:

	Invalid build system patterns found by ./dist/tools/buildsystem_sanity_check/check.sh:
	Applications Makefile should use "BOARD ?="
		tests/external_board_native/Makefile:BOARD = native

Indeed, I also added a comment to describe that there is not need for a WHITELIST. It was the low level reason that made me do this = here but was wrong on my side.

@aabadie
Copy link
Contributor

aabadie commented Oct 14, 2019

I will review this soon because I think this is very useful. At first sight the PR seems in a good shape (with tests and documentation).

@aabadie
Copy link
Contributor

aabadie commented Oct 14, 2019

You can squash the squash commit since no code review was already started AFAICS.

@aabadie aabadie self-requested a review October 14, 2019 17:29
@cladmi
Copy link
Contributor Author

cladmi commented Oct 14, 2019

You can squash the squash commit since no code review was already started AFAICS.

I squashed the fixup for BOARD ?= and rebased on master.

@javierfileiv
Copy link
Contributor

javierfileiv commented Oct 28, 2019

Hi everyone... I was checking this MR on Mac OS and there is a problem with the build that I've solve changing this lines

$(RIOTBUILD_CONFIG_HEADER_C): $(RIOTBUILD_CONFIG_HEADER_C).in
	$(Q)sed -n -e '1i /* Generated file do not edit */' -e '/^#.*/ p' $< > $@

.SECONDARY: $(RIOTBUILD_CONFIG_HEADER_C).in
$(RIOTBUILD_CONFIG_HEADER_C).in: FORCE | $(CLEAN)
	@mkdir -p '$(dir $@)'
	$(Q)'$(RIOTTOOLS)/genconfigheader/genconfigheader.sh' $(CFLAGS_WITH_MACROS) \
		| '$(LAZYSPONGE)' $(LAZYSPONGE_FLAGS) '$@'

I commented the line using sed for Mac as it doesn't work and I didn't understand why are we generating riotbuild.h.in, I guess it's not to create it several times if CFLAGS had not change.
I was able to test it in mac commenting that line and it's working OK but I don't know how to make it work with them.

@benpicco
Copy link
Contributor

@javierfileiv does this patch work for you #12435 ?

@javierfileiv
Copy link
Contributor

javierfileiv commented Oct 28, 2019

@benpicco Thanks! Actually I solved it installing gnu sed with homebrew and changing the path as its shown below as @vincent-d told me to do! :)

First line on rc file:

# Add gnu make as default
export PATH="/usr/local/opt/make/libexec/gnubin:$PATH"
export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"

Beside that little problem, everything was working fine for me.

@benpicco
Copy link
Contributor

Can you also give #12435 a try?
If it solves a build issue on OS X we should probably backport it into the upcoming release.

@benpicco
Copy link
Contributor

@cladmi I like the PR!
But may I suggest a small addition:

diff --git a/Makefile.include b/Makefile.include
index 20901af1d..93f1314a7 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -248,6 +248,11 @@ ifeq (,$(UNZIP_HERE))
   endif
 endif
 
+# allow fall-back to upstream boards if BOARDSDIR is set to a custom value
+ifneq (0,$(shell test -d $(BOARDSDIR)/$(BOARD); echo $$?))
+    BOARDSDIR := $(RIOTBOARD)
+endif
+
 # Tool saving stdin to a file only on content update.
 # It keeps the file timestamp if it would end up the same.
 LAZYSPONGE ?= $(RIOTTOOLS)/lazysponge/lazysponge.py

This way you can still use the upstream boards even when BOARDSDIR is set.
I like being able to run the same tests on dev boards as well as on custom board and I find myself switching around between them often.

This way I can set BOARDSDIR to my custom board directory, but still am able to use all the standard boards.

@javierfileiv
Copy link
Contributor

Can you also give #12435 a try?
If it solves a build issue on OS X we should probably backport it into the upcoming release.

I was testing it wrong... it didn't work on my MAC... what I can do it's just pull the PR and try it but I guess I did the mods he has done

@benpicco
Copy link
Contributor

@javierfileiv You can just apply the patch directly:

curl https://github.com/RIOT-OS/RIOT/commit/ec869ebef9eab6e39cdb01c9c43f8ebb24b4d3dc.patch | patch -p1

@javierfileiv
Copy link
Contributor

Thank @benpicco ... it didn't work... actually riotbuild.h.in gets generated but riotbuild.h it's empty. What I have done before knowing @vincent-d patch was to only create riotbuild.h, without using the .in file. But as I said before, with the steps that Vincent told me was working flawlessly

@cladmi
Copy link
Contributor Author

cladmi commented Oct 30, 2019

Hi everyone... I was checking this MR on Mac OS and there is a problem with the build that I've solve changing this lines

$(RIOTBUILD_CONFIG_HEADER_C): $(RIOTBUILD_CONFIG_HEADER_C).in
	$(Q)sed -n -e '1i /* Generated file do not edit */' -e '/^#.*/ p' $< > $@

.SECONDARY: $(RIOTBUILD_CONFIG_HEADER_C).in
$(RIOTBUILD_CONFIG_HEADER_C).in: FORCE | $(CLEAN)
	@mkdir -p '$(dir $@)'
	$(Q)'$(RIOTTOOLS)/genconfigheader/genconfigheader.sh' $(CFLAGS_WITH_MACROS) \
		| '$(LAZYSPONGE)' $(LAZYSPONGE_FLAGS) '$@'

I commented the line using sed for Mac as it doesn't work and I didn't understand why are we generating riotbuild.h.in, I guess it's not to create it several times if CFLAGS had not change.
I was able to test it in mac commenting that line and it's working OK but I don't know how to make it work with them.

The riotbuild.h.in was introduced to still have a newly created file on CFLAGS change, but not include them in the final file riotbuild.h as it caused ccache issues with a full path in a comment.
#12348

The issue here must be with the sed command with multiple -e which has a different handling on osx. I though multiple -e would work but it did not.

@cladmi
Copy link
Contributor Author

cladmi commented Oct 30, 2019

@cladmi I like the PR!
But may I suggest a small addition:

diff --git a/Makefile.include b/Makefile.include
index 20901af1d..93f1314a7 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -248,6 +248,11 @@ ifeq (,$(UNZIP_HERE))
   endif
 endif
 
+# allow fall-back to upstream boards if BOARDSDIR is set to a custom value
+ifneq (0,$(shell test -d $(BOARDSDIR)/$(BOARD); echo $$?))
+    BOARDSDIR := $(RIOTBOARD)
+endif
+
 # Tool saving stdin to a file only on content update.
 # It keeps the file timestamp if it would end up the same.
 LAZYSPONGE ?= $(RIOTTOOLS)/lazysponge/lazysponge.py

This way you can still use the upstream boards even when BOARDSDIR is set.
I like being able to run the same tests on dev boards as well as on custom board and I find myself switching around between them often.

This way I can set BOARDSDIR to my custom board directory, but still am able to use all the standard boards.

This half handling of a board PATH would break the make info-boards-supported and related commands. It would be nice for one usage but not for the system in general. So half broken by design. If you need a per board BOARDSDIR you can change it per board in a RIOT_MAKEFILES_GLOBAL_PRE and bear the inconsistencies.
You can try adding it in another PR with detailed justification and adapted specific testing procedure.

Also this implementation relies on calling the shell and doing := for nothing.

Makefile.include Outdated Show resolved Hide resolved
Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in general and ACK for BOARDSDIR variable name.

The testing procedure is well described and is working. Also thanks for providing a test. I found a couple of typos, that's why I'm requesting changes. You can squash the fixes right away and we'll be good to go.

I agree that @benpicco's improvement suggestion can be done in a follow-up PR (and will need careful review, e.g without use of shell and := ;) ).

@cladmi
Copy link
Contributor Author

cladmi commented Dec 12, 2019

Agreed, but you can also port an external board without reusing anything from boards/common. This is why I marked these lines as 'misleading'.

It would then be the same as implementing as a normal board that does not use any common (I had no idea what was required for this tbh so never wrote it), except an appendix to say to overwrite BOARDSDIR. But giving it a special place so it is visible is also good for the companies case.

So in here, adding comments like "Include the common Makefile.dep, this board is implemented as if $(RIOTBOARD)/native was a $(RIOTBOARD)/common/native" could be better.

Feel free to push the changes you would like directly.

@fjmolinas
Copy link
Contributor

@dylad @aabadie I agree with the fact that the documentation here is not very clear, or can be confusing when looking at the test example. It would indead be good to document how to port a BOARD, the documentation on this is spread out and would be great to add.

I propose we open a follow-up PR extending the documentation and limit this one to the technical feature. This to ease up future changes since the original contributor isn't active anymore (@cladmi commented but isn't developping anymore)

Other than that there is still something I would like to see in this PR and is to generally fallback to setting BOARDSDIR to RIOTBOARD if a BOARD is not found in BOARDSDIR. I did this in #12952 commits 0b385b0, c9ad7ff and 8d24270. What do you think?

@dylad
Copy link
Member

dylad commented Dec 16, 2019

This is a very useful feature so I'm not opposed to merge it as it now and improve the documentation later.

I would like to see in this PR and is to generally fallback to setting BOARDSDIR to RIOTBOARD if a BOARD is not found in BOARDSDIR

I have no strong opinion on this point as long as it doesn't duplicate or complicate stuff in the build system.

@fjmolinas
Copy link
Contributor

I would like to see in this PR and is to generally fallback to setting BOARDSDIR to RIOTBOARD if a BOARD is not found in BOARDSDIR

I have no strong opinion on this point as long as it doesn't duplicate or complicate stuff in the build system.

Ok, lets handle this in another PR then, and discuss it there.

Copy link
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK on my side,
Works as intented.

@fjmolinas
Copy link
Contributor

I opened an issue #12963 for the documentation and auto-assigned it to myself, I'll deal with it at soon as possible and before the end of this release cycle (unless someone does it before).

@dylad
Copy link
Member

dylad commented Dec 16, 2019

@aabadie Do you have any more changes request pending ?

@aabadie
Copy link
Contributor

aabadie commented Dec 16, 2019

There's a problem with the static tests. I'll have a look.

cladmi and others added 10 commits December 16, 2019 15:35
Allow defining new directory variables that will not be overridden when
set from command line.

Command line is supposed to override from the value in make.
Promoting another behavior is against `make`.
Introduce a new variable 'BOARDSDIR' to use when referencing the base
boards directory.

This is a transition to allow defining external boards while still using
the `RIOT/boards` directory for like `boards/common` for example through
'RIOTBOARD'.
Replace uses of 'RIOTBOARD' by 'BOARDSDIR' during the compilation.
Replace uses of 'RIOTBOARD' by 'BOARDSDIR' for tools.
Handle setting 'BOARDSDIR' when building in docker.
Replace using 'RIOTBOARD' by 'BOARDSDIR' to define external boards.
Add an example that implements an external board based on native.
It relies on 'BOARDSDIR' and uses common files from 'RIOT/boards'
through 'RIOTBOARDS'.

This application also works with the docker integration.
Replace uses of 'RIOTBOARD' by 'BOARDSDIR' in examples.
Replace using 'RIOTBOARD' by 'BOARDSDIR' to define external boards.
This test application must act as a regular application to showcase how to provide a board support from an external directory
@aabadie
Copy link
Contributor

aabadie commented Dec 16, 2019

I pushed I fix: exclude the new test application from one of the build system static test. Straight forward. If you are fine with this @dylad, then I'll approve this PR.

@dylad
Copy link
Member

dylad commented Dec 16, 2019

@aabadie Let's move forward. I'm happy with the current state.

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@dylad
Copy link
Member

dylad commented Dec 16, 2019

Here we go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: build system Area: Build system CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants