# Using CMAKE\_CROSSCOMPILING evaluates to FALSE after -DCMAKE\_CROSSCOMPILING=ON

**URL:** https://discourse.cmake.org/t/using-cmake-crosscompiling-evaluates-to-false-after-dcmake-crosscompiling-on/4911
**Category:** Usage
**Tags:** os:linux
**Created:** [January 26, 2022, 7:51pm UTC](https://discourse.cmake.org/t/using-cmake-crosscompiling-evaluates-to-false-after-dcmake-crosscompiling-on/4911 "2022-01-26T19:51:01Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![agostini01](https://discourse.cmake.org/user_avatar/discourse.cmake.org/agostini01/32/2131_2.png) [@agostini01](https://discourse.cmake.org/u/agostini01)
#### Post date: [January 26, 2022, 7:51pm UTC](https://discourse.cmake.org/t/using-cmake-crosscompiling-evaluates-to-false-after-dcmake-crosscompiling-on/4911/1 "2022-01-26T19:51:01Z")

</div>

Hi, I am scratching my head trying to find out why checks with `if(CMAKE_CROSSCOMPILING)` return false (running cmake version 3.18.2).

I am trying to cross compile pieces of the llvm-project with the following command-line in clean build folders:

```auto
cmake -GNinja \
  "-H$LLVM_SRC_DIR/llvm" \
  "-B$build_dir$suffix" \
  -DCMAKE_INSTALL_PREFIX=$install_dir$suffix \
  -DMLIR_TABLEGEN=$mlir_tablegen \
  -DLLVM_INSTALL_UTILS=OFF \
  -DLLVM_ENABLE_LLD=OFF \
  -DLLVM_ENABLE_PROJECTS="mlir" \
  -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc-7 \
  -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++-7 \
  -DCMAKE_CXX_FLAGS='-fcompare-debug-second' \
  -DCMAKE_CROSSCOMPILING:BOOL=ON \
  -DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabihf \
  -DLLVM_TARGET_ARCH=ARM \
  -DLLVM_TARGETS_TO_BUILD=ARM \
  -DLLVM_BUILD_TOOLS=OFF \
  -DLLVM_INCLUDE_TESTS=OFF \
  -DMLIR_INCLUDE_TESTS=OFF \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DLLVM_BUILD_EXAMPLES=OFF

cmake --build "$build_dir$suffix" --target mlir_c_runner_utils mlir_runner_utils

```

Note the ` -DCMAKE_CROSSCOMPILING:BOOL=ON` option. This is correctly shown in CMakeCache.txt:

```auto
$ cat CMakeCache.txt | grep CROSS
CMAKE_CROSSCOMPILING:BOOL=ON

```

But when I try to `message` or test the variable, it evaluates to FALSE

```auto
message (STATUS "!!! CMAKE_CROSSCOMPILING flag value: ${CMAKE_CROSSCOMPILING}")

if(CMAKE_CROSSCOMPILING)
  message (STATUS "!!! Crosscompiling, SystemC api libraries are disabed")
else()
  message (STATUS "!!! Not Crosscompiling, SystemC api libraries are enabled")
  endif()
endif()

```

```auto
[0/1] Re-running CMake...
...
-- Targeting ARM
-- !!! CMAKE_CROSSCOMPILING flag value: FALSE
-- !!! Not Crosscompiling, SystemC api libraries are enabled
...

```

Should I be using a different approach to set and check CMAKE\_CROSSCOMPILING?  
It appears that some internal logic is overriding my variable.

I appreciate any help.

* * *

ps.: I was redirected here from this issue [https://gitlab.kitware.com/cmake/cmake/-/issues/21744](https://gitlab.kitware.com/cmake/cmake/-/issues/21744)  
ps.: Others have pointed similar problems ([cmake - How do I detect that I am cross-compiling in CMakeLists.txt? - Stack Overflow](https://stackoverflow.com/questions/40528254/how-do-i-detect-that-i-am-cross-compiling-in-cmakelists-txt)). Their solution was to change it in CMakeLists.txt file, but I was trying to avoid this approach, favoring the usage of the -DCMAKE\_CROSSCOMPILING option.

---

<div class="post-metadata">

### Author: ![petwu](https://discourse.cmake.org/user_avatar/discourse.cmake.org/petwu/32/1399_2.png) [@petwu](https://discourse.cmake.org/u/petwu)
#### Post date: [January 27, 2022, 11:17am UTC](https://discourse.cmake.org/t/using-cmake-crosscompiling-evaluates-to-false-after-dcmake-crosscompiling-on/4911/2 "2022-01-27T11:17:56Z")

</div>

The reason is, that CMake internally _always_ sets `CMAKE_CROSSCOMPILING` as a normal variable to either `TRUE` or `FALSE`. You set it only as a cache variable but not as a normal one. As per [cmake-language(7)](https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#variables):

> _When evaluating [Variable References](https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#variable-references), CMake first searches the function call stack, if any, for a binding and then falls back to the binding in the current directory scope, if any. If a “set” binding is found, its value is used. If an “unset” binding is found, or no binding is found, CMake then searches for a cache entry. If a cache entry is found, its value is used. Otherwise, the variable reference evaluates to an empty string. The `$CACHE{VAR}` syntax can be used to do direct cache entry lookups._

This means that the normal variable set internally by CMake will shadow your cache variable. You can check, that `${CMAKE_CROSSCOMPILING}` and `$CACHE{CMAKE_CROSSCOMPILING}` should have contradicting values.

The [documentation](https://cmake.org/cmake/help/latest/variable/CMAKE_CROSSCOMPILING.html) states, that the value of `CMAKE_CROSSCOMPILING` depends on whether `CMAKE_SYSTEM_NAME` was explicitly set or not. This is rather unintuitive, but until this behavior gets changed with a new policy as discussed in the [issue](https://gitlab.kitware.com/cmake/cmake/-/issues/21744) you linked, the best approach is to simply set `-DCMAKE_SYSTEM_NAME=...` or set it in a [toolchain file](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling).

If your target system is not supported by CMake (I had this issue e.g. with VxWorks), you can either set it to `Generic` if appropriate (e.g. embedded devices without any OS) or provide a custom platform description file, which must be located at `<CMAKE_MODULE_PATH>/Platform/<CMAKE_SYSTEM_NAME>.cmake`. You can take a look at the ones provided by CMake [here](https://github.com/Kitware/CMake/tree/master/Modules/Platform).

---

<div class="post-metadata">

### Author: ![agostini01](https://discourse.cmake.org/user_avatar/discourse.cmake.org/agostini01/32/2131_2.png) [@agostini01](https://discourse.cmake.org/u/agostini01)
#### Post date: [February 1, 2022, 5:46pm UTC](https://discourse.cmake.org/t/using-cmake-crosscompiling-evaluates-to-false-after-dcmake-crosscompiling-on/4911/3 "2022-02-01T17:46:37Z")

</div>

Thank you for the explanation and links. The toolchain file approach addressed my problem.
