Project Configuration

[中文]

The extension has multiple settings to configure the ESP-IDF project. To allow multiple configuration settings for the same project, you can use the Project Configuration Editor to define multiple profiles with different settings for each profile. The table of contents is as follows:

Configuring the Extension for One Build Configuration

A typical ESP-IDF Project Structure is as follows:

- /path/to/esp-project/
            - CMakeLists.txt
            - sdkconfig
            - components/ - component1/ - CMakeLists.txt
                                        - Kconfig
                                        - src1.c
                          - component2/ - CMakeLists.txt
                                        - Kconfig
                                        - src1.c
                                        - include/ - component2.h
            - main/       - CMakeLists.txt
                          - src1.c
                          - src2.c

            - build/

In the ESP-IDF CMake build system, the project configuration settings are saved using the SDK Configuration Editor, which stores these values in a /path/to/esp-project/sdkconfig file. By default, this file is created in the ESP-IDF project root directory, and a /path/to/esp-project/build directory is used as the build directory path.

When the current ESP-IDF project is under version control, the /path/to/esp-project/sdkconfig can change with any user build, potentially altering the project’s expected behavior. To prevent this, it is better to move project-specific settings to a sdkconfig.defaults file (or list of files) that is not modified by the build system. /path/to/esp-project/sdkconfig can be added to the .gitignore list. The sdkconfig.defaults can be generated by the ESP-IDF: Save Default SDKCONFIG file (save-defconfig) command available in ESP-IDF v5.0 or higher.

Note

The sdkconfig.defaults file is used by the build system to override defaults project settings when creating the sdkconfig file, as described in the ESP-IDF documentation Custom Sdkconfig Defaults.

With this extension’s settings, the default build path (/path/to/esp-project/build), sdkconfig file path, and sdkconfig.defaults can be modified from their default location.

In this extension, you can define the build directory with the idf.buildPath (idf.buildPathWin for Windows) configuration setting and the list of sdkconfig default files with idf.sdkconfigDefaults configuration. These values will be used by the extension build command.

For example, to create product 1:

  1. You have sdkconfig files sdkconfig.prod_common and sdkconfig.prod1 and want the resulting firmware to be generated in <your-project>/build_prod1, where build_prod1 is the name of the custom build folder.

  2. Add these settings in <your-project>/.vscode/settings.json:

    {
    // ...
    "idf.buildPath": "${workspaceFolder}/build_prod1",
    "idf.sdkconfigDefaults": ["sdkconfig.prod_common", "sdkconfig.prod1"]
    // ...
    }
    
  3. Build your project using the ESP-IDF: Build your Project command.

  4. Your resulting files will be generated in <your-project>/build_prod1, and the sdkconfig used by the SDK Configuration Editor will be <your-project>/build_prod1/sdkconfig.

    Note

    The ESP-IDF CMake Multiple configuration example defines the sdkconfig location in the CMakeLists.txt file, which will make idf.sdkconfigFilePath NOT work.

  5. Change values in step 2 for different products and configurations.

With the ESP-IDF: SDK Configuration Editor, you can specify the build directory with Build Directory Path, the location of the SDKConfig file with SDKConfig File Path, and the default configuration files with SDKConfig Defaults to generate the SDKConfig file in the specified path.

Configuring the Extension for Multiple Build Configurations

The extension uses the standard CMake Presets format to manage multiple build configurations. Configuration profiles are defined in CMakePresets.json (and optionally CMakeUserPresets.json for user-specific overrides) in your project root directory.

With CMakePresets.json you can define multiple locations of the build directory with binaryDir, SDKCONFIG for the SDKConfig file path and SDKCONFIG_DEFAULTS for the list of SDKConfig default files to create the SDKConfig file in the specified path.

To create multiple build configurations:

  1. Create or edit CMakePresets.json in your project root directory. The ESP-IDF: Create Project Configuration command writes a starter file with two presets, default and production, that you can rename and extend.

  2. Define your configuration presets in the configurePresets array. Each preset can override the following extension settings:

Extension Setting

CMakePresets Location

idf.cmakeCompilerArgs

vendor["espressif/vscode-esp-idf"].settings (type: compileArgs)

idf.ninjaArgs

vendor["espressif/vscode-esp-idf"].settings (type: ninjaArgs)

idf.buildPath

binaryDir

idf.sdkconfigFilePath

cacheVariables.SDKCONFIG

idf.sdkconfigDefaults

cacheVariables.SDKCONFIG_DEFAULTS (semicolon-separated string)

idf.customExtraVars

environment (IDF_TARGET is in cacheVariables.IDF_TARGET)

idf.flashBaudRate

vendor["espressif/vscode-esp-idf"].settings (type: flashBaudRate)

idf.monitorBaudRate

vendor["espressif/vscode-esp-idf"].settings (type: monitorBaudRate)

idf.openOcdDebugLevel

vendor["espressif/vscode-esp-idf"].settings (type: openOCD, field: debugLevel)

idf.openOcdConfigs

vendor["espressif/vscode-esp-idf"].settings (type: openOCD, field: configs)

idf.openOcdLaunchArgs

vendor["espressif/vscode-esp-idf"].settings (type: openOCD, field: args)

idf.preBuildTask

vendor["espressif/vscode-esp-idf"].settings (type: tasks, field: preBuild)

idf.postBuildTask

vendor["espressif/vscode-esp-idf"].settings (type: tasks, field: postBuild)

idf.preFlashTask

vendor["espressif/vscode-esp-idf"].settings (type: tasks, field: preFlash)

idf.postFlashTask

vendor["espressif/vscode-esp-idf"].settings (type: tasks, field: postFlash)

  1. After defining your presets, use the ESP-IDF: Select Project Configuration command to choose the configuration to use.

    • Go to menu View > Command Palette

    • Type ESP-IDF: Select Project Configuration command to choose the configuration to override extension configuration settings.

Note

When you select a project configuration, the extension automatically attaches vendor settings under espressif/vscode-esp-idf for the chosen preset (for example, OpenOCD configuration and IDF_TARGET) based on your currently selected board configuration and target in the extension. These settings are merged with any vendor settings you’ve defined in your CMakePresets.json file.

Project configuration profiles are saved in CMakePresets.json and CMakeUserPresets.json

Project configurations are stored using the standard CMake Presets format in CMakePresets.json (typically committed to version control) and optionally CMakeUserPresets.json (user-specific overrides, typically gitignored).

The CMakePresets.json file structure follows the CMake Presets schema with ESP-IDF-specific vendor settings. The extension registers its own schema, which extends the official CMake Presets schema with the ESP-IDF vendor fields, for both CMakePresets.json and CMakeUserPresets.json. Validation and autocompletion are therefore available as soon as you open either file, and no $schema field is required.

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "displayName": "Default Configuration",
      "description": "Default build configuration",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "IDF_TARGET": "esp32",
        "SDKCONFIG_DEFAULTS": "sdkconfig.defaults",
        "SDKCONFIG": "${sourceDir}/build/sdkconfig"
      },
      "environment": {},
      "vendor": {
        "espressif/vscode-esp-idf": {
          "schemaVersion": 1,
          "settings": [
            {
              "type": "compileArgs",
              "value": []
            },
            {
              "type": "ninjaArgs",
              "value": []
            },
            {
              "type": "flashBaudRate",
              "value": "921600"
            },
            {
              "type": "monitorBaudRate",
              "value": ""
            },
            {
              "type": "openOCD",
              "value": {
                "debugLevel": 2,
                "configs": [],
                "args": []
              }
            },
            {
              "type": "tasks",
              "value": {
                "preBuild": "",
                "preFlash": "",
                "postBuild": "",
                "postFlash": ""
              }
            }
          ]
        }
      }
    }
  ]
}

The preset name (name field) is used to identify the profile when using the ESP-IDF: Select Project Configuration command. The preset name is also used to display the current profile in the status bar. The preset name is case-sensitive.

The selected profile is remembered per workspace and restored when you reopen it, so it only needs to be selected once. Set idf.saveLastProjectConfiguration to false to start with no profile selected instead. While the presets files cannot be read, for example during an unfinished edit or when two presets share a name, the extension reports the error and shows no profile, then restores your selection once the files parse again.

Hidden Presets

A preset with "hidden": true is a base meant only to be inherited from, exactly as in cmake --list-presets. The extension does not offer it in the ESP-IDF: Select Project Configuration list, but presets that list it in their inherits field still receive all of its settings. Use this to keep settings shared by several profiles in a single place:

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "common",
      "hidden": true,
      "cacheVariables": {
        "IDF_TARGET": "esp32c6"
      },
      "vendor": {
        "espressif/vscode-esp-idf": {
          "schemaVersion": 1,
          "settings": [
            {
              "type": "monitorBaudRate",
              "value": "115200"
            }
          ]
        }
      }
    },
    {
      "name": "prod1",
      "displayName": "Product 1",
      "inherits": "common",
      "binaryDir": "${sourceDir}/build_prod1"
    }
  ]
}

Only prod1 appears in the configuration list, and it builds for esp32c6 with a monitor baud rate of 115200 inherited from common. hidden itself is never inherited, so a visible preset can freely extend a hidden one.

CMakeUserPresets.json follows the same structure and is where you keep settings you do not want to share. This allows you to:

  • Keep project-wide configurations in CMakePresets.json (committed to version control)

  • Keep personal customizations in CMakeUserPresets.json (gitignored)

Preset names must be unique across both files. CMake refuses to read any preset when a name is declared twice, and the extension behaves the same way: no configuration is offered while a duplicate exists, and an error message names the presets involved. To personalize a shared preset, add a preset under a different name that inherits it.

Example: Using CMakeUserPresets.json for Personal Overrides

Suppose you have a project-wide CMakePresets.json with a production preset:

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "production",
      "displayName": "Production",
      "binaryDir": "${sourceDir}/build_production",
      "cacheVariables": {
        "SDKCONFIG_DEFAULTS": "sdkconfig.defaults",
        "SDKCONFIG": "${sourceDir}/build_production/sdkconfig"
      }
    }
  ]
}

You can create a CMakeUserPresets.json file with your own preset that inherits production and sets only what you want to change, such as flash baud rate or monitor baud rate:

{
  "version": 3,
  "configurePresets": [
    {
      "name": "production-local",
      "displayName": "Production (local)",
      "inherits": "production",
      "vendor": {
        "espressif/vscode-esp-idf": {
          "schemaVersion": 1,
          "settings": [
            {
              "type": "flashBaudRate",
              "value": "115200"
            },
            {
              "type": "monitorBaudRate",
              "value": "115200"
            }
          ]
        }
      }
    }
  ]
}

Both presets appear in the configuration list. When you select production-local, the extension uses your flash and monitor baud rates (115200) and inherits the build directory and SDKConfig settings from production. This allows each team member to have their own serial port settings without modifying the shared project configuration.

While each field is self-explanatory, here is the mapping of the CMakePresets structure to the extension settings:

Extension Setting

CMakePresets Location

idf.cmakeCompilerArgs

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "compileArgs"

idf.ninjaArgs

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "ninjaArgs"

idf.buildPath

configurePresets[].binaryDir

idf.sdkconfigFilePath

configurePresets[].cacheVariables.SDKCONFIG

idf.sdkconfigDefaults

configurePresets[].cacheVariables.SDKCONFIG_DEFAULTS (semicolon-separated string)

idf.customExtraVars

configurePresets[].environment (IDF_TARGET is in cacheVariables.IDF_TARGET)

idf.flashBaudRate

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "flashBaudRate"

idf.monitorBaudRate

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "monitorBaudRate"

idf.openOcdDebugLevel

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "openOCD", field: debugLevel

idf.openOcdConfigs

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "openOCD", field: configs

idf.openOcdLaunchArgs

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "openOCD", field: args

idf.preBuildTask

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "tasks", field: preBuild

idf.postBuildTask

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "tasks", field: postBuild

idf.preFlashTask

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "tasks", field: preFlash

idf.postFlashTask

configurePresets[].vendor["espressif/vscode-esp-idf"].settings[] where type == "tasks", field: postFlash

Multiple Configuration Tutorial

Use the ESP-IDF CMake Multiple Build Configurations Example to follow this tutorial.

Note

The ESP-IDF multi_config example already ships with a ready-to-use CMakePresets.json and works out of the box. When you select a project configuration in this extension, the extension will automatically attach vendor settings under espressif/vscode-esp-idf for the chosen preset (for example, OpenOCD configuration and IDF_TARGET) based on your currently selected board configuration and target in the extension.

To create multiple configurations manually, create or edit CMakePresets.json in your project root with two configuration presets: prod1 and prod2:

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "displayName": "Default (development)",
      "description": "Development configuration",
      "binaryDir": "${sourceDir}/build/default",
      "cacheVariables": {
        "SDKCONFIG": "${sourceDir}/build/default/sdkconfig"
      }
    },
    {
      "name": "prod1",
      "displayName": "Product 1",
      "description": "Production configuration for product 1",
      "binaryDir": "${sourceDir}/build/prod1",
      "cacheVariables": {
        "SDKCONFIG_DEFAULTS": "sdkconfig.defaults.prod_common;sdkconfig.defaults.prod1",
        "SDKCONFIG": "${sourceDir}/build/prod1/sdkconfig"
      }
    },
    {
      "name": "prod2",
      "displayName": "Product 2",
      "description": "Production configuration for product 2",
      "binaryDir": "${sourceDir}/build/prod2",
      "cacheVariables": {
        "SDKCONFIG_DEFAULTS": "sdkconfig.defaults.prod_common;sdkconfig.defaults.prod2",
        "SDKCONFIG": "${sourceDir}/build/prod2/sdkconfig"
      }
    }
  ]
}

In the SDKCONFIG_DEFAULTS field, multiple sdkconfig default files are specified as a semicolon-separated string. The values are loaded in order as explained in the ESP-IDF documentation.

After creating your CMakePresets.json file:

  1. Use the ESP-IDF: Select Project Configuration command to choose the configuration to use (default, prod1, or prod2).

  2. After a configuration profile is selected, the selected profile will be shown in the status bar.

  3. Use the ESP-IDF: Build your Project to build the project for the selected profile. You can observe binaries generated for each profile in the path defined in each preset’s binaryDir field.

  4. Use the ESP-IDF: Select Project Configuration command to switch between configurations at any time.

To modify, add, or delete configuration profiles, edit the CMakePresets.json file directly. If you want to stop using these profiles, remove the presets from the file or delete the file entirely.

Development and Release Profiles for ESP-IDF Project

For this example we will create two profiles, development and production, to define separate build directories and sdkconfig files.

  1. Click menu View > Command Palette…

  2. Type ESP-IDF: Save Default SDKCONFIG file (save-defconfig) and select the command to generate a sdkconfig.defaults file. This command is added in ESP-IDF v5.0. You can also create this sdkconfig.defaults manually.

  3. Create or edit CMakePresets.json in your project root directory with the following structure:

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "production",
      "displayName": "Production",
      "description": "Production build configuration",
      "binaryDir": "${sourceDir}/build_production",
      "cacheVariables": {
        "SDKCONFIG_DEFAULTS": "sdkconfig.defaults",
        "SDKCONFIG": "${sourceDir}/build_production/sdkconfig"
      }
    },
    {
      "name": "development",
      "displayName": "Development",
      "description": "Development build configuration",
      "binaryDir": "${sourceDir}/build_dev",
      "cacheVariables": {
        "SDKCONFIG": "${sourceDir}/build_dev/sdkconfig"
      }
    }
  ]
}
  1. After creating your CMakePresets.json file, use the ESP-IDF: Select Project Configuration command to choose the desired profile.

  2. When you choose the production profile and use the ESP-IDF: Build your Project command, the /path/to/esp-project/build_production/sdkconfig will be created and the binaries will be generated in /path/to/esp-project/build_production.

  3. If you choose the development profile, the /path/to/esp-project/build_dev/sdkconfig will be created and the binaries will be generated in /path/to/esp-project/build_dev.

The production profile can be split into multiple production profiles, as shown in the Multiple configuration tutorial, by separating sdkconfig.defaults into common SDKConfig settings in a sdkconfig.prod_common file and product-specific settings in sdkconfig.prod1 and sdkconfig.prod2 files respectively. Multiple SDKConfig defaults files can be specified in the SDKCONFIG_DEFAULTS cache variable as a semicolon-separated string (e.g., "sdkconfig.prod_common;sdkconfig.prod1") where the values are loaded in order as explained in the ESP-IDF documentation.

Migrating from Legacy Project Configuration Format

If you have an existing project using the legacy esp_idf_project_configuration.json format, the extension will automatically detect and offer to migrate it to the new CMakePresets.json format.

Automatic Migration:

  1. When you open a project with an existing esp_idf_project_configuration.json file, the extension will prompt you to migrate.

  2. If you accept, the extension will automatically convert all profiles from the legacy format to CMakePresets.json.

  3. The legacy file will remain in your project (you can delete it after verifying the migration).

Manual Migration:

If you prefer to migrate manually or need to understand the conversion:

  1. The legacy esp_idf_project_configuration.json structure is converted to CMakePresets format as follows:

    • Legacy profile name → CMakePresets name field

    • build.buildDirectoryPathbinaryDir

    • build.sdkconfigFilePathcacheVariables.SDKCONFIG

    • build.sdkconfigDefaults (array) → cacheVariables.SDKCONFIG_DEFAULTS (semicolon-separated string)

    • idfTargetcacheVariables.IDF_TARGET

    • envenvironment

    • All other settings (compileArgs, ninjaArgs, flashBaudRate, monitorBaudRate, openOCD, tasks) → vendor["espressif/vscode-esp-idf"].settings array

  2. Create a CMakePresets.json file following the structure shown in the examples above.

  3. Convert each profile from the legacy format to the new format.

  4. Delete the esp_idf_project_configuration.json file after verification.

Note

After migration, the extension will use CMakePresets.json for all configuration operations. The legacy file format is no longer supported for new configurations.

The previous production profile can be divided into multiple production presets, as demonstrated in the ESP-IDF CMake multi_config example. This is achieved by splitting the sdkconfig.defaults file into a common settings file (sdkconfig.prod_common) and product-specific settings files (sdkconfig.prod1 and sdkconfig.prod2). In CMakePresets.json, specify multiple SDKCONFIG_DEFAULTS files as a semicolon-separated string (e.g., sdkconfig.prod_common;sdkconfig.prod1), and these files will be loaded in order as explained here.

This is just one example of what the Project Configuration Editor can do. You can also define multiple profiles for other development scenarios, such as testing, profiling, and more.