mirror of https://github.com/ARMmbed/mbed-os.git
Change linker script handling logic to use only one linker script target
parent
967ead5a79
commit
4897b885d6
|
@ -269,6 +269,9 @@ if(NOT MBED_IS_NATIVE_BUILD)
|
||||||
# Create a distro for the microcontroller cmake target, ensuring its sources are only compiled once
|
# Create a distro for the microcontroller cmake target, ensuring its sources are only compiled once
|
||||||
mbed_create_distro(${MBED_TARGET_CMAKE_NAME}-lib ${MBED_TARGET_CMAKE_NAME} mbed-core-flags)
|
mbed_create_distro(${MBED_TARGET_CMAKE_NAME}-lib ${MBED_TARGET_CMAKE_NAME} mbed-core-flags)
|
||||||
|
|
||||||
|
# Set up the linker script and hook it up to the MCU cmake target
|
||||||
|
mbed_setup_linker_script(${MBED_TARGET_CMAKE_NAME}-lib)
|
||||||
|
|
||||||
# Now make the Mbed OS code depend on the target, ensuring everything has access to the uC's flags and objects.
|
# Now make the Mbed OS code depend on the target, ensuring everything has access to the uC's flags and objects.
|
||||||
target_link_libraries(mbed-core-flags INTERFACE ${MBED_TARGET_CMAKE_NAME}-lib)
|
target_link_libraries(mbed-core-flags INTERFACE ${MBED_TARGET_CMAKE_NAME}-lib)
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,9 @@ function(mbed_create_distro NAME) # ARGN: modules...
|
||||||
|
|
||||||
get_property(CURR_MODULE_TYPE TARGET ${CURR_MODULE} PROPERTY TYPE)
|
get_property(CURR_MODULE_TYPE TARGET ${CURR_MODULE} PROPERTY TYPE)
|
||||||
|
|
||||||
|
# Pass up mbed linker script property, which is used by the top level code to select the linker script
|
||||||
|
copy_append_property(INTERFACE_MBED_LINKER_SCRIPT ${CURR_MODULE} ${NAME})
|
||||||
|
|
||||||
if("${CURR_MODULE_TYPE}" STREQUAL "STATIC_LIBRARY")
|
if("${CURR_MODULE_TYPE}" STREQUAL "STATIC_LIBRARY")
|
||||||
# Don't need to do anything other than linking it
|
# Don't need to do anything other than linking it
|
||||||
target_link_libraries(${NAME} PUBLIC ${CURR_MODULE})
|
target_link_libraries(${NAME} PUBLIC ${CURR_MODULE})
|
||||||
|
|
|
@ -2,53 +2,88 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#
|
#
|
||||||
# Preprocesses and sets the linker script for an Mbed target.
|
# Sets the linker script for an Mbed target.
|
||||||
# Called once for each MCU target in the build system.
|
# Called once by the buildscripts for each MCU target in the build system.
|
||||||
|
# Note: Linker script path may be absolute or relative. If relative, it will be interpreted relative to the current source dir.
|
||||||
#
|
#
|
||||||
function(mbed_set_linker_script input_target raw_linker_script_path)
|
function(mbed_set_linker_script input_target raw_linker_script_path)
|
||||||
|
|
||||||
set(LINKER_SCRIPT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${input_target}.link_script.ld)
|
# Make sure that we have an absolute path so that it can be used from a different directory
|
||||||
|
get_filename_component(raw_linker_script_path ${raw_linker_script_path} ABSOLUTE)
|
||||||
|
|
||||||
|
# Use a custom property to store the linker script. This property will be read and passed up by mbed_create_distro()
|
||||||
|
set_property(TARGET ${input_target} PROPERTY INTERFACE_MBED_LINKER_SCRIPT ${raw_linker_script_path})
|
||||||
|
|
||||||
|
endfunction(mbed_set_linker_script)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Set up the linker script for the top-level Mbed MCU target.
|
||||||
|
# If needed, this also creates another target to preprocess the linker script.
|
||||||
|
#
|
||||||
|
function(mbed_setup_linker_script mbed_mcu_target)
|
||||||
|
|
||||||
|
# Find the path to the desired linker script
|
||||||
|
get_property(RAW_LINKER_SCRIPT_PATHS TARGET ${mbed_mcu_target} PROPERTY INTERFACE_MBED_LINKER_SCRIPT)
|
||||||
|
|
||||||
|
# Check if two (or more) different linker scripts got used
|
||||||
|
list(REMOVE_DUPLICATES RAW_LINKER_SCRIPT_PATHS)
|
||||||
|
list(LENGTH RAW_LINKER_SCRIPT_PATHS NUM_RAW_LINKER_SCRIPT_PATHS)
|
||||||
|
if(NUM_RAW_LINKER_SCRIPT_PATHS GREATER 1)
|
||||||
|
message(FATAL_ERROR "More than one linker script selected for the current MCU target. Perhaps multiple targets with linker scripts set were linked together?")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Make sure the linker script exists
|
||||||
|
if(NOT EXISTS "${RAW_LINKER_SCRIPT_PATHS}")
|
||||||
|
message(FATAL_ERROR "Selected linker script ${RAW_LINKER_SCRIPT_PATHS} does not exist!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(LINKER_SCRIPT_PATH ${CMAKE_BINARY_DIR}/${MBED_TARGET_CMAKE_NAME}.link_script.ld)
|
||||||
|
|
||||||
# To avoid path limits on Windows, we create a "response file" and set the path to it as a
|
# 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,
|
# 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.
|
# so it can expand any macro definitions in the linker script.
|
||||||
get_property(_linker_preprocess_definitions GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE)
|
get_property(linker_defs_response_file GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE)
|
||||||
if(MBED_TOOLCHAIN STREQUAL "GCC_ARM")
|
if(MBED_TOOLCHAIN STREQUAL "GCC_ARM")
|
||||||
|
|
||||||
|
get_filename_component(RAW_LINKER_SCRIPT_NAME ${RAW_LINKER_SCRIPT_PATHS} NAME)
|
||||||
|
get_filename_component(LINKER_SCRIPT_NAME ${LINKER_SCRIPT_PATH} NAME)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT
|
OUTPUT
|
||||||
${LINKER_SCRIPT_PATH}
|
${LINKER_SCRIPT_PATH}
|
||||||
PRE_LINK
|
PRE_LINK
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_C_COMPILER} ${_linker_preprocess_definitions}
|
${CMAKE_C_COMPILER} @${linker_defs_response_file}
|
||||||
-E -x assembler-with-cpp
|
-E -x assembler-with-cpp
|
||||||
-P ${raw_linker_script_path}
|
-P ${RAW_LINKER_SCRIPT_PATHS}
|
||||||
-o ${LINKER_SCRIPT_PATH}
|
-o ${LINKER_SCRIPT_PATH}
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${raw_linker_script_path}
|
${RAW_LINKER_SCRIPT_PATHS}
|
||||||
|
${linker_defs_response_file}
|
||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMENT
|
COMMENT
|
||||||
"Link line:"
|
"Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
# CMake will not let us add PRE_LINK commands to INTERFACE targets, and input_target could
|
|
||||||
# be an INTERFACE target.
|
# The job to create the linker script gets attached to the mbed-linker-script target,
|
||||||
# To get around this we create an intermediate custom target depending on the preprocessed
|
# which is then added as a dependency of the MCU target. This ensures the linker script will exist
|
||||||
# linker script output by CPP. We add this custom target as a dependency of input_target.
|
# by the time we need it.
|
||||||
# This ensures CMake runs our custom command to preprocess the linker script before trying
|
add_custom_target(mbed-linker-script DEPENDS ${LINKER_SCRIPT_PATH} VERBATIM)
|
||||||
# to build input_target.
|
add_dependencies(${mbed_mcu_target} mbed-linker-script)
|
||||||
set(LinkerScriptTarget ${input_target}LinkerScript)
|
|
||||||
add_custom_target(${LinkerScriptTarget} DEPENDS ${LINKER_SCRIPT_PATH} VERBATIM)
|
# Add linker flags to the MCU target to pick up the preprocessed linker script
|
||||||
add_dependencies(${input_target} ${LinkerScriptTarget})
|
target_link_options(${mbed_mcu_target}
|
||||||
target_link_options(${input_target}
|
|
||||||
INTERFACE
|
INTERFACE
|
||||||
"-T" "${LINKER_SCRIPT_PATH}"
|
"-T" "${LINKER_SCRIPT_PATH}"
|
||||||
)
|
)
|
||||||
elseif(MBED_TOOLCHAIN STREQUAL "ARM")
|
elseif(MBED_TOOLCHAIN STREQUAL "ARM")
|
||||||
target_link_options(${input_target}
|
target_link_options(${mbed_mcu_target}
|
||||||
INTERFACE
|
INTERFACE
|
||||||
"--scatter=${raw_linker_script_path}"
|
"--scatter=${raw_linker_script_path}"
|
||||||
"--predefine=${_linker_preprocess_definitions}"
|
"--predefine=${_linker_preprocess_definitions}"
|
||||||
"--map"
|
"--map"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction(mbed_setup_linker_script)
|
||||||
|
|
Loading…
Reference in New Issue