Skip to content

make: allow alias for board names #7976

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

Closed
wants to merge 8 commits into from

Conversation

haukepetersen
Copy link
Contributor

Some boards have unique, but quite ugly names (e.g. pba-d-01-kw2x) and we use different names in the day-to-day operation (e.g. phynode for the former). Event though this 'nicer' name ist not a 100% correct (as there are also phynodes based on other CPUs out there, just not in the RIOT universe...), it is sometimes much easier to remember and use. Also, there are some boards that have a specific, cryptic name (e.g. SLTB001A), but also a nice user friendly one (thunderboard-sense in that case). So I think it would be nice, to be able to use both (or even more?) aliases for a certain board.

This PR contains a quick draft, on how this could be implemented. It works, but is it nice enough?

BOARD=phynode make ...   -> will build `BOARD=pba-d-01-kw2x`
BOARD=linux make ... -> will build 'BOARD=native`, just for demo purposes...

Maybe we can even think of something that combines this approach with my idea about board revisions ( #7975). What do you think?

@haukepetersen haukepetersen added Area: boards Area: Board ports Area: build system Area: Build system Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Nov 9, 2017
Copy link
Member

@jnohlgard jnohlgard left a comment

Choose a reason for hiding this comment

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

See my comments inline.
It might make the file a bit more readable if we use the variable inside variable names look up table design pattern. I don't think it is possible to abuse the variable name lookup by setting malicious values for BOARD, because it will always have the prefix BOARD_ALIAS_ regardless of what BOARD is set to.

ifneq (,$(filter phynode,$(BOARD)))
BOARD := pba-d-01-kw2x
endif
ifneq (,$(filter linux,$(BOARD)))
Copy link
Member

Choose a reason for hiding this comment

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

  • Ditch the filter call, BOARD is a single value, not a list.
  • Make this an else if

else ifneq (linux, $(BOARD))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, makes sense -> gotten so used to the filter thing that I don't even question it anymore as it seems :-)

@@ -0,0 +1,9 @@
ALIAS = linux phynode

# this basically implements a look-up table, is there a nicer way in make?
Copy link
Member

Choose a reason for hiding this comment

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

the only other way that I know of is using variables inside variable names, but it's ugly in a different way.

BOARD_ALIAS_linux = native
BOARD_ALIAS_phynode = pba-d-01-kw2x
ifneq (,$(BOARD_ALIAS_$(BOARD)))
  override BOARD = $(BOARD_ALIAS_$(BOARD))
endif


# this basically implements a look-up table, is there a nicer way in make?
ifneq (,$(filter phynode,$(BOARD)))
BOARD := pba-d-01-kw2x
Copy link
Member

Choose a reason for hiding this comment

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

This needs override in order to be able to replace the BOARD setting if given on the command line: make BOARD=linux, instead of BOARD=linux make or export BOARD=linux

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it worked without the override, but maybe that war more a coincidence then? Anyway, makes much sense and I will fix this.

@@ -0,0 +1,9 @@
ALIAS = linux phynode
Copy link
Member

Choose a reason for hiding this comment

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

this is unused as far as I can see?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, leftover from some earlier playing around... Seems like i forgot to delete it.

@jnohlgard
Copy link
Member

I like the idea of having easier to remember names for some of the boards, especially the pba-d-01-kw2x was one that I kept having trouble remembering at first..

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.

I like the idea.

I propose another solution for the lookup table, see the comment below. What do you think ?

@@ -0,0 +1,9 @@
ALIAS = linux phynode
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this line for ?

@@ -0,0 +1,9 @@
ALIAS = linux phynode

# this basically implements a look-up table, is there a nicer way in make?
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this SO thread could be the start of a solution.

What about:

# pba-d-01-kw2x Makefile:
BOARD_ALIAS += phynode

# native Makefile:
BOARD_ALIAS += linux raspberrypi ubuntu

# in alias.inc.mk:
alias.phynode := pba-d-01-kw2x
alias.linux := native

ifneq (,$(filter $(BOARD), $(BOARD_ALIAS)))
  BOARD := ${alias.${BOARD}}
endif

Not sure if it works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This won't work per se, as the contents of the board makefiles are not yet known when parsing the alias.inc.mk file. In fact, the board can only be started to be parsed after the alias has been resolved...

But think I like the idea using variable names, will provide another draft of this

@aabadie
Copy link
Contributor

aabadie commented Nov 9, 2017

@gebart, you were faster :)

@haukepetersen
Copy link
Contributor Author

how about this?

@haukepetersen
Copy link
Contributor Author

wait, now the non-aliased targets don't work anymore... Will provide a fix.

@haukepetersen
Copy link
Contributor Author

done. Now what do you think about this solution?

#TODO remove this line (as its just for show)
ALIAS.linux = native

# this temporary variable is needed as we can not use BOARD when assigning BOARD
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see how this can work. How about filling a list of existing alias on a per board basis and if the BOARD name is found in this list, use the alias trick ? (as I suggested in one of my previous comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for one: it does :-)
second: this basically checks the list of defined aliases above, and if it finds a fitting entry the board variable is substituted. I think makes calls this concept Computed Variable Names

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why you think this doesn't work?
All of the alias definitions are on the lines above.
If BOARD is set to linux, then ALIAS_TARGET will be assigned the value $(ALIAS.linux), which evaluates to native.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh ok, now I have it.


# this temporary variable is needed as we can not use BOARD when assigning BOARD
ALIAS_TARGET := $(ALIAS.$(BOARD))
ifdef ALIAS_TARGET
Copy link
Member

Choose a reason for hiding this comment

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

Better to check for non-empty value: ifneq (,$(ALIAS_TARGET))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually, this did for some reason not work. Not sure if I had a typo or if something else went wrong. Could you maybe quickly verify if the non-empty value check works for you?

#TODO remove this line (as its just for show)
ALIAS.linux = native

# this temporary variable is needed as we can not use BOARD when assigning BOARD
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why you think this doesn't work?
All of the alias definitions are on the lines above.
If BOARD is set to linux, then ALIAS_TARGET will be assigned the value $(ALIAS.linux), which evaluates to native.

@haukepetersen
Copy link
Contributor Author

@gebart never mind, seems like a had some kind of typo in my file... Works now like a charm

@aabadie
Copy link
Contributor

aabadie commented Nov 9, 2017

I tried to build one of the example applications and it doesn't build. Changing the BOARD variable with an alias has some unwanted effect on the build:

$  make BOARD=linux -C examples/hello-world/ all term
make: Entering directory '/home/aabadie/RIOT/examples/hello-world'
Building application "hello-world" for "native" with MCU "native".

"make" -C /home/aabadie/RIOT/boards/linux
make[2]: *** /home/aabadie/boards/linux: No such file or directory.  Stop.
/home/aabadie/RIOT/Makefile.base:20: recipe for target 'ALL--/home/aabadie/RIOT/boards/linux' failed
make[1]: *** [ALL--/home/aabadie/RIOT/boards/linux] Error 2
/home/aabadie/RIOT/examples/hello-world/../../Makefile.include:309: recipe for target 'link' failed
make: *** [link] Error 2
make: Leaving directory '/home/aabadie/RIOT/examples/hello-world'

@haukepetersen
Copy link
Contributor Author

arg... I'd seem to never understand the different handling of env variables dependent on how one sets them. In this case, the override BOARD... line seems to have not effect.

It seems to me, that when calling make like you do, the given BOARD value preceeds the one exported by vars.inc.mk. But why, I can't say, seems like my understanding on the way the processes are created and given their environment is limited here. Anyone?

@haukepetersen
Copy link
Contributor Author

Hm, as I understand it, the override should take care of making sure that our version of the BOARD var instead of the one passed from the command line is used in all spawned make calls. Strange...

@cladmi
Copy link
Contributor

cladmi commented Nov 9, 2017

If I understood correctly, override only overrides values from environment variables, for command line it should be done with MAKEOVERRIDES.
That's why in Makefile.include both are done.

ALIAS.linux = native

# this temporary variable is needed as we can not use BOARD when assigning BOARD
ALIAS_TARGET := $(ALIAS.$(BOARD))
Copy link
Contributor

Choose a reason for hiding this comment

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

ALIAS_TARGET is just used in here but is a generic name, I would like to see it namespaced, and so use BOARD_ALIAS_TARGET, or just BOARD_ALIAS.

# this temporary variable is needed as we can not use BOARD when assigning BOARD
ALIAS_TARGET := $(ALIAS.$(BOARD))
ifneq (,$(ALIAS_TARGET))
override BOARD = $(ALIAS_TARGET)
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't this have to be BOARD := $(ALIAS_TARGET)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In general yes, and also tried that, but does not solve the problem above.

@haukepetersen
Copy link
Contributor Author

adding BOARD to MAKEFILEOVERRIDES does also not solve the issue at hand:

ifneq (,$(ALIAS_TARGET))
  override BOARD := $(ALIAS_TARGET)
  MAKEOVERRIDES += BOARD
endif

Am I misunderstanding the usage of this var?

@cladmi
Copy link
Contributor

cladmi commented Nov 10, 2017

MAKEOVERRIDES += BOARD=$(BOARD) It works with it.

The reason why we need these two, is because we are using recursive makefiles and want to modify the values.

@haukepetersen
Copy link
Contributor Author

@cladmi thanks, that was it!

@aabadie: would you mind to try again? Should work now...

@aabadie
Copy link
Contributor

aabadie commented Nov 10, 2017

Just tested again: works now.

Some side comments:

  • should we integrate this in the CI and if yes, how ?
  • it's a bit weird to define BOARD=linux and have message saying building for native etc
  • maybe the available aliases could be documented in the respective boards documentation ?

@haukepetersen
Copy link
Contributor Author

but maybe from a different angle.

So meaning that you have an alternate/better approach to this in mind? And should be block this PR and evaluate your solution first? Or merge this PR and migrate to your solution if agreed upon?

@smlng
Copy link
Member

smlng commented Nov 13, 2017

So meaning that you have an alternate/better approach to this in mind?

not exactly, but my idea originated from that fact the we have lots of boards that have (nearly) identical configs only mainly differ by their name. The problem until now was that our build system requires a boards/<name> directory per board to build RIOT.

But see for instance arduino-uno, arduino-duemilanove and arduino-nano ( #7540 ), which are basically the same, my idea was to allow several aliases per actual board implementation and allow to adapt minimal board-specific config via #ifdef, for instance the arduino-uno has 6 ADC while the nano has 8 - such mini diffs do not require a fully copy of the directory.

However, to allow for that it would require to pass the board-name plus the name of the underlying board to the build system, the former to allow for usage of #ifdef (if needed) and the latter to find the correct subdirectory.

Besides the Arduinos this also applies for many Nucleos which share lots of stuff, in the end this would allow to reduce number of subdirectories in boards, ease changes to common config and thereby omit errors which result from bad copy-pasta.

Hope you get what I mean.

@haukepetersen
Copy link
Contributor Author

I do, and I already proposed a solution to that :-) -> see #7975

@smlng
Copy link
Member

smlng commented Nov 13, 2017

I do, and I already proposed a solution to that

oops, I need to catch up with recent PRs - but great!

@haukepetersen
Copy link
Contributor Author

No problem. Its work in progress with some open questions, so maybe you can add your ideas :-)

@temmihoo
Copy link

For the non-technical side, of what aliases to provide. I would like that you could find the boards by vendor, by the board name however obscure that is, by the default connectivity, by the MCU family and so on and so on.

Of the technical solution on how to make the aliases happen, I propose that instead of a .mk macro lookup, the aliases would be just symlinks. That way you could refer to them by their name starting from boards/ like so:
BOARD="nucleo64-f401"
BOARD="stm32/nucleo64-f401"
and so on and so on.

In this I'm not really proposing any actual hierarchy layout but just another technical solution on how the aliases are made to work. First I'd just like to see a few non-hirarchial simple alias names available.

I think it would be tremendously helpful if board names and their aliases showed up using the same tool ie. ls for us cli geeks and various file managers for gui folks instead of having to know there is a .mk macro file somewhere not in boards/ but under the makefiles/ tree.

If any of RIOT tools actually traverses the boards/* files by file system traversal, my approach needs making that tool aware of symlinks, which by easiest is to skip all symlinks alltogether.

@cladmi
Copy link
Contributor

cladmi commented Jan 12, 2018

Actually, I found the "phynode -> pba-d-01-kw2x" nicer to read then "pba-d-01-kw2x (phynode)", but this is very subjective I guess. Don't have a strong opinion here.

This would make default example break as the alias would not be listed in BOARD_PROVIDES_NETIF.

@haukepetersen
Copy link
Contributor Author

This would make default example break as the alias would not be listed in BOARD_PROVIDES_NETIF.

Yapp, and this is because the default example is broken :-) Having all those 'provides netif' thingies was meant to be a quick-fix once, and it seemed to have survived quite a bit... In an ideal case, the Makefile in the default example should do something like if FEATURES_PROVIDED contains netif, then. But this does of course not work in the application makefile.

As a (quick) fix: could we simply include makefiles/boards/alias.inc.mk right after BOARD ?= xx in the application Makefile for all the applications that actually do something with the board name in their application makefile? This would also remove the resetriction on test apps only being buildable with the original board name. Any thoughts on this?

@cladmi
Copy link
Contributor

cladmi commented Jan 23, 2018

I would agree for the quick fix with a comment.


A real fix should not use 'if' but declare a configuration that will be evaluated later. The problem of the current state and the 'if' is that it is not deferred but evaluated immediately.

These kind of configurations will need to be taken into account when updating the build system.
Optional dependencies and CFLAGS triggered by an available feature.

@haukepetersen
Copy link
Contributor Author

included the (quick) fix for using aliases in example applications that use the $(BOARD) variable in their makefiles.

@haukepetersen
Copy link
Contributor Author

rebased.

@cladmi @kaspar030 @aabadie @gebart Is this PR acceptable in the current form? I don't really want to spend time on this (as the Makesystem is not my primary concern...), so either we take it or I will close it and somebody else will need to continue this thought. What do you think?

@haukepetersen haukepetersen added the State: archived State: The PR has been archived for possible future re-adaptation label Sep 11, 2018
@haukepetersen
Copy link
Contributor Author

no progress here and I will not push this any further -> closing it as memo.

@chrysn
Copy link
Member

chrysn commented Sep 14, 2022

This looks good to me at a first glance, with many (if not all) concerns addressed. @haukepetersen, can I revive this PR (and keep pushing those you listed in #7976 (comment) to clear their concerns), or would you rather have this handled in a new PR where I'd essentially squash-and-resubmit your commits?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: boards Area: Board ports Area: build system Area: Build system Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR State: archived State: The PR has been archived for possible future re-adaptation State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants