# SPDX-License-Identifier: Apache-2.0 set_property(TARGET linker PROPERTY devices_start_symbol "__device_start") find_program(CMAKE_LINKER ${CROSS_COMPILE}lldac PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) # the prefix to transfer linker options from compiler set_ifndef(LINKERFLAGPREFIX -Wl,) # Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} # NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time macro(configure_linker_script linker_script_gen linker_pass_define) set(extra_dependencies ${ARGN}) set(template_script_defines ${linker_pass_define}) list(TRANSFORM template_script_defines PREPEND "-D") # Different generators deal with depfiles differently. if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") # Note that the IMPLICIT_DEPENDS option is currently supported only # for Makefile generators and will be ignored by other generators. set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT}) elseif(CMAKE_GENERATOR STREQUAL "Ninja") # Using DEPFILE with other generators than Ninja is an error. set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep) else() # TODO: How would the linker script dependencies work for non-linker # script generators. message(STATUS "Warning; this generator is not well supported. The Linker script may not be regenerated when it should.") set(linker_script_dep "") endif() zephyr_get_include_directories_for_lang(C current_includes) get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) # the command to generate linker file from template add_custom_command( OUTPUT ${linker_script_gen} DEPENDS ${LINKER_SCRIPT} ${AUTOCONF_H} ${extra_dependencies} # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' ${linker_script_dep} COMMAND ${CMAKE_C_COMPILER} -x c ${NOSYSDEF_CFLAG} -Hnocopyr -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} -D_LINKER -D_ASMLANGUAGE -imacros ${AUTOCONF_H} ${current_includes} ${current_defines} ${template_script_defines} ${LINKER_SCRIPT} -E -o ${linker_script_gen} VERBATIM WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMAND_EXPAND_LISTS ) 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(${LINKERFLAGPREFIX}-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} ${LINKERFLAGPREFIX}-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} ${LINKERFLAGPREFIX}--gc-sections ${LINKERFLAGPREFIX}--entry=__start ${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) # linker options of temporary linkage for code generation macro(toolchain_ld_baremetal) zephyr_ld_options( -Hlld -Hnosdata -Xtimer0 # to suppress the warning message -Hnoxcheck_obj -Hnocplus -Hhostlib= -Hheap=0 -Hnoivt -Hnocrt ) # There are two options: # - We have full MWDT libc support and we link MWDT libc - this is default # behavior and we don't need to do something for that. # - We use minimal libc provided by Zephyr itself. In that case we must not # link MWDT libc, but we still need to link libmw if(CONFIG_MINIMAL_LIBC) zephyr_ld_options( -Hnolib -Hldopt=-lmw ) endif() # Funny thing is if this is set to =error, some architectures will # skip this flag even though the compiler flag check passes # (e.g. ARC and Xtensa). So warning should be the default for now. # # Skip this for native application as Zephyr only provides # additions to the host toolchain linker script. The relocation # sections (.rel*) requires us to override those provided # by host toolchain. As we can't account for all possible # combination of compiler and linker on all machines used # for development, it is better to turn this off. # # CONFIG_LINKER_ORPHAN_SECTION_PLACE is to place the orphan sections # without any warnings or errors, which is the default behavior. # So there is no need to explicitly set a linker flag. if(CONFIG_LINKER_ORPHAN_SECTION_WARN) message(WARNING "MWDT toolchain does not support CONFIG_LINKER_ORPHAN_SECTION_WARN") elseif(CONFIG_LINKER_ORPHAN_SECTION_ERROR) zephyr_ld_options( ${LINKERFLAGPREFIX}--orphan-handling=error) endif() endmacro() # base linker options macro(toolchain_ld_base) if(NOT PROPERTY_LINKER_SCRIPT_DEFINES) set_property(GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES -D__MWDT_LINKER_CMD__) endif() # Sort the common symbols and each input section by alignment # in descending order to minimize padding between these symbols. zephyr_ld_option_ifdef( CONFIG_LINKER_SORT_BY_ALIGNMENT ${LINKERFLAGPREFIX}--sort-section=alignment ) endmacro() # generate linker script snippets from configure files macro(toolchain_ld_configure_files) configure_file( $ENV{ZEPHYR_BASE}/include/zephyr/arch/common/app_data_alignment.ld ${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld) configure_file( $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem.ld ${PROJECT_BINARY_DIR}/include/generated/app_smem.ld) configure_file( $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_aligned.ld ${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld) configure_file( $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_unaligned.ld ${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld) endmacro() # link C++ libraries macro(toolchain_ld_cpp) zephyr_link_libraries( -Hcplus ) endmacro() # use linker for relocation macro(toolchain_ld_relocation) set(MEM_RELOCATION_LD "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld") set(MEM_RELOCATION_SRAM_DATA_LD "${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld") set(MEM_RELOCATION_SRAM_BSS_LD "${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld") set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c") add_custom_command( OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/gen_relocate_app.py $<$:--verbose> -d ${APPLICATION_BINARY_DIR} -i \"$\" -o ${MEM_RELOCATION_LD} -s ${MEM_RELOCATION_SRAM_DATA_LD} -b ${MEM_RELOCATION_SRAM_BSS_LD} -c ${MEM_RELOCATION_CODE} DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY} ) add_library(code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE}) target_include_directories(code_relocation_source_lib PRIVATE ${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include) target_link_libraries(code_relocation_source_lib zephyr_interface) endmacro()