@@ -56,6 +56,8 @@ function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target target_de
56
56
OUTPUT
57
57
${LINKER_SCRIPT_PATH}
58
58
PRE_LINK
59
+ COMMAND
60
+ ${CMAKE_COMMAND} -E echo "Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME} "
59
61
COMMAND
60
62
${CMAKE_C_COMPILER} @${linker_defs_response_file}
61
63
-E -x assembler-with-cpp
@@ -68,23 +70,80 @@ function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target target_de
68
70
${target_defines_header}
69
71
WORKING_DIRECTORY
70
72
${CMAKE_CURRENT_SOURCE_DIR}
71
- COMMENT
72
- "Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME} "
73
73
VERBATIM
74
74
)
75
75
76
+
76
77
# The job to create the linker script gets attached to the mbed-linker-script target,
77
78
# which is then added as a dependency of the MCU target. This ensures the linker script will exist
78
79
# by the time we need it.
79
80
add_custom_target (mbed-linker-script DEPENDS ${LINKER_SCRIPT_PATH} VERBATIM )
80
81
foreach (TARGET ${mbed_baremetal_target} ${mbed_os_target} )
81
82
add_dependencies (${TARGET} mbed-linker-script )
82
83
83
- # Add linker flags to the MCU target to pick up the preprocessed linker script
84
- target_link_options (${TARGET}
84
+ # When building the Mbed internal tests, the tests get created before the mbed-os target does. So, the normal logic
85
+ # in mbed_set_post_build() to set the linker script does not work. So, we need to instead attach the linker script to
86
+ # the mbed-os and mbed-baremetal libraries themselves, so it will get picked up automatically.
87
+ # This prevents a custom linker script from being used in STANDALONE mode, but we don't need to do that.
88
+ set_target_properties (${TARGET} PROPERTIES LINKER_SCRIPT_PATH ${LINKER_SCRIPT_PATH} )
89
+
90
+ # add linker script only for tests
91
+ if (MBED_IS_STANDALONE )
92
+ target_link_options (${TARGET}
85
93
INTERFACE
86
94
"-T" "${LINKER_SCRIPT_PATH} "
87
- )
95
+ )
96
+ endif ()
88
97
endforeach ()
89
98
90
99
endfunction (mbed_setup_linker_script )
100
+
101
+
102
+ #
103
+ # Change the linker script to a custom supplied script instead of the built in.
104
+ # this function is called by mbed_set_post_build(target linker_script)
105
+ #
106
+ # target: CMake target for Mbed OS
107
+ # new_linker_script_path: raw linker script
108
+ #
109
+ function (mbed_set_custom_linker_script target new_linker_script_path )
110
+
111
+ set (RAW_LINKER_SCRIPT_PATHS ${CMAKE_CURRENT_SOURCE_DIR} /${new_linker_script_path} )
112
+ set (CUSTOM_LINKER_SCRIPT_PATH ${CMAKE_CURRENT_BINARY_DIR} /${target}.link_spript.ld )
113
+
114
+ # To avoid path limits on Windows, we create a "response file" and set the path to it as a
115
+ # global property. We need this solely to pass the compile definitions to GCC's preprocessor,
116
+ # so it can expand any macro definitions in the linker script.
117
+ get_property (linker_defs_response_file GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE )
118
+
119
+ get_filename_component (RAW_LINKER_SCRIPT_NAME ${RAW_LINKER_SCRIPT_PATHS} NAME )
120
+ get_filename_component (LINKER_SCRIPT_NAME ${CUSTOM_LINKER_SCRIPT_PATH} NAME )
121
+
122
+ add_custom_command (
123
+ TARGET
124
+ ${target}
125
+ PRE_LINK
126
+ COMMAND
127
+ ${CMAKE_COMMAND} -E echo "Preprocess custom linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME} "
128
+ COMMAND
129
+ ${CMAKE_C_COMPILER} @${linker_defs_response_file}
130
+ -E -x assembler-with-cpp
131
+ -include ${CMAKE_BINARY_DIR} /mbed-os/mbed-target-config.h
132
+ -P ${RAW_LINKER_SCRIPT_PATHS}
133
+ -o ${CUSTOM_LINKER_SCRIPT_PATH}
134
+ DEPENDS
135
+ ${RAW_LINKER_SCRIPT_PATHS}
136
+ ${linker_defs_response_file}
137
+ ${target_defines_header}
138
+ WORKING_DIRECTORY
139
+ ${CMAKE_CURRENT_SOURCE_DIR}
140
+ VERBATIM
141
+ )
142
+
143
+ # Add linker flags to the target to pick up the preprocessed linker script
144
+ target_link_options (${target}
145
+ PRIVATE
146
+ "-T" "${CUSTOM_LINKER_SCRIPT_PATH} "
147
+ )
148
+
149
+ endfunction (mbed_set_custom_linker_script )
0 commit comments