diff --git a/cmake/compiler/armclang/compiler_flags.cmake b/cmake/compiler/armclang/compiler_flags.cmake new file mode 100644 index 00000000000..48c0e0c798c --- /dev/null +++ b/cmake/compiler/armclang/compiler_flags.cmake @@ -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}") diff --git a/cmake/compiler/armclang/generic.cmake b/cmake/compiler/armclang/generic.cmake new file mode 100644 index 00000000000..44d34ddcdbe --- /dev/null +++ b/cmake/compiler/armclang/generic.cmake @@ -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() diff --git a/cmake/compiler/armclang/target.cmake b/cmake/compiler/armclang/target.cmake new file mode 100644 index 00000000000..2a88bc294e7 --- /dev/null +++ b/cmake/compiler/armclang/target.cmake @@ -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() diff --git a/cmake/linker/armlink/scatter_script.cmake b/cmake/linker/armlink/scatter_script.cmake new file mode 100644 index 00000000000..779c4cac862 --- /dev/null +++ b/cmake/linker/armlink/scatter_script.cmake @@ -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=, 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) diff --git a/cmake/linker/armlink/target.cmake b/cmake/linker/armlink/target.cmake new file mode 100644 index 00000000000..615a1b7cd25 --- /dev/null +++ b/cmake/linker/armlink/target.cmake @@ -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="$" + -DGROUPS="$" + -DSECTIONS="$" + -DSECTION_SETTINGS="$" + -DSYMBOLS="$" + ${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 $) + list(APPEND ZEPHYR_LIBS_OBJECTS $) + 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} + $ + --map --list=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} + ${ZEPHYR_LIBS_OBJECTS} + kernel + $ + --library_type=microlib + --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) diff --git a/cmake/toolchain/armclang/generic.cmake b/cmake/toolchain/armclang/generic.cmake new file mode 100644 index 00000000000..8a94102dd15 --- /dev/null +++ b/cmake/toolchain/armclang/generic.cmake @@ -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") diff --git a/cmake/toolchain/armclang/target.cmake b/cmake/toolchain/armclang/target.cmake new file mode 100644 index 00000000000..5a1a0e51313 --- /dev/null +++ b/cmake/toolchain/armclang/target.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This file intentionally left blank.