-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build multiple images with different sdkconfigs (IDFGH-3735) #5658
Comments
Hi @galah92 , In general, we don't really supporting building more than one instance of IDF in a single invocation of CMake. There are quite a few global properties that won't play nicely together. For the situation you describe, would recommend if possible that you have two project directories, one for the WiFi app and one for the BLE app. Make a third directory like If you do it this way then you can choose to use the "normal" IDF build system process or the more CMake-style process that uses You will have to run Does that work for your use case? If not, can you please give some more details about the requirements you have? |
Hi @projectgus, thank you for your comment. Let me elaborate regarding my situation:
Regarding the ESP32-based apps:
It seems like there are multiple things I need to work differently in ESP-IDF in order to support my case:
|
Another bug I found when trying to work with the |
@atanisoft Thanks. I'm still trying to figure out a way to build multiple binaries using single CMake invocation though. Your script seems to build specific targets using different CMake configurations (different directories). Am I correct? |
With how the CMake scripts are configured I don't think this will be feasible anytime soon unfortunately.
The script is the equivalent of "idf.py build size" when the build directory and sdkconfig file does not exist. The GitHub Actions run in different containers so the output directory is "build" in both configurations that I'm currently using (sdkconfig.defaults and sdkconfig.defaults.pcb). |
Now I get it, thanks. Unfortunately it looks like I'll have to patch things in order to have a better control over the compilation of the bootloader, partition table, and all the rest. It just feels awkward that the way IDF wraps CMake actually disabled all the great features of it. |
Hi @galah92, Thanks for explaining your use case and thanks @atanisoft for showing your build system approach. I can confirm that at the moment there's no way for this to work all in one CMake invocation with the ESP-IDF build system. The closest thing that works now is probably to use ExternalProject to invoke the ESP-IDF build system as a separate CMake instance, once per ESP-IDF project to build. Which is obviously still hacky compared to what you're asking for. We'll keep the request open to track this requirement and when we're next revisiting the build system architecture then we will look at it again and see if we can accommodate it. Unfortunately this isn't something I can give you an ETA for. If you end up with any patches for ESP-IDF that maintain compatibility with the way it works now then please consider sending Pull Requests.
This is an understandable sentiment, especially given you are clearly quite familiar with CMake. The reason for this is can be summed up as the classic "historical reasons". When we introduced the CMake build system we already had a lot of ESP-IDF users familiar with the existing GNU Make build system, and we needed a path forward that was familiar for them. The GNU Make build system we already had includes some complex things which do not fit neatly into "the CMake way" of what a build system is (for example running flashing or serial tools, as you noted above). Could we have done better? Undoubtedly. Could we have switched absolutely everything over to "the CMake way" without causing a lot of anguish for our existing users? I think probably not. We are interested in continuing to move closer to "the CMake way" where it's possible, though.
I don't fully understand the issue here, but this is something we can look at separately. Could you open a github issue with a few more details, please? |
Hi, One only thing wich I wish for the future is to select the right sdkconfig from the commandline for example : I have written a skript in powershell wich renames the sdkconfig and runs then the build script. Here is my powershell script:
One more thing what I noticed is that if I rename the sdkconfig file and do not have a seperated build folder for this file. I need to run the menuconfig that to have |
@projectgus Thank you for the details response, I really appreciate it. First I'd like to the my words back - I understand most of the constraints you're facing with, especially regarding backward compatibility and "historical reasons". I'm glad that you're open towards the idea of moving closet to "the CMake way". I think about it more and more these days, and I started realizing that there's probably no good reason to maintain a I'd like to contribute as much as possible to the build system procedure, what changes are acceptable and what aren't, in your views? @waterfox207 Thanks! I'm trying to to something like that in bare CMake, without using |
Hi @waterfox207, This might be a command line option we can support, the old GNU Make build system used to allow overriding this with an environment variable. I think it could be made into a cache variable in CMake to the same effect. Will look into it, I'm afraid I can't promise an ETA though - but your workaround looks good for now. Hi @galah92,
To check I understand: The proposed change is to store the sdkconfig settings in CMake cache variables of CMakeCache.txt for all of the current sdkconfig configuration values. Keeping the same KConfig files, I think we looked into this when we were choosing the build system to move to. It may be my lack of CMake understanding, but it boiled down to that CMakeCache.txt is conceptually a configuration file for the build rather than a configuration file for the project.
Let me know if I'm misunderstanding anything here.
Thanks, that's great to hear! We have a policy of not making breaking changes in minor versions (and we try to avoid them in major versions as well.) So the hard requirement for a build system change is not to break anything which is documented in the current version, or to break any "public" APIs (these are harder to define in terms of CMake functions but basically anything which is in the docs or any example is probably "public".) Aside from this, we're open to anything which is useful or which simplifies the design or the implementation. If you have an idea that's going to be a large change and need a lot of work then it's probably best to discuss it first and we can give you some feedback. I should mention that we would consider making breaking changes in the next major release. The only difficulty is that we don't have any ETA for that yet - we won't plan a major version bump until we absolutely have to. But if you have other requests like this one that would be breaking changes in the build system, feel free to make them and we'll keep them in mind. |
Hi @projectgus, I'm raising this thread again since I started to port my build to First I'd like to address your previous comments regarding sdkconfig-vs-cmake-variables:
Also, could you please elaborate regarding the build system changes which are planned for the next major release? Now, coming to my point at last.. leaving off the requirement for different Is it possible to add a mechanism which will allow me to compile multiple application sharing multiple libraries, where everything compile only once? My list of applications grows large and, among others, I'd like to minimize the total compilation time and don't want to compile shared libraries multiple times. Thank you EDIT: I'd like to add - my ultimate goal is creating a unified build-system (relying on CMake) to support building multiple apps, sharing multiple common libraries, for different platforms. Most of my other platforms play well with normal CMake - I just specify as input the toolchain file and it all just works. IDF is the weird one here - I'm OK with having to call specific CMake functions for IDF, but the current situation makes it almost impossible to tinker with the build system. It's just not flexible enough.
|
+1 would like to see support for multiple SDK configs. In our case, we use a CI/CD platform to create and distribute our builds. When we build for release we disable the logging output, UART downloader and enable flash encryption. The first thing a developer has to do every time they work on a feature is turn off all the security features or risk disabling their local development board. Later we then have to run a bunch of checks on the CI to ensure that the developer didn't commit an insecure change. If however we used development config by default instead and just manually edit the sdkconfig during the CI production build. The image will always have a dirty version tag. We can get around this by having auto commits that prevent insecure builds but this seems like a hack and adds complexity to the build. Another reason we would like to see multiple sdkconfig support which is similar to @galah92 is we have multiple builds (same hardware and firmware) but whereby the only difference is the Bluetooth advertising name, the device hostname and a GPIO configuration. TLDR: multiple sdkconfigs would make our lives easier. |
@AshUK would something like this work for you?
Edit: forgot to address the 2nd part of your question. You can extend this to use more sdkconfig.defaults-like files. The list of sdkconfig.defaults files can also be set in your project CMakeLists.txt file using SDKCONFIG_DEFAULTS variable, so you can add some additional logic in project CMakeLists.txt file to determine which sdkconfig.defaults files need to be included, based e.g. on environment variables. The only limitation is that IDF libraries will still be built multiple times, even if differences in sdkconfig are very small. However if you install |
@igrr regarding the option you posted above for "production" and having multiple |
When sdkconfig file doesn't exist, all sdkconfig.defaults-like files are concatenated to obtain the initial sdkconfig file. For each file listed in SDKCONFIG_DEFAULTS variable, the build system also adds That is, in the example above, the files would be combined in this order, assuming IDF_TARGET=esp32:
The target-specific files are optional. Options listed later in sdkconfig override the ones listed earlier. So you can even explicitly set some option to Edit: I'm sorry, I actually made a mistake in the above order when posting this. Here's the link to CMake code for this part. We'll update the docs to make the order clear. esp-idf/tools/cmake/kconfig.cmake Lines 161 to 173 in cf457d4
|
Thank you very much for this information. I can confirm this is exactly what we were looking, not sure how we missed it in the docs. I have already updated our CI tools to use this method of composable sdkconfigs and is working as expected. Brilliant as no more superfluous dirty tags on builds. Not sure how much pain this cause when updating to a new IDF version as it will be difficult to see what has changed. |
Do you mean the difficulty would be because sdkconfig files would be different between IDF versions? I think this should be fine, because sdkconfig option names are backwards compatible. If we are renaming some sdkconfig option, for example because it is moved between components, we add it to The other potential problem is related to relying on default option values provided by IDF. It is recommended to keep Thanks for your feedback on this approach. We will add an example to IDF to demonstrate this mechanism, to make it easier to find this solution for other users in the future. |
By the way, here is a small improvement to the approach I suggested above. Instead of passing cmake_minimum_required(VERSION 3.5)
set(SDKCONFIG "${CMAKE_BINARY_DIR}/sdkconfig")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(your_project) This way the generated sdkconfig file will never be placed into the project root directory and will always stay in the build directory, making it possible for developers to have side-by-side builds for different products/configurations. |
The build log will also contain all renames as warnings near the top when generating the "final" sdkconfig / sdkconfig.h files.
@AshUK With this note above I'd suggest adding a mechanism to your CI tool where it diffs the generated sdkconfig file from the current build to the previous and flag any options which are not expected to change. |
This example shows how to use ESP-IDF build system features to build multiple configurations of an app from the same source files. Configurations are set by overriding SDKCONFIG_DEFAULTS variable when invoking idf.py. Related: #5658
I'm running into this specific issue too, but I can do just with the ability to use different per-board sdkconfig.defaults in Platform IO. |
I'll close this issue now since the example of building different configs was added in 5730711. |
* fixes #45 * see here for better explanation: espressif/esp-idf#5658 (comment)
Using ESP-IDF v4.2.
My use case is an app with two different images - one is WiFi-based and the other one is BLE-based. I'd like to share components between the two.
I opted for the bare
idf_build_process()
as shown in idf_as_lib example, but not I now face the problem the incorporating two sdkconfig files, one for each image, where the first one has WiFi custom config and BLE disabled and the second one does the opposite.By calling
idf_build_process()
twice I got the following:It looks like the second call is trying to create a target already created.
What can be done?
The text was updated successfully, but these errors were encountered: