1# Multiple Build Configurations Example 2 3(See the README.md file in the upper level 'examples' directory for more information about examples.) 4 5This example demonstrates how to build multiple configurations of a single application. This can be useful in the following cases: 6 7* Building binaries for multiple similar products from single codebase 8* Building the application for development or production hardware 9* Optimizing the application differently for development and production 10 11This example contains three build configurations: 12 13* Development configuration, described by `sdkconfig.defaults` file. This configuration is used by default if the application is built using `idf.py build`. 14* Production configuration for product 1 ("Blinky Smart Light"), described in `sdkconfig.prod1` file. This configuration is not built by default, however it can be built as shown in the next section. It is used together `sdkconfig.prod_common`, common configuration file for all products. 15* Production configuration for product 2 ("Blinky Smart Switch"), described in `sdkconfig.prod2` file. Differs from `prod1` configuration only in product name. 16 17For each configuration, a few configuration options are set: 18 19* Project-specific Kconfig options, `CONFIG_EXAMPLE_PRODUCT_NAME` and `CONFIG_EXAMPLE_FUNC_IMPL`. These options are declared in [component Kconfig.projbuild](main/Kconfig.projbuild). These are used to demonstrate how to create and set project-specific options. These options are set differently in `sdkconfig.defaults` and `sdkconfig.prod_common` files. 20 - `CONFIG_EXAMPLE_PRODUCT_NAME` is a simple `string` option. It is used to set the product name. 21 - `CONFIG_EXAMPLE_FUNC_IMPL` is a `choice` option. It is used to select which of the two source files, [func_dev.c](main/func_dev.c) or [func_prod.c](main/func_prod.c), is compiled and linked. See [component CMakeLists.txt file](main/CMakeLists.txt) for related logic. 22* ESP-IDF configuration options, `CONFIG_COMPILER_OPTIMIZATION_SIZE`, `CONFIG_BOOTLOADER_LOG_LEVEL_NONE`, `CONFIG_LOG_DEFAULT_LEVEL_NONE` are set in `sdkconfig.prod_common` to illustrate a typical production configuration where log messages are disabled and optimization for size is used. 23 24## How to Use Example 25 26### Development build 27 28In this example, Development configuration is specified in `sdkconfig.defaults`, so it is the default one. You can build the project as usual: 29 30``` 31idf.py build 32``` 33 34To flash the project and see the output, run: 35 36``` 37idf.py -p PORT flash monitor 38``` 39 40(To exit the serial monitor, type ``Ctrl-]``.) 41 42### Production build 43 44To build one of the Production configurations, specify a different build directory and `SDKCONFIG_DEFAULTS` file. For example, to build `prod1` configuration: 45 46``` 47idf.py -B build_prod1 -D SDKCONFIG_DEFAULTS="sdkconfig.prod_common;sdkconfig.prod1" build 48``` 49 50* `-B build_prod1` sets the build directory to `build_prod1` 51* `-D SDKCONFIG_DEFAULTS="sdkconfig.prod_common;sdkconfig.prod1"` selects `sdkconfig.prod_common` and `sdkconfig.prod1` files to be used for creating app configuration (sdkconfig), instead of the usual `sdkconfig.defaults`. See the section below on how these two default configuration files are combined. 52 53To flash the project and see the output, run: 54 55``` 56idf.py -B build_prod1 -p PORT flash monitor 57``` 58 59Note that it is not necessary to repeat `-D SDKCONFIG_DEFAULTS=...` option once the build directory has been created and `sdkconfig` file generated. For example, to build the project again, run: 60 61``` 62idf.py -B build_prod1 build 63``` 64 65To build and run the app with `prod2` configuration, repeat the steps above, replacing `prod1` with `prod2`. 66 67### Combining multiple files in `SDKCONFIG_DEFAULTS` 68 69`SDKCONFIG_DEFAULTS` build system variable selects the file which contains the default app configuration, used when no `sdkconfig` file is present. If not specified, `SDKCONFIG_DEFAULTS` is set to `"sdkconfig.defaults"`. 70 71`SDKCONFIG_DEFAULTS` can be set to a different name from the command line, using `-D` flag of `idf.py`, as shown above. It can also be set from the project CMakeLists.txt file, before `project.cmake` is included. 72 73It is possible to specify multiple files in this variable, separating them with semicolons. In the example given in the previous section, this is used to create a common config file for production builds and product-specific config files: 74 75* product 1: `sdkconfig.prod_common;sdkconfig.prod1` 76* product 2: `sdkconfig.prod_common;sdkconfig.prod2` 77 78This way the common options do not need to be repeated in each of `sdkconfig.prodN` files. 79 80### Generated `sdkconfig` file 81 82In this example, `sdkconfig` file is placed into the build directory, instead of the project root directory as it is done by default. This allows development and production builds to exist side by side. The location of `sdkconfig` file is set using `SDKCONFIG` variable in [project CMakeLists.txt](CMakeLists.txt) file. 83 84## Example Output 85 86### Development build output 87 88``` 89I (310) cpu_start: Starting scheduler on PRO CPU. 90I (0) cpu_start: Starting scheduler on APP CPU. 91This app is built for running on: Blinky Development Board 92func() from func_dev.c (Development) called. 93See README.md for building and running other app configurations. 94``` 95 96### Production build output 97 98When building with `-DSDKCONFIG_DEFAULTS="sdkconfig.prod_common;sdkconfig.prod1"` option: 99 100``` 101This app is built for running on: Blinky Smart Light 102func() from func_prod.c (Production) called. 103See README.md for building and running other app configurations. 104``` 105 106When building with `-DSDKCONFIG_DEFAULTS="sdkconfig.prod_common;sdkconfig.prod2"` option: 107 108``` 109This app is built for running on: Blinky Smart Switch 110func() from func_prod.c (Production) called. 111See README.md for building and running other app configurations. 112``` 113 114