Browse Source

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>
pull/38105/head
Torsten Rasmussen 5 years ago committed by Anas Nashif
parent
commit
40a2ffd2ea
  1. 6
      cmake/compiler/armclang/compiler_flags.cmake
  2. 38
      cmake/compiler/armclang/generic.cmake
  3. 79
      cmake/compiler/armclang/target.cmake
  4. 270
      cmake/linker/armlink/scatter_script.cmake
  5. 108
      cmake/linker/armlink/target.cmake
  6. 21
      cmake/toolchain/armclang/generic.cmake
  7. 3
      cmake/toolchain/armclang/target.cmake

6
cmake/compiler/armclang/compiler_flags.cmake

@ -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}")

38
cmake/compiler/armclang/generic.cmake

@ -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()

79
cmake/compiler/armclang/target.cmake

@ -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()

270
cmake/linker/armlink/scatter_script.cmake

@ -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)

108
cmake/linker/armlink/target.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)

21
cmake/toolchain/armclang/generic.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")

3
cmake/toolchain/armclang/target.cmake

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
# This file intentionally left blank.
Loading…
Cancel
Save