суббота, 26 сентября 2009 г.

Кросс-компиляция C/C++ программ для Windows в Linux

Кратко расскажу как создать так называемый cross-compile toolchain для компиляции Windows-программ из под Linux. Cross-compile toolchain - это набор средств для создания приложений для целевой платформы не имея собственно самой целевой платформы. Обычно это используется при сборке программ под различные экзотические платформы, в данном случае такой целевой платформой выступает далеко не экзотическая Windows. Термин "целевая платформа" уже прозвучал, помимо него имеется еще термин "хост-платформа" (или "платформа сборки"), думаю их значение пояснять не нужно.
Хватит рассуждать пора делом заниматься, привожу краткую инструкцию в результате которой вы получите готовый инструмент для сборки С/С++ программ для Windows непосредственно в Linux. Используя инструкцию собрал toolchain в ArchLinux и CentOS 5.3, после собрал с помощью него MinGW32 для Windows с последним GCC 4.4.1 с поддержкой C/C++ прямо в Linux. В итоге остался очень доволен и получил ценный опыт, которым собираюсь поделиться с вами.


Перед тем как непосредственно приступить убедитесь что у вас установлены средства разработки, такие как GCC, G++, CVS, Automake, Autoconf, make и т.п. Если что-то не сработает в ходе выполнения инструкции - возможно в системе не хватило каких-то пакетов. Если вы занимаетесь разработкой на C/C++ то скорее всего все эти пакеты в вашей системе уже установлены.


Первым делом получим последние версии MinGW Win32 API и MinGW Win32 Runtime:

export CVSROOT=:pserver:anoncvs@cygwin.com:/cvs/src
cvs login (пароль anoncvs)
cvs -z3 co -d mingwrt src/winsup/mingw
cvs -z3 co -d w32api src/winsup/w32api

Теперь скачаем Binutils, GCC, GCC-G++, GMP и MPFR:
wget http://ftp.gnu.org/gnu/binutils/binutils-2.19.1.tar.bz2
wget http://gcc-uk.internet.bs/releases/gcc-4.4.1/gcc-core-4.4.1.tar.bz2
wget http://gcc-uk.internet.bs/releases/gcc-4.4.1/gcc-g++-4.4.1.tar.bz2
wget ftp://ftp.gnu.org/gnu/gmp/gmp-4.3.1.tar.bz2
wget http://www.mpfr.org/mpfr-current/mpfr-2.4.1.tar.bz2

Распакуем все что скачали:
tar xjf binutils-2.19.1.tar.bz2
tar xjf gcc-core-4.4.1.tar.bz2
tar xjf gcc-g++-4.4.1.tar.bz2
tar xjf gmp-4.3.1.tar.bz2
tar xjf mpfr-2.4.1.tar.bz2

Начнем со сборки и установки Binutils для целевой платформы:
cd binutils-2.19.1
mkdir build && cd build
../configure --target=i686-pc-mingw32 --disable-multilib
make
sudo make install
cd ../..

make install установит собранные бинарники в /usr/local/i686-pc-mingw32
Для дальнейшей сборки надо скопировать заголовочные файлы MinGW в папку куда будут устанавливаться файлы для целевой архитектуры:
sudo cp -r mingwrt/include /usr/local/i686-pc-mingw32
sudo cp -r w32api/include /usr/local/i686-pc-mingw32

Если в переменной окружения PATH у вас отсутствует путь /usr/local/bin - добавте его:
export PATH="/usr/local/bin:$PATH"

Теперь соберем и установим GCC с ключом -gcc (предварительно сделаем ссылки на GMP и MPFR, чтобы они тоже собрались):
cd gcc-4.4.1
ln -s ../gmp-4.3.1 gmp
ln -s ../mpfr-2.4.1 mpfr
mkdir build && cd build
../configure --target=i686-pc-mingw32 --disable-multilib
make all-gcc
sudo make install-gcc
cd ../..

Понадобятся библиотеки из MinGW API:
cd w32api
mkdir build && cd build
../configure --host=i686-pc-mingw32 --prefix=/usr/local/i686-pc-mingw32
make
sudo make install
cd ../..

К сожалению тут идет неприятная часть с кросс-зависимостями между GCC и MinGW Runtime, которая, впрочем, решается довольно просто. Мы повторно собираем GCC но уже с ключом all:
cd gcc-4.4.1/build
make

Сборка завершится с ошибкой, но нам это не важно, главное были собраны необходимые библиотеки, которые понадобятся для сборки MinGW Runtime, скопируем их в папку целевой платформы:
sudo cp i686-pc-mingw32/libgcc/crtbegin.o i686-pc-mingw32/libgcc/crtend.o \
i686-pc-mingw32/libgcc/libgcc_eh.a i686-pc-mingw32/libgcc/libgcc.a \
/usr/local/i686-pc-mingw32/lib/
cd ../..

Теперь можно собрать и установить MinGW Runtime:
cd mingwrt
mkdir build && cd build
../configure --host=i686-pc-mingw32 --prefix=/usr/local/i686-pc-mingw32
make
sudo make install
cd ../..

Возвращаемся к сборке GCC, теперь все должно собраться нормально:
cd gcc-4.4.1/build
make
sudo make install
cd ../..

Ну вот и все, cross-compile toolchain готов, можете приступать к сборке нативных Windows-приложений не выходя из Linux. В качестве компилятора для C используйте i686-pc-mingw32-gcc и для C++ используйте i686-pc-mingw32-g++. Для autoconf скриптов configure достаточно указать опции --host=i686-pc-mingw32 и --target=i686-pc-mingw32, тогда скрипт сам определит нужные программы и по возможности попытается собрать весь проект для запуска на целевой платформе, именно так собирается GCC 4.4.1 для запуска в Windows, но об этом в другой раз. Удачных сборок :)