aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorTTornblom <thomas.tornblom@iar.com>2019-12-17 16:22:38 +0100
committerTTornblom <thomas.tornblom@iar.com>2020-04-23 12:18:51 +0200
commit99f0be29ae6d025bf436e3c15a8cb7f5206f04d3 (patch)
treea5f4a5a8678741f1560fc9a402c37def1e608a9d /cmake
parente304f966ef9aef8926798e96d3a30dcb7544d538 (diff)
downloadtrusted-firmware-m-99f0be29ae6d025bf436e3c15a8cb7f5206f04d3.tar.gz
Build: IAR support
- This patch contains IAR specific changes to a few source files, mostly #pragmas to allow calling external functions from inline. - Startup code and linker scripts - cmake files - cmsis file for the IAR compiler Other targets are added in later commits There are still lots of warnings generated for non-standard C, which I plan to address in later updates - Cleaned out some dead definitions in the common linker script in preparation for psoc64 integration. - Made sure that .rodata from tfm_its_secure_api.o is placed in TFM_UNPRIV_CODE, which otherwised caused a memory management fault in test TFM_ITS_TEST_2023 when compiled without optimization. - Added dummy initializers to tfm_secure_irq_handlers.inc.template to avoid illegal empty arrays. - Reworked the iovec_args_t struct handling in tfm_func_api.c, which was causing runtime errors when compiled with optimization. According to the compiler developers the old implemetation is illegal, you are not allowed to use the address of a scalar as an address outside of that scalar. - Added conditional around ".syntax unified" in tfm_nspm_ipc.c. - Added "template" attribute for the IAR linker script in tfm_generated_file_list.yaml. - Cleaned up some indentation and tab/space issues Change-Id: I8599d461f62194bc734e472a28d7111ba3b5046a Signed-off-by: TTornblom <thomas.tornblom@iar.com>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/Common/CompilerDetermineASM.cmake4
-rw-r--r--cmake/Common/CompilerDetermineC.cmake6
-rw-r--r--cmake/Common/CompilerDetermineCXX.cmake6
-rw-r--r--cmake/Common/CompilerIarArm842.cmake80
-rw-r--r--cmake/Common/CompilerIarArm850.cmake80
-rw-r--r--cmake/Common/CompilerIarArmCommon.cmake275
-rw-r--r--cmake/Common/FindIARARM.cmake118
-rw-r--r--cmake/Common/IARArMerge.cmake117
-rw-r--r--cmake/Compiler/IARARM-ASM.cmake11
-rw-r--r--cmake/Compiler/IARARM-C.cmake9
-rw-r--r--cmake/Compiler/IARARM-CXX.cmake9
-rw-r--r--cmake/Compiler/IARARM.cmake55
12 files changed, 763 insertions, 7 deletions
diff --git a/cmake/Common/CompilerDetermineASM.cmake b/cmake/Common/CompilerDetermineASM.cmake
index 7bef05d23..e38bce53f 100644
--- a/cmake/Common/CompilerDetermineASM.cmake
+++ b/cmake/Common/CompilerDetermineASM.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,6 +22,8 @@ elseif(_ASM_COMPILER_NAME MATCHES "^.*armasm(\\.exe)?$")
set(ARM_TOOLCHAIN_FILE "Compiler/ARMCC-ASM")
elseif (_ASM_COMPILER_NAME MATCHES "^.*gcc(\\.exe)?$")
set(ARM_TOOLCHAIN_FILE "Compiler/GNUARM-ASM")
+elseif (_ASM_COMPILER_NAME MATCHES "^.*iasmarm(\\.exe)?$")
+ set(ARM_TOOLCHAIN_FILE "Compiler/IARARM-ASM")
else()
message(FATAL_ERROR "ASM Compiler executable ${_ASM_COMPILER_NAME} is \
unknown. Please add needed settings to ${CMAKE_CURRENT_LIST_FILE}")
diff --git a/cmake/Common/CompilerDetermineC.cmake b/cmake/Common/CompilerDetermineC.cmake
index a429120f8..7d363d721 100644
--- a/cmake/Common/CompilerDetermineC.cmake
+++ b/cmake/Common/CompilerDetermineC.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -28,8 +28,8 @@ elseif (_C_COMPILER_NAME MATCHES "^.*gcc(\\.exe)?$")
set(CMAKE_C_COMPILER_ID "GNUARM" CACHE INTERNAL "C compiler ID" FORCE)
set(ARM_TOOLCHAIN_FILE "Compiler/GNUARM-C")
elseif (_C_COMPILER_NAME MATCHES "^.*iccarm(\\.exe)?$")
- set(CMAKE_C_COMPILER_ID "IAR" CACHE INTERNAL "C compiler ID" FORCE)
- set(ARM_TOOLCHAIN_FILE "Compiler/IAR-C")
+ set(CMAKE_C_COMPILER_ID "IARARM" CACHE INTERNAL "C compiler ID" FORCE)
+ set(ARM_TOOLCHAIN_FILE "Compiler/IARARM-C")
else()
message(FATAL_ERROR "C Compiler executable ${_C_COMPILER_NAME} is unknown.\
Please add needed settings to ${CMAKE_CURRENT_LIST_FILE}")
diff --git a/cmake/Common/CompilerDetermineCXX.cmake b/cmake/Common/CompilerDetermineCXX.cmake
index 6d1f142bf..bf2336759 100644
--- a/cmake/Common/CompilerDetermineCXX.cmake
+++ b/cmake/Common/CompilerDetermineCXX.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -27,8 +27,8 @@ elseif (_CXX_COMPILER_NAME MATCHES "^.*gcc(\\.exe)?$")
set(CMAKE_CXX_COMPILER_ID "GNUARM" CACHE INTERNAL "C++ compiler ID" FORCE)
set(ARM_TOOLCHAIN_FILE "Compiler/GNUARM-CXX")
elseif (_CXX_COMPILER_NAME MATCHES "^.*iccarm(\\.exe)?$")
- set(CMAKE_CXX_COMPILER_ID "IAR" CACHE INTERNAL "C++ compiler ID" FORCE)
- set(ARM_TOOLCHAIN_FILE "Compiler/IAR-CXX")
+ set(CMAKE_CXX_COMPILER_ID "IARARM" CACHE INTERNAL "C++ compiler ID" FORCE)
+ set(ARM_TOOLCHAIN_FILE "Compiler/IARARM-CXX")
else()
message(FATAL_ERROR "C++ Compiler executable ${_C_COMPILER_NAME} is \
unknown. Please add needed settings to ${CMAKE_CURRENT_LIST_FILE}")
diff --git a/cmake/Common/CompilerIarArm842.cmake b/cmake/Common/CompilerIarArm842.cmake
new file mode 100644
index 000000000..7d5c4225e
--- /dev/null
+++ b/cmake/Common/CompilerIarArm842.cmake
@@ -0,0 +1,80 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#This file contains settings to specify how ICCARM shall be used
+
+#Include some dependencies
+Include(Common/CompilerIarArmCommon)
+Include(Common/Utils)
+
+check_iccarm_input_vars("8.42")
+
+if(NOT DEFINED ARM_CPU_ARCHITECTURE)
+ set(_NO_ARM_CPU_ARCHITECTURE true)
+elseif (${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv8-M.BASE")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+ string_append_unique_item(STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+elseif(${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv8-M.MAIN")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+elseif(${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv7-M")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item(STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+elseif(${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv6-M")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item(STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+else()
+ message(FATAL_ERROR "Unknown or unsupported ARM cpu architecture setting.")
+endif()
+
+#Prefer architecture definition over cpu type.
+if(NOT DEFINED ARM_CPU_ARCHITECTURE)
+ if(NOT DEFINED ARM_CPU_TYPE)
+ string_append_unique_item(_NO_ARM_CPU_TYPE true)
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M3")
+ string_append_unique_item (CMAKE_C_FLAGS_CPU "--cpu Cortex-M3")
+ string_append_unique_item (CMAKE_CXX_FLAGS_CPU "--cpu Cortex-M3")
+ string_append_unique_item (CMAKE_ASM_FLAGS_CPU "--cpu Cortex-M3")
+ string_append_unique_item (CMAKE_LINK_FLAGS_CPU "--cpu Cortex-M3")
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M33")
+ string_append_unique_item (CMAKE_C_FLAGS_CPU "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item (CMAKE_CXX_FLAGS_CPU "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item (CMAKE_ASM_FLAGS_CPU "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item (CMAKE_LINK_FLAGS_CPU "--cpu Cortex-M3.no_dsp3")
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M23")
+ string_append_unique_item (CMAKE_C_FLAGS_CPU "--cpu Cortex-M23")
+ string_append_unique_item (CMAKE_CXX_FLAGS_CPU "--cpu Cortex-M23")
+ string_append_unique_item (CMAKE_ASM_FLAGS_CPU "--cpu Cortex-M23")
+ string_append_unique_item (CMAKE_LINK_FLAGS_CPU "--cpu Cortex-M23")
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M4")
+ string_append_unique_item (STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item (STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item (STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item (STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ set(ARM_CPU_ARCHITECTURE "ARMv7-M")
+ elseif (${ARM_CPU_TYPE} STREQUAL "Cortex-M0p")
+ string_append_unique_item (STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item (STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item (STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item (STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ set(ARM_CPU_ARCHITECTURE "ARMv6-M")
+ else()
+ message(FATAL_ERROR "Unknown ARM cpu setting.")
+ endif()
+endif()
+
+if (_NO_ARM_CPU_TYPE AND _NO_ARM_CPU_ARCHITECTURE)
+ message(FATAL_ERROR "Can not set CPU specific compiler flags: neither the ARM CPU type nor the architecture is set.")
+endif()
diff --git a/cmake/Common/CompilerIarArm850.cmake b/cmake/Common/CompilerIarArm850.cmake
new file mode 100644
index 000000000..bf40e6452
--- /dev/null
+++ b/cmake/Common/CompilerIarArm850.cmake
@@ -0,0 +1,80 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#This file contains settings to specify how ICCARM shall be used
+
+#Include some dependencies
+Include(Common/CompilerIarArmCommon)
+Include(Common/Utils)
+
+check_iccarm_input_vars("8.50")
+
+if(NOT DEFINED ARM_CPU_ARCHITECTURE)
+ set(_NO_ARM_CPU_ARCHITECTURE true)
+elseif (${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv8-M.BASE")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+ string_append_unique_item(STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M23")
+elseif(${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv8-M.MAIN")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M33.no_dsp")
+elseif(${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv7-M")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item(STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+elseif(${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv6-M")
+ string_append_unique_item(STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item(STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item(STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item(STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+else()
+ message(FATAL_ERROR "Unknown or unsupported ARM cpu architecture setting.")
+endif()
+
+#Prefer architecture definition over cpu type.
+if(NOT DEFINED ARM_CPU_ARCHITECTURE)
+ if(NOT DEFINED ARM_CPU_TYPE)
+ string_append_unique_item(_NO_ARM_CPU_TYPE true)
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M3")
+ string_append_unique_item (CMAKE_C_FLAGS_CPU "--cpu Cortex-M3")
+ string_append_unique_item (CMAKE_CXX_FLAGS_CPU "--cpu Cortex-M3")
+ string_append_unique_item (CMAKE_ASM_FLAGS_CPU "--cpu Cortex-M3")
+ string_append_unique_item (CMAKE_LINK_FLAGS_CPU "--cpu Cortex-M3")
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M33")
+ string_append_unique_item (CMAKE_C_FLAGS_CPU "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item (CMAKE_CXX_FLAGS_CPU "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item (CMAKE_ASM_FLAGS_CPU "--cpu Cortex-M33.no_dsp")
+ string_append_unique_item (CMAKE_LINK_FLAGS_CPU "--cpu Cortex-M3.no_dsp3")
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M23")
+ string_append_unique_item (CMAKE_C_FLAGS_CPU "--cpu Cortex-M23")
+ string_append_unique_item (CMAKE_CXX_FLAGS_CPU "--cpu Cortex-M23")
+ string_append_unique_item (CMAKE_ASM_FLAGS_CPU "--cpu Cortex-M23")
+ string_append_unique_item (CMAKE_LINK_FLAGS_CPU "--cpu Cortex-M23")
+ elseif(${ARM_CPU_TYPE} STREQUAL "Cortex-M4")
+ string_append_unique_item (STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item (STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item (STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ string_append_unique_item (STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M4")
+ set(ARM_CPU_ARCHITECTURE "ARMv7-M")
+ elseif (${ARM_CPU_TYPE} STREQUAL "Cortex-M0p")
+ string_append_unique_item (STRING CMAKE_C_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item (STRING CMAKE_CXX_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item (STRING CMAKE_ASM_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ string_append_unique_item (STRING CMAKE_LINK_FLAGS_CPU KEY "--cpu" VAL "--cpu Cortex-M0+")
+ set(ARM_CPU_ARCHITECTURE "ARMv6-M")
+ else()
+ message(FATAL_ERROR "Unknown ARM cpu setting.")
+ endif()
+endif()
+
+if (_NO_ARM_CPU_TYPE AND _NO_ARM_CPU_ARCHITECTURE)
+ message(FATAL_ERROR "Can not set CPU specific compiler flags: neither the ARM CPU type nor the architecture is set.")
+endif()
diff --git a/cmake/Common/CompilerIarArmCommon.cmake b/cmake/Common/CompilerIarArmCommon.cmake
new file mode 100644
index 000000000..78cbdd7bf
--- /dev/null
+++ b/cmake/Common/CompilerIarArmCommon.cmake
@@ -0,0 +1,275 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2017-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#This file contains settings to specify how IARARM shall be used
+
+function(check_iccarm_input_vars MY_VERSION)
+ #Specify where IARARM is
+ if (NOT DEFINED IARARM_PATH)
+ message(FATAL_ERROR "Please set IARARM_PATH to the root directory of the IARARM installation. e.g. set(IARARM_PATH \"C:/Program Files (x86)/IAR Systems/Embedded Workbench ${MY_VERSION}\")")
+ endif()
+
+ STRING(REGEX REPLACE "([0-9]+).([0-9]+).*" "\\1.\\2" _MY_MAJOR_MINOR "${MY_VERSION}")
+ STRING(REGEX REPLACE "([0-9]+).([0-9]+).*" "\\1.\\2" _IARARM_MAJOR_MINOR "${IARARM_VER}")
+
+ #Check iccarm version.
+ if (NOT "${_MY_MAJOR_MINOR}" VERSION_EQUAL "${_IARARM_MAJOR_MINOR}")
+ message(FATAL_ERROR "IARARM version (IARARM_VER=${IARARM_VER}) does not match ${MY_VERSION}")
+ endif()
+
+ if (NOT DEFINED ARM_CPU_ARCHITECTURE AND NOT DEFINED ARM_CPU_TYPE)
+ message(FATAL_ERROR "ARM_CPU_TYPE and ARM_CPU_ARCHITECTURE is not defined! Please include the CPU specific config file before this one.")
+ endif()
+
+endfunction()
+
+message(STATUS "Using IARARM compiler package v${IARARM_VER} from ${IARARM_PATH}")
+
+
+#Tell cmake which compiler we use
+if (EXISTS "c:/")
+ set (CMAKE_C_COMPILER "${IARARM_PATH}/bin/iccarm.exe")
+ set (CMAKE_CXX_COMPILER "${IARARM_PATH}/bin/iccarm.exe")
+ set (CMAKE_ASM_COMPILER "${IARARM_PATH}/bin/iasmarm.exe")
+else()
+ set (CMAKE_C_COMPILER "${IARARM_PATH}/bin/iccarm")
+ set (CMAKE_CXX_COMPILER "${IARARM_PATH}/bin/iccarm")
+ set (CMAKE_ASM_COMPILER "${IARARM_PATH}/bin/iasmarm")
+endif()
+
+if("CXX" IN_LIST languages)
+ set(CMAKE_CXX_COMPILER_ID "IARARM" CACHE INTERNAL "CXX compiler ID" FORCE)
+ include(Compiler/IARARM-CXX)
+endif()
+
+if("C" IN_LIST languages)
+ set(CMAKE_C_COMPILER_ID "IARARM" CACHE INTERNAL "C compiler ID" FORCE)
+ include(Compiler/IARARM-C)
+endif()
+
+function(compiler_get_preinclude_option_string INCLUDE RES)
+ set(${RES} "--preinclude ${INCLUDE}" PARENT_SCOPE)
+endfunction()
+
+function(compiler_set_preinclude_file)
+ #Option (on/off) arguments.
+ set( _OPTIONS_ARGS GLOBAL)
+ #Single option arguments.
+ set( _ONE_VALUE_ARGS INCLUDE)
+ #List arguments
+ set( _MULTI_VALUE_ARGS TARGETS FILES)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+ if(NOT DEFINED _MY_PARAMS)
+ message(FATAL_ERROR "compiler_set_preinclude_file: missing mandatory parameter INCLUDE.")
+ endif()
+ compiler_get_preinclude_option_string(${INCLUDE} _OPTION_STRING)
+ #If include is to be set globally, we ignore TARGETS and FILES
+ if(_MY_PARAMS_GLOBAL)
+ set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY COMPILE_OPTIONS "${_OPTION_STRING}")
+ else()
+ #If GLOBAL was not passed, then either TARGETS or FILES must be present
+ if(NOT DEFINED _MY_PARAM_TARGETS AND NOT DEFINED _MY_PARAM_FILES)
+ message(FATAL_ERROR "compiler_set_preinclude_file: missing mandatory parameter. Either TARGETS and/or FILES must be specified.")
+ endif()
+ #Iterate over targets. Note: call embedded_set_target_compile_flags to
+ #allow the target to be defined after this function call. This helps
+ #modularisation
+ foreach(_TGT IN_LISTS _MY_PARAM_TARGETS)
+ embedded_set_target_compile_flags(TARGET ${_TGT} LANGUAGE "C" FLAGS "${_OPTION_STRING}")
+ endforeach()
+ #Iterate over files
+ foreach(_FILE IN_LISTS _MY_PARAM_FILES)
+ set_property(FILE ${_FILE} APPEND PROPERTY COMPILE_OPTIONS "${_OPTION_STRING}")
+ endforeach()
+ endif()
+endfunction()
+
+function(compiler_set_linkercmdfile)
+ set( _OPTIONS_ARGS ) #Option (on/off) arguments.
+ set( _ONE_VALUE_ARGS TARGET PATH) #Single option arguments.
+ set( _MULTI_VALUE_ARGS DEFINES INCLUDES) #List arguments
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+
+ #Check passed parameters
+ if(NOT _MY_PARAMS_TARGET)
+ message(FATAL_ERROR "compiler_set_linkercmdfile: mandatory parameter 'TARGET' is missing.")
+ endif()
+ if (NOT TARGET ${_MY_PARAMS_TARGET})
+ message(FATAL_ERROR "compiler_set_linkercmdfile: value of parameter 'TARGET' is invalid.")
+ endif()
+
+ if(NOT _MY_PARAMS_PATH)
+ message(FATAL_ERROR "compiler_set_linkercmdfile: mandatory parameter 'PATH' is missing.")
+ endif()
+ set(_FILE_PATH ${_MY_PARAMS_PATH})
+
+ #Create additional target if linker script needs to be pre-processed.
+ if (_MY_PARAMS_DEFINES OR _MY_PARAMS_INCLUDES)
+ #Name of pre-processed linker script file.
+ set(FINAL_LD_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${_MY_PARAMS_TARGET}.icf.i")
+ #Name of the target doing the pre-processing
+ set(LD_PP_TARGET_NAME "${_MY_PARAMS_TARGET}_ldpp")
+ compiler_preprocess_file(SRC ${_MY_PARAMS_PATH}
+ DST ${FINAL_LD_FILE_NAME}
+ TARGET_PREFIX ${_MY_PARAMS_TARGET}
+ BEFORE_TARGET ${_MY_PARAMS_TARGET}
+ DEFINES ${_MY_PARAMS_DEFINES}
+ INCLUDES ${_MY_PARAMS_INCLUDES})
+
+ #Tell cmake to delete the intermediate linker script when the clean rule is executed.
+ get_directory_property(_ADDITIONAL_MAKE_CLEAN_FILES DIRECTORY "./" ADDITIONAL_MAKE_CLEAN_FILES)
+ set_directory_properties(PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_ADDITIONAL_MAKE_CLEAN_FILES} ${FINAL_LD_FILE_NAME}")
+ #Set the path to linker script point to the intermediate file.
+ set(_FILE_PATH ${FINAL_LD_FILE_NAME})
+ endif()
+
+ #Note: the space before the option is important!
+ set_property(TARGET ${_MY_PARAMS_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${_FLAGS} --config=${_FILE_PATH}")
+ set_property(TARGET ${_MY_PARAMS_TARGET} APPEND PROPERTY LINK_DEPENDS ${_FILE_PATH})
+ #Tell cmake .map files shall be removed when project is cleaned (make clean)
+ get_filename_component(_TARGET_BASE_NAME ${_MY_PARAMS_TARGET} NAME_WE)
+ get_directory_property(_ADDITIONAL_MAKE_CLEAN_FILES DIRECTORY "./" ADDITIONAL_MAKE_CLEAN_FILES)
+ set_directory_properties(PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_ADDITIONAL_MAKE_CLEAN_FILES} ${_TARGET_BASE_NAME}.map")
+endfunction()
+
+function(compiler_set_cmse_output TARGET FILE_PATH)
+ #Note: the space before the option is important!
+ set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " --import_cmse_lib_out=${FILE_PATH}")
+ #Tell cmake cmse output is a generated object file.
+ SET_SOURCE_FILES_PROPERTIES("${FILE_PATH}" PROPERTIES EXTERNAL_OBJECT true GENERATED true)
+ #Tell cmake cmse output shall be removed by clean target.
+ get_directory_property(_ADDITIONAL_MAKE_CLEAN_FILES DIRECTORY "./" ADDITIONAL_MAKE_CLEAN_FILES)
+ set_directory_properties(PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_ADDITIONAL_MAKE_CLEAN_FILES} ${FILE_PATH}")
+endfunction()
+
+function(compiler_merge_library)
+ set( _OPTIONS_ARGS ) #Option (on/off) arguments.
+ set( _ONE_VALUE_ARGS DEST) #Single option arguments.
+ set( _MULTI_VALUE_ARGS LIBS) #List arguments
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+
+ #Check passed parameters
+ if(NOT _MY_PARAMS_DEST)
+ message(FATAL_ERROR "compiler_merge_library: no destination target specified. Please see the DEST parameter.")
+ endif()
+ #Check if destination is a library
+ get_target_property(_tmp ${_MY_PARAMS_DEST} TYPE)
+ if(NOT "${_tmp}" STREQUAL "STATIC_LIBRARY")
+ message(FATAL_ERROR "compiler_merge_library: parameter DEST must be a static library target.")
+ endif()
+ set(_DEST ${_MY_PARAMS_DEST})
+
+ if(NOT _MY_PARAMS_LIBS)
+ message(FATAL_ERROR "compiler_merge_library: no source libraries specified. Please see the LIBS parameter.")
+ endif()
+ set(_LIBS ${_MY_PARAMS_LIBS})
+
+ ##Find the cmake script doing the merge.
+ find_file(_MERGE_SCRIPT "IARArMerge.cmake" PATHS ${CMAKE_MODULE_PATH} PATH_SUFFIXES Common NO_DEFAULT_PATH)
+
+ #Now add a custom command for each source library to our custom target to
+ #merge into the destination.
+ foreach(SRC_LIB ${_LIBS})
+ get_filename_component(_SRC_LIB_NAME "${SRC_LIB}" NAME)
+ add_custom_command(TARGET ${_DEST} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -DCMAKE_AR=${CMAKE_AR} -DSOURCE=${SRC_LIB} -DDESTINATION=$<TARGET_FILE:${_DEST}> -P ${_MERGE_SCRIPT}
+ COMMENT "\t\tmerging objects from ${_SRC_LIB_NAME}")
+ endforeach()
+endfunction()
+
+function(compiler_generate_binary_output TARGET)
+ add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IARARM_IELFTOOL} ARGS --silent --bin $<TARGET_FILE:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin)
+endfunction()
+
+# Function for creating a new target that preprocesses a .c file
+#INPUTS:
+# SRC - (mandatory) - file to be preprocessed
+# DST - (mandatory) - output file for the preprocessing
+# TARGET_PREFIX - (optional) - prefix for the target that this function creates and which manages the preprocessing
+# BEFORE_TARGET - (optional) - target which is dependent on the preprocessing target in the below function
+# DEFINES - (optional) - additional command line switches from macro definitions for preprocessing
+# INCLUDES - (optional) - additional command line switches from include paths for preprocessing
+function(compiler_preprocess_file)
+ #Option (on/off) arguments.
+ set( _OPTIONS_ARGS)
+ #Single option arguments.
+ set( _ONE_VALUE_ARGS SRC DST TARGET_PREFIX BEFORE_TARGET)
+ #List arguments
+ set( _MULTI_VALUE_ARGS DEFINES INCLUDES)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+
+ #Check passed parameters
+ if(NOT DEFINED _MY_PARAMS_SRC)
+ message(FATAL_ERROR "compiler_preprocess_file: mandatory parameter 'SRC' is missing.")
+ endif()
+
+ if(NOT DEFINED _MY_PARAMS_DST)
+ message(FATAL_ERROR "compiler_preprocess_file: mandatory parameter 'DST' is missing.")
+ endif()
+
+ if(DEFINED _MY_PARAMS_BEFORE_TARGET)
+ if(NOT TARGET ${_MY_PARAMS_BEFORE_TARGET})
+ message(FATAL_ERROR "compiler_preprocess_file: optional parameter 'BEFORE_TARGET' is not target.")
+ endif()
+ endif()
+
+ #Compose additional command line switches from macro definitions.
+ set(_FLAGS "")
+ if (_MY_PARAMS_DEFINES)
+ foreach(_DEFINE IN LISTS _MY_PARAMS_DEFINES)
+ list(APPEND _FLAGS "-D${_DEFINE}")
+ endforeach()
+ endif()
+
+ #Compose additional command line switches from include paths.
+ if (_MY_PARAMS_INCLUDES)
+ foreach(_INCLUDE IN LISTS _MY_PARAMS_INCLUDES)
+ list(APPEND _FLAGS "-I${_INCLUDE}")
+ endforeach()
+ endif()
+
+ #The compiler flag might contain leading spaces which can fail the preprocess operation, these are removed
+ STRING(STRIP ${CMAKE_C_FLAGS_CPU} _MY_TEMP_CMAKE_C_FLAGS_CPU)
+ #If a string contains spaces, then it is inserted amongst quotation marks. Furthermore the compiler fails if it is
+ #called with multiple switches included in one quotation mark. If the extra spaces are replaced by semicolons,
+ #then the insertion will be advantageous for the compiler.
+ STRING(REPLACE " " ";" _MY_TEMP2_CMAKE_C_FLAGS_CPU ${_MY_TEMP_CMAKE_C_FLAGS_CPU})
+ set(_LOCAL_CMAKE_C_FLAGS_CPU "")
+ foreach(_C_FLAG IN LISTS _MY_TEMP2_CMAKE_C_FLAGS_CPU)
+ list(APPEND _LOCAL_CMAKE_C_FLAGS_CPU "${_C_FLAG}")
+ endforeach()
+
+ add_custom_command(OUTPUT ${_MY_PARAMS_DST}
+ COMMAND ${CMAKE_C_COMPILER} ${_LOCAL_CMAKE_C_FLAGS_CPU} ${_FLAGS} ${_MY_PARAMS_SRC} --silent --preprocess=ns ${_MY_PARAMS_DST}
+ DEPENDS ${_MY_PARAMS_SRC}
+ COMMENT "Preprocess the ${_MY_PARAMS_SRC} file"
+ )
+
+ set(_MY_TARGET_PREFIX "")
+ if(TARGET ${_MY_PARAMS_TARGET_PREFIX})
+ set(_MY_TARGET_PREFIX "${_MY_PARAMS_TARGET_PREFIX}")
+ endif()
+ #The preprocessing related target name is obtained by indexing the file's name that is to be preprocessed
+ get_filename_component(_MY_FILENAME_TO_BE_INDEXED ${_MY_PARAMS_SRC} NAME_WE)
+ foreach(_SUFFIX RANGE 1 100)
+ if (NOT TARGET ${_MY_TARGET_PREFIX}_pp_${_MY_FILENAME_TO_BE_INDEXED}_${_SUFFIX})
+ set(_PREPROCESS_TARGET_NAME "${_MY_TARGET_PREFIX}_pp_${_MY_FILENAME_TO_BE_INDEXED}_${_SUFFIX}")
+ break()
+ endif()
+ if (_SUFFIX EQUAL 100)
+ message(FATAL_ERROR "You have called 'compiler_preprocess_file' too many times (${_SUFFIX} function calls).")
+ endif()
+ endforeach()
+
+ #Make the original target depend on the new one.
+ if(TARGET ${_MY_PARAMS_BEFORE_TARGET})
+ add_custom_target(${_PREPROCESS_TARGET_NAME} DEPENDS ${_MY_PARAMS_DST})
+ add_dependencies(${_MY_PARAMS_BEFORE_TARGET} ${_PREPROCESS_TARGET_NAME})
+ else()
+ add_custom_target(${_PREPROCESS_TARGET_NAME} ALL DEPENDS ${_MY_PARAMS_DST})
+ endif()
+endfunction()
diff --git a/cmake/Common/FindIARARM.cmake b/cmake/Common/FindIARARM.cmake
new file mode 100644
index 000000000..4ace90b4c
--- /dev/null
+++ b/cmake/Common/FindIARARM.cmake
@@ -0,0 +1,118 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Find the location of the IAR C/C++ compiler.
+#
+# Find iccarm on the specified location or on the PATH and optionally validate its version.
+#
+#Inputs:
+# IARARM_PATH - (optional)- install path of iccarm compiler to use. If not set the
+# compiler on the PATH is used.
+# IARARM_VER - (optional)- version number. If set the module will validate the compiler version.
+#
+#outputs:
+# IARARM_PATH - will be set to the root directory of the compiler. Only set if undefined.
+# IARARM_VER - will be set to the version number found. Only set if undefined.
+# IARARM_MODULE - set to the name of the cmake module to be included for this iccarm version.
+#
+
+#Include some dependencies
+Include(Common/Utils)
+
+#Get the version of iccarm.
+#
+# Execute iccarm and extract its version number for its output.
+#
+#Exmaples:
+# Get the version reported by iccarm at location c:/foo/bin/iccarm to variable VER
+# get_iccarm_version(ICCARM "c:/foo/bin/iccarm" RES VER)
+#
+#INPUTS:
+# ICCARM - (mandatory) - iccarm executable
+# RES - (mandatory) - variable name to put result to
+#
+#OUTPUTS
+# The variable named after "RES" will be set to the version number matches
+#
+function(get_iccarm_version)
+ #Parse our arguments
+ set( _OPTIONS_ARGS ) #No option (on/off) arguments (e.g. IGNORE_CASE)
+ set( _ONE_VALUE_ARGS ICCARM RES) #Single option arguments (e.g. PATH "./foo/bar")
+ set( _MULTI_VALUE_ARGS ) #One list argument (e.g. LANGUAGES C ASM CXX)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+
+ #Check mandatory parameters
+ if(NOT _MY_PARAMS_RES)
+ message (FATAL_ERROR "get_iccarm_version(): Missing result parameter!")
+ endif()
+ set (_RES ${_MY_PARAMS_RES})
+
+ if(NOT _MY_PARAMS_ICCARM)
+ message (FATAL_ERROR "get_iccarm_version(): Missing ICCARM parameter!")
+ endif()
+ set (_ICCARM ${_MY_PARAMS_ICCARM})
+
+ #Call specified executable
+ execute_process(COMMAND "${_ICCARM}" --version
+ OUTPUT_VARIABLE _OUTPUT
+ ERROR_VARIABLE _OUTPUT
+ )
+ #Cut off version number. Just the numbers ignore anything after.
+ STRING(REGEX REPLACE "IAR.* Compiler V(([0-9]+\.)+[0-9]+).*" "\\1" _VER "${_OUTPUT}")
+
+ if (NOT _VER)
+ message (FATAL_ERROR "get_iccarm_version(): Failed to extract version number from iccarm output.")
+ endif()
+
+ set(${_RES} ${_VER} PARENT_SCOPE)
+endfunction()
+
+#If the install location needs to be found.
+if(NOT DEFINED IARARM_PATH)
+ #Set IARARM_PATH to default value.
+ set (IARARM_PATH "IARARM_PATH-NOTFOUND")
+
+ #First check if iccarm is on the PATH
+ #find_program puts() its output to the cmake cache. We don't want that, so we use a local variable, which
+ #is unset later.
+ find_program (
+ _IARARM_PATH
+ iccarm
+ PATHS env PATH
+ DOC "IARARM compiler location."
+ )
+
+ #Yes, check the version number if it is specified.
+ if(_IARARM_PATH STREQUAL "_IARARM_PATH-NOTFOUND")
+ message (FATAL_ERROR "iccarm install location is unset. Either put iccarm on the PATH or set IARARM_PATH.")
+ endif()
+
+ #Cut off executable name directory name to get install location.
+ STRING(REGEX REPLACE "(.*)/bin/iccarm.*" "\\1" IARARM_PATH "${_IARARM_PATH}")
+
+ #Remove unwanted junk from CMake cache.
+ unset(_IARARM_PATH CACHE)
+endif()
+
+get_iccarm_version(ICCARM "${IARARM_PATH}/bin/iccarm" RES _VER)
+
+#Check the version if needed
+if(NOT DEFINED IARARM_VER)
+ set(IARARM_VER ${_VER})
+endif()
+
+if(NOT "${IARARM_VER}" VERSION_EQUAL "${_VER}")
+ message (FATAL_ERROR "FindIARArm.cmake: iccarm compiler version ${_VER} does not match ${IARARM_VER}.")
+endif()
+
+STRING(REGEX REPLACE "([0-9]+)\.([0-9]+)(\.[0-9]+)*.*" "CompilerIarArm\\1\\2" IARARM_MODULE "${IARARM_VER}")
+
+message(STATUS "Version: ${IARARM_VER}/${IARARM_MODULE}")
+
+if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${IARARM_MODULE}.cmake")
+ message(FATAL_ERROR "ERROR: Unsupported IARARM compiler version found on PATH.")
+endif()
diff --git a/cmake/Common/IARArMerge.cmake b/cmake/Common/IARArMerge.cmake
new file mode 100644
index 000000000..e9d19f98d
--- /dev/null
+++ b/cmake/Common/IARArMerge.cmake
@@ -0,0 +1,117 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#A cmake script to merge two archives using IAR iarchive.
+#
+# The script will first run iarchive to get the list of files in the source archive.
+# Then each file is:
+# -extracted
+# -added to the target archive
+# -deleted
+#
+# The loop is needed to avoid losing files with matching name in the source
+# archive.
+# The destination archive is updated in a way not to overwrite existing files
+# with matching names.
+#
+#Examples:
+# cmake -DCMAKE_AR=iarchive -DDESTINATION=new_lib.a -DSOURCE=/foo/bar/old_lib.a -P ./IARArMerge.cmake
+#
+#Parameters:
+# SOURCE - archive file to copy all members from
+# DESTINATION - archive file to copy members to. If file exists, then new
+# members are added without overwriting existing ones.
+# CMAKE_AR - GNU AR executable
+#
+
+#Execute AR and capture its output
+#
+# Script execution will stop with a fatal error if AR execution fails.
+#
+#Examples:
+# List content of archive:
+# run_ar(RESULT t /foo/bar/my_lib.a)
+# Add object file to archive
+# run_ar(RESULT q /foo/bar/my_lib.a new_obj.o)
+#
+#INPUTS:
+# RESULT - (mandatory) - name of variable to put result in
+# All remaining parameters will be command line options to AR
+#
+#OUTPUTS
+# RESULT - text output of AR command
+#
+function(run_ar OUTPUT )
+ execute_process(COMMAND ${CMAKE_AR} ${ARGN}
+ TIMEOUT 120
+ OUTPUT_VARIABLE _RES
+ RESULT_VARIABLE _STATUS_CODE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if (STATUS_CODE GREATER 0)
+ message(FATAL_ERROR "ERROR: Failed to execute \"${CMAKE_AR} ${ARGN}\".")
+ endif()
+ set(${OUTPUT} ${_RES} PARENT_SCOPE)
+endfunction()
+
+#Delete a file
+#
+# Function to delete a file. No error will be reported if file is missing.
+# Script execution will stop with a fatal error if AR execution fails.
+#
+#Examples:
+# rm(/foo/bar/my_lib.a)
+#
+#INPUTS:
+# FILE - path to file to delete
+#
+#OUTPUTS
+# N/A
+#
+function(rm FILE)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${FILE}
+ RESULT_VARIABLE _STATUS_CODE
+ TIMEOUT 120)
+ if (STATUS_CODE GREATER 0)
+ message(FATAL_ERROR "ERROR: Failed to execute \"${CMAKE_COMMAND} -E remove ${FILE}\".")
+ endif()
+endfunction()
+
+
+#############################################################################
+# Entry point
+#############################################################################
+#Verify input variables.
+
+if(NOT DEFINED SOURCE)
+ message(FATAL_ERROR "GNUArMerge.cmake: Variable SOURCE is not defined.")
+endif()
+
+if(NOT DEFINED DESTINATION)
+ message(FATAL_ERROR "GNUArMerge.cmake: Variable DESTINATION is not defined.")
+endif()
+
+if(NOT DEFINED CMAKE_AR)
+ message(FATAL_ERROR "GNUArMerge.cmake: Variable CMAKE_AR is not defined.")
+endif()
+
+
+#Get list of archive members
+run_ar("OBJ_LIST" -t ${SOURCE})
+
+#Convert AR output to cmake list
+string(REPLACE "\n" ";" OBJ_LIST ${OBJ_LIST})
+
+#Iterate over member list.
+foreach(OBJ ${OBJ_LIST})
+ #Extract member
+ run_ar("_DUMMY" -x ${SOURCE} ${OBJ})
+ #Add member to destination archive
+ run_ar("_DUMMY" -r ${DESTINATION} ${OBJ})
+ #Remove extracted member
+ rm("${OBJ}")
+endforeach()
diff --git a/cmake/Compiler/IARARM-ASM.cmake b/cmake/Compiler/IARARM-ASM.cmake
new file mode 100644
index 000000000..e13b88153
--- /dev/null
+++ b/cmake/Compiler/IARARM-ASM.cmake
@@ -0,0 +1,11 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include(Compiler/IARARM)
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm)
+__compiler_iararm(ASM)
+
diff --git a/cmake/Compiler/IARARM-C.cmake b/cmake/Compiler/IARARM-C.cmake
new file mode 100644
index 000000000..bde93f972
--- /dev/null
+++ b/cmake/Compiler/IARARM-C.cmake
@@ -0,0 +1,9 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include(Compiler/IARARM)
+__compiler_iararm(C)
diff --git a/cmake/Compiler/IARARM-CXX.cmake b/cmake/Compiler/IARARM-CXX.cmake
new file mode 100644
index 000000000..04ab85c73
--- /dev/null
+++ b/cmake/Compiler/IARARM-CXX.cmake
@@ -0,0 +1,9 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include(Compiler/IARARM)
+__compiler_iararm(CXX)
diff --git a/cmake/Compiler/IARARM.cmake b/cmake/Compiler/IARARM.cmake
new file mode 100644
index 000000000..5bb2a37c2
--- /dev/null
+++ b/cmake/Compiler/IARARM.cmake
@@ -0,0 +1,55 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+if(_IARARM_CMAKE_LOADED_TFM)
+ return()
+endif()
+set(_IARARM_CMAKE_LOADED_TFM TRUE)
+
+get_filename_component(_CMAKE_C_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
+get_filename_component(_CMAKE_CXX_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
+
+set(CMAKE_EXECUTABLE_SUFFIX ".axf")
+
+find_program(CMAKE_IARARM_LINKER ilinkarm HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
+find_program(CMAKE_IARARM_AR iarchive HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
+find_program(CMAKE_IARARM_IELFTOOL ielftool HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
+
+set(CMAKE_LINKER "${CMAKE_IARARM_LINKER}" CACHE FILEPATH "The IAR linker" FORCE)
+mark_as_advanced(CMAKE_IARARM_LINKER)
+set(CMAKE_AR "${CMAKE_IARARM_AR}" CACHE FILEPATH "The IAR archiver" FORCE)
+mark_as_advanced(CMAKE_IARARM_AR)
+
+macro(__compiler_iararm lang)
+ if(NOT CMAKE_${lang}_FLAGS_SET)
+ set(CMAKE_${lang}_FLAGS_SET TRUE)
+ set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ")
+ string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
+
+ if (NOT ${lang} STREQUAL "ASM")
+ string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " --debug -On")
+ string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Ohz -DNDEBUG")
+ string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -Ohs -DNDEBUG")
+ string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -Ohs --debug")
+ endif()
+
+ set(CMAKE_${lang}_OUTPUT_EXTENSION ".o")
+ set(CMAKE_${lang}_OUTPUT_EXTENSION_REPLACE 1)
+ set(CMAKE_STATIC_LIBRARY_PREFIX_${lang} "")
+ set(CMAKE_STATIC_LIBRARY_SUFFIX_${lang} ".a")
+
+ set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+ set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ")
+
+ set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> --map <TARGET_BASE>.map")
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> --create <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> --preprocess=n <PREPROCESSED_SOURCE> <SOURCE> ")
+ set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE> -la <ASSEMBLY_SOURCE>")
+
+ set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ins <DEPFILE>")
+ endif()
+endmacro()