Build: Refactor code-sharing primitives
Makes the interface more aligned with modern cmake, and generally
streamlines the experience.
Change-Id: Iad289c7e6be1af1e7ae80d3792698a31b2d9368e
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/toolchain_GNUARM.cmake b/toolchain_GNUARM.cmake
index 83eab4b..4efd4d0 100644
--- a/toolchain_GNUARM.cmake
+++ b/toolchain_GNUARM.cmake
@@ -256,95 +256,85 @@
)
endmacro()
-# Macro for sharing code among independent binaries. This function extracts
-# some parts of the code based on a symbol template file and creates a text
-# file, which contains the symbols with their absolute addresses, which can be
-# picked up by the linker when linking the other target.
-# INPUTS:
-# TARGET - - Target to extract the symbols/objects from
-# SHARED_SYMBOL_TEMPLATE - Template with names of symbols to share
-macro(compiler_create_shared_code TARGET SHARED_SYMBOL_TEMPLATE)
- # Create a temporary file, which contains all extracted symbols from 'TARGET'
- set(ALL_SYMBOLS ${CMAKE_CURRENT_BINARY_DIR}/all_symbols.txt)
-
- # Find the CMake script doing the symbol filtering.
- find_file(FILTER_SYMBOLS_SCRIPT "FilterSharedSymbols.cmake" PATHS ${CMAKE_MODULE_PATH} PATH_SUFFIXES Common NO_DEFAULT_PATH)
- find_file(STRIP_UNSHARED_CODE "StripUnsharedCode.cmake" PATHS ${CMAKE_MODULE_PATH} PATH_SUFFIXES Common NO_DEFAULT_PATH)
-
- find_program(GNUARM_NM arm-none-eabi-nm)
- if (GNUARM_NM STREQUAL "GNUARM_NM-NOTFOUND")
- message(FATAL_ERROR "toolchain_GNUARM.cmake: mandatory tool '${GNUARM_NM}' is missing.")
+macro(target_share_symbols target symbol_name_file)
+ get_target_property(TARGET_TYPE ${target} TYPE)
+ if (NOT TARGET_TYPE STREQUAL "EXECUTABLE")
+ message(FATAL_ERROR "${target} is not an executable. Symbols cannot be shared from libraries.")
endif()
- # Multiple steps are required:
- # - Extract all symbols from sharing target
- # - Filter the unwanted symbols from all_symbols.txt
- # - Create a stripped shared_code.axf file which contains only the symbols which are meant to be shared
- add_custom_command(TARGET ${TARGET}
- POST_BUILD
+ FILE(STRINGS ${symbol_name_file} KEEP_SYMBOL_LIST
+ LENGTH_MINIMUM 1
+ )
- COMMAND ${GNUARM_NM}
- ARGS
- ${CMAKE_BINARY_DIR}/bin/${TARGET}.axf > ${ALL_SYMBOLS}
- COMMENT "Dumping all symbols"
- COMMAND ${CMAKE_COMMAND}
- -DSHARED_SYMBOL_TEMPLATE=${SHARED_SYMBOL_TEMPLATE}
- -DALL_SYMBOLS=${ALL_SYMBOLS}
- -P ${FILTER_SYMBOLS_SCRIPT}
- BYPRODUCTS
- ${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_name.txt
- ${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_addr.txt
- COMMENT "Filtering shared symbols"
-
- COMMAND ${CMAKE_COMMAND}
- -E copy ${CMAKE_BINARY_DIR}/bin/${TARGET}.axf ${CMAKE_CURRENT_BINARY_DIR}/shared_code.axf
- COMMENT "Copy and rename ${TARGET} to strip"
-
- COMMAND ${CMAKE_COMMAND}
- -DSHARED_SYMBOLS_FILE=${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_name.txt
- -DEXECUTABLE_TO_STRIP=${CMAKE_CURRENT_BINARY_DIR}/shared_code.axf
- -P ${STRIP_UNSHARED_CODE}
- COMMENT "Stripping unshared code from ${CMAKE_CURRENT_BINARY_DIR}/shared_code.axf"
+ list(TRANSFORM KEEP_SYMBOL_LIST PREPEND --keep-symbol=)
+ # strip all the symbols except those proveded as arguments
+ add_custom_command(
+ TARGET ${target}
+ POST_BUILD
+ COMMAND ${CROSS_COMPILE}-objcopy
+ ARGS $<TARGET_FILE:${target}> --wildcard ${KEEP_SYMBOL_LIST} --strip-all $<TARGET_FILE_DIR:${target}>/${target}_shared_symbols.axf
)
endmacro()
-macro(compiler_weaken_symbols TARGET SHARED_CODE_PATH ORIG_TARGET LIB_LIST)
- # Find the CMake scripts
- find_file(WEAKEN_SYMBOLS_SCRIPT "WeakenSymbols.cmake" PATHS ${CMAKE_MODULE_PATH} PATH_SUFFIXES Common NO_DEFAULT_PATH)
+macro(target_link_shared_code target)
+ foreach(symbol_provider ${ARGN})
+ if (TARGET ${symbol_provider})
+ get_target_property(SYMBOL_PROVIDER_TYPE ${symbol_provider} TYPE)
+ if (NOT SYMBOL_PROVIDER_TYPE STREQUAL "EXECUTABLE")
+ message(FATAL_ERROR "${symbol_provider} is not an executable. Symbols cannot be shared from libraries.")
+ endif()
+ endif()
- add_custom_command(TARGET ${TARGET}
- PRE_LINK
-
- COMMAND ${CMAKE_COMMAND}
- -DLIB_LIST='${LIB_LIST}'
- -DSHARED_CODE_PATH=${SHARED_CODE_PATH}
- -P ${WEAKEN_SYMBOLS_SCRIPT}
- COMMENT "Set conflicting symbols to be weak in the original libraries to avoid collision")
-
- # If sharing target is defined by TF-M build then setup dependency
- if(NOT ${ORIG_TARGET} STREQUAL "EXTERNAL_TARGET")
- add_dependencies(${TARGET} ${ORIG_TARGET})
- endif()
+ add_dependencies(${target} ${symbol_provider})
+ target_link_options(${target} PRIVATE LINKER:-R$<TARGET_FILE_DIR:${symbol_provider}>/${symbol_provider}_shared_symbols.axf)
+ endforeach()
endmacro()
-# Macro for linking shared code to given target. Location of shared code could
-# be outside of the TF-M project. Its location can be defined with the CMake
-# command line argument "SHARED_CODE_PATH". The file containing the shared objects
-# must be named "shared_symbols_addr.txt".
-# INPUTS:
-# TARGET Target to link the shared code to
-# SHARED_CODE_PATH Shared code located in this folder
-# ORIG_TARGET Target that shared code was extraced from <TARGET | "EXTERNAL_TARGET">
-# LIB_LIST List of libraries which are linked to top level target
-macro(compiler_link_shared_code TARGET SHARED_CODE_PATH ORIG_TARGET LIB_LIST)
- # GNUARM requires to link a stripped version (only containing the shared symbols) of the
- # original executable to the executable which want to rely on the shared symbols.
- target_link_options(${TARGET} PRIVATE -Wl,-R${SHARED_CODE_PATH}/shared_code.axf)
+macro(target_strip_symbols target)
+ set(SYMBOL_LIST "${ARGN}")
+ list(TRANSFORM SYMBOL_LIST PREPEND --strip-symbol=)
- compiler_weaken_symbols(${TARGET}
- ${SHARED_CODE_PATH}
- ${ORIG_TARGET}
- "${LIB_LIST}"
+ add_custom_command(
+ TARGET ${target}
+ POST_BUILD
+ COMMAND ${CROSS_COMPILE}-objcopy
+ ARGS $<TARGET_FILE:${target}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${target}>
+ )
+endmacro()
+
+macro(target_strip_symbols_from_dependency target dependency)
+ set(SYMBOL_LIST "${ARGN}")
+ list(TRANSFORM SYMBOL_LIST PREPEND --strip-symbol=)
+
+ add_custom_command(
+ TARGET ${target}
+ PRE_LINK
+ COMMAND ${CROSS_COMPILE}-objcopy
+ ARGS $<TARGET_FILE:${dependency}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${dependency}>
+ )
+endmacro()
+
+macro(target_weaken_symbols target)
+ set(SYMBOL_LIST "${ARGN}")
+ list(TRANSFORM SYMBOL_LIST PREPEND --weaken-symbol=)
+
+ add_custom_command(
+ TARGET ${target}
+ POST_BUILD
+ COMMAND ${CROSS_COMPILE}-objcopy
+ ARGS $<TARGET_FILE:${target}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${target}>
+ )
+endmacro()
+
+macro(target_weaken_symbols_from_dependency target dependency)
+ set(SYMBOL_LIST "${ARGN}")
+ list(TRANSFORM SYMBOL_LIST PREPEND --weaken-symbol=)
+
+ add_custom_command(
+ TARGET ${target}
+ PRE_LINK
+ COMMAND ${CROSS_COMPILE}-objcopy
+ ARGS $<TARGET_FILE:${dependency}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${dependency}>
)
endmacro()