Кросскомпиляция под виндовс на линукс

Уважаемые форумчане, встретился с проблемой. Мне нужно скомпилировать проект под виндовс, но это всё делается на ubuntu 18.04, а на ней в cmake нет генератора mingw.

Пошагово, что я делал:

cmake -S /... -B /... -G "MinGW Makefiles"

После чего получаю ошибку

CMake Error: Could not create named generator Mingw Makefiles

Каким образом можно с ubuntu скомпилировать проект для других ОС. Заранее спасибо за помощь!)

P.S. ставить все библиотеки на винду очень геморно и должен быть адекватный способ сделать это на линуксе


Ответы (1 шт):

Автор решения: aleksandr barakin

как написано в документации, для сборки portable executable при помощи mingw32, всё что надо — это задействовать «toolchain-файл». минимальный пример файла приведён там же.

указать его можно с помощью опции -DCMAKE_TOOLCHAIN_FILE:

$ cmake -DCMAKE_TOOLCHAIN_FILE=путь.к.toolchain-файлу другие.аргументы

демонстрация (на основе упомянутого примера):

  1. устанавливаю в docker-образе («для чистоты эксперимента», для чистоты же беру образ постарее — debian:8) пакеты: cmake mingw32 make file (последний — лишь для проверки результата).

  2. скачиваю в текущий каталог пример «toolchain-файла»:

    $ cat Toolchain-cross-mingw32-linux.cmake
    # the name of the target operating system
    SET(CMAKE_SYSTEM_NAME Windows)
    
    # Choose an appropriate compiler prefix
    
    # for classical mingw32
    # see http://www.mingw.org/
    #set(COMPILER_PREFIX "i586-mingw32msvc")
    
    # for 32 or 64 bits mingw-w64
    # see http://mingw-w64.sourceforge.net/
    set(COMPILER_PREFIX "i686-w64-mingw32")
    #set(COMPILER_PREFIX "x86_64-w64-mingw32"
    
    # which compilers to use for C and C++
    find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
    #SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres)
    find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
    #SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
    find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)
    #SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
    
    
    # here is the target environment located
    SET(USER_ROOT_PATH /home/erk/erk-win32-dev)
    SET(CMAKE_FIND_ROOT_PATH  /usr/${COMPILER_PREFIX} ${USER_ROOT_PATH})
    
    # adjust the default behaviour of the FIND_XXX() commands:
    # search headers and libraries in the target environment, search
    # programs in 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)
    
  3. создаю файл с исходниками и с правилами для cmake:

    $ cat main.c 
    #include <stdio.h>
    
    int main()
    {
       printf("Hello world\n");
       return 0;
    }
    
    $ cat CMakeLists.txt 
    ADD_EXECUTABLE(hello main.c)
    
  4. генерирую makefile и прочее «cmake-овское хозяйство»:

    $ cmake -DCMAKE_TOOLCHAIN_FILE=./Toolchain-cross-mingw32-linux.cmake .
    -- The C compiler identification is GNU 4.9.1
    -- The CXX compiler identification is GNU 4.9.1
    -- Check for working C compiler: /usr/bin/i686-w64-mingw32-gcc
    -- Check for working C compiler: /usr/bin/i686-w64-mingw32-gcc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working CXX compiler: /usr/bin/i686-w64-mingw32-g++
    -- Check for working CXX compiler: /usr/bin/i686-w64-mingw32-g++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: .
    
  5. запускаю make:

    $ make
    Scanning dependencies of target hello
    [100%] Building C object CMakeFiles/hello.dir/main.c.obj
    Linking C executable hello.exe
    [100%] Built target hello
    
  6. проверяю, что же получилось:

    $ file hello.exe 
    hello.exe: PE32 executable (console) Intel 80386, for MS Windows
    
→ Ссылка