Difference between revisions of "Cross compiling/ru"

From Free Pascal wiki
Jump to navigationJump to search
Line 180: Line 180:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Памятка: универсальные двоичные файлы создаются из отдельных (i386 и powerpc) двоичных файлов с использованием lipo.
+
Памятка: универсальные двоичные файлы создаются из отдельных (i386 и powerpc) двоичных файлов с использованием [команды] lipo.
  
 
==Из Darwin i386 на x86_64==
 
==Из Darwin i386 на x86_64==

Revision as of 15:19, 25 September 2018

Deutsch (de) English (en) español (es) français (fr) magyar (hu) português (pt) русский (ru) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)



ENG: AT THE MOMENT THIS PAGE IS UNDER TRANSLATION.
RUS: В НАСТОЯЩИЙ МОМЕНТ СТРАНИЦА НАХОДИТСЯ В ПРОЦЕССЕ ПЕРЕВОДА.




-- Zoltanleo 19:49, 24 September 2018 (CEST) Ввиду сложности дословного перевода текста с английского на русский слова, требующиеся по смыслу, но отсутствующие в английской версии, указаны в квадратных скобках.



Предисловие

Это краткое введение для новичков. В следующих разделах описывается, как настроить систему для кросскомпиляции, что означает создание двоичных файлов (исполняемых файлов) для платформы, отличной от той, которая используется для компиляции, напр., работающих под Linux и создающих исполняемые файлы Win32 (или для FreeBSD или Darwin и т.д.). В этом случае платформу, используемую для компиляции, обычно называют "хостом" [(host)] (Linux в приведенном выше примере), а платформа, в которой вы хотите запускать созданные двоичные файлы, является вашей "целью" [(target)]. FreePascal является компилятором и в основном преобразует исходный код в двоичные файлы (машинный язык). Эти двоичные файлы также содержат информацию о том, как операционная система запускает исполняемые файлы. Более того, двоичные файлы относятся к API-интерфейсам, предоставляемым конкретной операционной системой, поэтому для разных операционных систем необходима другая реализация нашей библиотеки времени выполнения. Следовательно, эти двоичные файлы являются специфичными для платформы. Сам FreePascal не нуждается в большой настройке. Он может создавать двоичные файлы для многих платформ. Таким образом, просто прикажите [компилятору] сделать это.

Хост и цель на одном процессоре

FPC разработан таким образом, что распределенный компилятор может создавать машинный код для определенного процессора [(CPU)] (поскольку разные процессоры нуждаются в разном компьютерном коде), и он знает конкретные требования для всех поддерживаемых платформ (операционных систем), доступных на этом конкретном процессоре. Это означает, что вы можете выполнять кросс-компиляцию с тем же компилятором, который используется для встроенной компиляции, если вы придерживаетесь одного и того же CPU.

Хост и цель на разных процессорах

Если необходимо создать двоичные файлы для другого процессора, вам нужен специальный кросскомпилятор, то есть компилятор, работающий на платформе хоста, но способный создавать машинный код для другого процессора (в случае FPC такой кросс-компилятор снова можно нацелить на все поддерживаемые платформы, доступные в _target_ CPU). Этот кросс-компилятор обычно сохраняется в том же каталоге, что и собственный компилятор. Такой кросс-компилятор может быть либо скомпилирован вами, либо вы можете использовать готовый распределенный кросс-компилятор, предоставляемый для некоторых платформ непосредственно командой [разработчиков] FPC (обычно это платформы, которые в основном используются в портативных устройствах, таких как arm-linux или arm-wince, потому что они обычно не используются в качестве хост-платформ). Затем двоичный файл Fpc может выбрать правильный компилятор (собственный компилятор или кросскомпилятор) для целевого CPU, выбранного с использованием параметра -P.

Ассемблер и компоновщик

Компилятор - это только одна часть. Нам также нужен ассемблер и компоновщик. FPC предоставляет внутренний ассемблер и/или компоновщик для некоторых платформ, но для других платформ нужны внешние инструменты. Обычно эти инструменты не могут создавать двоичные файлы для разных платформ. Вот почему мы должны использовать разные специальные компоновщики 'ld' и ассемблер 'как' для каждой целевой платформы. Это [и есть] binutils.

См. Binutils

Модули, [необходимые] для целевой платформы

После создания (или наличия/установки) кросс-инструментов требуется FPC RTL и другие модули, скомпилированные для выбранной целевой платформы. Например, каждая целевая платформа нуждается в другом файле system.ppu (модуль System) и т.д. Эти модули могут быть скомпилированы с использованием вашего компилятора, настроенного для компиляции на целевую платформу, или вы можете использовать официально распространяемые модули, скомпилированные (и распространяемые) с точно такой же версией FPC (если она доступна в формате, доступном для конкретной платформы хоста).

Конфигурация

Затем будет настроен ваш конфигурационный файл fpc так, что кросс-компиляция станет настолько простой, что вы сможете забыть все скучные детали. То же самое будет сделано для LCL - библиотеки компонентов lazarus (при использовании Lazarus). И после этого вы можете перекрестно скомпилировать программы паскаля для (другой) целевой платформы. Полученные двоичные файлы затем могут быть скопированы на машину с запущенной целевой платформой или запущены под эмулятором (например, в Wine для Win32 двоичные файлы под Linux и т.д.).

Основные шаги

Есть несколько общих шагов, связанных с кросс-компиляцией, которые вы должны делать в каждом случае:

  • Уже иметь компилятор FreePascal для платформы, из которой вы хотите компилировать.
  • У вас должен быть исходный код FreePascal (за исключением специальных случаев, когда все [было] подготовлено кем-то другим).
  • Вам нужно [будет] либо собрать из исходного кода, либо получить двоичные файлы cross-binutils (см. Binutils), которые [будут] запускаться на платформе, на которой вы находитесь [(хост-платформе)], и [будут] предназначены для создания программ для вашей целевой платформы.
  • Иногда вам [будут] нужны некоторые файлы из целевой [платформы], [под] которую вы компилируете.

Из Linux

Из Linux x64 на Linux i386

Скорее всего, ваш 64-разрядный дистрибутив Linux уже способен компилировать 32-битные программы, но из-за того, [что] процесс сборки fpc [так] разработан, есть несколько вещей, которые вам, возможно, придется сделать.

  • На мультиархитектурном debian/ubuntu вы должны установить пакет libc6-dev-i386
  • Сначала проверьте, есть ли у вас файлы i386-linux-ld и i386-linux-as:
$ which i386-linux-ld
$ which i386-linux-as

Если у вас есть эти файлы, пропустите заголовок "Compile FPC" [("Компилировать FPC")]. Оба [файла] могут быть созданы с использованием следующего сценария:

#!/bin/bash

# Создаем /usr/bin/i386-linux-ld
cat >/usr/bin/i386-linux-ld << EOF
#!/bin/bash
ld -A elf32-i386 $@
EOF
chmod +x /usr/bin/i386-linux-ld

# Создаем /usr/bin/i386-linux-as
cat >/usr/bin/i386-linux-as << EOF
#!/bin/bash
as --32 $@
EOF
chmod +x /usr/bin/i386-linux-as
  • Компилируем FPC:
cd /usr/share/fpcsrc/<version>
sudo make all CPU_TARGET=i386

затем:

sudo make crossinstall CPU_TARGET=i386

Вот и все. Отредактируйте ваш файл /etc/fpc.cfg при необходимости. Обратите внимание, что, по крайней мере, [начиная с версии fpc] 3.0.4, выше упомянутая кроссинсталляция помещает файлы в /usr/local/lib/fpc/3.0.4/units/i386-linux и оставшуюся часть системы fpc помещается в /usr/lib/... [Это] легко фиксируется символической ссылкой, но гораздо приятнее сделать так:

sudo make crossinstall CPU_TARGET=i386 INSTALL_PREFIX=/usr

Обратите внимание: если вы видите сообщения о том, что не удалось найти файлы, такие как crtn.o, и о прогнозируемых сбоях линковки, это [происходит], вероятно, потому, что ваш дистрибутив Linux любит хранить свои 32-битные библиотеки gcc в /usr/lib32. Проверьте, если недостающие файлы и в самом деле [находятся] в /usr/lib32, сделайте небольшое изменение в вашем [конфигурационном] файле /etc/fpc.cfg, напр., в строке #177 есть раздел, который выглядит следующим образом:

#ifdef cpui386
-Fl/usr/lib/gcc/x86_64-linux-gnu/6/32
#endif

Сделайте это так, [добавьте] еще одну строку:

#ifdef cpui386
-Fl/usr/lib/gcc/x86_64-linux-gnu/6/32
-Fl/usr/lib32
#endif

Из Linux на ARM Linux

Сведения о таргетинге на Linux, запущенном на ARM (напр., Zaurus), можно найти в Setup Cross Compile For ARM.

Из Linux на Windows

Информацию о кросс-компиляции с Lazarus можно найти в Cross compiling for Win32 under Linux

Из Linux на Darwin или Mac OS X

Пожалуйста, см. Cross compiling OSX on Linux.

Из Windows

Из Windows на Linux

Это менее тривиально [, чем на Linux'е], есть некоторая информация в buildfaq

См. также fpcup для описания работы binutils и того, какие библиотеки/файлы нужно копировать.


-- Zoltanleo 23:19, 24 September 2018 (CEST) Вместо fpcup я бы настоятельно советовал использовать ее более продвинутый форк fpcupdeluxe.
Русскоязычной аудитории, возможно, будет интересен некоторый мой собственный опыт его использования тут. И я не буду возражать, если кто-то, сочтя это за рекламу, удалит ссылку на блог :Р
.


Как объясняется в FAQ по сборке, вам понадобятся файлы библиотеки (.so-файлы) из целевой системы, напр., из /lib и /user/lib (но может быть больше мест). В некоторых системах некоторые .so-файлы на самом деле являются скриптами; проверьте [это командой]

grep -i "ld script" *

Удалите эти .so-файлы и скопируйте поверх .so.x-файлы (или симлинки), которые вам нужно использовать, чтобы компоновщик их нашел.

Из Windows на GO32v2

Подробная информация может быть найдена в Cross-compilation from Win32 to GO32v2.

Из Windows на wince

arm-wince описывает, как настроить кросс-компилятор для arm CPU
i386-wince описывает, как настроить компиляцию для i386 CPU (без кросскомпиляции)

Light bulb  Примечание: У инсталлятора Lazarus есть установщик, который автоматически добавляет Windows к настройкам кросскомпиляции Wince

Из win32 на win64

Если вы компилируете ветку fpc 2.1.1 или старше, вы можете просто сделать:

$ make all OS_TARGET=win64 CPU_TARGET=x86_64

и затем

$ make crossinstall OS_TARGET=win64 CPU_TARGET=x86_64

Из win64 на win32

Установите lazarus-1.6.0-fpc-3.0.0-cross-i386-win32-win64.exe, затем настройте параметры проекта [таким образом], чтобы [стало]:

  • Target OS : Win32
  • Target CPU : i386

Неправильная установка CPU (по умолчанию) приведет к неправильной платформе win32-x86_64!

Из Darwin (OS X)

Из Darwin i386 на powerpc

Официальный установщик FPC для OS X/i386 включает в себя кросс-компилятор PowerPC и все модули, необходимые для компиляции программ PowerPC (используйте "ppcppc" вместо "ppc386" для компиляции ваших программ). Приведенные ниже инструкции необходимы только в том случае, если вы хотите скомпилировать и установить новую версию из svn.

  • Компилируем FPC:
$ cd fpc
$ make all CPU_TARGET=powerpc -j 2

Это создаст компилятор powerpc cross-compiler (fpc/compiler/ppcrosspcc) и все модули. Вы можете установить их, используя следующие команды:

$ sudo make FPC=`pwd`/compiler/ppc386 install CPU_TARGET=powerpc CROSSINSTALL=1
$ INSTALLED_VERSION=`./compiler/ppc386 -iV`
$ sudo mv /usr/local/lib/fpc/$INSTALLED_VERSION/ppcrossppc /usr/local/lib/fpc/$INSTALLED_VERSION/ppcppc

Памятка: универсальные двоичные файлы создаются из отдельных (i386 и powerpc) двоичных файлов с использованием [команды] lipo.

Из Darwin i386 на x86_64

Официальный установщик FPC для OS X/i386 включает компилятор x86_64 и все модули, необходимые для компиляции программ x86_64 (используйте ppcx64 вместо ppc386 для компиляции ваших программ или использования fpc -Px86_64). Приведенные ниже инструкции необходимы только в том случае, если вы хотите скомпилировать и установить новую версию из svn.

  • Компилируем FPC:
$ cd fpc
$ make all CPU_TARGET=x86_64

Этот [код] создает кросс-компилятор x86_64 (fpc/compiler/ppcrossx64) и все модули. Вы можете установить их, используя следующие команды:

$ sudo make crossinstall CPU_TARGET=x86_64
$ sudo mv /usr/local/lib/fpc/2.7.1/ppcrossx64 /usr/local/lib/fpc/2.7.1/ppcx64

Если вы хотите сделать этот недавно установленный компилятор версией по умолчанию (это не рекомендуется, т.к. это нарушит вашу способность создавать новые версии FPC 2.7.1 без явного указания пути к последнему официальному FPC), также выполните следующую команду:

$ sudo ln -sf /usr/local/lib/fpc/2.7.1/ppcx64 /usr/local/bin/ppcx64

Предполагая, что все компоненты LCL, используемые вашим проектом, поддерживаются с помощью Cocoa widgetset, вы можете скомпилировать проект Lazarus из командной строки, используя такую команду (возможно необходим полный путь к компилятору):

$ lazbuild -B project1.lpr --ws=cocoa --cpu=x86_64 --os=darwin --compiler=/usr/local/bin/ppcx64

Вы можете проверить, что ваш исполняемый файл является 64-битным, использует команду "file":

$ file ./project1
$ ./project1: Mach-O 64-bit executable x86_64

Кроме того, вы можете настроить свой проект на компиляцию как 64-бит с помощью графического интерфейса Lazarus:

a.) Выберите пункт меню Project/ProjectOptions
b.) В [пункте] CompilerOptions/ConfigAndTarget установите "Target CPU family" в "x86_64"
c.) В [пункте] CompilerOptions/AdditionsAndOverrides сохраните "LCLWidgetType := cocoa" в LPI

Обратите внимание, что 64-разрядный компьютер OS X может работать с 32-разрядными исполняемыми файлами. Однако, если вы хотите создать бинарник, который выполняется на 32-разрядном Intel также хорошо, как и в 64-битном режиме на 64-битном компьютере Intel, вы можете использовать команду «lipo». Это позволило бы 64-разрядному компьютеру получить доступ к большему количеству памяти и теоретически возможно немного улучшиться (например, различные оптимизации компилятора, больше регистров, но с большими указателями). Предполагается, что вы создали отдельные 32-разрядные ("project32") и 64-разрядные ("project64") исполняемые файлы на Lazarus.

$ lipo -create project32 project64 -o projectUniversal

From Darwin x86_64 to i386

Similar to above, except instead of CPU_TARGET use CPU_SOURCE .

From Darwin to Windows, Linux and others

The fpc package of the package manager fink has a 64-bit compiler. In addition, there is a list of packages for crosscompiling to windows, linux, freebsd on various CPUs.

Examples for installing a crosscompiler are:

$ fink install fpc-cross-i386-win32

or

$ fink install fpc-cross-arm-linux

To compile use these commands:

fpc -Pi386 -Twin32 FILENAME
fpc -Parm -Tlinux FILENAME

This command gives the list of cross compilers:

$ fink list fpc-cross

Currently (fpc 3.0.0), it gives:

fpc-cross-arm-gba
fpc-cross-arm-linux
fpc-cross-arm-nds
fpc-cross-arm-wince
fpc-cross-arm-armv4t-embedded
fpc-cross-arm-armv7m-embedded
fpc-cross-i386-darwin
fpc-cross-i386-freebsd
fpc-cross-i386-go32v2
fpc-cross-i386-linux
fpc-cross-i386-solaris
fpc-cross-i386-win32
fpc-cross-i386-wince
fpc-cross-jvm-android
fpc-cross-jvm-java
fpc-cross-m68k-linux
fpc-cross-mipsel-linux
fpc-cross-powerpc-linux
fpc-cross-sparc-linux
fpc-cross-x86-64-freebsd
fpc-cross-x86-64-linux
fpc-cross-x86-64-win64

For other platforms (processors and systems) you have to do the setup by yourself. It is basically the same scheme: First, you need the corresponding binutils (See Binutils) and second, the crosscompiler and the run time library. Some more details of the building procedure can be learned from the fink package description files of the crosscompilers from above.

From FreeBSD

FreeBSD to SPARC

Warning-icon.png

Предупреждение: This section appears to date from around 2005 and may not be relevant anymore. Updates are welcome.

I managed to crosscompile from x86 to Sparc Solaris 9. However the result doesn't work very well, but here is my cmdline:

in compiler/ execute:

gmake cycle CPU_TARGET=sparc OS_TARGET=solaris CROSSBINUTILPREFIX=solaris-sparc- CROSSOPT='-Xd -Fl~/src/sollib'

~/src/sollib is a directory that contains:

  • a set of .o's from /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3
  • libgcc.a from /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3
  • a set of lib*.so from /usr/lib: libaio.so libmd5.so libc.so libelf.so librt.so libdl.so libm.so

Problem is illustrated by the following binary.

 Free Pascal Compiler version 2.1.1 [2006/03/17] for sparc
 Copyright (c) 1993-2005 by Florian Klaempfl
 Target OS: Solaris for SPARC
 Compiling system.pp
 system.pp(15,1) Fatal: Syntax error, "BEGIN" expected but "identifier UNIT" found

I suspect wrong .o's are taken.

From within Docker container

Cross compiling hello world with Docker image and Free Pascal Compiler 3.0.4

1. pull docker image:

sudo docker pull taraworks/lazarus-cross:0.0.2 (do not use latest)

2. create container with virtual volume based on the pulled image:

a. identify image ID (first 4 digits are needed): sudo docker images

b. use the image for the container, map virtual volume from host: sudo docker create --name pascalContainer -v /home/tudi/pascal_files:/home/tudi/pascal_files -ti image ID

3. start the container

a. identify container ID (first 4 digits are needed): sudo docker ps -a

b. start container: sudo docker start container ID

4. compile file

a. copy pascal file hello.pas from https://github.com/taraworks/lazarus-cross to folder /home/tudi/pascal_files on host:

run on host:

cd /home/tudi/pascal_files

git clone https://github.com/taraworks/lazarus-cross.git

b. attach to container to check the cloned repo is presented:

run on host:

sudo docker attach container ID

press enter one more time and check hello.pas is in container folder. do not detach with exit from container as container will stop.

c. compile from container. change directory to the folder containing hello.pas:

for Windows:

PATH=$PATH:/opt/clang/bin:/opt/osxcross/target/bin /opt/windows/lib/fpc/3.0.4/ppcross386 -Twin32 -va hello.pas

for OSX:

PATH=$PATH:/opt/clang/bin:/opt/osxcross/target/bin /opt/darwin/lib/fpc/3.0.4/ppcross386 -Tdarwin -XR/opt/osxcross/target/SDK/MacOSX10.11.sdk -va hello.pas

d. compile from host.

sudo docker exec pascalContainer bash -c "cd ${CI_PROJECT_DIR} && PATH=$PATH:/opt/clang/bin:/opt/osxcross/target/bin /opt/windows/lib/fpc/3.0.4/ppcross386 -Twin32 -va /home/tudi/pascal_files/lazarus-cross/hello.pas"

General Unix/Linux notes

Option -XLA is used to rename library dependencies specified in pascal units. Format is -XLAold=new, to modify ld link option -l<old> to -l<new>.

Option -XR<sysroot> (recent trunk) that can be used to specify the target system root. It's used for:

  • adding a prefix to the default added library paths; in the past you used to specify -Xd and these paths manually. E.g. for i386-linux instead of passing /lib, /usr/lib, and /usr/X11R6/lib to ld, it will pass <sysroot>/lib, <sysroot>/usr/lib, and <sysroot>/usr/X11R6/lib to ld.
  • detecting the C library (linux specific): glibc or uclibc. E.g. for uclibc detection '<sysroot>/lib/ld-uClibc.so.0' is tried.

Cross compiling the LCL

Since 0.9.31 the LCL is a normal Lazarus package and the IDE will automatically cross compile all needed packages, when you change the target platform of your project.

If something goes wrong, here are some hints that might help to find out why:

Test cross compiler

Test if you have installed the cross compiled fpc correctly:

Create a hello world program test.pas:

program test;
begin
  writeln('DATE ',{$i %DATE%});
  writeln('FPCTARGET ',{$i %FPCTARGET%});
  writeln('FPCTARGETCPU ',{$i %FPCTARGETCPU%});
  writeln('FPCTARGETOS ',{$i %FPCTARGETOS%});
  writeln('FPCVERSION ',{$i %FPCVERSION%});
end.

And compile it with your source/original platform. Example for x86 Windows:

fpc -Twin32 -Pi386 test.pas

Then test source compiler:

test

Replace win32 and i386 with your targets. Example for target Windows 64 bit:

fpc -Twin64 -Px86_64 test.pas

Then test cross compiler:

test

The program fpc is a wrapper that searches the right compiler (e.g. ppcrossx64) for the target and executes it.

If this does not work, your cross compiler was not installed correctly. When this works you can cross compile the LCL.

Cross compiling the LCL in Lazarus 0.9.30 and below

If you are sure your cross compiler works, you can do the actual cross compile.

Perform the following steps in the Lazarus IDE to do an LCL cross compile: In older IDEs:

  • Set in Tools -> Options -> Environment -> Files the Compiler path to the path to fpc. Normally this is already done.
  • Then open Tools -> Configure Build Lazarus.
  • Set Target OS (e.g. to Win64) and Target CPU (e.g. to x86_64)
  • Click the Build button.

Command line

Apart from the IDE, the command line also allows you to build a cross compiled LCL.

Light bulb  Примечание: Since 0.9.31 you should use lazbuild to cross compile Lazarus packages. See lazbuild -h for a list of options.

An example: you would cross compile a Windows 64 cross compiler using: First thoroughly clean any 64 bit leftovers. This does not touch your 32 bit environment:

make distclean LCL_PLATFORM=win32 CPU_TARGET=x86_64 OS_TARGET=win64

Then build LCL and its required dependencies. We're using LCL_PLATFORM as that presumably corresponds to the widgetset, which is still Windows 32 even on Windows 64 (the widgetsets are the same).

make packager/registration lazutils lcl LCL_PLATFORM=win32 CPU_TARGET=x86_64 OS_TARGET=win64

As in the previous section, the LCL for your normal OS is untouched.

Cross compiling LCL applications

You first need to cross compile the LCL. See above.

Cross compiling applications means: compiling plus linking. When you have cross compiled the LCL the compilation part is easy. Just set in the compiler options of the IDE the Target OS and Target CPU. The tricky part is the linking. If you cross compile a project you may see something like this:

/usr/local/bin/arm-linux-ld: cannot find -lX11

This means you have to install the graphical libraries of the target system. This has nothing to do with FPC/Lazarus, but with cross compiling a library. Some distributions provides pre compiled packages for this. For example Microsoft provides cross compiled libraries for WinCE for Windows. Under Linux you can install Wine to cross compile from Linux to Windows. Some Linux distributions provide 64bit libraries for 32bit systems.

Cross compile FAQ

Why cross compile?

So you can develop a program for one OS/CPU and compile it for another OS/CPU without rebooting or switching computers.

Why not cross compile?

In many cases, you want to test the resulting program on the native platform. Compiling the application on that platform may be easier to set up.

Why cross compile from Unix to Windows and not the other way around?

See Cross compiling for Win32 under Linux

I want more information on building Freepascal. Where is it?

There is a general FAQ in pdf format about how to build and configure FPC: buildfaq

Errors like compiler "/usr/bin/fpc" does not support target arm-linux

Apart from other causes, this error may occur if you edited fpc.cfg with incorrect options for the cross compiler (e.g. specifying parameters all on one line instead of one per line).

See also