zephyr/cmake/mcuboot.cmake

135 lines
4.9 KiB
CMake

# Copyright (c) 2020 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
# This file includes extra build system logic that is enabled when
# CONFIG_BOOTLOADER_MCUBOOT=y.
#
# It builds signed binaries using imgtool as a post-processing step
# after zephyr/zephyr.elf is created in the build directory.
#
# Since this file is brought in via include(), we do the work in a
# function to avoid polluting the top-level scope.
function(zephyr_mcuboot_tasks)
set(keyfile "${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE}")
# Check for misconfiguration.
if("${keyfile}" STREQUAL "")
# No signature key file, no signed binaries. No error, though:
# this is the documented behavior.
return()
endif()
if(NOT WEST)
# This feature requires west.
message(FATAL_ERROR "Can't sign images for MCUboot: west not found. To fix, install west and ensure it's on PATH.")
endif()
if(NOT IS_ABSOLUTE "${keyfile}")
# Relative paths are relative to 'west topdir'.
set(keyfile "${WEST_TOPDIR}/${keyfile}")
set(keyfile_relative TRUE)
else()
set(keyfile_relative FALSE)
endif()
if(NOT EXISTS "${keyfile}")
if(keyfile_relative)
set(relative_msg " Note: relative paths are relative to the west workspace topdir \"${WEST_TOPDIR}\".")
else()
set(relative_msg "")
endif()
message(FATAL_ERROR "Can't sign images for MCUboot: CONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE}\" not found.${relative_msg}")
elseif(NOT (CONFIG_BUILD_OUTPUT_BIN OR CONFIG_BUILD_OUTPUT_HEX))
message(FATAL_ERROR "Can't sign images for MCUboot: Neither CONFIG_BUILD_OUTPUT_BIN nor CONFIG_BUILD_OUTPUT_HEX is enabled, so there's nothing to sign.")
endif()
# Find imgtool. Even though west is installed, imgtool might not be.
# The user may also have a custom manifest which doesn't include
# MCUboot.
#
# Therefore, go with an explicitly installed imgtool first, falling
# back on mcuboot/scripts/imgtool.py.
if(IMGTOOL)
set(imgtool_path "${IMGTOOL}")
elseif(DEFINED ZEPHYR_MCUBOOT_MODULE_DIR)
set(IMGTOOL_PY "${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts/imgtool.py")
if(EXISTS "${IMGTOOL_PY}")
set(imgtool_path "${IMGTOOL_PY}")
endif()
endif()
# No imgtool, no signed binaries.
if(NOT DEFINED imgtool_path)
message(FATAL_ERROR "Can't sign images for MCUboot: can't find imgtool. To fix, install imgtool with pip3, or add the mcuboot repository to the west manifest and ensure it has a scripts/imgtool.py file.")
return()
endif()
# Basic 'west sign' command and output format independent arguments.
set(west_sign ${WEST} sign --quiet --tool imgtool
--tool-path "${imgtool_path}"
--build-dir "${APPLICATION_BINARY_DIR}")
# Arguments to imgtool.
if(NOT CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS STREQUAL "")
# Separate extra arguments into the proper format for adding to
# extra_post_build_commands.
#
# Use UNIX_COMMAND syntax for uniform results across host
# platforms.
separate_arguments(imgtool_extra UNIX_COMMAND ${CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS})
else()
set(imgtool_extra)
endif()
set(imgtool_args -- --key "${keyfile}" ${imgtool_extra})
# Extensionless prefix of any output file.
set(output ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME})
# List of additional build byproducts.
set(byproducts)
# 'west sign' arguments for confirmed and unconfirmed images.
set(unconfirmed_args)
set(confirmed_args)
# Set up .bin outputs.
if(CONFIG_BUILD_OUTPUT_BIN)
list(APPEND unconfirmed_args --bin --sbin ${output}.signed.bin)
list(APPEND byproducts ${output}.signed.bin)
if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE)
list(APPEND confirmed_args --bin --sbin ${output}.signed.confirmed.bin)
list(APPEND byproducts ${output}.signed.confirmed.bin)
endif()
endif()
# Set up .hex outputs.
if(CONFIG_BUILD_OUTPUT_HEX)
list(APPEND unconfirmed_args --hex --shex ${output}.signed.hex)
list(APPEND byproducts ${output}.signed.hex)
if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE)
list(APPEND confirmed_args --hex --shex ${output}.signed.confirmed.hex)
list(APPEND byproducts ${output}.signed.confirmed.hex)
endif()
endif()
# Add the west sign calls and their byproducts to the post-processing
# steps for zephyr.elf.
#
# CMake guarantees that multiple COMMANDs given to
# add_custom_command() are run in order, so adding the 'west sign'
# calls to the "extra_post_build_commands" property ensures they run
# after the commands which generate the unsigned versions.
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
${west_sign} ${unconfirmed_args} ${imgtool_args})
if(confirmed_args)
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
${west_sign} ${confirmed_args} ${imgtool_args} --confirm)
endif()
set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${byproducts})
endfunction()
zephyr_mcuboot_tasks()