Adding an optional global config.h file per sketch

neroroxxx

Well-known member
Hi all, for a while I've been working on BMC, it's a MIDI Controller library with it's own Editor App, if you're interested you can check it out here https://github.com/neroroxxx/BMC and install it via the Arduino library manager.

BMC handles everything from button presses to midi communication and so on, there is a main BMC.h file which includes a bunch of dependencies to read buttons, encoders, send/receive/merge/filter midi etc. All and all it works great.

Now BMC is scalable so it lets you have any combination of buttons/encoder/leds/pots etc and BMC also uses EEPROM (built-in/24LC256/SD Card) to store data that can then be edited with the Editor app and in order to do this it needs a global configuration for the program that is being uploaded, this configuration file contains things like the number of buttons, which pin each button is connected to, what pins are uses for serial midi (if any) weather EEPROM will be the builtin or the 24LC256 or the built-in SD card etc.

This configuration file must be seen by the BMC.h file and by all other files that are being included by BMC.h, so I had a few options:

#1 have a config.h as part of the library, when you want to upload a sketch just go and update that config.h file with the config.h generated by the editor app. The downside is that anytime you update the library that file would be reset to it's default! also if you have to build multiple midi controller with different configurations then you would have to constantly update this file.

#2 add a global config file that would reside in the sketch folder along with the .ino the upside of this method is that you can have a sketch for one midi controller and then another sketch for a larger midi controller and so on. The problem with this method is that there is no default way to include this config file for all libraries and it's dependencies to it's definitions. The only way to make this work is by modifying the boards.txt by appending to the "build.flags.cpp" for each teensy the following:

-include "{build.source.path}/config.h"

the issue with this is that now every sketch must have a config.h file in it's folder (event if the config.h is empty)

the solution to that is to add a new option to the Tools Menu on Arduino in the boards.txt, this is a mod that is required for BMC to work, this mod is appended at the bottom of the boards.txt flle



# ----- Include BMC Config Mod Starts -----
menu.bmcsketchconfig=Require BMC Config
teensy41.menu.bmcsketchconfig.no=No
teensy41.menu.bmcsketchconfig.yes=Yes
teensy41.menu.bmcsketchconfig.yes.build.flags.cpp=-std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -include "{build.source.path}/config.h"
teensy40.menu.bmcsketchconfig.no=No
teensy40.menu.bmcsketchconfig.yes=Yes
teensy40.menu.bmcsketchconfig.yes.build.flags.cpp=-std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -include "{build.source.path}/config.h"
teensy36.menu.bmcsketchconfig.no=No
teensy36.menu.bmcsketchconfig.yes=Yes
teensy36.menu.bmcsketchconfig.yes.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -include "{build.source.path}/config.h"
teensy35.menu.bmcsketchconfig.no=No
teensy35.menu.bmcsketchconfig.yes=Yes
teensy35.menu.bmcsketchconfig.yes.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -include "{build.source.path}/config.h"
teensy31.menu.bmcsketchconfig.no=No
teensy31.menu.bmcsketchconfig.yes=Yes
teensy31.menu.bmcsketchconfig.yes.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -include "{build.source.path}/config.h"
teensyLC.menu.bmcsketchconfig.no=No
teensyLC.menu.bmcsketchconfig.yes=Yes
teensyLC.menu.bmcsketchconfig.yes.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -include "{build.source.path}/config.h"
# ----- Include BMC Config Mod Ends -----

With this mod the user will now see a new option under Tools "Require BMC Config" that option will have 2 selections "Yes" and "No" if the user selects yes then when the sketch is compiled the config.h file will be included into the build, if the user selects No then that file will not be include.

This works fine for BMC except for the fact that users have to go in and find the boards.txt file and then add the mod and whenever they update Teensyduino it will remove this mod so the user has to go back and add it again.

I'm wondering if Paul would consider adding this option as a default to Teensyduino and maybe just label "Import Sketch config.h" or anything like that so that users don't have to use this mod.

I do see a few issues specially with newbies, for example, if you upload a sketch with library that requires this config.h and you don't check that option then you would get an error because the definitions are not there, or if you upload a sketch that doesn't have a config.h file in it's folder and they have the option checked then the user would see an error because the config.h wasn't found.

I hope this post makes sense, in my view Teensy boards are too powerful not to have more complex libraries that do all the work for the user and instead the user can use a simple app to communicate with the teensy and control them there as BMC does.
 
I'm having a similar issue with the TeensyTimerTool. I solved it by using __has_include:

config.h
Code:
#pragma once

#if __has_include("userConfig.h")
    #include "userConfig.h"
#else
    #include "defaultConfig.h"
#endif

The code tries to find userConfig.h in the search path and includes it if it finds the file. If not it includes a defaultConfig file. This of course requires that the sketch folder is in the include search path. Therefore, for the Arduino IDE you still need to either change boards.txt (as you did) or platform.txt (as I did). But "__has_include" solves the problem with absent userConfig files. (BTW: PIO and vsTeensy include the sketch folder in the search path per default, so that stuff works out of the box there)

Instead of changing platform.txt I use a platform.local.txt file which is less intrusive and only requires copying a file. Here an example how I instruct users about this. https://github.com/luni64/TeensyTimerTool/wiki/Configuration It also contains a link to a corresponding platform.local.txt

Would be really helpful if the stock platform.txt / boards.txt would add the sketch folder to the include search path. See here
https://forum.pjrc.com/threads/6074...Arduino-sketch?p=238053&viewfull=1#post238053 for some discussion. Paul at least considered changing this in later versions...
Given the massive changes in TD1.54beta this might fit in as well?
 
Great to see theres another option, hopefully something like this can be added with some guidelines like al libraries that use that method to add defines should have all definitions prependended their linrary name like #define BMC_xxx and so on that way there wouldnt be issues with redefinitions
 
You could write a Arduino IDE "Plugin"
That automatically adds the required
choices to the boards file then when it loads again it could just check if the contents have the text "# ----- Include BMC Config Mod Starts ---" to avoid adding it more times.
I have made a plugin that you can look at, it includes a method to get the arduino install root folder called GetArduinoRootDir().
Note that the example I provide contains a lot other stuff to that you could just remove
To compile it you need java jdk 8 (1.8) because that's what the arduino ide runs on. To install the plugin just copy the whole folder API_WEBSERVER to the tools folder of arduino installation.

https://github.com/manicken/manicken.github.io/tree/master/API_WebServer
 
I found out by looking at Arduino IDE source code using the ultimate search program "Agent Ransack" (windows 10 search sucks)

taken direct from the source code:
Code:
// Allow overriding values in boards.txt. This allows changing
// boards.txt (e.g. to add user-specific items to a menu), without
// having to modify boards.txt (which, when running from git,
// prevents files being marked as changed).
File localboardsFile = new File(folder, "boards.local.txt");

with this I tried to create a boards.local.txt with your additional contents
and it works.
 
Back
Top