Using --build-property to set optimize and define symbols

It is possible, nay likely, that I am stupid, but it has taken me half a day to achieve something that I thout would be simple. I need to build several versions of a sketch depending on setting a #define and I also want to set the maximum optimization. There appears to be no obvious help anywhere on how to do this. My first attempt used the following on the command line (after the arduino-cli) based on clues in other posts that claimed to have got this to work:

--build-property "build.extra_flags=-D MYSYMBOL -O3 -flto" ...more stuff...

This seems to be ignored. I then tried using "compiler.cpp.extra_flags=-D MYSYMBOL" following the pattern suggested by the forum thread where --build-property was developed. Also ignored.

Finally, I used --show-properties to see what is being set and came up with:

--build-property "build.flags.defs=-D__IMXRT1062__ -DTEENSYDUINO=159 -D MYSYMBOL"
--build-property "build.flags.optimize="-O3 -lto"

This does work. I am happy with the optimize as this replaces the original entirely. But replacing build.flags.defs is a mess because it means if either of the other two definitions changes, or new system ones are added, I must re-edit.

I have seen other requests for a command line -D SYMBOL[=VALUE] option, which does not seem unreasonable. Perhaps --build-property "build.extra_flags=-D MYSYMBOL -O3 -flto" is intended to work and its failure is a bug?

So some requests for what I consider to be the most likely things folks will need:

  1. Please document how we are to set definitions in addition to the existing ones
  2. Please document how to change optimization

Hi @reggthims. What is the FQBN you are compiling for?

I am targetting a Teensy 4.0, so Teensy:avr:Teensy40 (if this is what you are asking). This is using the Arduino support described at:
https://www.pjrc.com/teensy/teensyduino.html

Thanks. That is the information I needed.

When you add a flag like this to your arduino-cli compile command:

--build-property "build.extra_flags=-D MYSYMBOL"

It sets the value of the build.extra_flags platform property to -D MYSYMBOL. All template references ({build.extra_flags}) in the platform configuration files (e.g., boards.txt, platform.txt) will be replaced with that value.

But the choice of which property references to include in the various templates, and how those properties might be used internally is completely up to each platform author. This means that you must have a good understanding of the configuration of the platform in order to use this very advanced --build-property flag. The examples in the arduino-cli compile --help command line reference are only intended to demonstrate how you might set the value of an arbitrary platform property, not as a universally valid recipe.

Great work on finding a solution! Although there is a common convention for platforms to provide the ability for the user to easily inject arbitrary flags into the compilation commands without colliding with internal usage of platform properties, as is done in all the official Arduino boards platforms, unfortunately this was not done in the Teensy boards platform so I don't think there is any better solution than the one you found, even though it is not ideal.

There is a proposal for formalizing a standard convention for platform developers to provide the ability for users to reliably inject arbitrary flags into compilation commands here:

If you have a GitHub account, you can subscribe to that thread to get notifications of any new developments related to this subject:

screenshot of Subscribe button


:exclamation: Please only comment on the GitHub issue thread if you have new technical information that will assist with the resolution. General discussion and support requests are always welcome here on the Arduino Forum.


You are free to use any property name you like with the --build-property flag. For example:

--build-property "foo=bar"

Will define a property named foo with the value bar. But the property will only have an effect if the developer of the platform you are using referenced it somewhere in the platform configuration files.

Arduino has implemented a standard system for doing this, which is documented in the the arduino-cli compile --help command line reference:

https://arduino.github.io/arduino-cli/latest/commands/arduino-cli_compile/#options

--optimize-for-debug                    Optional, optimize compile output for debugging, rather than for release.

and the way a platform developer can configure the optimization flags according to whether or not that flag is present here:

https://arduino.github.io/arduino-cli/latest/platform-specification/#optimization-level-for-debugging

But each platform developer has the freedom to chose whether or not they want to make use of that flag. The Teensy platform does not, so the --optimize-for-debug flag has no effect when compiling for Teensy boards.

A custom system has been implemented in the Teensy platform for controlling optimization (which is may be why they didn't set up a system for --optimize-for-debug). You can see it by running the following arduino-cli command:

arduino-cli board details --fqbn teensy:avr:teensy40
$ arduino-cli board details --fqbn teensy:avr:teensy40

Board name:                Teensy 4.0
FQBN:                      teensy:avr:teensy40
Board version:             1.59.0

Identification properties: modelID=0x24

Package name:              teensy
Package maintainer:        Paul Stoffregen
Package URL:               https://www.pjrc.com/teensy/package_teensy_index.json
Package website:           https://www.pjrc.com/teensy/td_download.html
Package online help:       https://forum.pjrc.com/forum.php

Platform name:             Teensy
Platform category:         Contributed
Platform architecture:     avr
Platform URL:              https://www.pjrc.com/teensy/td_159/teensy-package-1.59.0.tar.zst
Platform file name:        teensy-package-1.59.0.tar.zst
Platform size (bytes):     26727514
Platform checksum:         SHA-256:b9c1ea852bd5ac625559685a864d40803df566650864b415e7c14c9623520c59

Required tool: teensy:teensy-compile                 11.3.1
Required tool: teensy:teensy-tools                   1.59.0

Option:        USB Type                                     usb
               Serial                                ✔      usb=serial
               Dual Serial                                  usb=serial2
               Triple Serial                                usb=serial3
               Keyboard                                     usb=keyboard
               Keyboard + Touch Screen                      usb=touch
               Keyboard + Mouse + Touch Screen              usb=hidtouch
               Keyboard + Mouse + Joystick                  usb=hid
               Serial + Keyboard + Mouse + Joystick         usb=serialhid
               MIDI                                         usb=midi
               MIDIx4                                       usb=midi4
               MIDIx16                                      usb=midi16
               Serial + MIDI                                usb=serialmidi
               Serial + MIDIx4                              usb=serialmidi4
               Serial + MIDIx16                             usb=serialmidi16
               Audio                                        usb=audio
               Serial + MIDI + Audio                        usb=serialmidiaudio
               Serial + MIDIx16 + Audio                     usb=serialmidi16audio
               MTP Disk (Experimental)                      usb=mtp
               Serial + MTP Disk (Experimental)             usb=serialmtp
               Raw HID                                      usb=rawhid
               Flight Sim Controls                          usb=flightsim
               Flight Sim Controls + Joystick               usb=flightsimjoystick
Option:        CPU Speed                                    speed
               600 MHz                               ✔      speed=600
               528 MHz                                      speed=528
               450 MHz                                      speed=450
               396 MHz                                      speed=396
               150 MHz                                      speed=150
               24 MHz                                       speed=24
               720 MHz (overclock)                          speed=720
               816 MHz (overclock)                          speed=816
               912 MHz (overclock, cooling req'd)           speed=912
               960 MHz (overclock, cooling req'd)           speed=960
               1.008 GHz (overclock, cooling req'd)         speed=1008
Option:        Optimize                                     opt
               Faster                                ✔      opt=o2std
               Faster with LTO                              opt=o2lto
               Fast                                         opt=o1std
               Fast with LTO                                opt=o1lto
               Fastest                                      opt=o3std
               Fastest with LTO                             opt=o3lto
               Debug                                        opt=ogstd
               Smallest Code                                opt=osstd
               Smallest Code with LTO                       opt=oslto
Option:        Keyboard Layout                              keys
               US English                            ✔      keys=en-us
               Canadian French                              keys=fr-ca
               Canadian Multilingual                        keys=xx-ca
               Czech                                        keys=cz-cz
               Danish                                       keys=da-da
               Finnish                                      keys=fi-fi
               French                                       keys=fr-fr
               French Belgian                               keys=fr-be
               French Swiss                                 keys=fr-ch
               German                                       keys=de-de
               German (Mac)                                 keys=de-dm
               German Swiss                                 keys=de-ch
               Icelandic                                    keys=is-is
               Irish                                        keys=en-ie
               Italian                                      keys=it-it
               Norwegian                                    keys=no-no
               Portuguese                                   keys=pt-pt
               Portuguese Brazilian                         keys=pt-br
               Serbian (Latin Only)                         keys=rs-rs
               Spanish                                      keys=es-es
               Spanish Latin America                        keys=es-mx
               Swedish                                      keys=sv-se
               Turkish (partial)                            keys=tr-tr
               United Kingdom                               keys=en-gb
               US International                             keys=usint
Programmers:   ID                                    Name

Note this part of the board details:

Option:        Optimize                                     opt
               Faster                                ✔      opt=o2std
               Faster with LTO                              opt=o2lto
               Fast                                         opt=o1std
               Fast with LTO                                opt=o1lto
               Fastest                                      opt=o3std
               Fastest with LTO                             opt=o3lto
               Debug                                        opt=ogstd
               Smallest Code                                opt=osstd
               Smallest Code with LTO                       opt=oslto

These are "custom board options" defined in the Teensy board platform's boards.txt configuration file for the teensy40 ("Teensy 4.0") board:

teensy40.menu.opt.o2std=Faster
teensy40.menu.opt.o2std.build.flags.optimize=-O2
teensy40.menu.opt.o2std.build.flags.ldspecs=
teensy40.menu.opt.o2lto=Faster with LTO
teensy40.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects
teensy40.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin
teensy40.menu.opt.o1std=Fast
teensy40.menu.opt.o1std.build.flags.optimize=-O1
teensy40.menu.opt.o1std.build.flags.ldspecs=
teensy40.menu.opt.o1lto=Fast with LTO
teensy40.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects
teensy40.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin
teensy40.menu.opt.o3std=Fastest
teensy40.menu.opt.o3std.build.flags.optimize=-O3
teensy40.menu.opt.o3std.build.flags.ldspecs=
#teensy40.menu.opt.o3purestd=Fastest + pure-code
#teensy40.menu.opt.o3purestd.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__
#teensy40.menu.opt.o3purestd.build.flags.ldspecs=
teensy40.menu.opt.o3lto=Fastest with LTO
teensy40.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects
teensy40.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin
#teensy40.menu.opt.o3purelto=Fastest + pure-code with LTO
#teensy40.menu.opt.o3purelto.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -flto -fno-fat-lto-objects
#teensy40.menu.opt.o3purelto.build.flags.ldspecs=-fuse-linker-plugin
teensy40.menu.opt.ogstd=Debug
teensy40.menu.opt.ogstd.build.flags.optimize=-Og
teensy40.menu.opt.ogstd.build.flags.ldspecs=
#teensy40.menu.opt.oglto=Debug with LTO
#teensy40.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects
#teensy40.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin
teensy40.menu.opt.osstd=Smallest Code
teensy40.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs
teensy40.menu.opt.osstd.build.flags.ldspecs=
teensy40.menu.opt.oslto=Smallest Code with LTO
teensy40.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs
teensy40.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin

When you only use the base FQBN (in this case teensy:avr:teensy40) in the arduino-cli command, the default settings of any custom board options are used, but you can select other settings via the FQBN, which has this format:

<vendor ID>:<architecture>:<board ID>[:<menu ID>=<option ID>[,<menu ID>=<option ID>]...]

So if, for example, you wanted to select the "Fastest with LTO" (option ID o3lto) option of the the "Optimize" custom board option (menu ID opt), you would use this FQBN in your arduino-cli commands:

teensy:avr:teensy40:opt=o3lto

If possible, you should use this user friendly formal public API provided by the Teensy boards platform to configure the optimization level rather than resorting to tampering with internal platform properties via the advanced --build-property flag.

Many thanks for your very clear and comprehensive answer; given the effort involved I hope this is a useful resource for others.
I have changed the optimization as you suggested, I guess the -D stuff is my problem until a general solution is agreed on
and implemented.

You are welcome. I'm glad if I was able to be of assistance.

Regards,
Per

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.