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
|
||||
${LINKER_SCRIPT_PATH}
|
||||
PRE_LINK
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E echo "Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
|
||||
COMMAND
|
||||
${CMAKE_C_COMPILER} @${linker_defs_response_file}
|
||||
-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}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT
|
||||
"Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
||||
# 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
|
||||
# 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})
|
||||
add_dependencies(${TARGET} mbed-linker-script)
|
||||
|
||||
# Add linker flags to the MCU target to pick up the preprocessed linker script
|
||||
target_link_options(${TARGET}
|
||||
# When building the Mbed internal tests, the tests get created before the mbed-os target does. So, the normal logic
|
||||
# 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
|
||||
"-T" "${LINKER_SCRIPT_PATH}"
|
||||
)
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
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
|
||||
#
|
||||
# target: the affected target
|
||||
# 2nd arg: optional, linker script path
|
||||
#
|
||||
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
|
||||
# executable suffix for all toolchains as CMake hardcodes the name of the
|
||||
# diagnostic output file for some toolchains.
|
||||
|
|
Loading…
Reference in New Issue