7

The CMake documentation suggests that CMAKE_CROSSCOMPILING is set when cross-compiling. In my CMakeLists.txt I have the lines:

IF(CMAKE_CROSSCOMPILING)
    message(STATUS "Cross-compiling so skipping unit tests.")
    option(GAME_PORTAL_UNIT_TEST "Enable unit testing of Game Portal code" OFF)
ELSE()
    message(STATUS "Enabling unit testing of Game Portal code")
    option(GAME_PORTAL_UNIT_TEST "Enable unit testing of Game Portal code" ON)
ENDIF()

The output from running:

cmake -DCMAKE_TOOLCHAIN_FILE=../crosscompile/raspberry_pi/CMakeCross.txt .

Includes the text "Enabling unit testing of Game Portal code", so clearly this variable is not being set, or not so it evaluates to true anyway.

I tried modifying CMakeCross.txt to include:

set(CMAKE_CROSSCOMPILING ON CACHE BOOL "Cross-compiling" FORCE)

and after cleaning the old CMakeCache.txt and rerunning my cmake command I can see that the new CMakeCache.txt now includes this variable, but I still get the same result as previously with regards to the unit tests being enabled.

How can I reliably detect that I am cross-compiling so I can properly disable the unit tests?

As requested, the full cross-compile file is:

# Set minimum cmake version required for cross-compiling to work.
cmake_minimum_required(VERSION 2.6)
# Build with rm CMakeCache.txt; cmake -DCMAKE_TOOLCHAIN_FILE=/home/crosscompile/dev/raspberry_pi/CMakeCross.txt .. 

# Set target system name.
SET (CMAKE_SYSTEM_NAME Linux)

# Set compiler name.
SET (CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
SET (CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)

# Set path(s) to search for libraries/binaries/headers.
SET (CMAKE_FIND_ROOT_PATH /home/crosscompile/dev/raspberry_pi/rootfs/)

# Ensure only cross-compiler directories are searched.
SET (ONLY_CMAKE_FIND_ROOT_PATH TRUE)

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# Set output/install directory to safe place.
SET (CMAKE_INSTALL_PREFIX /home/crosscompile/dev/raspberry_pi/install/)

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rpath-link=/lib/arm-linux-gnueabihf")
set(THREADS_PTHREAD_ARG 0)
set(CMAKE_CROSSCOMPILING ON CACHE BOOL "Cross-compiling" FORCE)
AlastairG
  • 4,119
  • 5
  • 26
  • 41
  • from what I saw is you have to set this variable to true in your toolchain file. Example: http://stackoverflow.com/questions/6476203/how-can-i-make-cmake-use-specific-compiler-and-flags-when-final-compilation-stag – Hayt Nov 10 '16 at 13:02
  • 1
    @Hayt: No, it should be sufficient to set variable `CMAKE_SYSTEM_NAME` in the toolchain file. After that, variable `CMAKE_CROSSCOMPILING` should be set automatically. For author: Show the toolchain file itself. – Tsyvarev Nov 10 '16 at 13:08
  • @Tsyvarev ah ok good to know :) – Hayt Nov 10 '16 at 13:11
  • Added cross-compile file as requested. I tried setting the CMAKE_SYSTEM_NAME to "arm-linux-gnueabihf" as Linux is a bit generic and I am compiling on Linux, but it made no difference. – AlastairG Nov 10 '16 at 13:16

4 Answers4

7

The test for CMAKE_CROSSCOMPILING must come after the "project" instruction in CMakeLists.txt.

AlastairG
  • 4,119
  • 5
  • 26
  • 41
1

With in-source builds, one need to manually cleanup build files when change configuration parameters a lot.

E.g., if you did native build before, and then decide to cross-compile, you need to perform manual cleanup: CMake cannot automatically adjust build directory from one build type to another.

This is one of the reasons why in-source builds are not recommended and should be replaced with out-of-source builds.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • It's a clean repo. I haven't done a native build at all. Moreover I have been periodically cleaning up all the CMake generated files. – AlastairG Nov 10 '16 at 13:26
  • I just did the following after deleting all the CMake generated files: mkdir build cd build cmake -DCMAKE_TOOLCHAIN_FILE=../..//crosscompile/raspberry_pi/CMakeCross.txt .. – AlastairG Nov 10 '16 at 13:29
  • I may wrong, but `CMakeCache.txt` is not the only file which is needed to be cleaned for switch to cross-compile. And if your source directory is not clean (from previous builds), then you cannot perform out-of-source builds. Actually, I cannot imaging other reasons, why setting `CMAKE_SYSTEM_NAME` in toolchain file doesn't cause `CMAKE_CROSSCOMPILING` to be set. – Tsyvarev Nov 10 '16 at 13:38
  • I did a "find" comand to find all instances and piped the output to "rm -rf". I did this for CMakeCache.txt, CMakeFiles, and cmake_install.cmake. Anyway, since I was running the command in a "build" subdirectory it is superfluous. – AlastairG Nov 10 '16 at 13:48
0

This is working in my example:

  • CMakeLists.txt
    cmake_minimum_required(VERSION 3.0)
    project(STM32F4Examples C)    

    set(CMAKE_CROSSCOMPILE OFF CACHE BOOL "is crosscompiled")
    message(STATUS "CMAKE_CROSSCOMPILE ${CMAKE_CROSSCOMPILE}")
  • CMakeToolChain_STM32F4.txt
    # cmake toolchain
    # Use this file with cmake -DCMAKE_TOOLCHAIN_FILE=[PATH/TO/This/FILE] PATH/TO/SOURCES

    set(CMAKE_CROSSCOMPILE ON CACHE BOOL "is crosscompiled" FORCE)

Th. Thielemann
  • 2,592
  • 1
  • 23
  • 38
0

This cmake -DCMAKE_TOOLCHAIN_FILE=.. command will set CMAKE_TOOLCHAIN_FILE.
Check cross compiling with following:

if (CMAKE_TOOLCHAIN_FILE)
    # This is in cross compiling condition.
    set(PROJECT_OUT_NAME ${PROJECT_NAME}.elf)
else ()
    set(PROJECT_OUT_NAME ${PROJECT_NAME})
endif()
add_executable(${PROJECT_OUT_NAME} "main.cpp")
Hill
  • 3,391
  • 3
  • 24
  • 28