armclang: support for armclang compiler and armlink linker
This is the initial support for the armclang compiler together with the armlink linker. Introduced in this commit: - armclang compiler support - armlink linker support - armlink scatter file generator for scatter loading - dual pass linker script generation Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
parent
4de0d5511c
commit
40a2ffd2ea
7 changed files with 525 additions and 0 deletions
6
cmake/compiler/armclang/compiler_flags.cmake
Normal file
6
cmake/compiler/armclang/compiler_flags.cmake
Normal file
|
@ -0,0 +1,6 @@
|
|||
# First step is to inherit all properties from gcc, as clang is compatible with most flags.
|
||||
include(${ZEPHYR_BASE}/cmake/compiler/clang/compiler_flags.cmake)
|
||||
|
||||
# Required ASM flags when using armclang, this should be handled by CMake, but
|
||||
# fails because of: https://gitlab.kitware.com/cmake/cmake/-/issues/19963
|
||||
set_property(TARGET asm APPEND PROPERTY required "--target=${triple}")
|
38
cmake/compiler/armclang/generic.cmake
Normal file
38
cmake/compiler/armclang/generic.cmake
Normal file
|
@ -0,0 +1,38 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Configures CMake for using ccac
|
||||
|
||||
find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME}/bin NO_DEFAULT_PATH)
|
||||
|
||||
set(triple arm-arm-none-eabi)
|
||||
|
||||
set(CMAKE_DTS_PREPROCESSOR
|
||||
${CMAKE_C_COMPILER}
|
||||
"--target=${triple}"
|
||||
# -march=armv6-m is added to silence the warnings:
|
||||
# 'armv4t' and 'arm7tdmi' is unsupported.
|
||||
# We only do preprocessing so the actual arch is not important.
|
||||
"-march=armv6-m"
|
||||
)
|
||||
|
||||
set(CMAKE_C_COMPILER_TARGET ${triple})
|
||||
set(CMAKE_ASM_COMPILER_TARGET ${triple})
|
||||
set(CMAKE_CXX_COMPILER_TARGET ${triple})
|
||||
|
||||
if(CMAKE_C_COMPILER STREQUAL CMAKE_C_COMPILER-NOTFOUND)
|
||||
message(FATAL_ERROR "Zephyr was unable to find the armclang compiler")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} --version
|
||||
RESULT_VARIABLE ret
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
if(ret)
|
||||
message(FATAL_ERROR "Executing the below command failed. "
|
||||
"Are permissions set correctly? '${CMAKE_C_COMPILER} --version' "
|
||||
"And is the license setup correctly ?"
|
||||
)
|
||||
endif()
|
79
cmake/compiler/armclang/target.cmake
Normal file
79
cmake/compiler/armclang/target.cmake
Normal file
|
@ -0,0 +1,79 @@
|
|||
# find the compilers for C, CPP, assembly
|
||||
find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
||||
find_program(CMAKE_CXX_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
||||
find_program(CMAKE_ASM_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
||||
|
||||
# The CMAKE_REQUIRED_FLAGS variable is used by check_c_compiler_flag()
|
||||
# (and other commands which end up calling check_c_source_compiles())
|
||||
# to add additional compiler flags used during checking. These flags
|
||||
# are unused during "real" builds of Zephyr source files linked into
|
||||
# the final executable.
|
||||
#
|
||||
include(${ZEPHYR_BASE}/cmake/gcc-m-cpu.cmake)
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${GCC_M_CPU})
|
||||
|
||||
list(APPEND TOOLCHAIN_C_FLAGS
|
||||
-fshort-enums
|
||||
)
|
||||
|
||||
if(CONFIG_ARM64)
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_M_CPU})
|
||||
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mabi=lp64)
|
||||
list(APPEND TOOLCHAIN_LD_FLAGS -mabi=lp64)
|
||||
else()
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_M_CPU})
|
||||
|
||||
if(CONFIG_COMPILER_ISA_THUMB2)
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mthumb)
|
||||
endif()
|
||||
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mabi=aapcs)
|
||||
|
||||
# Defines a mapping from GCC_M_CPU to FPU
|
||||
|
||||
if(CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION)
|
||||
set(PRECISION_TOKEN)
|
||||
else()
|
||||
set(PRECISION_TOKEN sp-)
|
||||
endif()
|
||||
|
||||
set(FPU_FOR_cortex-m4 fpv4-${PRECISION_TOKEN}d16)
|
||||
set(FPU_FOR_cortex-m7 fpv5-${PRECISION_TOKEN}d16)
|
||||
set(FPU_FOR_cortex-m33 fpv5-${PRECISION_TOKEN}d16)
|
||||
|
||||
if(CONFIG_FPU)
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mfpu=${FPU_FOR_${GCC_M_CPU}})
|
||||
if (CONFIG_FP_SOFTABI)
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mfloat-abi=softfp)
|
||||
elseif(CONFIG_FP_HARDABI)
|
||||
list(APPEND TOOLCHAIN_C_FLAGS -mfloat-abi=hard)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(file_name include/stddef.h)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} --print-file-name=${file_name}
|
||||
OUTPUT_VARIABLE _OUTPUT
|
||||
)
|
||||
get_filename_component(_OUTPUT "${_OUTPUT}" DIRECTORY)
|
||||
string(REGEX REPLACE "\n" "" _OUTPUT ${_OUTPUT})
|
||||
|
||||
list(APPEND NOSTDINC ${_OUTPUT})
|
||||
endforeach()
|
||||
|
||||
foreach(isystem_include_dir ${NOSTDINC})
|
||||
list(APPEND isystem_include_flags -isystem ${isystem_include_dir})
|
||||
endforeach()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags})
|
||||
string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
|
||||
# Load toolchain_cc-family macros
|
||||
|
||||
macro(toolchain_cc_nostdinc)
|
||||
if(NOT "${ARCH}" STREQUAL "posix")
|
||||
zephyr_compile_options( -nostdinc)
|
||||
endif()
|
||||
endmacro()
|
270
cmake/linker/armlink/scatter_script.cmake
Normal file
270
cmake/linker/armlink/scatter_script.cmake
Normal file
|
@ -0,0 +1,270 @@
|
|||
cmake_minimum_required(VERSION 3.17)
|
||||
|
||||
set(SORT_TYPE_NAME Lexical)
|
||||
|
||||
#
|
||||
# String functions - start
|
||||
#
|
||||
|
||||
function(system_to_string)
|
||||
cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN})
|
||||
|
||||
get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME)
|
||||
get_property(regions GLOBAL PROPERTY ${STRING_OBJECT}_REGIONS)
|
||||
get_property(format GLOBAL PROPERTY ${STRING_OBJECT}_FORMAT)
|
||||
|
||||
foreach(region ${regions})
|
||||
get_property(empty GLOBAL PROPERTY ${region}_EMPTY)
|
||||
if(NOT empty)
|
||||
to_string(OBJECT ${region} STRING ${STRING_STRING})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(group_to_string)
|
||||
cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN})
|
||||
|
||||
get_property(type GLOBAL PROPERTY ${STRING_OBJECT}_OBJ_TYPE)
|
||||
if(${type} STREQUAL REGION)
|
||||
get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME)
|
||||
get_property(address GLOBAL PROPERTY ${STRING_OBJECT}_ADDRESS)
|
||||
get_property(size GLOBAL PROPERTY ${STRING_OBJECT}_SIZE)
|
||||
set(${STRING_STRING} "${${STRING_STRING}}\n${name} ${address} NOCOMPRESS ${size}\n{\n")
|
||||
endif()
|
||||
|
||||
get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_SECTIONS_FIXED)
|
||||
foreach(section ${sections})
|
||||
to_string(OBJECT ${section} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
|
||||
get_property(groups GLOBAL PROPERTY ${STRING_OBJECT}_GROUPS)
|
||||
foreach(group ${groups})
|
||||
to_string(OBJECT ${group} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
|
||||
get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_SECTIONS)
|
||||
foreach(section ${sections})
|
||||
to_string(OBJECT ${section} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
|
||||
get_parent(OBJECT ${STRING_OBJECT} PARENT parent TYPE SYSTEM)
|
||||
get_property(regions GLOBAL PROPERTY ${parent}_REGIONS)
|
||||
list(REMOVE_ITEM regions ${STRING_OBJECT})
|
||||
foreach(region ${regions})
|
||||
get_property(vma GLOBAL PROPERTY ${region}_NAME)
|
||||
get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_SECTIONS_FIXED)
|
||||
foreach(section ${sections})
|
||||
to_string(OBJECT ${section} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
|
||||
get_property(groups GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_GROUPS)
|
||||
foreach(group ${groups})
|
||||
to_string(OBJECT ${group} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
|
||||
get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_SECTIONS)
|
||||
foreach(section ${sections})
|
||||
to_string(OBJECT ${section} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
get_property(symbols GLOBAL PROPERTY ${STRING_OBJECT}_SYMBOLS)
|
||||
foreach(symbol ${symbols})
|
||||
to_string(OBJECT ${symbol} STRING ${STRING_STRING})
|
||||
endforeach()
|
||||
|
||||
if(${type} STREQUAL REGION)
|
||||
set(${STRING_STRING} "${${STRING_STRING}}\n}\n")
|
||||
endif()
|
||||
set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(section_to_string)
|
||||
cmake_parse_arguments(STRING "" "SECTION;STRING" "" ${ARGN})
|
||||
|
||||
get_property(name GLOBAL PROPERTY ${STRING_SECTION}_NAME)
|
||||
get_property(address GLOBAL PROPERTY ${STRING_SECTION}_ADDRESS)
|
||||
get_property(type GLOBAL PROPERTY ${STRING_SECTION}_TYPE)
|
||||
get_property(align GLOBAL PROPERTY ${STRING_SECTION}_ALIGN)
|
||||
get_property(subalign GLOBAL PROPERTY ${STRING_SECTION}_SUBALIGN)
|
||||
get_property(endalign GLOBAL PROPERTY ${STRING_SECTION}_ENDALIGN)
|
||||
get_property(vma GLOBAL PROPERTY ${STRING_SECTION}_VMA)
|
||||
get_property(lma GLOBAL PROPERTY ${STRING_SECTION}_LMA)
|
||||
get_property(noinput GLOBAL PROPERTY ${STRING_SECTION}_NOINPUT)
|
||||
get_property(noinit GLOBAL PROPERTY ${STRING_SECTION}_NOINIT)
|
||||
|
||||
string(REGEX REPLACE "^[\.]" "" name_clean "${name}")
|
||||
string(REPLACE "." "_" name_clean "${name_clean}")
|
||||
|
||||
set(TEMP " ${name_clean}")
|
||||
if(DEFINED address)
|
||||
set(TEMP "${TEMP} ${address}")
|
||||
else()
|
||||
set(TEMP "${TEMP} +0")
|
||||
endif()
|
||||
|
||||
if(noinit)
|
||||
# Currently we simply uses offset +0, but we must support offset defined
|
||||
# externally.
|
||||
set(TEMP "${TEMP} UNINIT")
|
||||
endif()
|
||||
|
||||
if(subalign)
|
||||
# Currently we simply uses offset +0, but we must support offset defined
|
||||
# externally.
|
||||
set(TEMP "${TEMP} ALIGN ${subalign}")
|
||||
endif()
|
||||
|
||||
if(NOT noinput)
|
||||
set(TEMP "${TEMP}\n {")
|
||||
|
||||
if("${type}" STREQUAL NOLOAD)
|
||||
set(TEMP "${TEMP}\n *.o(${name}*)")
|
||||
set(TEMP "${TEMP}\n *.o(${name}*.*)")
|
||||
elseif(VMA_FLAGS)
|
||||
# ToDo: Proper names as provided by armclang
|
||||
# set(TEMP "${TEMP}\n *.o(${SEC_NAME}*, +${VMA_FLAGS})")
|
||||
# set(TEMP "${TEMP}\n *.o(${SEC_NAME}*.*, +${VMA_FLAGS})")
|
||||
set(TEMP "${TEMP}\n *.o(${name}*)")
|
||||
set(TEMP "${TEMP}\n *.o(${name}*.*)")
|
||||
else()
|
||||
set(TEMP "${TEMP}\n *.o(${name}*)")
|
||||
set(TEMP "${TEMP}\n *.o(${name}*.*)")
|
||||
endif()
|
||||
else()
|
||||
set(empty TRUE)
|
||||
endif()
|
||||
|
||||
get_property(indicies GLOBAL PROPERTY ${STRING_SECTION}_SETTINGS_INDICIES)
|
||||
foreach(idx ${indicies})
|
||||
get_property(align GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_ALIGN)
|
||||
get_property(any GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_ANY)
|
||||
get_property(first GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_FIRST)
|
||||
get_property(keep GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_KEEP)
|
||||
get_property(sort GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_SORT)
|
||||
get_property(flags GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_FLAGS)
|
||||
get_property(input GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_INPUT)
|
||||
get_property(offset GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_OFFSET)
|
||||
if(DEFINED offset)
|
||||
set(section_close TRUE)
|
||||
math(EXPR offset_dec "${offset} + 0")
|
||||
if(empty)
|
||||
set(TEMP "${TEMP} EMPTY 0x0\n {")
|
||||
set(empty FALSE)
|
||||
endif()
|
||||
set(last_index ${offset_dec})
|
||||
if(sort)
|
||||
set(sorttype "SORTTYPE ${SORT_TYPE_${sort}}")
|
||||
endif()
|
||||
set(TEMP "${TEMP}\n }")
|
||||
set(TEMP "${TEMP}\n ${name_clean}_${offset_dec} (ImageBase(${name_clean}) + ${offset}) ${sorttype}\n {")
|
||||
elseif(sort)
|
||||
set(section_close TRUE)
|
||||
if(empty)
|
||||
set(TEMP "${TEMP} EMPTY 0x0\n {")
|
||||
set(empty FALSE)
|
||||
endif()
|
||||
set(last_index ${idx})
|
||||
set(TEMP "${TEMP}\n }")
|
||||
set(TEMP "${TEMP}\n ${name_clean}_${idx} +0 SORTTYPE ${SORT_TYPE_${sort}}\n {")
|
||||
endif()
|
||||
|
||||
if(empty)
|
||||
set(TEMP "${TEMP}\n {")
|
||||
set(empty FALSE)
|
||||
endif()
|
||||
|
||||
foreach(setting ${input})
|
||||
#set(SETTINGS ${SETTINGS_INPUT})
|
||||
|
||||
# # ToDo: The code below had en error in original implementation, causing
|
||||
# # settings not to be applied
|
||||
# # Verify behaviour and activate if working as intended.
|
||||
# if(align)
|
||||
# set(setting "${setting}, OVERALIGN ${align}")
|
||||
# endif()
|
||||
|
||||
#if(SETTINGS_KEEP)
|
||||
# armlink has --keep=<section_id>, but is there an scatter equivalant ?
|
||||
#endif()
|
||||
|
||||
if(first)
|
||||
set(setting "${setting}, +First")
|
||||
set(first "")
|
||||
endif()
|
||||
|
||||
set(TEMP "${TEMP}\n *.o(${setting})")
|
||||
endforeach()
|
||||
|
||||
if(any)
|
||||
if(NOT flags)
|
||||
message(FATAL_ERROR ".ANY requires flags to be set.")
|
||||
endif()
|
||||
string(REPLACE ";" " " flags "${flags}")
|
||||
|
||||
set(TEMP "${TEMP}\n .ANY (${flags})")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(section_close OR DEFINED endalign)
|
||||
set(section_close)
|
||||
set(TEMP "${TEMP}\n }")
|
||||
|
||||
if(DEFINED endalign)
|
||||
if(DEFINED last_index)
|
||||
set(align_expr "AlignExpr(ImageLimit(${name_clean}_${last_index}), ${endalign}) FIXED")
|
||||
else()
|
||||
set(align_expr "AlignExpr(ImageLimit(${name_clean}), ${endalign}) FIXED")
|
||||
endif()
|
||||
else()
|
||||
set(align_expr "+0")
|
||||
endif()
|
||||
|
||||
set(TEMP "${TEMP}\n ${name_clean}_end ${align_expr} EMPTY 0x0\n {")
|
||||
set(last_index)
|
||||
endif()
|
||||
|
||||
set(TEMP "${TEMP}")
|
||||
# ToDo: add patterns here.
|
||||
|
||||
set(TEMP "${TEMP}\n }")
|
||||
|
||||
set(${STRING_STRING} "${${STRING_STRING}}\n${TEMP}\n" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(symbol_to_string)
|
||||
cmake_parse_arguments(STRING "" "SYMBOL;STRING" "" ${ARGN})
|
||||
|
||||
get_property(name GLOBAL PROPERTY ${STRING_SYMBOL}_NAME)
|
||||
get_property(expr GLOBAL PROPERTY ${STRING_SYMBOL}_EXPR)
|
||||
get_property(size GLOBAL PROPERTY ${STRING_SYMBOL}_SIZE)
|
||||
get_property(symbol GLOBAL PROPERTY ${STRING_SYMBOL}_SYMBOL)
|
||||
get_property(subalign GLOBAL PROPERTY ${STRING_SYMBOL}_SUBALIGN)
|
||||
|
||||
string(REPLACE "\\" "" expr "${expr}")
|
||||
string(REGEX MATCHALL "%([^%]*)%" match_res ${expr})
|
||||
|
||||
foreach(match ${match_res})
|
||||
string(REPLACE "%" "" match ${match})
|
||||
get_property(symbol_val GLOBAL PROPERTY SYMBOL_TABLE_${match})
|
||||
string(REPLACE "%${match}%" "ImageBase(${symbol_val})" expr ${expr})
|
||||
endforeach()
|
||||
|
||||
if(DEFINED subalign)
|
||||
set(subalign "ALIGN ${subalign}")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED size)
|
||||
set(size "0x0")
|
||||
endif()
|
||||
|
||||
set(${STRING_STRING}
|
||||
"${${STRING_STRING}}\n ${symbol} ${expr} ${subalign} ${size} { }\n"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endfunction()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../linker_script_common.cmake)
|
108
cmake/linker/armlink/target.cmake
Normal file
108
cmake/linker/armlink/target.cmake
Normal file
|
@ -0,0 +1,108 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# In order to ensure that the armlink symbol name is correctly passed to
|
||||
# gen_handles.py, we must first ensure that it is properly escaped.
|
||||
# For Python to work, the `$` must be passed as `\$` on command line.
|
||||
# In order to pass a single `\` to command line it must first be escaped, that is `\\`.
|
||||
# In ninja build files, a `$` is not accepted but must be passed as `$$`.
|
||||
# CMake, Python and Ninja combined results in `\\$$` in order to pass a sing `\$` to Python,
|
||||
# so `$$` thus becomes: `\\$$\\$$`.
|
||||
set_property(TARGET linker PROPERTY devices_start_symbol "Image\\$$\\$$device\\$$\\$$Base")
|
||||
|
||||
find_program(CMAKE_LINKER ${CROSS_COMPILE}armlink PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
||||
|
||||
add_custom_target(armlink)
|
||||
|
||||
macro(toolchain_ld_base)
|
||||
endmacro()
|
||||
|
||||
function(toolchain_ld_force_undefined_symbols)
|
||||
foreach(symbol ${ARGN})
|
||||
zephyr_link_libraries(--undefined=${symbol})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
macro(toolchain_ld_baremetal)
|
||||
endmacro()
|
||||
|
||||
macro(configure_linker_script linker_script_gen linker_pass_define)
|
||||
if("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_PREBUILT")
|
||||
set(PASS 1)
|
||||
elseif("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_FINAL;-DLINKER_PASS2")
|
||||
set(PASS 2)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${linker_script_gen}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DPASS=${PASS}
|
||||
-DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>"
|
||||
-DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>"
|
||||
-DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>"
|
||||
-DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>"
|
||||
-DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>"
|
||||
${STEERING_FILE_ARG}
|
||||
${STEERING_C_ARG}
|
||||
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
|
||||
-P ${ZEPHYR_BASE}/cmake/linker/armlink/scatter_script.cmake
|
||||
)
|
||||
endmacro()
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
foreach(lib ${ZEPHYR_LIBS_PROPERTY})
|
||||
if(NOT ${lib} STREQUAL arch__arm__core__aarch32__cortex_m)
|
||||
list(APPEND ZEPHYR_LIBS_OBJECTS $<TARGET_OBJECTS:${lib}>)
|
||||
list(APPEND ZEPHYR_LIBS_OBJECTS $<TARGET_PROPERTY:${lib},LINK_LIBRARIES>)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
target_link_libraries(
|
||||
${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
|
||||
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
|
||||
--scatter=${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
|
||||
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
|
||||
$<TARGET_OBJECTS:arch__arm__core__aarch32__cortex_m>
|
||||
--map --list=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
|
||||
${ZEPHYR_LIBS_OBJECTS}
|
||||
kernel
|
||||
$<TARGET_OBJECTS:${OFFSETS_LIB}>
|
||||
--library_type=microlib
|
||||
--entry=$<TARGET_PROPERTY:linker,ENTRY>
|
||||
"--keep=\"*.o(.init_*)\""
|
||||
"--keep=\"*.o(.device_*)\""
|
||||
# The scatter file is generated, and thus sometimes input sections are specified
|
||||
# even though there will be no such sections found in the libraries linked.
|
||||
--diag_suppress=6314
|
||||
# We use empty excution sections in order to define custom symbols, such as
|
||||
# __kernel_ram_x symbols, but nothing will go in those section, so silnence
|
||||
# the warning. Note, marking the section EMPTY causes armlink to reserve the
|
||||
# address which in some cases leads to overlapping section errors.
|
||||
--diag_suppress=6312
|
||||
# Use of '.gnu.linkonce' sections. Those are used by ld, and # supported by armlink, albeit
|
||||
# deprecated there. For current ARMClang support phase, we accept this warning, but we should
|
||||
# look into changing to COMDAT groups.
|
||||
--diag_suppress=6092
|
||||
# Wildcard matching of keep sections, Those are needed for gnu ld, and thus we inherit the same
|
||||
# keep flags and apply them to armlink. Consider adjusting keep flags per linker in future.
|
||||
--diag_suppress=6319
|
||||
# Match pattern for an unused section that is being removed.
|
||||
--diag_suppress=6329
|
||||
${TOOLCHAIN_LIBS_OBJECTS}
|
||||
|
||||
${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
|
||||
)
|
||||
endfunction(toolchain_ld_link_elf)
|
||||
|
||||
include(${ZEPHYR_BASE}/cmake/linker/ld/target_base.cmake)
|
||||
#include(${ZEPHYR_BASE}/cmake/linker/ld/target_baremetal.cmake)
|
||||
include(${ZEPHYR_BASE}/cmake/linker/ld/target_cpp.cmake)
|
||||
include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)
|
||||
include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake)
|
21
cmake/toolchain/armclang/generic.cmake
Normal file
21
cmake/toolchain/armclang/generic.cmake
Normal file
|
@ -0,0 +1,21 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set_ifndef(ARMCLANG_TOOLCHAIN_PATH "$ENV{ARMCLANG_TOOLCHAIN_PATH}")
|
||||
set(ARMCLANG_TOOLCHAIN_PATH ${ARMCLANG_TOOLCHAIN_PATH} CACHE PATH "armclang tools install directory")
|
||||
assert(ARMCLANG_TOOLCHAIN_PATH "ARMCLANG_TOOLCHAIN_PATH is not set")
|
||||
|
||||
if(NOT EXISTS ${ARMCLANG_TOOLCHAIN_PATH})
|
||||
message(FATAL_ERROR "Nothing found at ARMCLANG_TOOLCHAIN_PATH: '${ARMCLANG_TOOLCHAIN_PATH}'")
|
||||
endif()
|
||||
|
||||
set(TOOLCHAIN_HOME ${ARMCLANG_TOOLCHAIN_PATH})
|
||||
|
||||
set(COMPILER armclang)
|
||||
set(LINKER armlink)
|
||||
set(BINTOOLS armclang)
|
||||
|
||||
set(SYSROOT_TARGET arm)
|
||||
|
||||
set(CROSS_COMPILE ${TOOLCHAIN_HOME}/bin/)
|
||||
|
||||
set(TOOLCHAIN_HAS_NEWLIB OFF CACHE BOOL "True if toolchain supports newlib")
|
3
cmake/toolchain/armclang/target.cmake
Normal file
3
cmake/toolchain/armclang/target.cmake
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# This file intentionally left blank.
|
Loading…
Add table
Add a link
Reference in a new issue