mirror of https://github.com/ARMmbed/mbed-os.git
cmake: Refactor mbed_set_mbed_target_linker_script
Move the mbed_set_mbed_target_linker_script function into its own file and make it set the linkerscript on the target passed in, rather than setting the linkerscript on the top level mbed-core target. We use CMake's automatic forwarding of usage requirements to forward the linker script to the top level target. This commit also adds a condition to check whether the MBED_TARGET is a CMake buildsystem target. If it is we will just link to it in the idiomatic CMake way, if it's not then we use the 'old' mechanism of setting the linkerscript for the mbed-core target. This check will be useful when we refactor MBED_TARGETS to be CMake buildsystem targets as it will allow us to do the refactoring incrementally.pull/14199/head
parent
8f47212085
commit
0e491cc0cf
|
@ -6,6 +6,7 @@
|
|||
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
|
||||
|
||||
include(${MBED_CONFIG_PATH}/mbed_config.cmake)
|
||||
include(tools/cmake/set_linker_script.cmake)
|
||||
|
||||
add_library(mbed-core INTERFACE)
|
||||
|
||||
|
@ -86,6 +87,15 @@ target_include_directories(mbed-core
|
|||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# We need to generate a "response file" to pass to the C preprocessor because of path length
|
||||
# limitations on Windows. We set the response file and bind the path to a global property here.
|
||||
# We query this global property when we set the linker script for the MBED_TARGET being built.
|
||||
#
|
||||
# TODO: Remove this and find a more idiomatic way of passing compile definitions to CPP without
|
||||
# using global properties.
|
||||
mbed_generate_options_for_linker(${APP_TARGET} LINKER_PREPROCESS_DEFINITIONS)
|
||||
set_property(GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE ${LINKER_PREPROCESS_DEFINITIONS})
|
||||
|
||||
# These targets are made visible here so their source files which
|
||||
# are spread in different directories can be referenced and can be linked against
|
||||
# by libraries that depend on them.
|
||||
|
@ -110,6 +120,22 @@ add_subdirectory(features EXCLUDE_FROM_ALL)
|
|||
add_subdirectory(cmsis/CMSIS_5/CMSIS/RTOS2 EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(cmsis/device/rtos EXCLUDE_FROM_ALL)
|
||||
|
||||
# This is a temporary workaround to prevent the build from failing for MBED_TARGETS that
|
||||
# haven't been converted to build system targets yet.
|
||||
# The refactored MBED_TARGETS set the linker script and forward it to the build system as a
|
||||
# usage requirement. The 'old' mechanism was to set the linker script on the top level mbed-core
|
||||
# target. This was needed because MBED_TARGETS were not registered as buildsystem targets,
|
||||
# preventing CMake from working its usage requirements magic and forcing us to set the linker
|
||||
# script globally.
|
||||
#
|
||||
# TODO: Remove when all MBED_TARGETS have been converted to build system targets.
|
||||
if(TARGET ${MBED_TARGET})
|
||||
target_link_libraries(mbed-core INTERFACE ${MBED_TARGET})
|
||||
else()
|
||||
get_property(LINKER_SCRIPT GLOBAL PROPERTY MBED_TARGET_LINKER_FILE)
|
||||
mbed_set_linker_script(mbed-core ${LINKER_SCRIPT})
|
||||
endif()
|
||||
|
||||
#
|
||||
# Configures the application
|
||||
#
|
||||
|
@ -122,45 +148,6 @@ function(mbed_configure_app_target target)
|
|||
)
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# Specifies linker script used for linking `target`.
|
||||
#
|
||||
function(mbed_set_mbed_target_linker_script target)
|
||||
get_property(mbed_target_linker_script GLOBAL PROPERTY MBED_TARGET_LINKER_FILE)
|
||||
mbed_generate_options_for_linker(${target} _linker_preprocess_definitions)
|
||||
if(MBED_TOOLCHAIN STREQUAL "GCC_ARM")
|
||||
set(CMAKE_PRE_BUILD_COMMAND
|
||||
COMMAND "arm-none-eabi-cpp" ${_linker_preprocess_definitions} -x assembler-with-cpp -E -Wp,-P
|
||||
${mbed_target_linker_script} -o ${CMAKE_BINARY_DIR}/${target}.link_script.ld
|
||||
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
BYPRODUCTS "${CMAKE_BINARY_DIR}/${target}.link_script.ld"
|
||||
)
|
||||
target_link_options(mbed-core
|
||||
INTERFACE
|
||||
"-T" "${CMAKE_BINARY_DIR}/${target}.link_script.ld"
|
||||
"-Wl,-Map=${CMAKE_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.map"
|
||||
)
|
||||
elseif(MBED_TOOLCHAIN STREQUAL "ARM")
|
||||
set(CMAKE_PRE_BUILD_COMMAND COMMAND "")
|
||||
target_link_options(mbed-core
|
||||
INTERFACE
|
||||
"--scatter=${mbed_target_linker_script}"
|
||||
"--predefine=${_linker_preprocess_definitions}"
|
||||
"--map"
|
||||
)
|
||||
endif()
|
||||
add_custom_command(
|
||||
TARGET
|
||||
${target}
|
||||
PRE_LINK
|
||||
${CMAKE_PRE_BUILD_COMMAND}
|
||||
COMMENT
|
||||
"Link line:"
|
||||
VERBATIM
|
||||
)
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# Converts output file of `target` to binary file and to Intel HEX file.
|
||||
#
|
||||
|
|
|
@ -43,8 +43,6 @@ macro(mbed_greentea_add_test)
|
|||
|
||||
mbed_configure_app_target(${TEST_NAME})
|
||||
|
||||
mbed_set_mbed_target_linker_script(${TEST_NAME})
|
||||
|
||||
target_include_directories(${TEST_NAME}
|
||||
PRIVATE
|
||||
.
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# Copyright (c) 2021 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#
|
||||
# Preprocesses and sets the linker script for an Mbed target.
|
||||
#
|
||||
function(mbed_set_linker_script input_target raw_linker_script_path)
|
||||
set(LINKER_SCRIPT_PATH ${CMAKE_BINARY_DIR}/${input_target}.link_script.ld)
|
||||
# To avoid path limits on Windows, we create a "response file" and set the path to it as a
|
||||
# global property. We need this solely to pass the compile definitions to GCC's preprocessor,
|
||||
# so it can expand any macro definitions in the linker script.
|
||||
get_property(_linker_preprocess_definitions GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE)
|
||||
if(MBED_TOOLCHAIN STREQUAL "GCC_ARM")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${LINKER_SCRIPT_PATH}
|
||||
PRE_LINK
|
||||
COMMAND
|
||||
${CMAKE_C_COMPILER} ${_linker_preprocess_definitions}
|
||||
-E -x assembler-with-cpp
|
||||
-P ${raw_linker_script_path}
|
||||
-o ${LINKER_SCRIPT_PATH}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT
|
||||
"Link line:"
|
||||
VERBATIM
|
||||
)
|
||||
# CMake will not let us add PRE_LINK commands to INTERFACE targets, and input_target could
|
||||
# be an INTERFACE target.
|
||||
# To get around this we create an intermediate custom target depending on the preprocessed
|
||||
# linker script output by CPP. We add this custom target as a dependency of input_target.
|
||||
# This ensures CMake runs our custom command to preprocess the linker script before trying
|
||||
# to build input_target.
|
||||
set(LinkerScriptTarget ${input_target}LinkerScript)
|
||||
add_custom_target(${LinkerScriptTarget} DEPENDS ${LINKER_SCRIPT_PATH} VERBATIM)
|
||||
add_dependencies(${input_target} ${LinkerScriptTarget})
|
||||
target_link_options(${input_target}
|
||||
INTERFACE
|
||||
"-T" "${LINKER_SCRIPT_PATH}"
|
||||
"-Wl,-Map=${CMAKE_BINARY_DIR}/${APP_TARGET}${CMAKE_EXECUTABLE_SUFFIX}.map"
|
||||
)
|
||||
elseif(MBED_TOOLCHAIN STREQUAL "ARM")
|
||||
target_link_options(${input_target}
|
||||
INTERFACE
|
||||
"--scatter=${raw_linker_script_path}"
|
||||
"--predefine=${_linker_preprocess_definitions}"
|
||||
"--map"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
Loading…
Reference in New Issue