Browse Source
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>pull/38105/head
7 changed files with 525 additions and 0 deletions
@ -0,0 +1,6 @@
@@ -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}") |
@ -0,0 +1,38 @@
@@ -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() |
@ -0,0 +1,79 @@
@@ -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() |
@ -0,0 +1,270 @@
@@ -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) |
@ -0,0 +1,108 @@
@@ -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) |
@ -0,0 +1,21 @@
@@ -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") |
Loading…
Reference in new issue