3

I have cmake project which I've successfully set up and used for cross compiling with a toolchain file.

I have a separate variable I want to set in my top level cmake file based on the value of the CMAKE_SYSTEM_PROCESSOR variable that is set in the tool chain file. But when referenced in the top level cmake file, the value of CMAKE_SYSTEM_PROCESSOR does not have the value from the toolchain file.

I can reproduce the conditions with a simple cmake file and one line toolchain file.

If I have the following cmake file:

project(ToolchainTest C)
message("CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}")

and run

cmake .

I get

CMAKE_SYSTEM_PROCESSOR x86_64

as I expect.

With the following one line toolchain file "toolchain.cmake":

set(CMAKE_SYSTEM_PROCESSOR aarch64)

when I run

cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake

I get exactly the same output, x86_64, and not aarch64 as I expected.

I looked over the following related posts, but as I'm just printing the value and not doing a string match (in the example) I don't think they apply.

Can I use CMAKE_SYSTEM_PROCESSOR, defined in a toolchain file, in CMakeLists?

CMake compare to empty string with STREQUAL failed

I'm using cmake version 3.13.4 on Ubuntu 19.04.

M. Krajnak
  • 97
  • 1
  • 9
  • 1
    Have you seen the question and response [here](https://stackoverflow.com/a/41272239/3987854)? The toolchain file is not read until CMake encounters the `project()` command. – Kevin May 19 '20 at 14:32
  • There's a lot of very good information there. I've added a project directive to my sample cmake file base on my initial reading, but it didn't change the outcome. I'll continue to look into the other references cited in that question. – M. Krajnak May 19 '20 at 14:50
  • My previous comment may not be entirely correct, it appears that even without the `project()` command, CMake still gathers the system/compiler information before processing the CMakeLists file (it pretends there is a `project()` command). This is when I imagine the toolchain is first parsed. Your issue may be more subtle, perhaps, a cached vs non-cached variable issue... – Kevin May 19 '20 at 14:56
  • I've tried set(CMAKE_SYSTEM_PROCESSOR aarch64 CACHE STRING "doc") and set(CMAKE_SYSTEM_PROCESSOR aarch64 CACHE STRING "doc" FORCE) with no effect. I'm also trying to make sure I clean out my generated files every time. Maybe worth noting too that -DCMAKE_SYSTEM_PROCESSOR= on the command line also seems to have no effect. – M. Krajnak May 19 '20 at 15:50
  • Is your toolchain ever has an effect? E.g. if you firstly run `cmake .` without toolchain then further `cmake .` would ignore toolchain setting. Until you clear the cache. – Tsyvarev May 19 '20 at 19:22
  • I'm trying to me careful about clearing the cache from the build directory (rm -rf *) before I run the generator. I see an effect in the sense that I've added message command in the toolchain and in the CMakeLists.txt file and I can see them print messages as I expect when I expect. I've also set a user variable ("FOO" in this case) in the toolchain file and I see the effect both in the toolchain and in the CMakeList's file when I print the values using message() – M. Krajnak May 23 '20 at 01:01
  • I'd be interested in knowing if anyone can reproduce the issue with the stripped down file content I posted in the question. – M. Krajnak May 23 '20 at 01:06
  • 1
    @M.Krajnak - I am facing a similar issue. How did you resolve this ? – User1234 May 12 '22 at 16:58

2 Answers2

0

I didn't find a better way than include it. But it should be included by the cmake internally.

cmake_minimum_required(VERSION 3.10)
project(ToolchainTest C)

if(DEFINED CMAKE_TOOLCHAIN_FILE)
    include(${CMAKE_TOOLCHAIN_FILE})
endif()    

This happens because cmake overwrites mentioned variable. Let's debug with --trace parameter

C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake(6):  include(C:/test/toolchain.cmake )
   Called from: [2] C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake
                [1] C:/test/CMakeLists.txt
C:/test/toolchain.cmake(1):  set(CMAKE_SYSTEM_PROCESSOR aarch64 )
   Called from: [3] C:/test/toolchain.cmake
                [2] C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake
                [1] C:/test/CMakeLists.txt
C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake(8):  set(CMAKE_SYSTEM Windows-10.0.19044 )
   Called from: [2] C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake
                [1] C:/test/CMakeLists.txt
C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake(9):  set(CMAKE_SYSTEM_NAME Windows )
   Called from: [2] C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake
                [1] C:/test/CMakeLists.txt
C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake(10):  set(CMAKE_SYSTEM_VERSION 10.0.19044 )
   Called from: [2] C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake
                [1] C:/test/CMakeLists.txt
C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake(11):  set(CMAKE_SYSTEM_PROCESSOR AMD64 )
   Called from: [2] C:/test/build/CMakeFiles/3.19.0-rc2/CMakeSystem.cmake
                [1] C:/test/CMakeLists.txt

So, As you can see CMAKE_SYSTEM_PROCESSOR is set to aarch64 (by toolchain) and then overwritten to AMD64 if somebody knows why would be nice to get it. CMakeSystem.cmake just has a construction like

  • set(CMAKE_HOST_SYSTEM* ...
  • include(toolchain.cmake")
  • set(CMAKE_SYSTEM* ... including CMAKE_SYSTEM_PROCESSOR

How to stop this? Until we have found the answer to this question you can use mentioned workaround at the top of my post.

CMake: In which order are files parsed (cache, toolchain, etc.)?

Dmitry
  • 906
  • 1
  • 13
  • 32
0

I had a similar issue. The answer is that when CMAKE_SYSTEM_NAME is not set, CMake overwrites CMAKE_SYSTEM_PROCESSOR (source code). This is arguably a bug but regardless is how CMake behaves.

The solution is to set both, even if you're compiling for the same system:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
Cyanfish
  • 3,907
  • 1
  • 14
  • 12