Technical question regarding `includes.txt`

I'm using the Seeed Studio XIAO BLE - nRF52840 and I'm facing issues regarding a tradeoff between either using NFC functionality with their mbed-enabled board definition while being unable to compile projects for the XIAO Round Display, or using the non-mbed definition for the display without NFC functionality (I want both).

I was exploring both board packages directories and their structure since I think I could merge the missing files from one pkg to the other.

I've found everything I need, but now I'm facing issues regarding how to include all of them in the fastest and cleanest way possible.

I saw that for the mbed-enabled version, they used this kind of implementation in their boards.txt: xiaonRF52840.compiler.mbed.includes={build.variant.path}/includes.txt. Having then in this includes.txt everything needed for satisfying the dependencies.

Essentially, I think Seeed Studio based this pkg kind of in this other one: ArduinoCore-nRF528x-mbedos/variants/ARDUINO_NANO33BLE/includes.txt at master · arduino/ArduinoCore-nRF528x-mbedos · GitHub

In a closed issue there, @facchinm answered:

That procedure takes advantage of Directory Options (Using the GNU Compiler Collection (GCC)) , so that paths length is greatly reduced (and can be specified as relative to {runtime.platform.path} ).
I think the missing piece you are looking for is "-iprefix{build.core.path}" ; in this way, gcc replaces internally the withprefixbefore string with the one provided.

_Originally posted by @facchinm in Please explain '-iwithprefixbefore' in 'includes.txt' · Issue #78 · arduino/ArduinoCore-nRF528x-mbedos · GitHub

Therefore, I was wondering whether I could use the same includes.txt file approach for a non-mbed version of this nRF52840 MCU board definition.

I tried doing: xiaonRF52840.build.includes={build.variant.path}/includes.txt and/or xiaonRF52840.compiler.includes={build.variant.path}/includes.txt inside boards.txt and boards.local.txt of the non-mbed version with no success.

Thanks!

Hi @andriandreo.

The term we use for the things like xiaonRF52840.build.includes is "properties" (or in cases where that general term might be ambiguous "platform properties").

We can define a property like this:

salutation=Hello

And reference a property in the definition of another property:

message={salutation} world!

An important thing to understand about properties is that they fall into multiple distinct classes of usage:

Framework-Defined Properties

Some properties (e.g., runtime.platform.path) are automatically defined by the Arduino boards platform framework internally.

These properties framework-defined properties act as a way for the framework to pass data to the platform.

So you can reference these properties in your platform configuration files, but defining a value for them in the configuration file wouldn't make sense as they already contain the expected data.

All the "framework-defined properties" are documented in the Arduino Platform Specification.

Framework Configuration Properties

The values of some properties set within the platform configuration files (e.g., recipe.cpp.o.pattern) are used internally by the Arduino boards platform framework.

These properties act as an way for the platform to pass data to the framework.

All the "framework configuration properties" are documented in the Arduino Platform Specification.

Arbitrary Properties

The platform developer can also define any number of additional properties with any arbitrary name.

These properties act as a way to pass data from a definition to a reference in another definition elsewhere in the platform configuration files (like how we use a variable in an Arduino sketch).

You won't find any mention of specific "arbitrary properties" found in a given platform in the Arduino Platform Specification or other official documentation since they are neither defined nor used by the Arduino boards platform framework.


xiaonRF52840.compiler.mbed.includes is an "arbitrary property". This means it will only have an effect if it is referenced (either directly or transitively) in the definition of one of the framework configuration properties.

We can see the xiaonRF52840.compiler.mbed.includes property defined here in the boards.txt file of the "Seeed nRF52 mbed-enabled Boards" platform:

Note that the definition of this property contains a reference to the build.variant.path property. This is a "framework-defined property".

The properties defined in boards.txt (or boards.local.txt) have a board ID prefix (in this case xiaonRF52840.). This is done to allow properties to be defined according to which board the user has selected. The properties with the prefix matching the board ID of the currently selected board are defined, named according to the rest of the boards.txt property name (in this case compiler.mbed.includes).

We can see the compiler.mbed.includes property is referenced in the definition of the recipe.c.o.pattern, recipe.cpp.o.pattern, and recipe.S.o.pattern properties here in the platform's platform.txt file:

recipe.c.o.pattern, recipe.cpp.o.pattern, and recipe.S.o.pattern are "framework configuration properties". These properties define the command the framework will run when compiling C, C++, and assembly source files.

So the end result of setting the xiaonRF52840.compiler.mbed.includes property to the value {build.variant.path}/includes.txt is that an argument like this is added to the compilation commands:

@C:\Users\per\AppData\Local\Arduino15\packages\Seeeduino\hardware\mbed\2.9.2\variants\SEEED_XIAO_NRF52840/includes.txt

(in this example, the framework set the build.variant.path property to C:\Users\per\AppData\Local\Arduino15\packages\Seeeduino\hardware\mbed\2.9.2\variants\SEEED_XIAO_NRF52840)

Note that the @ part of the argument (which tells the compiler to use the list of command line options in the referenced file)comes from the definition of the recipe.c.o.pattern, recipe.cpp.o.pattern, and recipe.S.o.pattern properties:

"@{compiler.mbed.includes}"

The reason for this is likely that you did not reference those arbitrary properties in a "framework configuration property". Try adding the references to the recipe.c.o.pattern, recipe.cpp.o.pattern, and recipe.S.o.pattern properties in your platform.txt file, just as was done in the "Seeed nRF52 mbed-enabled Boards" platform.

Another important thing to be aware of is that Arduino IDE loads the platform configuration files on startup. So Arduino IDE won't recognize any changes you make to the platform configuration files while the IDE is running. So make sure to always restart Arduino IDE after you modify the platform configuration.

Many many thanks! Quite an insightful explanation!!
Now I finally understand how it works.

And you were totally right, I was missing the "@{compiler.mbed.includes}" framework configuration property in my platform.local.txt.

I'm still getting compiler errors, but they're no longer related to #include dependencies. Thanks!

You are welcome. I'm glad it is working as expected now.

Regards,
Per