Cross-Platform Build Under Windows Targeting Linux Using Cmake

Cross-platform build under Windows targeting Linux using CMake

You will want to look here: cmake-toolchains(7) if you do cross compiling. However, I would suggest that you install a Linux VM like virtual box on your windows machine and build naively on Linux. It will compile much faster and you will not have to worry about cross compiling. You can mount the windows disk from the linux VM so you can share the same source tree. The linux VM will compile much faster than gcc running under windows.

CMake cross compile - separate invocation per platform?

C), separate invocation per platform. I would also recommend clearing the binary directory between builds, or using a separate directory for each build if you want to preserve the build(s).

Settings are usually done in a toolchain file, not the command line (for reproducability):

$ cmake --help-variable CMAKE_TOOLCHAIN_FILE
CMAKE_TOOLCHAIN_FILE
--------------------

Path to toolchain file supplied to ``cmake(1)``.

This variable is specified on the command line when cross-compiling with CMake.
It is the path to a file which is read early in the CMake run and which specifies
locations for compilers and toolchain utilities, and other target platform and
compiler related information.

A simple toolchain file can look like this:

# Name of the target operating system
set( CMAKE_SYSTEM_NAME Windows )

# Which compilers to use
find_program( CMAKE_C_COMPILER NAMES /opt/mxe/usr/bin/x86_64-w64-mingw32.static-gcc )
find_program( CMAKE_CXX_COMPILER NAMES x86_64-w64-mingw32.static-g++ )
find_program( CMAKE_RC_COMPILER NAMES x86_64-w64-mingw32.static-windres )

# Where to look for resources
set( CMAKE_FIND_ROOT_PATH /opt/mxe/usr/x86_64-w64-mingw32.static/ )

# Adjust find_*() behavior:
# Headers and libs from the target environment,
# programs from the host environment.
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )

Some cross-compiling environments, like MXE, come with pre-made toolchain files and wrappers calling them. (MXE in particular, you run i686-w64-mingw32.static-cmake instead of standard cmake to configure your build.)

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

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 Topics



Leave a reply



Submit