Home > Enterprise >  WIN32 and UNIX don't change in CMake cross-compile
WIN32 and UNIX don't change in CMake cross-compile

Time:03-27

I made a test CMakeLists.txt. I set system name and version before reading variables (although I didn't set the compiler):

cmake_minimum_required(VERSION 3.10)

project(test)

include_directories(.)

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_VERSION 10.0.10240.0)

add_executable(test test.c)

target_link_libraries(test)

message("cmake system name = ${CMAKE_SYSTEM_NAME}")
message("cmake host name = ${CMAKE_HOST_SYSTEM_NAME}")
message("cmake system version = ${CMAKE_SYSTEM_VERSION}")
message("unix = ${UNIX}")
message("win32 = ${WIN32}")

Here is the output from "cmake ." on the terminal:

-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c   - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
cmake system name = Windows
cmake host name = Linux
cmake system version = 10.0.10240.0
unix = 1
win32 = 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/francisco/Documents

The CMake documentation says UNIX and WIN32 are set to the target OS. Here I set the target OS and yet they remain set to the host OS. Why?

CodePudding user response:

You're not supposed to write CMAKE_SYSTEM_NAME after the first project() command is encountered by CMake. At the first project command the choices of compiler and target system are made and you cannot change the effects of this later. As you have seen you can overwrite the value of CMAKE_SYSTEM_NAME, but the only effect of doing this are that you and any external cmake logic that may be invoked (e.g. scripts executed when using find_package) see a value that is wrong (i.e. not matching the choice of compiler).

For setting this kind of information your CMakeLists.txt files are the wrong place. This kind of info belongs into a toolchain file alongside your choice of compiler that actually produces binaries for the target platform:

toolchain-windows.cmake

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_VERSION 10.0.10240.0)

set(CMAKE_C_COMPILER <command/absolute path to executable to use as C compiler goes here>)
set(CMAKE_CXX_COMPILER <command/absolute path to executable to use as C   compiler goes here>)

...

Configure the project using something like

cmake --toolchain path/to/toolchain-windows.cmake -S path/to/source -B path/to/build/dir

Note: The default compiler on your linux almost certainly won't be able cross compile for windows targets.

  • Related