Description
Bug Report
Current behavior
Currently, boards.txt
allows specifying "menu" options for a board. E.g. for the Arduino Mini, boards.txt
contains the following (heavily redacted to just show the bare minimum):
menu.cpu=Processor
mini.name=Arduino Mini
mini.menu.cpu.atmega328=ATmega328P
mini.menu.cpu.atmega328.build.mcu=atmega328p
mini.menu.cpu.atmega168=ATmega168
mini.menu.cpu.atmega168.build.mcu=atmega168
When selecting the Arduino Mini board, this allows specifying the "cpu" option as part of the FQBN, and depending on its value the build.mcu
option gets a different value. In the Java IDE, this also causes a menu to be shown that allows the user to select between the two options.
These menu options work fine for such board-specific "subselections" or board-specific options, but often there are also platform-wide options. For example, the Adafruit SAMD core defines a "debug" and "usbstack" menu that is used for pretty much all boards: https://github.com/adafruit/ArduinoCore-samd/blob/1e92424a500a8b3fc5be0701bbbab0da167f2cc6/boards.txt#L17-L22 Currently, this means that the menu options and resulting build properties must be repeated for all board definitions, which is less-than-ideal. The ESP32 and STM32 cores have an even bigger number of options.
This could be greatly simplified if platform-wide menus could be specified. Essentially, these would be menus that are defined outside of any board and are shown for all boards. They can probably also be implemented as such, which should make this rather easy. Specifying/storing the values for these menus can still happen as part of the FQBN, it's just the way the menus are specified that would be simplified.
One open question is where to specify these platform-wide menus? We could put them in platform.txt
, which would make sense, or put them at the top of the boards.txt
. The latter is probably easier and more consistent with the current menu.cpu=Processor
line.
Boards-specific subsets of global options
Sometimes, you might want to have global options that apply to most but not all boards. For example, the Adafruit "usbstack" option is really a platform-wide option, but it only applies to boards with native USB. For this, it would be helpful if you could specify a menu globally, but enable/disable it on a board-by-board basis. Maybe this can be done by setting/clearing the menu title? E.g. (I invented a dummy board here, turns out all of the actual boards in the Adafruit SAMD core have USB):
menu.usbstack=USB Stack
menu.usbstack.arduino=Arduino
menu.usbstack.tinyusb=TinyUSB
menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB
adafruit_feather_m0.name=Adafruit Feather M0
# No menu options here, usbstack is inherit from global
board_without_usb.name=Foo board
# Unset usbstack title to hide it
board_without_usb.menu.usbstack=
Another option would be to do opt-in by not specifying the menu title globally, but specifying it per-board. This requires duplicating the title when a menu is used for multiple boards, though:
# Only specify options, no title
menu.usbstack.arduino=Arduino
menu.usbstack.tinyusb=TinyUSB
menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB
adafruit_feather_m0.name=Adafruit Feather M0
# Set a title to include this menu for this board
board_without_usb.menu.usbstack=USB Stack
board_without_usb.name=Foo board
# No title specified, so usbstack menu not used
A final option could be to make it more explicit by supporting an
"disabled" subproperty (which defaults to "no" for compatibility). A
downside of this approach is that it breaks a menu that wants to use
"enabled" and "disabled" as valid options (maybe we can find a name that is less likely to collide than "disabled"?).
# Only specify options, no title
menu.usbstack=USB Stack
menu.usbstack.arduino=Arduino
menu.usbstack.tinyusb=TinyUSB
menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB
menu.usbstack.disabled=yes
adafruit_feather_m0.name=Adafruit Feather M0
board_without_usb.menu.usbstack=USB Stack
board_without_usb.menu.usbstack.disabled=no
board_without_usb.name=Foo board
We could probably support multiple of these approaches (e.g. both the title based opt-in and opt-out together, or maybe all three of them by hiding options that either have no title, or have "disabled=yes").
The same approaches can also be considered to hide single options from a menu on a board-by-board basis, in addition to hiding complete menus.
Also note that currently, the menu title (e.g. menu.cpu=Processor
) must be specified globally (outside of any board definition). Regardless of what we choose here, I would suggest allowing this line to be global or board-specific. If you then have a menu that is only defined for one particular board, it can just be specified for that board, without splitting up the definition of the menu and without cluttering the global definitions. More generally, you could just split the menu definitions arbitrarily between the global and board-specific parts of the file (even allowing something like a global menu with 2 options and then add a third option for just one board).
Implementation-wise, this could mean you just take all global menu options, apply the board-specific ones for the current board on top, and then treat the result just like menus are being treated now, making this fairly easy to implement.