Кросскомпиляция
Модератор: Модераторы
- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
Долго не было возможности все проверить — пишу только сейчас.
Нижеследующее проверено мной при компиляции простого тестового примера для Linux
из-под Win32 компилятором версии 2.0. Согласно документации для других сочетаний
целевой и хост-платформы последовательность действий должна быть той же.
1. Что касается непосредственно компиляции — тут проблем нет никаких, по крайней
мере с FPC 2.0. Кросскомпиляция поддерживается вполне, для чего служит ключ
-T<xxx>, где <xxx> — целевая система. Хуже дело обстоит с компоновкой.
2. Во-первых, нужны соответствующие целевой системе версии модулей: бинарные или
в исходниках. В случае бинарных модулей, они должны соответствовать версии
компилятора. В случае исходников, важно следующее: помимо модуля System
компилятор использует маленький объектный файл, ассемблерные исходники
которого находятся вместе с исходниками RTL для соответствующей системы,
однако as, идущий в составе дистрибутива, кросскомпиляцией не владеет.
Соответствующий as следует брать там же, где и ld (см. ниже).
В конфигурационном файле fpc.cfg должны быть строки примерно такого вида:
-FuC:\pp\units\$FPCTARGET\rtl
-FuC:\pp\units\$FPCTARGET\fcl и т.д.
и
-FDC:\PP\bin\$FPCTARGET
Первая указывает путь поиска модулей, а вторая — утилит, таких как as или ld.
Переменная $FPCTARGET зависит от целевой платформы и имеет вид
<процессор>-<OS>. Соответственно, модули и кросс-версию BinUtils следует так
и расположить. Лично я просто выдернул каталог модулей i386-linux из
соответствующего rpm-дистрибутива.
3. Теперь о компоновке. Нужна соответствующая версия линкера ld. Искать
компилятор ее будет согласно ключу -FD<xxx>. Взять кроссплатформеные версии
пакета BinUtils, то есть ld, as и иже с ними можно с FTP-сервера
freepascal.org по адресу: <a href='ftp://ftp.freepascal.org/fpc/contrib/cross/' target='_blank'>ftp://ftp.freepascal.org/fpc/contrib/cross/</a>
Конкретно Win32 -> прочие системы находится в файле:
<a href='ftp://ftp.freepascal.org/fpc/contrib/cross/mingw/win32crossbinutils2005.zip' target='_blank'>ftp://ftp.freepascal.org/fpc/contrib/cros...inutils2005.zip</a>
В наличии имеются:
- arm-linux
- i386-freebsd
- i386-linux
- mingw32
- powerpc-linux
- sparc-linux
- sparc64-freebsd
- sparc64-linux
- x86_64-freebsd
- x86_64-linux
Правда, в архиве некоторые файлы имеют не те имена, например — ld называется
i386-linux-ld.exe. Можно их после распаковки переименовать, можно
скопировать, а можно даже создать жесткие ссылки — NTFS 5-й версии такое
позволяет.
4. После того как все файлы рассованы по своим местам и пути прописаны в fpc.cfg
при помощи переменной $FPCTARGET остается только набрать в командной строке
что-то вроде:
fpc -Tlinux test.pp
И возрадоваться получившемуся.
5. При компоновке с внешними библиотеками через директиву {$LinkLib ...}
возможны некоторые проблемы. Полагаю, нужно лишь выдернуть соответствующую
библиотеку (*.a) из целевой платформы, однако проверить у меня пока не
получилось.
Такая ситуация возникает, например, при попытке скомпилировать из-под Win32
примеры с GTK, однако в моем дистрибутиве linux (Mandrake 9.2) некоторые *.a
файлы отсутствуют, хотя *.h и *.so на месте… Т.е. под Linux'ом у меня эти
примеры также не компилируются.
Нижеследующее проверено мной при компиляции простого тестового примера для Linux
из-под Win32 компилятором версии 2.0. Согласно документации для других сочетаний
целевой и хост-платформы последовательность действий должна быть той же.
1. Что касается непосредственно компиляции — тут проблем нет никаких, по крайней
мере с FPC 2.0. Кросскомпиляция поддерживается вполне, для чего служит ключ
-T<xxx>, где <xxx> — целевая система. Хуже дело обстоит с компоновкой.
2. Во-первых, нужны соответствующие целевой системе версии модулей: бинарные или
в исходниках. В случае бинарных модулей, они должны соответствовать версии
компилятора. В случае исходников, важно следующее: помимо модуля System
компилятор использует маленький объектный файл, ассемблерные исходники
которого находятся вместе с исходниками RTL для соответствующей системы,
однако as, идущий в составе дистрибутива, кросскомпиляцией не владеет.
Соответствующий as следует брать там же, где и ld (см. ниже).
В конфигурационном файле fpc.cfg должны быть строки примерно такого вида:
-FuC:\pp\units\$FPCTARGET\rtl
-FuC:\pp\units\$FPCTARGET\fcl и т.д.
и
-FDC:\PP\bin\$FPCTARGET
Первая указывает путь поиска модулей, а вторая — утилит, таких как as или ld.
Переменная $FPCTARGET зависит от целевой платформы и имеет вид
<процессор>-<OS>. Соответственно, модули и кросс-версию BinUtils следует так
и расположить. Лично я просто выдернул каталог модулей i386-linux из
соответствующего rpm-дистрибутива.
3. Теперь о компоновке. Нужна соответствующая версия линкера ld. Искать
компилятор ее будет согласно ключу -FD<xxx>. Взять кроссплатформеные версии
пакета BinUtils, то есть ld, as и иже с ними можно с FTP-сервера
freepascal.org по адресу: <a href='ftp://ftp.freepascal.org/fpc/contrib/cross/' target='_blank'>ftp://ftp.freepascal.org/fpc/contrib/cross/</a>
Конкретно Win32 -> прочие системы находится в файле:
<a href='ftp://ftp.freepascal.org/fpc/contrib/cross/mingw/win32crossbinutils2005.zip' target='_blank'>ftp://ftp.freepascal.org/fpc/contrib/cros...inutils2005.zip</a>
В наличии имеются:
- arm-linux
- i386-freebsd
- i386-linux
- mingw32
- powerpc-linux
- sparc-linux
- sparc64-freebsd
- sparc64-linux
- x86_64-freebsd
- x86_64-linux
Правда, в архиве некоторые файлы имеют не те имена, например — ld называется
i386-linux-ld.exe. Можно их после распаковки переименовать, можно
скопировать, а можно даже создать жесткие ссылки — NTFS 5-й версии такое
позволяет.
4. После того как все файлы рассованы по своим местам и пути прописаны в fpc.cfg
при помощи переменной $FPCTARGET остается только набрать в командной строке
что-то вроде:
fpc -Tlinux test.pp
И возрадоваться получившемуся.
5. При компоновке с внешними библиотеками через директиву {$LinkLib ...}
возможны некоторые проблемы. Полагаю, нужно лишь выдернуть соответствующую
библиотеку (*.a) из целевой платформы, однако проверить у меня пока не
получилось.
Такая ситуация возникает, например, при попытке скомпилировать из-под Win32
примеры с GTK, однако в моем дистрибутиве linux (Mandrake 9.2) некоторые *.a
файлы отсутствуют, хотя *.h и *.so на месте… Т.е. под Linux'ом у меня эти
примеры также не компилируются.
- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
-
Trustmaster
- незнакомец
- Сообщения: 6
- Зарегистрирован: 12.09.2005 22:30:53
Пытаюсь обеспечить кросскомпиляцию программы, но вот только проблема с динамической библиотекой. У меня это, правда, не gtk, а еще банальнее - GNU libc (libc.so). Насчет файла libc.a ничего сказать не могу, т.к. и в никсовой системе, и в пакете glibc он отсутствует, а FPC под той же *NIX-системой при этом преспокойно компилирует программы. Выглядит как минимум странно. Если пытаться обойти это с помощью динамического подключений (во время выполнения), то получается замкнутый круг (функции динамической загрузки находятся в той же libc.so). За помощь и информацию буду признателен.
- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
Но мы пойдем другим путем
или особенности национальной кросскомпиляции
Есть:FreeBSD 5.4. и FPC 2.0.0
Надо скомпилировать экзешник для Windows.
1. Ну тут все понятно.
2. Следует учесть, что на момент написания данного сообщения FPC 2.0.0 все еще не появился в портах, поэтому лично у меня сначала установлены бинарники, а затем все пересобрано из исходников. Все это с префиксом по умолчанию - /usr/local.
Соответственно бинарники попали в /usr/local/bin, а юниты и тп в /usr/local/lib.
Собранные для win32 юниты (каталог какой-то_путь\i386-win32) берем из дистрибутива для win32 и помещаем в /usr/local/lib/fpc/2.0.0/units/ рядом с i386-freebsd.
В файле ~/.fpc.cfg добавляем только -FD/usr/home/stakan/fpc/$fpctarget/bin
(/usr/home/stakan - мой домашний каталог пользователя, замените на свой!)
Теперь выполняем следующие магические действия:
cd
mkdir fpc
cd fpc
ln -s /usr/local i386-freebsd
mkdir i386-win32/bin
2. Как было сказано - идем на <a href='ftp://ftp.freepascal.org/fpc/contrib/cross/' target='_blank'>ftp://ftp.freepascal.org/fpc/contrib/cross/</a>. Там заходим в каталог freebsd и тянем от туда <a href='ftp://ftp.freepascal.org/fpc/contrib/cross/freebsd/binutils-2.11.2-cross-freebsd44.2.win32.tar.bz2' target='_blank'>binutils-2.11.2-cross-freebsd44.2.win32.tar.bz2</a>
Содержимое данного архива кладем в каталог ~/fpc/i386-win32/bin .
Важно! Данные бинарники для FreeBSD 4! Поэтому надо либо установить соответвующий дистрибутив (в sysinstall что-то вроде compat_4x) или указать в файле /etc/make.conf опцию COMPAT4X=yes и прересобрать исходники системы.
Но это еще не все. FPC будет пытаться запустить "-as" и "-ld". Поэтому:
cd ~/fpc/i386-win32/bin
ln -s as "-as"
ln -s ld "-ld"
Все. Навстройка завершена.
Теперь делаем, что-то вроде
fpc -Twin32 winhello.pp
и получаем готовый экзешничек для Windows. Запустить можно например так
wine winhello.exe
(если установлен соответвующий порт)
Надеюсь ничего не упустил.
--------
Программы написанные для Windows можно портировать в FreeBSD (и тп) прилинковав их к winelib (содержит WinAPI). Известно как это делать для программ на Си. А вот для программ на Паскале нужны юниты Windows.pas и тп. К сожалению стандартные Windows-юниты похоже для этого не подходят. (подробности на сайте <a href='http://www.winehq.com' target='_blank'>www.winehq.com</a> )
Есть:FreeBSD 5.4. и FPC 2.0.0
Надо скомпилировать экзешник для Windows.
1. Ну тут все понятно.
2. Следует учесть, что на момент написания данного сообщения FPC 2.0.0 все еще не появился в портах, поэтому лично у меня сначала установлены бинарники, а затем все пересобрано из исходников. Все это с префиксом по умолчанию - /usr/local.
Соответственно бинарники попали в /usr/local/bin, а юниты и тп в /usr/local/lib.
Собранные для win32 юниты (каталог какой-то_путь\i386-win32) берем из дистрибутива для win32 и помещаем в /usr/local/lib/fpc/2.0.0/units/ рядом с i386-freebsd.
В файле ~/.fpc.cfg добавляем только -FD/usr/home/stakan/fpc/$fpctarget/bin
(/usr/home/stakan - мой домашний каталог пользователя, замените на свой!)
Теперь выполняем следующие магические действия:
cd
mkdir fpc
cd fpc
ln -s /usr/local i386-freebsd
mkdir i386-win32/bin
2. Как было сказано - идем на <a href='ftp://ftp.freepascal.org/fpc/contrib/cross/' target='_blank'>ftp://ftp.freepascal.org/fpc/contrib/cross/</a>. Там заходим в каталог freebsd и тянем от туда <a href='ftp://ftp.freepascal.org/fpc/contrib/cross/freebsd/binutils-2.11.2-cross-freebsd44.2.win32.tar.bz2' target='_blank'>binutils-2.11.2-cross-freebsd44.2.win32.tar.bz2</a>
Содержимое данного архива кладем в каталог ~/fpc/i386-win32/bin .
Важно! Данные бинарники для FreeBSD 4! Поэтому надо либо установить соответвующий дистрибутив (в sysinstall что-то вроде compat_4x) или указать в файле /etc/make.conf опцию COMPAT4X=yes и прересобрать исходники системы.
Но это еще не все. FPC будет пытаться запустить "-as" и "-ld". Поэтому:
cd ~/fpc/i386-win32/bin
ln -s as "-as"
ln -s ld "-ld"
Все. Навстройка завершена.
Теперь делаем, что-то вроде
fpc -Twin32 winhello.pp
и получаем готовый экзешничек для Windows. Запустить можно например так
wine winhello.exe
(если установлен соответвующий порт)
Надеюсь ничего не упустил.
--------
Программы написанные для Windows можно портировать в FreeBSD (и тп) прилинковав их к winelib (содержит WinAPI). Известно как это делать для программ на Си. А вот для программ на Паскале нужны юниты Windows.pas и тп. К сожалению стандартные Windows-юниты похоже для этого не подходят. (подробности на сайте <a href='http://www.winehq.com' target='_blank'>www.winehq.com</a> )
-
Trustmaster
- незнакомец
- Сообщения: 6
- Зарегистрирован: 12.09.2005 22:30:53
Иван Шихалев писал(а): Функции из модуля dynlibs не помогут?
А нельзя вообще без libc обойтись?
На что ругается компилятор?
external-объявления с явным указанием библиотеки позволяют обойтись без .a
.a-файлы следует искать в пакетах *-devel.
Я же сказал, что с dynlibs выходит замкнутый круг, т.к. dynlibs использует libc.so. Без libc обойтись нельзя, такова уж специфика программирования под систему (надо сказать, RTL и шагу не может ступить без WinAPI под Windows и libc под UNIX). Компилятор не ругается, ругается линкер
Error: error while linking
Кроме того, линкер ругается на то, что не может найти опцию -ldl.
-
Trustmaster
- незнакомец
- Сообщения: 6
- Зарегистрирован: 12.09.2005 22:30:53
Я же сказал, что с dynlibs выходит замкнутый круг, т.к. dynlibs использует libc.so. Без libc обойтись нельзя, такова уж специфика программирования под систему (надо сказать, RTL и шагу не может ступить без WinAPI под Windows и libc под UNIX). Компилятор не ругается, ругается линкер
Лично я проверял бинарники собранные в FreeBSD командой readelf. Они не линкуются с libc. Хотя может может они слинковались статически. Но судя по размеру - врядли.
А вообще как я понимаю - cygwin.dll это аналог libc для windows. Возможно стоит копать туда если вызовы из libc очень нужны.
Кроме того, линкер ругается на то, что не может найти опцию -ldl.
Может это он всетаки файл такой не может найти?
Попробу сделать соответвующий символьный линк.
-
Trustmaster
- незнакомец
- Сообщения: 6
- Зарегистрирован: 12.09.2005 22:30:53
Ну вот для примера простейшая программа, использующая libc:
У кого нормально настроена кросскомпиляция для i386-linux из под Windows может проверить. Лично у меня все равно выдает Error while linking.
Cygwin тут не поможет. Потому что Windows нам нужен только как оболочка, компилированная программа будет работать в Linux и преспокойно пользоваться libc.so.
Выглядит так, словно текущий i386-linux-ld.exe все-таки не поддерживает external и {$LINKLIB} при кросскомпиляции (а значит и не поддерживает dynlibs для UNIX). Я лично не очень расстроюсь, если так оно и будет оставаться некоторое время, ведь у меня рабочих Линуксов для разных целей достаточно. Просто я занимаюсь разработкой библиотеки Pascal Server Pages (наверняка слышали о такой) и хотел добавить такую возможность.
Код: Выделить всё
{$MODE OBJFPC}{$H+}{$Q+}{$R+}{$CHECKPOINTER ON}
program glibtest;
function getenv(const name: PChar): PChar; cdecl; external 'c' name 'getenv';
begin
writeln(getenv('PATH'));
end.У кого нормально настроена кросскомпиляция для i386-linux из под Windows может проверить. Лично у меня все равно выдает Error while linking.
Cygwin тут не поможет. Потому что Windows нам нужен только как оболочка, компилированная программа будет работать в Linux и преспокойно пользоваться libc.so.
Выглядит так, словно текущий i386-linux-ld.exe все-таки не поддерживает external и {$LINKLIB} при кросскомпиляции (а значит и не поддерживает dynlibs для UNIX). Я лично не очень расстроюсь, если так оно и будет оставаться некоторое время, ведь у меня рабочих Линуксов для разных целей достаточно. Просто я занимаюсь разработкой библиотеки Pascal Server Pages (наверняка слышали о такой) и хотел добавить такую возможность.
-
Trustmaster
- незнакомец
- Сообщения: 6
- Зарегистрирован: 12.09.2005 22:30:53
