mirror of https://github.com/ARMmbed/mbed-os.git
add custom linker script (#103)
* add custom linker script a custom linker script can be applied by adding the .ld filepath as 2nd argument to mbed_set_post_build * more detailed comment * add if is_standalone for text cases * replace COMMENT in add_custom_command by echo COMMENT is not reliable printedpull/15381/head
parent
310aac306f
commit
9d9ba58f68
|
@ -56,6 +56,8 @@ function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target target_de
|
||||||
OUTPUT
|
OUTPUT
|
||||||
${LINKER_SCRIPT_PATH}
|
${LINKER_SCRIPT_PATH}
|
||||||
PRE_LINK
|
PRE_LINK
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND} -E echo "Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_C_COMPILER} @${linker_defs_response_file}
|
${CMAKE_C_COMPILER} @${linker_defs_response_file}
|
||||||
-E -x assembler-with-cpp
|
-E -x assembler-with-cpp
|
||||||
|
@ -68,11 +70,10 @@ function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target target_de
|
||||||
${target_defines_header}
|
${target_defines_header}
|
||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMENT
|
|
||||||
"Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
|
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# The job to create the linker script gets attached to the mbed-linker-script target,
|
# The job to create the linker script gets attached to the mbed-linker-script target,
|
||||||
# which is then added as a dependency of the MCU target. This ensures the linker script will exist
|
# which is then added as a dependency of the MCU target. This ensures the linker script will exist
|
||||||
# by the time we need it.
|
# by the time we need it.
|
||||||
|
@ -80,11 +81,69 @@ function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target target_de
|
||||||
foreach(TARGET ${mbed_baremetal_target} ${mbed_os_target})
|
foreach(TARGET ${mbed_baremetal_target} ${mbed_os_target})
|
||||||
add_dependencies(${TARGET} mbed-linker-script)
|
add_dependencies(${TARGET} mbed-linker-script)
|
||||||
|
|
||||||
# Add linker flags to the MCU target to pick up the preprocessed linker script
|
# When building the Mbed internal tests, the tests get created before the mbed-os target does. So, the normal logic
|
||||||
target_link_options(${TARGET}
|
# in mbed_set_post_build() to set the linker script does not work. So, we need to instead attach the linker script to
|
||||||
|
# the mbed-os and mbed-baremetal libraries themselves, so it will get picked up automatically.
|
||||||
|
# This prevents a custom linker script from being used in STANDALONE mode, but we don't need to do that.
|
||||||
|
set_target_properties(${TARGET} PROPERTIES LINKER_SCRIPT_PATH ${LINKER_SCRIPT_PATH})
|
||||||
|
|
||||||
|
# add linker script only for tests
|
||||||
|
if(MBED_IS_STANDALONE)
|
||||||
|
target_link_options(${TARGET}
|
||||||
INTERFACE
|
INTERFACE
|
||||||
"-T" "${LINKER_SCRIPT_PATH}"
|
"-T" "${LINKER_SCRIPT_PATH}"
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
endfunction(mbed_setup_linker_script)
|
endfunction(mbed_setup_linker_script)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Change the linker script to a custom supplied script instead of the built in.
|
||||||
|
# this function is called by mbed_set_post_build(target linker_script)
|
||||||
|
#
|
||||||
|
# target: CMake target for Mbed OS
|
||||||
|
# new_linker_script_path: raw linker script
|
||||||
|
#
|
||||||
|
function(mbed_set_custom_linker_script target new_linker_script_path)
|
||||||
|
|
||||||
|
set(RAW_LINKER_SCRIPT_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/${new_linker_script_path})
|
||||||
|
set(CUSTOM_LINKER_SCRIPT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${target}.link_spript.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_defs_response_file GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE)
|
||||||
|
|
||||||
|
get_filename_component(RAW_LINKER_SCRIPT_NAME ${RAW_LINKER_SCRIPT_PATHS} NAME)
|
||||||
|
get_filename_component(LINKER_SCRIPT_NAME ${CUSTOM_LINKER_SCRIPT_PATH} NAME)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET
|
||||||
|
${target}
|
||||||
|
PRE_LINK
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND} -E echo "Preprocess custom linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_C_COMPILER} @${linker_defs_response_file}
|
||||||
|
-E -x assembler-with-cpp
|
||||||
|
-include ${CMAKE_BINARY_DIR}/mbed-os/mbed-target-config.h
|
||||||
|
-P ${RAW_LINKER_SCRIPT_PATHS}
|
||||||
|
-o ${CUSTOM_LINKER_SCRIPT_PATH}
|
||||||
|
DEPENDS
|
||||||
|
${RAW_LINKER_SCRIPT_PATHS}
|
||||||
|
${linker_defs_response_file}
|
||||||
|
${target_defines_header}
|
||||||
|
WORKING_DIRECTORY
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add linker flags to the target to pick up the preprocessed linker script
|
||||||
|
target_link_options(${target}
|
||||||
|
PRIVATE
|
||||||
|
"-T" "${CUSTOM_LINKER_SCRIPT_PATH}"
|
||||||
|
)
|
||||||
|
|
||||||
|
endfunction(mbed_set_custom_linker_script)
|
||||||
|
|
|
@ -126,7 +126,32 @@ endfunction()
|
||||||
#
|
#
|
||||||
# Set post build operations
|
# Set post build operations
|
||||||
#
|
#
|
||||||
|
# target: the affected target
|
||||||
|
# 2nd arg: optional, linker script path
|
||||||
|
#
|
||||||
function(mbed_set_post_build target)
|
function(mbed_set_post_build target)
|
||||||
|
# add linker script. Skip for greentea test code, there the linker script is set in mbed_setup_linker_script()
|
||||||
|
if (NOT MBED_IS_STANDALONE)
|
||||||
|
if("${ARGN}" STREQUAL "")
|
||||||
|
if(TARGET mbed-os)
|
||||||
|
get_target_property(LINKER_SCRIPT_PATH mbed-os LINKER_SCRIPT_PATH)
|
||||||
|
target_link_options(${target}
|
||||||
|
PRIVATE
|
||||||
|
"-T" "${LINKER_SCRIPT_PATH}"
|
||||||
|
)
|
||||||
|
elseif(TARGET mbed-baremetal)
|
||||||
|
get_target_property(LINKER_SCRIPT_PATH mbed-baremetal LINKER_SCRIPT_PATH)
|
||||||
|
target_link_options(${target}
|
||||||
|
PRIVATE
|
||||||
|
"-T" "${LINKER_SCRIPT_PATH}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS "${target} uses custom linker script ${ARGV2}")
|
||||||
|
mbed_set_custom_linker_script(${target} ${ARGV2})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# The mapfile name includes the top-level target name and the
|
# The mapfile name includes the top-level target name and the
|
||||||
# executable suffix for all toolchains as CMake hardcodes the name of the
|
# executable suffix for all toolchains as CMake hardcodes the name of the
|
||||||
# diagnostic output file for some toolchains.
|
# diagnostic output file for some toolchains.
|
||||||
|
|
Loading…
Reference in New Issue