# Possible bugs with armclang toolchain

**URL:** https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168
**Category:** Usage
**Created:** [November 8, 2019, 8:11am UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168 "2019-11-08T08:11:33Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![oscarh](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/aca169/32.png) [@oscarh](https://discourse.cmake.org/u/oscarh)
#### Post date: [November 8, 2019, 8:11am UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/1 "2019-11-08T08:11:33Z")

</div>

I have a project to cross compile firmware for ARM Cortex A53 platform. At the very beginning of my CMakeLists.txt, I defined armclang toolchain by:

> cmake\_minimum\_required(VERSION 3.10)
> 
> set(CMAKE\_SYSTEM\_NAME Generic)  
> set(CMAKE\_SYSTEM\_PROCESSOR cortex-a53)  
> set(CMAKE\_C\_COMPILER armclang)  
> set(CMAKE\_CXX\_COMPILER armclang)  
> set(CMAKE\_CROSSCOMPILING true)  
> add\_compile\_options(–target=aarch64-arm-none-eabi)

Then when I ran “cmake ”, cmake reported failure on compiler checking:

> The C compiler
> 
> ```
> "/opt/arm/DS-5_v5.29.2/sw/ARMCompiler6.10.1/bin/armclang"
> 
> ```
> 
> is not able to compile a simple test program.
> 
> It fails with the following output:
> 
> ```
> Change Dir: /home/oscarh/data/temp/fooPrj/build/CMakeFiles/CMakeTmp
> 
> Run Build Command(s):/usr/bin/make cmTC_4a0d6/fast && /usr/bin/make -f CMakeFiles/cmTC_4a0d6.dir/build.make CMakeFiles/cmTC_4a0d6.dir/build
> make[1]: Entering directory '/home/oscarh/data/temp/fooPrj/build/CMakeFiles/CMakeTmp'
> Building C object CMakeFiles/cmTC_4a0d6.dir/testCCompiler.o
> /opt/arm/DS-5_v5.29.2/sw/ARMCompiler6.10.1/bin/armclang --target=arm-arm-none-eabi -mcpu=cortex-a53 -o CMakeFiles/cmTC_4a0d6.dir/testCCompiler.o -c /home/oscarh/data/temp/fooPrj/build/CMakeFiles/CMakeTmp/testCCompiler.c
> Linking C executable cmTC_4a0d6.elf
> /opt/cmake-3.16.0-rc3/bin/cmake -E cmake_link_script CMakeFiles/cmTC_4a0d6.dir/link.txt --verbose=1
> /opt/arm/DS-5_v5.29.2/sw/ARMCompiler6.10.1/bin/armlink --cpu=cortex-a53 CMakeFiles/cmTC_4a0d6.dir/testCCompiler.o -o cmTC_4a0d6.elf --list cmTC_4a0d6.map
> Fatal error: L3903U: Argument 'cortex-a53' not permitted for option 'cpu'.
> Finished: 0 information, 0 warning, 0 error and 1 fatal error messages.
> CMakeFiles/cmTC_4a0d6.dir/build.make:86: recipe for target 'cmTC_4a0d6.elf' failed
> 
> ```

I think the problem is, cmake passed ${CMAKE\_SYSTEM\_PROCESSOR} directly to the --cpu option of armlink, which is unfortunately unregonized in this case. Why not use the driver program armclang for linking? In many cases, armlink even cannot have a --cpu option， see this statement from armlink’s documentation:

> You cannot specify targets with Armv8.4-A or later architectures on the armlink command-line. To link  
> for such targets, you must not specify the --cpu option when invoking armlink directly

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 8, 2019, 3:53pm UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/2 "2019-11-08T15:53:03Z")

</div>

Those settings should go in a toolchain file passed via [CMAKE\_TOOLCHAIN\_FILE](https://cmake.org/cmake/help/v3.16/variable/CMAKE_TOOLCHAIN_FILE.html) See also the [cmake-toolchains(7)](https://cmake.org/cmake/help/v3.16/manual/cmake-toolchains.7.html#cross-compiling) manual.

The `aarch64-arm-none-eabi` target can be set via [`CMAKE_{C,CXX}_COMPILER_TARGET`](https://cmake.org/cmake/help/v3.16/variable/CMAKE_LANG_COMPILER_TARGET.html) in the toolchain file.

---

<div class="post-metadata">

### Author: ![oscarh](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/aca169/32.png) [@oscarh](https://discourse.cmake.org/u/oscarh)
#### Post date: [November 11, 2019, 12:18am UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/3 "2019-11-11T00:18:27Z")

</div>

@brad.king，I moved those lines into a separate toochain file, and defined CMAKE\_{C,CXX}\_COMPILER\_TARGET in it, but it does not help. I still see the same error. The compiler checking step can pass if I comment out this line from the file share/cmake-3.16/Modules/Compiler/ARMClang.cmake:

> string(APPEND CMAKE\_${lang}\_LINK\_FLAGS “–cpu=${CMAKE\_SYSTEM\_PROCESSOR}”)

By the way, I didn’t use a toolchain file because I don’t want to type a long command line when invoking cmake command. I thought it was ok to define my toolchain at the beginning of CMakeLists.txt prior to the project() command. Any pitfalls with my approach?

---

<div class="post-metadata">

### Author: ![oscarh](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/aca169/32.png) [@oscarh](https://discourse.cmake.org/u/oscarh)
#### Post date: [November 11, 2019, 1:35am UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/4 "2019-11-11T01:35:19Z")

</div>

> [@oscarh](#):
>
> target=aarch64-arm-none-eabi

It seems there is another problem. When compiling ASM files, cmake does not get the --target option from CMAKE\_ASM\_COMPILER\_TARGET. Consequently, ARMClang complains that --target is not defined.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 11, 2019, 1:32pm UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/5 "2019-11-11T13:32:57Z")

</div>

The toolchain file must be defined separately and used via `CMAKE_TOOLCHAIN_FILE`. Defining the settings at the top of `CMakeLists.txt` is not sufficient because they won’t be included in `try_compile` projects and such.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 11, 2019, 1:33pm UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/6 "2019-11-11T13:33:25Z")

</div>

The `Modules/Compiler/ARMClang.cmake` support is relatively new so it may need to mature a bit. Please open an issue in the [CMake Issue Tracker](https://gitlab.kitware.com/cmake/cmake/issues) to report these problems.

---

<div class="post-metadata">

### Author: ![oscarh](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/aca169/32.png) [@oscarh](https://discourse.cmake.org/u/oscarh)
#### Post date: [November 12, 2019, 1:35am UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/7 "2019-11-12T01:35:15Z")

</div>

Thanks for your promt response, Brad.  
cmake tests the compiler designated by compiling a small c file. Is that done by calling try\_compile? If yes, it seems it does pick up the toolchain defined at the top of CMakeLists.txt. Myself won’d do try\_compile.

Just curious, why does cmake leave some options to command line which must be defined on command line by -D option, such as CMAKE\_TOOLCHAIN\_FILE? Isn’t it more consistent and unified if everything can be done in CMakeLists.txt? Then from command line, I only need to run cmake mySourceDir.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 12, 2019, 3:45pm UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/8 "2019-11-12T15:45:19Z")

</div>

The compiler identification does not use `try_compile` because it is a bootstrapping step that occurs before we have enough information to run a generator for `try_compile`. The compiler id step can see settings from `CMakeLists.txt`, but `try_compile` projects use their own generated temporary `CMakeLists.txt` file that does not see the main one. The toolchain file is included in both.

`CMAKE_TOOLCHAIN_FILE` was designed for the use case in which a project does not always cross-compile with a specific toolchain. Instead the project has generic build rules and the user chooses to cross-compile with a specific toolchain by configuring the project with `-DCMAKE_TOOLCHAIN_FILE=...`.

If you want to hard-code a specific toolchain in `CMakeLists.txt`, try this (untested):

```cmake
cmake_minimum_required(VERSION 3.10)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake" CACHE PATH "")
project(MyProj)

```

If `CMAKE_TOOLCHAIN_FILE` is added to the cache before the first `project()` or `enable_language` call then it should be used without having to specify it on the command line.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 12, 2019, 3:46pm UTC](https://discourse.cmake.org/t/possible-bugs-with-armclang-toolchain/168/9 "2019-11-12T15:46:08Z")

</div>

I see [CMake issue 19962](https://gitlab.kitware.com/cmake/cmake/issues/19962) and [CMake issue 19963](https://gitlab.kitware.com/cmake/cmake/issues/19963), thanks.
