Кросскомпиляция программ для Windows с использованием MinGW, Boost и Cmake в openSUSE

Давным-давно в далекой-далекой галактике один программист заметил, что проект скомпилированный в VisualStudio 2005 выполняется в Windows ощутимо медленнее, чем при использовании GCC в Linux. И решил программист сравнить производительности проекта при использовании VisualStudio и GCC под Windows.

Проект является приложением, написанным на языках С и С++ с использованием библиотек Boost и системы сборки CMake.
Ниже рассказывается о создании окружения для сборки проекта на базе кросскомпилятора MinGW-w64, библиотек Boost и Cmake в openSUSE 11.3 x86.
Установка MinGW и Boost
Установка не должна представлять особой сложности. MinGW-w64 есть в репозиториях openSUSE. Для компиляции приложений для Windows x86 нужно добавить в систему репозиторий http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_11.3/, а для Windows x86-64 — http://download.opensuse.org/repositories/windows:/mingw:/win64/openSUSE_11.3/.

После добавления репозитория необходимо установить следующие пакеты:
  • mingw32-cross-binutils
  • mingw32-cross-cpp
  • mingw32-cross-gcc
  • mingw32-cross-gcc-c++
  • mingw32-headers
  • mingw32-libgcc
  • mingw32-libstdc++
  • mingw32-runtime
  • mingw32-filesystem
  • mingw32-boost-devel
  • mingw32-libboost_date_time
  • mingw32-libboost_filesystem
  • mingw32-libboost_graph
  • mingw32-libboost_iostreams
  • mingw32-libboost_math
  • mingw32-libboost_program_options
  • mingw32-libboost_random
  • mingw32-libboost_regex
  • mingw32-libboost_serialization
  • mingw32-libboost_signals
  • mingw32-libboost_system
  • mingw32-libboost_test
  • mingw32-libboost_thread
  • mingw32-libboost_wave
  • mingw32-libbz2
  • mingw32-libbz2-devel
  • mingw32-libexpat
  • mingw32-libexpat-devel
  • mingw32-icu
  • mingw32-libicu
  • mingw32-libicu-devel
  • mingw32-zlib
  • mingw32-zlib-devel
После установики нужно зайти под пользователем root и в файле
/usr/i686-pc-mingw32/sys-root/mingw/include/mingw_inc/_socket_types.h
(или
/usr/x86_64-pc-mingw32/sys-root/mingw/include/mingw_inc/_socket_types.h
, если вы установили MinGW для компиляции приложений под Windows x86-64) заменить
#if 0
typedef UINT_PTR        SOCKET;
#else
typedef INT_PTR         SOCKET;
#endif
на
#if 1
typedef UINT_PTR        SOCKET;
#else
typedef INT_PTR         SOCKET;
#endif

Это связано с тем, что в BSD-сокетах дискриптор сокета знаковый тип, а в Windows — беззнаковый. Если не сделать данную замену, то приложения использующие Boost.Asio, которая в Windows ожидает беззнаковый тип SOCKET не будут компилироваться. К негативным последствиям можно отнести потенциальную возможность неправильной работы приложений, которые расчитаны на то, что тип дескриптора сокета может быть только знаковым.

На этом установка окружения завершена.
DLL файлы для распространения приложения находятся в каталоге
/usr/i686-pc-mingw32/sys-root/mingw/bin
(
/usr/x86_64-pc-mingw32/sys-root/mingw/bin
в случае Windows x86-64). Для того, чтобы определить, какие DLL-библиотеки использует скомпилированное приложение можно воспользоваться программой Dependency Walker, которая успешно работает под wine-1.3.10.

Кросскомпиляция с использованием Cmake
Для использования кросскомпиляции в Cmake необходимо создать файл настроек, путь к которому будет передаваться cmake через задаваемый в командной строке параметр
CMAKE_TOOLCHAIN_FILE
. В моем случае указание пути выглядело следующим образом:
-DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain/i686-pc-mingw32.cmake
Файл i686-pc-mingw32.cmake содержал следующие настрйки:
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME      Windows)
SET(CMAKE_SYSTEM_PROCESSOR i686)

# which compilers to use for C and C++ and ASM-ATT
SET(CMAKE_C_COMPILER       /usr/bin/i686-pc-mingw32-gcc )
SET(CMAKE_CXX_COMPILER     /usr/bin/i686-pc-mingw32-g++ )
SET(CMAKE_ASM-ATT_COMPILER /usr/bin/i686-pc-mingw32-as  )

# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH  /usr/i686-pc-mingw32
                          /usr/i686-pc-mingw32/sys-root/i686-pc-mingw32
    )

# 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)

На этом установка завершена. Теперь можно компилировать Windows-приложения прямо из рабочего оружения на Linux.

Список используемых источников
1. CmakeMingw — KitwarePublic
2. #5042 (error: redefinition of 'size_t boost::asio::detail::calculate_hash_value(SOCKET)') – Boost C++ Libraries
3. SourceForge.net: MinGW-w64 — for 32 and 64 bit Windows: Modify: 3152409 — signed SOCKET type
4. Socket Data Type (Windows)
5. Dependency Walker (depends.exe) Home Page


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.