Configure builds using CMake

Important

This is the Azure Sphere (Legacy) documentation. Azure Sphere (Legacy) is retiring on 27 September 2027, and users must migrate to Azure Sphere (Integrated) by this time. Use the Version selector located above the TOC to view the Azure Sphere (Integrated) documentation.

Azure Sphere uses CMake to configure builds for applications with Visual Studio, Visual Studio Code, and the Windows and Linux command lines. CMake is an open-source, cross-platform make system. For general information about CMake, see the CMake Wiki.

The following sources provide information about using CMake with Visual Studio or Visual Studio Code:

CMake builds use the following files:

File Purpose
CMakeLists.txt General CMake configuration file. Required for all builds.
CMakePresets.json Configuration presets file for Visual Studio and Visual Studio Code. Either this file or CMakeSettings.json is required for building with Visual Studio.
CMakeSettings.json Visual Studio configuration file. Either this file or CMakePresets.json is required for building with Visual Studio.
CMakeWorkspaceSettings.json Visual Studio configuration file for projects with multiple roots, as in the IntercoreComms sample.
.vscode/settings.json Visual Studio Code configuration file. Required for building with Visual Studio Code.

CMake parameters are separated by spaces. The line continuation character "^" for the Windows command line, " \ " for the Linux command line, or "`" for Powershell can be used for readability but is not required. The specific character is determined by the Windows or Linux terminal configuration.

CMake functions for Azure Sphere

The CMakeLists.txt file provides the general configuration settings that CMake uses to build an application. Azure Sphere supports the use of the following functions in CMakeLists.txt:

Name Purpose
azsphere_target_hardware_definition Specify target hardware.
azsphere_target_add_image_package Create an image package.

If you have an existing application that was created with an SDK earlier than 20.04, see Convert an existing app to use the CMake functions.

The CMakeLists.txt file must call the project command before any of the azsphere_ functions.

Target hardware definition

You can specify the hardware you are targeting by calling the azsphere_target_hardware_definition function to store the value in CMakeLists.txt. This function takes two parameters: a list of directories to search and a filename to search for. For example:

azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "<path>/my_app/contoso_hardware_definitions" "<path>/my_app/test_hardware" TARGET_DEFINITION "contoso_board.json")

The TARGET_DEFINITION parameter is required. It specifies the name of the hardware definition file your application requires. The TARGET_DIRECTORY parameter lists the directories in which to search for this file. This parameter is optional; if you omit it, CMake looks only in the HardwareDefinitions folder in the SDK installation. To specify multiple folders, enclose each folder name in double quotation marks and use a space to separate folder names, as in the example. In the example, <path> represents the path to the my_app folder on your development machine.

Image package creation

Specify the image package file and any resource files to include when building by calling the azsphere_target_add_image_package function to store the value in CMakeLists.txt. The azsphere_target_add_image_package function and the project to build are required; the resource files are optional.

The following function call creates an image package that contains only the Azure Sphere application:

azsphere_target_add_image_package(${PROJECT_NAME})

The next example creates an image package that contains a certificate in addition to an application:

azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/bundle.pem")

The CMake target passed to azsphere_target_add_image_package must be named ${PROJECT_NAME}, and the azsphere_target_add_image_package function can be called only once from the CMakeLists.txt file.

Deprecated CMake functions

Before SDK version 24.03, the CMake functions azsphere_configure_tools and azsphere_configure_api were used to specify the target SDK tools version and target API set in the CMakeLists.txt file. These functions are now deprecated, and the target API set should be specified in the appropriate configuration file instead. See the Application runtime version, sysroots, and Beta APIs page for details.

If you're using an older version of the SDK and see a CMake configuration error about an unsupported tools revision, you can work around it by re-adding those functions to the CMakeLists.txt. As an example:

azsphere_configure_tools(TOOLS_REVISION 23.05) azsphere_configure_api(TARGET_API_SET 16)

How to delete the CMake cache when changing configuration files

If you change one of the configuration files, you should delete the CMake cache to ensure that subsequent builds do not fail. Follow this procedure before attempting another build:

  • For Visual Studio Code builds, run the CMake:Delete Cache and Reconfigure command from the Command Palette.
  • For command-line (CLI) builds, delete the build directory that you created in an earlier step.

Visual Studio detects changes to the CMake configuration file and auto-deletes the cache.

Convert an existing app to use the CMake functions

If you already have an Azure Sphere application that was built with CMake prior to the 20.04 SDK, you should convert it to use these new functions. You can still build such applications unchanged for now, but support for them is limited and may be removed in a future release.

For an example of the changes you should make, look at how the CMakeLists.txt and *.json configuration files were changed for the External MCU Update high-level app for the 20.04 release.

Note

In addition to updates to use the functions, these files have been updated in the Azure Sphere samples to use lowercase function names, thus aligning with CMake conventions.

CMakeLists.txt configuration changes

The following examples show the changes needed to update the CMakeLists.txt file from 20.01 or earlier to use the new functions.

Example 20.01 SDK CMakeLists.txt file

CMAKE_MINIMUM_REQUIRED(VERSION 3.8)
PROJECT(ExternalMcuUpdateNrf52 C)

ADD_EXECUTABLE(${PROJECT_NAME} main.c file_view.c mem_buf.c epoll_timerfd_utilities.c nordic/slip.c nordic/crc.c nordic/dfu_uart_protocol.c)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} applibs pthread gcc_s c)

SET(ADDITIONAL_APPROOT_INCLUDES "ExternalNRF52Firmware/blinkyV1.bin;ExternalNRF52Firmware/blinkyV1.dat;ExternalNRF52Firmware/s132_nrf52_6.1.0_softdevice.bin;ExternalNRF52Firmware/s132_nrf52_6.1.0_softdevice.dat")
INCLUDE("${AZURE_SPHERE_MAKE_IMAGE_FILE}")

Updated CMakeLists.txt file

The updated CMakeLists.txt file calls the azsphere_target_hardware_definition functions to set the target hardware. It also calls azsphere_target_add_image_package to build the image package and optionally specify the files to include in it.

cmake_minimum_required(VERSION 3.20)

project(ExternalMcuUpdateNrf52 C)

add_executable(${PROJECT_NAME} main.c file_view.c mem_buf.c epoll_timerfd_utilities.c nordic/slip.c nordic/crc.c nordic/dfu_uart_protocol.c)
target_link_libraries(${PROJECT_NAME} applibs pthread gcc_s c)

azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "../../../HardwareDefinitions/mt3620_rdb" TARGET_DEFINITION "sample_hardware.json")

azsphere_target_add_image_package(
    ${PROJECT_NAME}
    RESOURCE_FILES
        "ExternalNRF52Firmware/blinkyV1.bin"
        "ExternalNRF52Firmware/blinkyV1.dat"
        "ExternalNRF52Firmware/s132_nrf52_6.1.0_softdevice.bin"
        "ExternalNRF52Firmware/s132_nrf52_6.1.0_softdevice.dat")

Note

Absolute paths are not supported for RESOURCE_FILES.

Visual Studio CMakePresets.json configuration

The CMakePresets.json file allows you to specify common configure, build, and test options, then share them with developers using other development environments. For example, you can use the same presets configuration file to invoke CMake in Visual Studio, Visual Studio Code, a Continuous Integration pipeline, or from the CLI on Windows, Linux, or macOS.

As of release 22.07, current projects use presets defined in CMakePresets.json, while existing projects can continue to use settings in CMakeSettings.json. Samples are shipped with only one config file, either CMakePresets.json or CMakeSettings.json. The development environment will use the file that is present. Refer to each sample project to see which file is used. For projects using CMakeSettings.json, see Visual Studio CMakeSettings.json configuration changes.

The CMakePresets.json files for a high-level application and for a real-time application are very similar; the only differences are in the CMAKE_TOOLCHAIN_FILE and ARM_GNU_PATH variables.

In a high-level application, ARM_GNU_PATH is not set, and CMAKE_TOOLCHAIN_FILE is set as follows:

    "CMAKE_TOOLCHAIN_FILE": "$env{AzureSphereDefaultSDKDir}/CMakeFiles/AzureSphereToolchain.cmake",

In a real-time application, CMAKE_TOOLCHAIN_FILE and ARM_GNU_PATH are set as follows:

    "CMAKE_TOOLCHAIN_FILE": "$env{AzureSphereDefaultSDKDir}/CMakeFiles/AzureSphereRTCoreToolchain.cmake",
    "ARM_GNU_PATH": "$env{ArmGnuPath}"

Visual Studio CMakeSettings.json configuration

Samples are shipped with either a CMakePresets.json or CMakeSettings.json configuration file. Refer to each project to see which file is used. This section describes the CMakeSettings.json configuration. For projects using CMakePresets.json, see Visual Studio CMakePresets.json configuration changes.

The following examples show the changes needed to update the CMakeSettings.json file in Visual Studio from 20.01 or earlier to use the new functions.

Example 20.01 SDK CMakeSettings.json file

{
  "environments": [
    {
      "environment": "AzureSphere",
      "AzureSphereTargetApiSet": "4",
      "AzureSphereTargetHardwareDefinitionDirectory": "${projectDir}\\..\\..\\..\\Hardware\\mt3620_rdb",
      "AzureSphereTargetHardwareDefinition": "sample_hardware.json"
    }
  ],
  "configurations": [
    {
      "name": "ARM-Debug",
      "generator": "Ninja",
      "configurationType": "Debug",
      "inheritEnvironments": [
        "AzureSphere"
      ],
      "buildRoot": "${projectDir}\\out\\${name}-${env.AzureSphereTargetApiSet}",
      "installRoot": "${projectDir}\\install\\${name}-${env.AzureSphereTargetApiSet}",
      "cmakeCommandArgs": "--no-warn-unused-cli",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "variables": [
        {
          "name": "CMAKE_TOOLCHAIN_FILE",
          "value": "${env.AzureSphereDefaultSDKDir}CMakeFiles\\AzureSphereToolchain.cmake"
        },
        {
          "name": "AZURE_SPHERE_TARGET_API_SET",
          "value": "${env.AzureSphereTargetApiSet}"
        },
        {
          "name": "AZURE_SPHERE_TARGET_HARDWARE_DEFINITION_DIRECTORY",
          "value": "${env.AzureSphereTargetHardwareDefinitionDirectory}"
        },
        {
          "name": "AZURE_SPHERE_TARGET_HARDWARE_DEFINITION",
          "value": "${env.AzureSphereTargetHardwareDefinition}"
        }
      ]
    },
    {
      "name": "ARM-Release",
      "generator": "Ninja",
      "configurationType": "Release",
      "inheritEnvironments": [
        "AzureSphere"
      ],
      "buildRoot": "${projectDir}\\out\\${name}-${env.AzureSphereTargetApiSet}",
      "installRoot": "${projectDir}\\install\\${name}-${env.AzureSphereTargetApiSet}",
      "cmakeCommandArgs": "--no-warn-unused-cli",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "variables": [
        {
          "name": "CMAKE_TOOLCHAIN_FILE",
          "value": "${env.AzureSphereDefaultSDKDir}CMakeFiles\\AzureSphereToolchain.cmake"
        },
        {
          "name": "AZURE_SPHERE_TARGET_API_SET",
          "value": "${env.AzureSphereTargetApiSet}"
        },
        {
          "name": "AZURE_SPHERE_TARGET_HARDWARE_DEFINITION_DIRECTORY",
          "value": "${env.AzureSphereTargetHardwareDefinitionDirectory}"
        },
        {
          "name": "AZURE_SPHERE_TARGET_HARDWARE_DEFINITION",
          "value": "${env.AzureSphereTargetHardwareDefinition}"
        }
      ]
    }
  ]
}

Updated SDK CMakeSettings.json file

The updated CMakeSettings.json file includes the following changes:

  • In the "environments" field, only "Azure Sphere" is required.
  • In the "configurations" field for both the Debug and Release builds:
    • The "buildRoot" and "installRoot" values no longer require the AzureSphereTargetApiSet setting.
    • The CMake toolchain is now defined in "cmakeToolChain", instead of in "variables".
    • The "variables" field now specifies only the target API set and uses the new "latest-lts" value to indicate that the project should build with the most recent long-term-stable (LTS) sysroot. The AZURE_SPHERE_TARGET_HARDWARE_DEFINITION_DIRECTORY and AZURE_SPHERE_TARGET_HARDWARE_DEFINITION settings are no longer required, because these values are now set in the CMakeLists.txt file.
{
  "environments": [
    {
      "environment": "AzureSphere"
    }
  ],
  "configurations": [
    {
      "name": "ARM-Debug",
      "generator": "Ninja",
      "configurationType": "Debug",
      "inheritEnvironments": [
        "AzureSphere"
      ],
      "buildRoot": "${projectDir}\\out\\${name}",
      "installRoot": "${projectDir}\\install\\${name}",
      "cmakeToolchain": "${env.AzureSphereDefaultSDKDir}CMakeFiles\\AzureSphereToolchain.cmake",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "variables": [
        {
          "name": "AZURE_SPHERE_TARGET_API_SET",
          "value": "latest-lts"
        }
      ]
    },
    {
      "name": "ARM-Release",
      "generator": "Ninja",
      "configurationType": "Release",
      "inheritEnvironments": [
        "AzureSphere"
      ],
      "buildRoot": "${projectDir}\\out\\${name}",
      "installRoot": "${projectDir}\\install\\${name}",
      "cmakeToolchain": "${env.AzureSphereDefaultSDKDir}CMakeFiles\\AzureSphereToolchain.cmake",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "variables": [
        {
          "name": "AZURE_SPHERE_TARGET_API_SET",
          "value": "latest-lts"
        }
      ]
    }
  ]
}

Visual Studio Code .vscode/settings.json configuration

The following examples show the changes needed to update the .vscode/settings.json file for Visual Studio Code from 20.01 or earlier to use the new functions.

Example 20.01 SDK .vscode/settings.json file

{
    "cmake.generator": "Ninja",
    "cmake.buildDirectory": "${workspaceRoot}/out/${buildType}-${command:azuresphere.AzureSphereTargetApiSet}",
    "cmake.buildToolArgs": [ "-v" ],
    "cmake.configureArgs": [ "--no-warn-unused-cli" ],
    "cmake.configureSettings": {
        "CMAKE_TOOLCHAIN_FILE": "${command:azuresphere.AzureSphereSdkDir}/CMakeFiles/AzureSphereToolchain.cmake",
        "AZURE_SPHERE_TARGET_HARDWARE_DEFINITION_DIRECTORY": "${workspaceRoot}/../../../HardwareDefinitions/mt3620_rdb",
        "AZURE_SPHERE_TARGET_HARDWARE_DEFINITION": "sample_hardware.json",
        "AZURE_SPHERE_TARGET_API_SET": "4"
    },
    "cmake.configureOnOpen": true,
    "C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools"
}

Updated .vscode/settings.json file

The .vscode/settings.json file contains workspace settings for Visual Studio Code.

The updated settings.json file includes the following changes to the "cmake.configureSettings" field:

  • The AZURE_SPHERE_TARGET_HARDWARE_DEFINITION_DIRECTORY and AZURE_SPHERE_TARGET_HARDWARE_DEFINITION settings are no longer required, because these values are now set in the CMakeLists.txt file.
  • The CMAKE_TOOLCHAIN_FILE and AZURE_SPHERE_TARGET_API_SET settings are no longer required, because these values are now set in the CMakePresets.json file. The AZURE_SPHERE_TARGET_API_SET value is now "latest-lts", which indicates that the project should build with the most recent long-term-stable (LTS) sysroot.

Note that the "cmake.configureArgs" field has also been deleted for reasons unrelated to CMake. (The field is no longer required because the --no-warn-unused-cli parameter is not needed for this build.)

The following fields apply to extensions:

  • "cmake.configureOnOpen": true notifies the cmake-tools extension to start configuring when the workspace opens.

  • "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" specifies the IntelliSense provider to use for the cpp-tools extension; in this case, the cmake-tools extension.

{
    "cmake.generator": "Ninja",
    "cmake.buildDirectory": "${workspaceRoot}/out/${buildType}-${command:azuresphere.AzureSphereTargetApiSet}",
    "cmake.buildToolArgs": [ "-v" ]
    },
    "cmake.configureOnOpen": true,
    "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}

Creating a CMakeWorkspaceSettings.json file

If you are using Visual Studio 2022, version 17.1 or later, and you have a project with multiple roots, such as the IntercoreComms sample, you will need to add a CMakeWorkspaceSettings.json file to the top-level folder of the project. The file has two entries, one to specify that CMake build is enabled and one containing the paths to the multiple roots. For example, for the IntercoreComms sample, the CMakeWorkspaceSettings.json has the following content:

{
  "enableCMake": true,
  "sourceDirectory": [ "IntercoreComms_HighLevelApp", "IntercoreComms_RTApp_MT3620_BareMetal" ]
}

The paths are specified relative to the folder containing the CMakeWorkspaceSettings.json file.