Просмотр исходного кода

IAR: Improve support for IAR ARM Compiler

Make the implementation for this compiler more complete.

IAR has multiple C++ modes, historically they were reduced c++ versions
for embedded that gradually improved to the full standard (which can be
reduced again by e.g. disabling rtti and exceptions).  The new
implementation picks the best available, but the c++ mode can also be
overridden by defining `CMAKE_IAR_CXX_FLAG`.

Add C/C++ standard flags so that all modes up to and including the last
supported standard are defined.

Fixes: #16826
Norbert Lange 8 лет назад
Родитель
Сommit
d8e6cd9ed8

+ 4 - 0
Help/release/dev/iar.rst

@@ -0,0 +1,4 @@
+iar
+---
+
+* Support for the IAR ARM Compiler was improved.

+ 1 - 0
Help/variable/CMAKE_LANG_COMPILER_ID.rst

@@ -20,6 +20,7 @@ include:
   G95 = G95 Fortran (g95.org)
   GNU = GNU Compiler Collection (gcc.gnu.org)
   HP = Hewlett-Packard Compiler (hp.com)
+  IAR = IAR Systems (iar.com)
   Intel = Intel Compiler (intel.com)
   MIPSpro = SGI MIPSpro (sgi.com)
   MSVC = Microsoft Visual Studio (microsoft.com)

+ 18 - 0
Modules/CMakeDetermineASMCompiler.cmake

@@ -103,8 +103,23 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
   include(CMakeDetermineCompilerId)
   set(userflags)
   CMAKE_DETERMINE_COMPILER_ID_VENDOR(ASM${ASM_DIALECT} "${userflags}")
+  if("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}" STREQUAL "IAR")
+    # primary necessary to detect architecture, so the right archiver and linker can be picked
+    # eg. IAR Assembler V8.10.1.12857/W32 for ARM
+    # Cut out identification first, newline handling is a pain
+    string(REGEX MATCH "IAR Assembler[^\r\n]*" _compileid "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT}")
+    if("${_compileid}" MATCHES "V([0-9]+\\.[0-9]+\\.[0-9]+)")
+      set(CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION ${CMAKE_MATCH_1})
+    endif()
+    if("${_compileid}" MATCHES "for[ ]+([A-Za-z0-9]+)")
+      set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_MATCH_1})
+    endif()
+  endif()
+  unset(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT)
+  unset(_compileid)
 endif()
 
+
 if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
   if(CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION)
     set(_version " ${CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION}")
@@ -149,6 +164,9 @@ endif ()
 
 
 include(CMakeFindBinUtils)
+set(_CMAKE_PROCESSING_LANGUAGE "ASM")
+include(Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-FindBinUtils OPTIONAL)
+unset(_CMAKE_PROCESSING_LANGUAGE)
 
 set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ENV_VAR "ASM${ASM_DIALECT}")
 

+ 3 - 0
Modules/CMakeDetermineCXXCompiler.cmake

@@ -73,6 +73,9 @@ else()
   set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS
     # Try compiling to an object file only.
     "-c"
+    # IAR does not detect language automatically
+    "--c++"
+    "--ec++"
     )
 endif()
 

+ 1 - 0
Modules/CMakeDetermineCompilerId.cmake

@@ -678,6 +678,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
         "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
         "matched \"${regex}\":\n${output}")
       set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
+      set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE)
       break()
     else()
       if("${result}" MATCHES  "timeout")

+ 10 - 0
Modules/CMakePlatformId.h.in

@@ -144,6 +144,16 @@
 #  define ARCHITECTURE_ID ""
 # endif
 
+#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+# if defined(__ICCARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__ICCAVR__)
+#  define ARCHITECTURE_ID "AVR"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
 #else
 #  define ARCHITECTURE_ID
 #endif

+ 12 - 5
Modules/Compiler/IAR-ASM.cmake

@@ -2,13 +2,20 @@
 
 include(Compiler/IAR)
 
-set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
-
-if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
+if("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM")
+set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+  __compiler_iar_ARM(ASM)
   set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
-endif()
 
+  string(APPEND CMAKE_ASM_FLAGS_INIT " ")
+  string(APPEND CMAKE_ASM_FLAGS_DEBUG_INIT " -r")
+  string(APPEND CMAKE_ASM_FLAGS_MINSIZEREL_INIT " -DNDEBUG")
+  string(APPEND CMAKE_ASM_FLAGS_RELEASE_INIT " -DNDEBUG")
+  string(APPEND CMAKE_ASM_FLAGS_RELWITHDEBINFO_INIT " -r -DNDEBUG")
 
-if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR")
+elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
+  set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+  __compiler_iar_AVR(ASM)
   set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s90;asm;msa)
+
 endif()

+ 23 - 20
Modules/Compiler/IAR-C.cmake

@@ -1,25 +1,29 @@
 # This file is processed when the IAR compiler is used for a C file
 
-
 include(Compiler/IAR)
-
-set(CMAKE_C_COMPILE_OBJECT             "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE     "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
-
-set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "-f ")
-set(CMAKE_DEPFILE_FLAGS_C "--dependencies=ns <DEPFILE>")
+include(Compiler/CMakeCommonCompilerMacros)
 
 # The toolchains for ARM and AVR are quite different:
-if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
-
-  set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
-  set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS> ")
-
-endif()
+if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM")
+  set(CMAKE_C90_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_C90_EXTENSION_COMPILE_OPTION -e)
+
+  if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.10)
+    set(CMAKE_C90_STANDARD_COMPILE_OPTION --c89)
+    set(CMAKE_C90_EXTENSION_COMPILE_OPTION --c89 -e)
+    set(CMAKE_C99_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_C99_EXTENSION_COMPILE_OPTION -e)
+  endif()
+  if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.10)
+    set(CMAKE_C11_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_C11_EXTENSION_COMPILE_OPTION -e)
+  endif()
 
+  __compiler_iar_ARM(C)
+  __compiler_check_default_language_standard(C 1.10 90 6.10 99 8.10 11)
 
-if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR")
+elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
+  __compiler_iar_AVR(C)
   set(CMAKE_C_OUTPUT_EXTENSION ".r90")
 
   if(NOT CMAKE_C_LINK_FLAGS)
@@ -29,9 +33,8 @@ if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR")
   set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
   set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> -o <TARGET> <OBJECTS> ")
 
+  # add the target specific include directory:
+  get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH)
+  get_filename_component(_compilerDir "${_compilerDir}" PATH)
+  include_directories("${_compilerDir}/inc" )
 endif()
-
-# add the target specific include directory:
-get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH)
-get_filename_component(_compilerDir "${_compilerDir}" PATH)
-include_directories("${_compilerDir}/inc" )

+ 33 - 19
Modules/Compiler/IAR-CXX.cmake

@@ -1,24 +1,39 @@
 # This file is processed when the IAR compiler is used for a C++ file
 
 include(Compiler/IAR)
+include(Compiler/CMakeCommonCompilerMacros)
+
+if("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM")
+  # "(extended) embedded C++" Mode
+  # old version: --ec++ or --eec++
+  # since 8.10:  --c++ --no_exceptions --no_rtti
+  #
+  # --c++ is full C++ and supported since 6.10
+  if(NOT CMAKE_IAR_CXX_FLAG)
+    if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.10)
+      set(CMAKE_IAR_CXX_FLAG --c++)
+    else()
+      set(CMAKE_IAR_CXX_FLAG --eec++)
+    endif()
+  endif()
 
-set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
-
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE     "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
-
-set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "-f ")
-set(CMAKE_DEPFILE_FLAGS_CXX "--dependencies=ns <DEPFILE>")
-
-if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
+  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION -e)
 
-  set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
-  set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS> ")
-
-endif()
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.10)
+  set(CMAKE_CXX03_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_CXX03_EXTENSION_COMPILE_OPTION -e)
+  set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION -e)
+  set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION -e)
+  endif()
 
+  __compiler_iar_ARM(CXX)
+  __compiler_check_default_language_standard(CXX 6.10 98 8.10 14)
 
-if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR")
+elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
+  __compiler_iar_AVR(CXX)
   set(CMAKE_CXX_OUTPUT_EXTENSION ".r90")
   if(NOT CMAKE_CXX_LINK_FLAGS)
     set(CMAKE_CXX_LINK_FLAGS "-Fmotorola")
@@ -27,9 +42,8 @@ if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR")
   set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
   set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> -o <TARGET> <OBJECTS> ")
 
+  # add the target specific include directory:
+  get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH)
+  get_filename_component(_compilerDir "${_compilerDir}" PATH)
+  include_directories("${_compilerDir}/inc")
 endif()
-
-# add the target specific include directory:
-get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH)
-get_filename_component(_compilerDir "${_compilerDir}" PATH)
-include_directories("${_compilerDir}/inc")

+ 16 - 2
Modules/Compiler/IAR-DetermineCompiler.cmake

@@ -1,4 +1,18 @@
-
 # IAR Systems compiler for embedded systems.
 #   http://www.iar.com
-set(_compiler_id_pp_test "defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)")
+#   http://supp.iar.com/FilesPublic/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf
+#
+# __IAR_SYSTEMS_ICC__ An integer that identifies the IAR compiler platform. The current value is 8. Note that
+#                     the number could be higher in a future version of the product
+# __ICCARM__          An integer that is set to 1 when the code is compiled with the IAR C/C++ Compiler for ARM
+# __VER__             An integer that identifies the version number of the IAR compiler in use. For example,
+#                     version 5.11.3 is returned as 5011003.
+
+set(_compiler_id_pp_test "defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)")
+
+set(_compiler_id_version_compute "
+# if defined(__VER__)
+#  define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@((__VER__) / 1000000)
+#  define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(((__VER__) / 1000) % 1000)
+#  define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@((__VER__) % 1000)
+# endif")

+ 54 - 0
Modules/Compiler/IAR-FindBinUtils.cmake

@@ -0,0 +1,54 @@
+if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
+  message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
+endif()
+
+# Try to find tools in the same directory as Clang itself
+get_filename_component(__iar_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" REALPATH)
+get_filename_component(__iar_hint_1 "${__iar_hint_1}" DIRECTORY)
+
+get_filename_component(__iar_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+
+set(__iar_hints "${__iar_hint_1}" "${__iar_hint_2}")
+
+if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM")
+  # could allow using normal binutils ar, since objects are normal ELF files?
+  find_program(CMAKE_IAR_LINKARM ilinkarm.exe HINTS ${__iar_hints}
+      DOC "The IAR ARM linker")
+  find_program(CMAKE_IAR_ARCHIVE iarchive.exe HINTS ${__iar_hints}
+      DOC "The IAR archiver")
+
+  # find auxillary tools
+  find_program(CMAKE_IAR_ELFTOOL ielftool.exe HINTS ${__iar_hints}
+      DOC "The IAR ELF Tool")
+    find_program(CMAKE_IAR_ELFDUMP ielfdumparm.exe HINTS ${__iar_hints}
+      DOC "The IAR ELF Dumper")
+  find_program(CMAKE_IAR_OBJMANIP iobjmanip.exe HINTS ${__iar_hints}
+      DOC "The IAR ELF Object Tool")
+  find_program(CMAKE_IAR_SYMEXPORT isymexport.exe HINTS ${__iar_hints}
+      DOC "The IAR Absolute Symbol Exporter")
+  mark_as_advanced(CMAKE_IAR_LINKARM CMAKE_IAR_ARCHIVE CMAKE_IAR_ELFTOOL CMAKE_IAR_ELFDUMP CMAKE_IAR_OBJMANIP CMAKE_IAR_SYMEXPORT)
+
+  set(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CUSTOM_CODE
+"set(CMAKE_IAR_LINKARM \"${CMAKE_IAR_LINKARM}\")
+set(CMAKE_IAR_ARCHIVE \"${CMAKE_IAR_ARCHIVE}\")
+set(CMAKE_IAR_ELFTOOL \"${CMAKE_IAR_ELFTOOL}\")
+set(CMAKE_IAR_ELFDUMP \"${CMAKE_IAR_ELFDUMP}\")
+set(CMAKE_IAR_OBJMANIP \"${CMAKE_IAR_OBJMANIP}\")
+set(CMAKE_IAR_LINKARM \"${CMAKE_IAR_LINKARM}\")
+")
+
+
+elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
+
+  # For AVR and AVR32, IAR uses the "xlink" linker and the "xar" archiver:
+  find_program(CMAKE_IAR_LINKER xlink.exe HINTS ${__iar_hints}
+      DOC "The IAR AVR linker")
+  find_program(CMAKE_IAR_AR xar.exe HINTS ${__iar_hints}
+      DOC "The IAR archiver")
+  mark_as_advanced(CMAKE_IAR_LINKER CMAKE_IAR_AR)
+
+  set(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CUSTOM_CODE
+"set(CMAKE_IAR_LINKER \"${CMAKE_IAR_LINKER}\")
+set(CMAKE_IAR_AR \"${CMAKE_IAR_AR}\")
+")
+endif()

+ 58 - 29
Modules/Compiler/IAR.cmake

@@ -2,46 +2,75 @@
 # Documentation can be downloaded here: http://www.iar.com/website1/1.0.1.0/675/1/
 # The initial feature request is here: https://gitlab.kitware.com/cmake/cmake/issues/10176
 # It also contains additional links and information.
+# See USER GUIDES -> C/C++ Development Guide and ReleaseNotes for:
+# version 6.30.8: http://supp.iar.com/FilesPublic/UPDINFO/006607/arm/doc/infocenter/index.ENU.html
+# version 7.60.1: http://supp.iar.com/FilesPublic/UPDINFO/011006/arm/doc/infocenter/index.ENU.html
+# version 8.10.1: http://netstorage.iar.com/SuppDB/Public/UPDINFO/011854/arm/doc/infocenter/index.ENU.html
 
-if(_IAR_CMAKE_LOADED)
+# C/C++ Standard versions
+#
+# IAR typically only supports one C and C++ Standard version,
+# the exception is C89 which is always supported and can be selected
+# if its not the default
+#
+# C++ is trickier, there were historically 3 switches,
+# and some IAR versions support multiple of those.
+# they are --eec++, --ec++ and --c++ and where used to
+# enable various language features like exceptions
+#
+# recent versions only have --c++ for full support
+# but can choose to disable features with further arguments
+#
+# C/C++ Standard compliance
+#
+# IAR has 3 modes: default, strict and extended
+# the extended mode is needed for popular libraries like CMSIS
+#
+# "Silent" Operation
+#
+# this really is different to most programs I know.
+# nothing meaningfull from the operation is lost, just some redundant
+# code and data size printouts (that can be inspected with common tools).
+
+# This module is shared by multiple languages; use include blocker.
+if(_IARARM_CMAKE_LOADED)
   return()
 endif()
-set(_IAR_CMAKE_LOADED TRUE)
+set(_IARARM_CMAKE_LOADED 1)
 
+macro(__compiler_iar_ARM lang)
+  set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+  if (${lang} STREQUAL "C" OR ${lang} STREQUAL "CXX")
 
-get_filename_component(_CMAKE_C_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
-get_filename_component(_CMAKE_CXX_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
-get_filename_component(_CMAKE_ASM_TOOLCHAIN_LOCATION "${CMAKE_ASM_COMPILER}" PATH)
+    set(CMAKE_${lang}_COMPILE_OBJECT             "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+    set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
+    set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE     "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
 
+    set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ")
+    set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEPFILE>")
 
-if("${CMAKE_C_COMPILER}" MATCHES "arm"  OR  "${CMAKE_CXX_COMPILER}" MATCHES "arm"  OR  "${CMAKE_ASM_COMPILER}" MATCHES "arm")
-  set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+    string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
+    string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -r")
+    string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Ohz -DNDEBUG")
+    string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -Oh -DNDEBUG")
+    string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -Oh -r -DNDEBUG")
+  endif()
 
-  # For arm, IAR uses the "ilinkarm" linker and "iarchive" archiver:
-  find_program(CMAKE_IAR_LINKER ilinkarm HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}")
-  find_program(CMAKE_IAR_AR iarchive HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}" )
+  set(CMAKE_${lang}_LINK_EXECUTABLE "\"${CMAKE_IAR_LINKARM}\" --silent <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
+  set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "\"${CMAKE_IAR_ARCHIVE}\" <TARGET> --create <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_CREATE "\"${CMAKE_IAR_ARCHIVE}\" <TARGET> --create <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_APPEND "\"${CMAKE_IAR_ARCHIVE}\" <TARGET> --replace <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_FINISH "")
 
-  set(IAR_TARGET_ARCHITECTURE "ARM" CACHE STRING "IAR compiler target architecture")
-endif()
+  set(CMAKE_LINKER "${CMAKE_IAR_LINKARM}" CACHE FILEPATH "The IAR linker" FORCE)
+  set(CMAKE_AR "${CMAKE_IAR_ARCHIVE}" CACHE FILEPATH "The IAR archiver" FORCE)
+endmacro()
 
-if("${CMAKE_C_COMPILER}" MATCHES "avr"  OR  "${CMAKE_CXX_COMPILER}" MATCHES "avr"  OR  "${CMAKE_ASM_COMPILER}" MATCHES "avr")
+macro(__compiler_iar_AVR lang)
   set(CMAKE_EXECUTABLE_SUFFIX ".bin")
 
-  # For AVR and AVR32, IAR uses the "xlink" linker and the "xar" archiver:
-  find_program(CMAKE_IAR_LINKER xlink HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}" )
-  find_program(CMAKE_IAR_AR xar HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}" )
-
-  set(IAR_TARGET_ARCHITECTURE "AVR" CACHE STRING "IAR compiler target architecture")
-
   set(CMAKE_LIBRARY_PATH_FLAG "-I")
 
-endif()
-
-if(NOT IAR_TARGET_ARCHITECTURE)
-  message(FATAL_ERROR "The IAR compiler for this architecture is not yet supported "
-          "by CMake. Please go to https://gitlab.kitware.com/cmake/cmake/issues "
-          "and enter a feature request there.")
-endif()
-
-set(CMAKE_LINKER "${CMAKE_IAR_LINKER}" CACHE FILEPATH "The IAR linker" FORCE)
-set(CMAKE_AR "${CMAKE_IAR_AR}" CACHE FILEPATH "The IAR archiver" FORCE)
+  set(CMAKE_LINKER "${CMAKE_IAR_LINKER}" CACHE FILEPATH "The IAR linker" FORCE)
+  set(CMAKE_AR "${CMAKE_IAR_AR}" CACHE FILEPATH "The IAR archiver" FORCE)
+endmacro()