Reputation: 43
I have one ESP-IDF application and two hardware boards. I use a preprocessor definition to control which hardware board version to build. For now, I'm modifying the config in the sdkconfig file via menuconfig. But I would like to build both versions at once from a script, or build only one specific config without the manual process of menuconfig.
I have a header that looks like this, and works when HW_VER
is set correctly:
#if HW_VER == 2
#define BTN_GPIO 9
#elif HW_VER == 3
#define BTN_GPIO 10
#endif
And from the a script I would like to build each by selecting a value for HW_VER
, for example:
idf.py build -DHW_VER=2
idf.py build -DHW_VER=3
The idf.py build command runs cmake and ninja. I'm new to cmake, so perhaps there is a natural way to do this?
I would also like to build release and debug builds, turn on/off memory debugging etc. from the command line.
I've tried idf.py build -DHW_VER=2
but I've learned that these vars are only sent to cmake and not to the preprocessor. The HW_VER
macro remains undefined.
Using add_definitions() in my CMakeLists.txt can set HW_VER, but doesn't help me make different builds from the same files.
Using a config variable like CONFIG_HW_VER in the sdkconfig works to control builds using menuconfig but I don't see a way to automate this.
I've considered modifying the configuration variable, CONFIG_HW_VER in the sdkconfig file programmatically, but this file is under source control, and it is auto generated by menuconfig, so that doesn't seem wise.
Similarly I can modify the CMakeLists.txt file programmatically, but that file is also under source control, and isn't a trivial format.
Upvotes: 4
Views: 2736
Reputation: 4780
I use two ways to feed custom configurations into an ESP IDF project.
Firstly, the light weight stuff like preprocessor definitions from the environment are quite simple. You have to configure CMakeLists.txt
file (the one in project root) to pass variable values from environment into the build process. For example, to create something equivalent to preprocessor definitions -DMY_NUMBER=123
and -DMY_STRING="abc"
add this somewhere before the "project" line:
add_compile_definitions(MY_NUMBER=$ENV{MY_NUMBER})
add_compile_definitions(MY_STRING=\"$ENV{MY_STRING}\")
...
project(myproject)
Assuming you're working in Bash, build with:
$ MY_NUMBER=123 MY_STRING="abc" idf.py build
or (for a slightly more "sticky" enviroment):
$ export MY_NUMBER=123 MY_STRING="abc"
$ idf.py build
You can use cmake to add more advanced logic, e.g. setting default values in case the environment doesn't set anything.
Secondly, the more powerful configuration tool for ESP IDF is the menuconfig target and sdkconfig
file. As you've already noticed, playing with sdkconfig
directly is not so easy. In my projects I consider this a generated temporary file and I never commit it to git. Instead I delete it. When sdkconfig
is missing, idf.py will take file sdkconfig.defaults
, copy it into sdkconfig
and work with this. That is your best mechanism for supporting different hardware configurations - no sdkconfig
and instead different variants of sdkconfig.defaults
for each hardware you wish to support.
As an example, assume you have two different HW versions described in sdkconfig.defaults.hw_ver1
and sdkconfig.defaults.hw_ver2
and you wish to build for HW ver2 configuration:
$ rm sdkconfig && cp sdkconfig.defaults.hw_ver2 sdkconfig.defaults
$ idf.py reconfigure
Now you can build for this configuration like you usually would:
$ idf.py build
When you wish to build for the other FW configuration, re-execute the previous commands with sdkconfig.defaults.hw_ver1
All this is rather thoroughly documented in the Build System documentation, so feel free to dig in.
Upvotes: 3