5

I have a large codebase with Linux dependencies, and I would like to use CMake to compile my code into an executable that can be run on Windows, i.e. I want CMake to produce an ".exe" file or something of that nature.

I have tried using the solution provided on the CMake website: https://cmake.org/cmake/help/v3.4/manual/cmake-toolchains.7.html#cross-compiling however it has not worked...

Here is my CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(myProject VERSION 1.0 LANGUAGES C CXX)
set(CMAKE_CROSSCOMPILING true)
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_VERSION 10.0)
set(CMAKE_SYSTEM_PROCESSOR arm)
find_package(... *all my required packages* REQUIRED)
include(... *required include files*)
add_executable(${PROJECT_NAME} ...)
target_link_libraries(${PROJECT_NAME} ...)

It compiles and will execute on Linux, however I want it to produce a Windows compatible executable.

Nikolai Long
  • 51
  • 1
  • 4
  • Yes, it is possible to build CMake project on Linux, and use resulted executable on Windows. This is known as **cross-compilation**. Cross-compilation is quite a large topic, so it cannot be described on Stack Overflow in every detail. Just google for something like "cmake cross-compile Linux Window", choose a reference suitable for your task and follow it. Would you face a **specific problem**, then you may ask here about this problem. – Tsyvarev Jul 30 '20 at 17:47
  • I have looked it up, however the solutions presented have not worked. I used the suggested toolchain on CMake's website: https://cmake.org/cmake/help/v3.4/manual/cmake-toolchains.7.html#cross-compiling-for-linux But it didn't change anything. I set CMAKE_CROSSCOMPILING to true, CMAKE_SYSTEM_NAME to Windows, CMAKE_SYSTEM_VERSION to 10.0 – Nikolai Long Jul 30 '20 at 18:47
  • I am also trying to compile in CMake using mingw, however I haven't gotten it to work yet. – Nikolai Long Jul 30 '20 at 18:49
  • Describe what **exactly** have you tried: which code you put into the toolchain file, how do you call `cmake` with that toolchain, what exact messages has you got, etc. Add this description into the question post. – Tsyvarev Jul 30 '20 at 19:31
  • 1
    You seems incorrectly understand what is a *toolchain* in CMake. It is not the *lines* you need to put into `CMakeLists.txt`. In CMake toolchain is a **separate file**. Exactly this file should contain settings like `CMAKE_CROSSCOMPILING`, `CMAKE_SYSTEM_NAME`, etc. The toolchain file is specified for `cmake` call with additional `-DCMAKE_TOOLCHAIN_FILE=path/to/file` option. – Tsyvarev Jul 30 '20 at 20:58

1 Answers1

5

You need a mingw-w64 toolchain in Linux to do this, for example on Arch Linux you can get all the necessary mingw-w64-... packages through AUR, including mingw-w64-cmake. These packets should get you going:

  • mingw-w64-binutils-symlinks
  • mingw-w64-gcc
  • mingw-w64-cmake

Install others to fulfill any dependencies of your software.

Then you can just run mingw-w64-cmake instead of cmake using your regular CMakeLists.txt. E.g.:

mkdir build-mingw; cd build-mingw
x86_64-w64-mingw32-cmake ../
make

However typically it is a good idea to use a static build so your executable will work standalone. Here is how I do it:

# STATIC stuff (Windows)
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
        set(BUILD_FOR_WIN TRUE)
endif()
option(STATIC_BUILD "Build a static binary." ${BUILD_FOR_WIN})

if (STATIC_BUILD)
        set(CMAKE_EXE_LINKER_FLAGS "-static")
        set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" CONFIG)
        set(BUILD_SHARED_LIBS OFF)
endif()

Which creates a variable, STATIC_BUILD, that the user can set, and is defaulted to ON if compiling for Windows.

There is not much more you need to adapt in your CMake files. For example I need to include extra Qt platform plugins when building Qt:

if (STATIC_BUILD AND ${CMAKE_SYSTEM_NAME} MATCHES "Windows")
        # include plugins into static build on windows
        # (we lack support for static on other platforms right now)
        set(QT_PLUGINS SvgIcon WindowsIntegration WindowsVistaStyle)
endif()

The key takeaway here for you is first to get the proper environment on your system.

ypnos
  • 50,202
  • 14
  • 95
  • 141