Skip to content

Commit

Permalink
Rework post-build to support multiple executables
Browse files Browse the repository at this point in the history
When building greentea tests, each test is an executable with its
own output binary path. This is also the case when a user project
produces multiple executables. But the current implementation of
post-build operations always assumes there's only one executable,
at the root of the build directory.

The post-build command depends on Mbed target, and it always takes
the the executable we build as an input file. To achieve this, we
let each Mbed target (that has a post-build command) define a function

    function(mbed_post_build_function target)

which takes a CMake executable target as an argument from which it can
get its binary path using generator expressions. It generates and adds
to the passed executable target a post-build custom command.

Notes:
* The function name needs to be exact, because CMake only supports
literal function calls - CMake can't dereference a function name from
a variable. To avoid multiple definitions of this function, each Mbed
target needs to guard it with a macro to checks if the user is
building this Mbed target.
* `mbed_post_build_function()` is a function, but it is usually
defined by another macro rather than a parent function, because
nesting functions would make many variables inaccessible inside the
innermost `mbed_post_build_function()`.
* There's no more need to force regenerate images. Previously, post-
build commands were custom *targets* which always got to run, so we
force regenerated images on every build to avoid patching an image
that's already been patched once on previous build. Now post-build
commands are custom *commands* of the same executable target, and they
are only run if the executable target itself is rebuilt.
  • Loading branch information
LDong-Arm committed Jul 22, 2021
1 parent fcd57b2 commit e0b103d
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 134 deletions.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,16 @@ target_include_directories(mbed-core
add_library(mbed-device_key INTERFACE)
add_library(mbed-rtos INTERFACE)

# Include targets/ first, because any post-build hook needs to be defined
# before other parts of Mbed OS can add greentea tests which require
# mbed_set_post_build().
add_subdirectory(targets)

add_subdirectory(cmsis)
add_subdirectory(drivers)
add_subdirectory(hal)
add_subdirectory(platform)
add_subdirectory(rtos)
add_subdirectory(targets)
add_subdirectory(storage)
add_subdirectory(events)
add_subdirectory(connectivity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@

include(mbed_set_post_build)

set(MBED_POST_BUILD_TFM_DIR "${CMAKE_CURRENT_LIST_DIR}")

#
# Sign TF-M secure and non-secure images and combine them with the bootloader
#
function(mbed_post_build_tfm_sign_image
mbed_target
macro(mbed_post_build_tfm_sign_image
mbed_tfm_target
tfm_target
target_path
secure_bin
)
find_package(Python3)

set(mbed_target_name ${mbed_target})
set(post_build_command
COMMAND ${Python3_EXECUTABLE}
${MBED_POST_BUILD_TFM_DIR}/generate_mbed_image.py
--tfm-target ${tfm_target}
--target-path ${target_path}
--secure-bin ${secure_bin}
--non-secure-bin ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.bin
)

mbed_set_post_build_operation()
endfunction()
if("${mbed_tfm_target}" STREQUAL "${MBED_TARGET}")
function(mbed_post_build_function target)
find_package(Python3)
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${Python3_EXECUTABLE}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/generate_mbed_image.py
--tfm-target ${tfm_target}
--target-path ${target_path}
--secure-bin ${secure_bin}
--non-secure-bin $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.bin
)
endfunction()
endif()
endmacro()
114 changes: 66 additions & 48 deletions targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,90 @@

include(mbed_set_post_build)

set(MBED_POST_BUILD_CYPRESS_DIR "${CMAKE_CURRENT_LIST_DIR}")

#
# Merge Cortex-M4 HEX and a Cortex-M0 HEX.
#
function(mbed_post_build_psoc6_merge_hex mbed_target_name)
find_package(Python3)
macro(mbed_post_build_psoc6_merge_hex cypress_psoc6_target)
if("${cypress_psoc6_target}" STREQUAL "${MBED_TARGET}")
function(mbed_post_build_function target)
find_package(Python3)

# Copy ${ARGN} to a variable first as it cannot be used directly with
# the list() command
set (extra_macro_args ${ARGN})
# Copy ${ARGN} to a variable first as it cannot be used directly with
# the list() command
set (extra_macro_args ${ARGN})

# Get the number of arguments past the last expected argument
list(LENGTH extra_macro_args num_extra_args)
# Get the number of arguments past the last expected argument
list(LENGTH extra_macro_args num_extra_args)

if(${num_extra_args} GREATER 0)
# Get extra argument as `cortex_m0_hex`
list(GET extra_macro_args 0 cortex_m0_hex)
set(post_build_command
COMMAND ${Python3_EXECUTABLE} ${MBED_POST_BUILD_CYPRESS_DIR}/PSOC6.py
merge
--elf ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.elf
--m4hex ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.hex
--m0hex ${cortex_m0_hex}
)
else()
set(post_build_command
COMMAND ${Python3_EXECUTABLE} ${MBED_POST_BUILD_CYPRESS_DIR}/PSOC6.py
merge
--elf ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.elf
--m4hex ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.hex
)
endif()
if(${num_extra_args} GREATER 0)
# Get extra argument as `cortex_m0_hex`
list(GET extra_macro_args 0 cortex_m0_hex)
set(post_build_command
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PSOC6.py
merge
--elf $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.elf
--m4hex $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.hex
--m0hex ${cortex_m0_hex}
)
else()
set(post_build_command
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PSOC6.py
merge
--elf $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.elf
--m4hex $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.hex
)
endif()

mbed_set_post_build_operation()
endfunction()
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${post_build_command}
)
endfunction()
endif()
endmacro()


#
# Sign a Cortex-M4 HEX with Cortex-M0 HEX.
#
function(mbed_post_build_psoc6_sign_image
macro(mbed_post_build_psoc6_sign_image
m0hex_filename
mbed_target_name
cypress_psoc6_target
policy_file_name
boot_scheme
cm0_img_id
cm4_img_id
cortex_m0_hex
)
find_package(Python3)
if("${cypress_psoc6_target}" STREQUAL "${MBED_TARGET}")
function(mbed_post_build_function target)
find_package(Python3)

set(post_build_command
COMMAND ${Python3_EXECUTABLE} ${MBED_POST_BUILD_CYPRESS_DIR}/PSOC6.py
sign
--build-dir ${CMAKE_BINARY_DIR}
--m0hex-filename ${m0hex_filename}
--target-name ${mbed_target_name}
--policy-file-name ${policy_file_name}
--boot-scheme ${boot_scheme}
--cm0-img-id ${cm0_img_id}
--cm4-img-id ${cm4_img_id}
--elf ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.elf
--m4hex ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.hex
--m0hex ${cortex_m0_hex}
)
set(post_build_command
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PSOC6.py
sign
--build-dir ${CMAKE_BINARY_DIR}
--m0hex-filename ${m0hex_filename}
--target-name ${cypress_psoc6_target}
--policy-file-name ${policy_file_name}
--boot-scheme ${boot_scheme}
--cm0-img-id ${cm0_img_id}
--cm4-img-id ${cm4_img_id}
--elf $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.elf
--m4hex $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.hex
--m0hex ${cortex_m0_hex}
)

mbed_set_post_build_operation()
endfunction()
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${post_build_command}
)
endfunction()
endif()
endmacro()
35 changes: 20 additions & 15 deletions targets/TARGET_NUVOTON/scripts/mbed_set_post_build_nuvoton.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,27 @@ include(${MBED_PATH}/tools/cmake/mbed_set_post_build.cmake)
#
# Sign TF-M secure and non-secure images and combine them with the bootloader
#
function(mbed_post_build_nuvoton_tfm_sign_image_tgt
mbed_target
macro(mbed_post_build_nuvoton_tfm_sign_image_tgt
nuvoton_target
tfm_import_path
signing_key
)
find_package(Python3)
if("${nuvoton_target}" STREQUAL "${MBED_TARGET}")
function(mbed_post_build_function target)
find_package(Python3)

set(mbed_target_name ${mbed_target})
set(post_build_command
COMMAND ${Python3_EXECUTABLE}
${MBED_PATH}/targets/TARGET_NUVOTON/scripts/NUVOTON.py
tfm_sign_image_tgt
--tfm-import-path ${tfm_import_path}
--signing_key ${signing_key}
--non-secure-bin ${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.bin
)

mbed_set_post_build_operation()
endfunction()
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${Python3_EXECUTABLE}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/NUVOTON.py
tfm_sign_image_tgt
--tfm-import-path ${tfm_import_path}
--signing_key ${signing_key}
--non-secure-bin $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.bin
)
endfunction()
endif()
endmacro()
27 changes: 15 additions & 12 deletions targets/TARGET_NXP/scripts/mbed_set_post_build_nxp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@

include(mbed_set_post_build)

set(MBED_POST_BUILD_NXP_DIR "${CMAKE_CURRENT_LIST_DIR}")

#
# Patch an LPC target vector table in the binary file.
#
function(mbed_post_build_lpc_patch_vtable mbed_target_name)
find_package(Python3)

set(post_build_command
COMMAND ${Python3_EXECUTABLE} ${MBED_POST_BUILD_NXP_DIR}/LPC.py
${CMAKE_BINARY_DIR}/$<TARGET_PROPERTY:mbed-post-build-bin-${mbed_target_name},application>.bin
)

mbed_set_post_build_operation()
endfunction()
macro(mbed_post_build_lpc_patch_vtable nxp_lpc_target)
if("${nxp_lpc_target}" STREQUAL "${MBED_TARGET}")
function(mbed_post_build_function target)
find_package(Python3)
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/LPC.py
$<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.bin
)
endfunction()
endif()
endmacro()
45 changes: 5 additions & 40 deletions tools/cmake/mbed_set_post_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,12 @@ function(mbed_generate_bin_hex target)
TARGET
${target}
POST_BUILD
COMMAND
${CMAKE_POST_BUILD_COMMAND}
COMMENT
"executable:"
VERBATIM
)

if(TARGET mbed-post-build-bin-${MBED_TARGET})
# Remove the .elf file to force regenerate the application binaries
# (including .bin and .hex). This ensures that the post-build script runs
# on a raw application instead of a previous build that already went
# through the post-build process once.
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf)

# Pass the application's name to the Mbed target's post build operation
set_target_properties(mbed-post-build-bin-${MBED_TARGET}
PROPERTIES
application ${target}
)

# The artefacts must be created before they can be further manipulated
add_dependencies(mbed-post-build-bin-${MBED_TARGET} ${target})

# Add a post-build hook to the top-level CMake target in the form of a
# CMake custom target. The hook depends on Mbed target specific
# post-build CMake target which has a custom command attached to it.
add_custom_target(mbed-post-build ALL DEPENDS mbed-post-build-bin-${MBED_TARGET})
endif()
endfunction()

#
Expand Down Expand Up @@ -112,25 +91,11 @@ function(mbed_set_post_build target)
mbed_validate_application_profile(${target})
mbed_generate_bin_hex(${target})

if(COMMAND mbed_post_build_function)
mbed_post_build_function(${target})
endif()

if(HAVE_MEMAP_DEPS)
mbed_generate_map_file(${target})
endif()
endfunction()


#
# Sets the post build operation for Mbed targets.
#
macro(mbed_set_post_build_operation)

add_custom_target(mbed-post-build-bin-${mbed_target_name})

add_custom_command(
TARGET
mbed-post-build-bin-${mbed_target_name}
POST_BUILD
COMMAND
${post_build_command}
VERBATIM
)
endmacro()

0 comments on commit e0b103d

Please sign in to comment.