Кросс компиляция windows linux

Кросс-компиляция и отладка C++ Windows-приложения под Linux

Показали мне недавно интересное приложение, под которое можно разрабатывать плагины. Приложение оказалось очень полезным для научной работы, но вот незадача — приложение разработано под Windows, у меня стоит Ubuntu. Windows для разработки под это приложение от лаборатории получить пока не удалось. Чтобы не тратить время, решил освоить кросс-компиляцию и отладку этого приложения.

Итого, имеется:
Ubuntu 12.10 x64
Не-юникодное приложение Мастерская Граф-Моделей (МГМ) (В командах консоли будет называться gmw.exe)

Нужно:
Разрабатывать и отлаживать плагины (dll-библиотеки), не устанавливая Windows.

И тут нам помогут Wine, Code::Blocks, портированное GDB, и boost.

Wine, не юникодное приложение, английский интерфейс Ubuntu и русский язык

При попытке открыть не юникодное приложение под Wine

получаются зюки следующего вида:

На эту проблему интернет очень быстро дает следующую подсказку:

В моём случае, данный подход не улучшил ситуацию ни на йоту.
Как выяснилось, русских локалей в системе не было добавлено (тыц).

Теперь запускаем с выше-указанной подсказкой

И, вуаля, запускается приложение с читаемым русским текстом:

Настройка IDE Code::Blocks для кросс-компиляции и отладки


Установка Code::Blocks

В дальнейшем для отладки нам потребуется менять код плагина отладки поэтому лучше сразу взять версию Code::Blocks из под svn.
Устанавливаем svn:

С помощью svn получаем код C::B, для этого переходим в папку, в которую хотим сохранить код C::B, где и набираем:

Переходим в полученную папку ‘trunk’.

Компиляция C::B происходит с помощью g++, autotools, automake и некоторых других утилит, которые необходимо установить:

Кроме того Code::Blocks зависит от wxWidgets:

Подстраиваем установщик под компьютер (можно запускать единожды):

И дальше, устанавливаем сам codeblocks (ключ —prefix можно упустить для использования настроек по-умолчанию):

Более подробно можно посмотреть по ссылке.

Настройка компиляции и линковки

Выполняем пункты с 1 по 5 с форума Code::Blocks. После этого компиляция программ должна работать, если не используется линковка к платформо-зависмым библиотекам (линковка с boost::regexp будет рассмотрена позже).
(*) В новом Code::Blocks немного изменилось меню по сравнению с инструкцией. Настройки искать нужно в ‘Settings->Compiler. ‘. Для старого Code::Blocks (10.05) пункт 5 нужно выполнить полностью, для нового же (12.11) настройку касающуюся gdb в 5 пункте пока трогать не будем.

Если используется boost его лучше положить отдельно от /usr/include, т.к. по этому адресу лежит много linux-специфичных заголовочных файлов, которые мы не хотим включать в проект при компиляции под Windows.

Начиная с пункта 7 по ссылке выше, описывается кросс-отладка, но, к сожалению, insight.exe, упоминающийся в инструкциях, найти не удается. Поэтому пойдем своим путем.

Кросс-отладка в Code::Blocks & MingW32 gdb для Windows

gdb, который является родным для линукса частично умеет отлаживать Windows приложения, правда, умеет он только останавливаться на исключениях и почти всегда игнорирует точки останова. Чтобы справиться с этими проблемами скачиваем gdb в пакете mingw32 под Windows. Для этого скачиваем и затем распаковываем и переходим в подпапку ‘bin’. Устанавливаем gdb под Windows:

Теперь в этой же папке bin появился файл gdb.exe, он-то нам и нужен.

Создаем скрипт для имитации обычного gdb для этого в файл /usr/bin/i586-mingw32msvc-gdb

Заносим следующие строки:

Для старого C::B все уже настроенно, для нового же отладчик нужно настроить дополнительно. В пункте ‘Settings->Debugger’ кликаем по ‘GDB/CDB debugger’ затем по ‘Create Config’. В новом конфиге меняем команду запуска отладчика на ‘/usr/bin/i586-mingw32msvc-gdb’, остальные настройки по желанию. После этого идем в ‘Settings->Compiler. «, в пункте ‘Selected Compiler’ выбираем тот компилятор, который настраивали до этого и затем на вкладке ‘Toolchain executables’ меняем ‘Debugger’ на наш свежесозданный конфиг. Теперь отладчик будет останавливаться на точках останова, хотя и остановить программу в произволльный момент не сможет (данная проблема пока еще не решена). Правда при попытке отладить,C::B выдает следующую ошибку:

Читайте также:  Виджет ежедневник для windows

Эта ошибка говорит о том, что плагин отладчика в C::B не понимает выдачу отладчика gdb.exe. Как выяснилось при ближайшем рассмотрении плагин отладчика имеет платформо-зависимый код, и вот тут-то и нужно вспомнить что у нас есть исходники C::B. Мы сейчас слегка подкоррекируем код этого плагина. Нужно будет поменять код только одного файла ‘/src/plugins/debuggergdb/gdb_driver.cpp’
Для этого нужно перейти в корень проекта C::B (откуда запускалась команды ./bootstrap), по умолчанию это папка ‘trunk’. И накактить патч:

Ну и пересобираем Code::Blocks:

И почти все готово, остается только создать проект. Шаги 12-13 по ссылке. Если же вы хотите создать проект dll-библиотеки, то указывайти создание динамической библиотеки в мастере и переименовывайте разширение в dll.
Проверям, что в настройках проекта стоит выбранная нами цепь компилятор-линкер-отладчик. ‘<Правая клавиша на проект>-Build Options. ‘ пункт ‘Selected compiler’, и можно радоваться и отлаживаться. Напомню, что по какой-то причине отладчик не может быть прерван во время исполнения, т.е. все отладочные действия могут буть применены только во время останова программы. В частности нельзя поставить новую точку останова, если программа не стоит на какой-либо другой точке останова…

Линкование статической библиотеки boost’а

Библиотека boost в основном является набором заголовочных файлов, и потому никаких проблем с линковкой обычно не возникает. Но для некоторых частей boost’а необходимо линковаться к статической библиотеке, например, boost::regex. Пробуем собрать проект и получаем:

Ошибка возникает из-за того, что мы пытаемся прилинковаться к linux билиотеке, для того чтобы построить windows-приложение.
Чтобы слинковаться нужно скомпилировать boost::regex с помощью MingW32 (про кросс-компиляцию). Скачиваем boost, распаковываем и переходим в папку с распаковынным boost’ом. Создаем файл user-config.jam в корне домашней директории:

Со следующим содержанием:

Дальше настраиваем сборку и собираем:

После выполнения последней команды у меня были ошибки «failed updating 1 target», что, правда, не мешает собираться программам.

В результате, у нас есть полностью подготовленная среда для написания, сборки и отладки Windows-приложений или Windows-библиотек из под Linux. Теперь можно приступать к работе…

Кросскомпиляция из под Linux на Windows C++ gtk3

Я скачал mingw на Linux и скомпилировал обычный Hello, world! для Windows всё получилось!

Но мне нужно скомпилировать с библиотекой gtk+-3.0:

widget.hpp:1:10: fatal error: gtk-3.0/gtk/gtk.h: No such file or directory 1 | #include

Вопрос, как мне подключить gtk+-3.0.

2 ответа 2

GTK3 для винды есть в репозиториях MSYS2. Сам MSYS2 не работает под Wine, но пакеты можно скачать и распаковать вручную (но придется вручную определять и ставить зависимости их тех же репозиториев — это долго).

На правах саморекламы: я сделал скрипты, которые автоматически качают пакеты из этих репозиториев вместе с нужными зависимостями, и заодно вписывают пути к ним в нужные переменные окружения.

Инструкции по использованию есть в readme.

Минимальный пример выглядит так:

Читаем readme, ставим необходимые программы. На данный момент нужны make , wget , tar , zstd .

Устанавливаем сами скрипты, и качаем ими пакеты.

Все устанавливается в текущую папку. Никакого мусора нигде не остается, эту папку потом можно просто стереть.

Теперь ставим нужные переменные окружения командой source env/vars.src .

Компилируем почти так же, но передаем в pkg-config флажок —define-prefix .

Результат работает под вайном.

Флажок нужен потому, что в .pc -файлах (из которых pkg-config берет флаги) этих пакетов пути написаны с расчетом на то, что пакеты стоят в /mingw64 , а у нас это не так. Этот флажок исправляет пути на настоящие.

Читайте также:  Дата выхода windows 10 home

Вместо этого флажка надежнее будет сделать /mingw64 ссылкой: (путь поменяйте на тот, куда клонировали репозиторий)

Но можно сделать еще лучше.

По крайней мере в репозиториях убунты x86_64-w64-mingw32-gcc — слегка старый, 9.x. А вот репозиториях MSYS2 есть новенький GCC, который прекрасно работает под Вайном, но работает медленно.

Есть отличный вариант: поставить MSYS2 GCC только ради библиотек, которые идут с ним в комплекте, а кросс-компилировать уже Clang-ом, с помощью этих библиотек. Любая сборка Clang-а (в отличие от GCC) умеет кросс-компилировать под любую поддерживаемую архитектуру, поэтому просто ставим обычный Clang для линукса.

Дальше ставим пакеты:

На всякий случай делаем /mingw64 ссылкой (нужно исправить путь на свой, см. выше зачем нужна ссылка):

Теперь запускаем env/shell.sh , и если все сделано правильно, то кланг должен запускаться командами win-clang и win-clang++ , сразу со всеми флажками, нужными для кросс-компиляции.

Предупреждение: env/shell.sh кроме прочего настраивает ядро для прозрачного запуска экзешников через Wine (в консоли будут работать вещи типа ./foo.exe ). Эта настройка сохраняется до ребута.

Для этого скрипт спросит пароль для sudo . Если рандомным скриптам из интернета нет доверия, то можно отказаться вводить пароль (Ctrl+C), ввести ту же команду руками, потом набрать sudo -k — чтобы sudo забыл только что введенный пароль, чтобы скрипт ничего не выполнил с этим сохраненным паролем. А потом перезапустить скрипт.

Cross-compile POCO из Windows для Linux

POCO — легковесный, мультиплатформенный open-source набор библиотек и классов С++, облегчающих написание мультиплатформенного ПО.
Выпускается под Boost Software License.
Дополнительные сведения о POCO:
pocoproject.org/features.html
ru.wikipedia.org/wiki/POCO
Прекрасно организованная документация по структуре классов доступна в html-онлайн, html-оффлайн.
Документация по основным возможностям с примерами использования — в pdf: pocoproject.org/documentation/index.html

POCO имеет богатейший функционал — очень многое — всё-всё, что нужно для счастливой жизни C++ программиста! Работает инструментарий отлично, имеет продуманный API.

POCO собирается для большого числа ОС, в т.ч. Desktop Windows, Windows CE, Linux.

По своему опыту замечу, что POCO для этих ОС собирается без проблем.
Методику кроссплатформенной сборки из Windows для этих ОС постараюсь вам, уважаемые с++ разработчики, донести в своих трёх статьях «Cross-compile POCO из Windows».

Статья «Cross-compile POCO из Windows для WinCE» habrahabr.ru/post/223157

Cross-compile POCO из Windows для Linux

Метод, разрабатывался:
— для cross-platform toochain терминала Spire (ARM9)
— хост-машина Windows 7 64
— POCO Basic Edition 1.4.6p4

Соберём POCO для динамического подключения (результат — файлы *.so ) или для статического подключения (результат — файлы *.a )

Подготовка POCO

Подготовить директорию с POCO:
— скачать по адресу pocoproject.org/download/index.html архив POCO последней стабильной версии Basic Edition. По кнопке «Sources for Linux, OS X, etc.». На момент написания статьи архив — poco-1.4.6p4.tar.gz
— разархивировать в отдельную директорию. К примеру, с помощью WinRAR и в директорию C:/poco/poco-1.4.6p4.

Подготовить файл описания сборки для Unix-платформ.
Этот файл будет использоваться командой configure для определения окружения (имя утилит toolchain и другие параметры для построения makefiles)
— найти в C:/poco/poco-1.4.6p4/build/config/ файл «ARM-Linux» и перекопировать его с другим именем, например с именем вашей платформы. Я присвоил имя ARM-Linux-Spire.
Внимание! Имя это будет использовано в шаге «Сборка POCO».
Информация по файлу описания сборки и системе сборки: http://pocoproject.org/docs/99150-GMakeBuildNotes.html
Изменить наш файл ARM-Linux-*** в текстовом редакторе (я использовал Notepad++):
1) Найти и закомментировать строки STLPORT_INCLUDE= , STLPORT_LIB= , OPENSSL_INCLUDE= , CFLAGS= . Должно получиться так:
#STLPORT_INCLUDE = /usr/local/include/stlport

#STLPORT_LIB = /usr/local/lib

#OPENSSL_INCLUDE = /usr/local/arm/2.95.3/include

#OPENSSL_LIB = /usr/local/arm/2.95.3/lib

#CFLAGS = -Isrc

2) Из SYSFLAGS = убрать -I$(STLPORT_INCLUDE) -I$(OPENSSL_INCLUDE)
Должно получиться так:
#SYSFLAGS = -I$(STLPORT_INCLUDE) -I$(OPENSSL_INCLUDE) -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_REENTRANT -D_THREAD_SAFE -DPOCO_NO_FPENVIRONMENT

Читайте также:  From windows system32 config

SYSFLAGS = -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_REENTRANT -D_THREAD_SAFE -DPOCO_NO_FPENVIRONMENT

3) Из SYSLIBS = убрать -L$(STLPORT_LIB) -L$(OPENSSL_LIB) -lstlport_arm-linux-gcc
Должно получиться так:
#SYSLIBS = -L$(STLPORT_LIB) -L$(OPENSSL_LIB) -lstlport_arm-linux-gcc -lpthread -ldl -lrt

SYSLIBS = -lpthread -ldl -lrt

4) Найти строку TOOL = arm-linux и изменить arm-linux на префикс утилит toolchain от вашего оборудования.
Я изменил так:
TOOL = arm-unknown-linux-gnu

Обычно toolchain кроссплатформенной разработки для Linux-устройства поставляется вместе с оборудованием.
Это просто архив с утилитами из набора GCC ( ru.wikipedia.org/wiki/GNU_Compiler_Collection ).

Для того, чтобы узнать имя префикса, перейдите в toolchain в директорию /bin, и обратите внимание на файл *-gcc.exe или *-g++.exe
Например, мой toolchain содержит файлы:
arm-unknown-linux-gnu-gcc.exe

arm-unknown-linux-gnu-g++.exe

, поэтому для моего toolchain префикс arm-unknown-linux-gnu .
5) Найти строку POCO_TARGET_OSARCH = ARM и присвоить произвольное имя, которое во время сборки будет использовано для создания директорий с результатами сборки. Я присвоил имя POCO_TARGET_OSARCH = ARM_Spire , чтобы отражало осмысленное имя платформы. Поэтому у меня библиотеки POCO после сборки будут располагаться в C:\poco\poco-1.4.6p4\lib\Linux\ARM_Spire .
6) Обратим внимание на настройку результата сборки:
если собирать POCO для динамического подключения:
LINKMODE должен стоять в SHARED
, а для статического подключения:
LINKMODE должен стоять в STATIC

Подготовка инструментов

Установить инструменты:
— MinGW msys. Будем использовать msys shell. У меня MinGW шёл в комплекте с sdk для устройства, а вы сможете взять с официального сайта www.mingw.org
— любую консоль для Windows с поддержкой copy-paste. Автор использовал ConEmu x64 www.conemu.ru

Открыть консоль с поддержкой copy-paste, все дальнейшие шаги будут из этой консоли.

Проверить доступность директории toochain/bin, ввести имя gcc-утилиты из вашего toochain. У меня так:
arm-unknown-linux-gnu-gcc -v
— если эта утилита не найдена, то прописать путь к ней. У меня путь такой:
set PATH=C:\Spire\SDT\TOOLCHAIN\20140226\bin;%PATH%
— снова проверить доступность toochain

Проверить доступность утилиты make:
make -v
— если эта утилита не найдена, то прописать путь к ней. У меня путь такой:
set PATH=C:\Spire\SDT\MinGW\bin;%PATH%
— снова проверить доступность make

Войти в командную оболочку msys, выполнить:
sh
— если эта утилита не найдена, то прописать путь к ней. У меня путь такой:
set PATH=C:\Spire\SDT\MinGW\msys\1.0\bin;%PATH%

Все дальнейшие шаги будут выполняться из консоли с поддержкой copy-paste + командной оболочки msys

Установить директорию с POCO текущей:
cd C:/poco/poco-1.4.6p4

Сборка POCO

Перед сборкой (для порядка) можно проверить доступность конфигуратора
./configure —help

Выполнить конфигурацию POCO:
./configure —config=ARM-Linux-Spire
или, для сборки POCO без тестов и примеров:
./configure —config=ARM-Linux-Spire —no-tests —no-samples
если конфигурация успешна, выведется примерно такое сообщение:
Configured for ARM-Linux-Spire

— выполнить сборку POCO:
make
время сборки POCO с тестами и примерами на моём ПЭВМ (Intel i5 3.300Gz 8Gb) заняло 12 минут.

Собранные библиотеки POCO будут находиться в \lib\Linux в директории, которую мы определили в переменной POCO_TARGET_OSARCH в файле настроек конфигурации.
У меня путь к собранным библиотекам POCO оказался такой: C:\poco\poco-1.4.6p4\lib\Linux\ARM_Spire

Возможные проблемы

У меня были проблемы, не связанные напрямую с POCO:
-У проекта со статическими POCO не разрешались зависимости в классе AtomicCounter от
__sync_add_and_fetch, __sync_fetch_and_add, __sync_sub_and_fetch, __sync_fetch_and_sub
Решение: добавить в SYSFLAGS = . -DPOCO_NO_GCC_ATOMICS чтобы использовать другую реализацию AtomicCounter .
-Проект со статическими POCO успешно собирается, но при запуске исполняемой программы на устройстве — в консоль выдается:
/lib/libgcc_s.so.1: version ‘GCC_4.3.0’ not found (required by ) это происходит из-за неодинаковых версий libgcc на устройстве и toolchain на хост-машине. Решение: прилинковать к исполняемой программе библиотеку libgcc .

Кардинальный путь поиска причин проблем связанных со сборкой POCO: подключить исходники POCO к исполняемому файлу и попробовать собрать в составе файла.

Источники информации

Готовые инструментарии с++ делают наш труд более приятным и более плодотворным. Успехов, уважаемые коллеги!

Оцените статью