From 4052bac93fcaf010d57e2d2c4ce3578d9269a7b1 Mon Sep 17 00:00:00 2001 From: Mark Ruvald Pedersen Date: Tue, 7 May 2019 16:32:36 +0200 Subject: [PATCH] cmake: Introduce toolchain_ld_link_elf to abstract linker invocation Final step of linker abstraction: * Abstract zephyr_lnk by including it in toolchain_ld_link_elf. * Abstract relevant uses of target_link_libraries. * Introduce toolchain_ld_force_undefined_symbols. No functional change expected. This is motivated by the wish to abstract Zephyr's usage of toolchains, permitting non-intrusive porting to other (commercial) toolchains. Signed-off-by: Mark Ruvald Pedersen --- CMakeLists.txt | 55 ++++++++++++++++++++++++------------ cmake/linker/ld/target.cmake | 47 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 069f4511c40..2586821ca6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,11 @@ zephyr_compile_options( # @Intent: Set fundamental linker specific flags toolchain_ld_base() +toolchain_ld_force_undefined_symbols( + _OffsetAbsSyms + _ConfigAbsSyms +) + if(NOT CONFIG_NATIVE_APPLICATION) # @Intent: Set linker specific flags for bare metal target toolchain_ld_baremetal() @@ -668,20 +673,6 @@ set_property(TARGET ${ZEPHYR_INCLUDE_DIRS} ) -set(zephyr_lnk - ${LINKERFLAGPREFIX},-Map=${PROJECT_BINARY_DIR}/${KERNEL_MAP_NAME} - -u_OffsetAbsSyms - -u_ConfigAbsSyms - ${LINKERFLAGPREFIX},--whole-archive - ${ZEPHYR_LIBS_PROPERTY} - ${LINKERFLAGPREFIX},--no-whole-archive - kernel - $ - ${LIB_INCLUDE_DIR} - -L${PROJECT_BINARY_DIR} - ${TOOLCHAIN_LIBS} - ) - if(CONFIG_GEN_ISR_TABLES) if(CONFIG_GEN_SW_ISR_TABLE) list(APPEND GEN_ISR_TABLE_EXTRA_ARG --sw-isr-table) @@ -1062,7 +1053,14 @@ if(CONFIG_USERSPACE) set(APP_SMEM_UNALIGNED_LIB app_smem_unaligned_output_obj_renamed_lib) add_executable( app_smem_unaligned_prebuilt misc/empty_file.c) - target_link_libraries(app_smem_unaligned_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker_app_smem_unaligned.cmd ${zephyr_lnk} ${CODE_RELOCATION_DEP}) + toolchain_ld_link_elf( + TARGET_ELF app_smem_unaligned_prebuilt + OUTPUT_MAP ${PROJECT_BINARY_DIR}/${KERNEL_MAP_NAME} + LIBRARIES_PRE_SCRIPT "" + LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker_app_smem_unaligned.cmd + LIBRARIES_POST_SCRIPT "" + DEPENDENCIES ${CODE_RELOCATION_DEP} + ) set_property(TARGET app_smem_unaligned_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_app_smem_unaligned.cmd) add_dependencies( app_smem_unaligned_prebuilt linker_app_smem_unaligned_script ${OFFSETS_LIB}) @@ -1107,14 +1105,28 @@ if(CONFIG_USERSPACE AND CONFIG_ARM) set(PRIV_STACK_LIB priv_stacks_output_obj_renamed_lib) add_executable( priv_stacks_prebuilt misc/empty_file.c) - target_link_libraries(priv_stacks_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd ${zephyr_lnk} ${CODE_RELOCATION_DEP}) + toolchain_ld_link_elf( + TARGET_ELF priv_stacks_prebuilt + OUTPUT_MAP ${PROJECT_BINARY_DIR}/${KERNEL_MAP_NAME} + LIBRARIES_PRE_SCRIPT "" + LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd + LIBRARIES_POST_SCRIPT "" + DEPENDENCIES ${CODE_RELOCATION_DEP} + ) set_property(TARGET priv_stacks_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd) add_dependencies( priv_stacks_prebuilt linker_priv_stacks_script ${OFFSETS_LIB}) endif() # FIXME: Is there any way to get rid of empty_file.c? add_executable( ${ZEPHYR_PREBUILT_EXECUTABLE} misc/empty_file.c) -target_link_libraries(${ZEPHYR_PREBUILT_EXECUTABLE} ${TOPT} ${PROJECT_BINARY_DIR}/linker.cmd ${PRIV_STACK_LIB} ${zephyr_lnk} ${CODE_RELOCATION_DEP}) +toolchain_ld_link_elf( + TARGET_ELF ${ZEPHYR_PREBUILT_EXECUTABLE} + OUTPUT_MAP ${PROJECT_BINARY_DIR}/${KERNEL_MAP_NAME} + LIBRARIES_PRE_SCRIPT "" + LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker.cmd + LIBRARIES_POST_SCRIPT ${PRIV_STACK_LIB} + DEPENDENCIES ${CODE_RELOCATION_DEP} +) set_property(TARGET ${ZEPHYR_PREBUILT_EXECUTABLE} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker.cmd) add_dependencies( ${ZEPHYR_PREBUILT_EXECUTABLE} ${PRIV_STACK_DEP} ${LINKER_SCRIPT_TARGET} ${OFFSETS_LIB}) @@ -1150,7 +1162,14 @@ else() ) add_executable( ${ZEPHYR_FINAL_EXECUTABLE} misc/empty_file.c ${GKSF}) - target_link_libraries(${ZEPHYR_FINAL_EXECUTABLE} ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass_final.cmd ${zephyr_lnk} ${CODE_RELOCATION_DEP}) + toolchain_ld_link_elf( + TARGET_ELF ${ZEPHYR_FINAL_EXECUTABLE} + OUTPUT_MAP ${PROJECT_BINARY_DIR}/${KERNEL_MAP_NAME} + LIBRARIES_PRE_SCRIPT ${GKOF} + LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker_pass_final.cmd + LIBRARIES_POST_SCRIPT "" + DEPENDENCIES ${CODE_RELOCATION_DEP} + ) set_property(TARGET ${ZEPHYR_FINAL_EXECUTABLE} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_pass_final.cmd) add_dependencies( ${ZEPHYR_FINAL_EXECUTABLE} ${PRIV_STACK_DEP} ${LINKER_PASS_FINAL_SCRIPT_TARGET}) diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index 0c82474167f..d3f63e474af 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -52,6 +52,53 @@ macro(configure_linker_script linker_script_gen linker_pass_define) ) endmacro() +# Force symbols to be entered in the output file as undefined symbols +function(toolchain_ld_force_undefined_symbols) + foreach(symbol ${ARGN}) + zephyr_link_libraries(-u${symbol}) + endforeach() +endfunction() + +# Link a target to given libraries with toolchain-specific argument order +# +# Usage: +# toolchain_ld_link_elf( +# TARGET_ELF +# OUTPUT_MAP +# LIBRARIES_PRE_SCRIPT [libraries_pre_script] +# LINKER_SCRIPT +# LIBRARIES_POST_SCRIPT [libraries_post_script] +# DEPENDENCIES [dependencies] +# ) +function(toolchain_ld_link_elf) + cmake_parse_arguments( + TOOLCHAIN_LD_LINK_ELF # prefix of output variables + "" # list of names of the boolean arguments + "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments + "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments + ${ARGN} # input args to parse + ) + + target_link_libraries( + ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} + ${TOPT} + ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} + + ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} + ${LINKERFLAGPREFIX},--whole-archive + ${ZEPHYR_LIBS_PROPERTY} + ${LINKERFLAGPREFIX},--no-whole-archive + kernel + $ + ${LIB_INCLUDE_DIR} + -L${PROJECT_BINARY_DIR} + ${TOOLCHAIN_LIBS} + + ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} + ) +endfunction(toolchain_ld_link_elf) # Load toolchain_ld-family macros include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake)