Cross compiling/zh CN
- 1 前言
- 2 From Linux
- 3 From Windows
- 4 From Darwin (Mac OS X) i386
- 5 Cross compile FAQ
这是一个为新手写的简短的引言。接下来的章节将说明如何设置你的系统以进行交叉编译，这表示用一个计算机平台编译出用于不同平台的可执行程序——例如，在Linux平台上编译出在win32平台上的可执行程序（或者FreeBSD或Darwin等等）。既然这样，这个运行编译器的平台通常被称为“host”（上述的Linux就是个例子，在上述情况下，Linux就被称为host），而那个你希望你编译出的程序能得以运行的平台就称为“target”。Free Pascal是个编译器，基本原理就是将源代码翻译成可执行文件（机器语言）。这些可执行文件通常也包含了指示操作系统如何开始执行这个文件的信息（比如，入口点信息，段信息，重定位表等等）。再者可执行文件也可能提及特定系统上的APIs（应用程序接口）的信息，那就是为什么不同操作系统必须用不同实现的（但几乎同样的接口）运行时库。因此，这些可执行文件是平台相关的。Free Pascal本身并不需要什么设置。它能够为不同平台编译可执行文件。只需要告诉它要怎么干就行。
FPC被设计以可以编译出适用于某种CPU的机器语言（因为不同CPU需要不同的机器语言），它也知道所有的被支持的平台（操作系统）上的，架构上的（CPU及其机器的体系结构）具体需要的，能用到的东西。This means that you can perform cross-compilation with the same compiler used for native compilation as long as you stick to the same CPU.
如果你要编译出一个运行于不同CPU上的可执行文件，你需要一个特殊的交叉编译器，例如，运行于一种平台上的编译器，能够翻译出不同的适用于不同CPU上的机器语言（就FPC来说，这样一个交叉编译器同样能够为所有支持的平台和CPU架构编译出适用的可执行文件）。This cross-compiler is then usually stored in the same directory as the native compiler. Such a cross-compiler may be either compiled by yourself, or you can use a ready made distributed cross-compiler provided for some platforms directly by the FPC team (usually platforms mostly used in portable devices like arm-linux or arm-wince, because these are usually not used as host platforms). Fpc binary can then select the right compiler (either the native compiler or the cross-compiler) for the target CPU selected using the -P parameter.
The compiler is only one part. We also need the assembler and the linker. FPC provides internal assembler and/or linker for just some platforms, other platforms needs to use external tools for that. And these tools are usually not able to create binaries for different platforms. That's why we have to different special linker 'ld' and assembler 'as' for every target platform. These are the binutils.
Units for target
After creating (or having/installing) the cross tools, one needs FPC RTL and other units compiled for the chosen target platform. For example, every target platform needs a different file system.ppu (System unit), etc. These units may be either compiled using your compiler set up for compilation to the target platform, or you may potentially use officially distributed units compiled (and distributed) with exactly the same FPC version (if available in format useable under the particular host platform).
Then your fpc config file will be setup, so that cross compilation becomes so easy, that you can forget all the boring details. The same will be done for the LCL - the lazarus component library (if using Lazarus). And after this you can cross compile pascal programs for the (different) target platform. The resulting binaries may then be copied to a machine running the target platform, or run under an emulator (e.g. Wine for Win32 binaries under Linux, etc.).
There are a few common steps involved in crosscompiling that you must do in every case:
- Have already a FreePascal compiler for the platform you wish to compile from.
- You need to have the FreePascal source code (except for the special case of having everything prepared by someone else).
- You need to either build from source or obtain binaries of the cross-binutils that run on the platform you are on and are designed to build programs for your desired target platform.
- Sometimes you will need some files from the target you are compiling to.
To be clear, the text below is to compile from linux(x86_64) to linux(i386). Information about targetting Linux running on ARM (e.g. Zaurus) may be found in Setup Cross Compile For ARM.
Chances are that your 64 bit linux distrubution is already capable of compiling 32 bit programs but due to the way the fpc build process is designed there are a couple of things you might have to do.
- First check if you already have the files i386-linux-ld and i386-linux-as:
bash $ which i386-linux-ld
bash $ which i386-linux-as
If you have these files skip to the "Compile FPC" heading.
I did not have these files so I made a couple of scripts:
#!/bin/bash # name this file /usr/bin/i386-linux-ld ld -A elf32-i386 $@
#!/bin/bash # name this file /usr/bin/i386-linux-as as --32 $@
- Make them executable:
bash $ chmod +x /usr/bin/i386-linux-as bash $ chmod +x /usr/bin/i386-linux-ld
- Compile FPC:
bash $ make all CPU_TARGET=i386
bash $ su -c "make install CPU_TARGET=i386"
That's it. Edit your /etc/fpc.cfg file if needed.
Information on cross-compilation with Lazarus may be found in Cross_compiling_for_Win32_under_Linux
If you are compiling the 2.1.1 or greater branch of fpc you can just do:
bash $ make all OS_TARGET=win32 CPU_TARGET=i386
bash $ su -c "make crossinstall OS_TARGET=win32 CPU_TARGET=i386"
Note: to build for win64 the make command is: make all OS_TARGET=win64 CPU_TARGET=x86_64
The reason for this simplicity is the internal linker included in this version of fpc.
To Darwin or Mac OS X
- First you need the binutils for the platform you want to compile to. Download odcctools from this site (use the cvs version) and follow their instructions for installing. http://www.opendarwin.org/projects/odcctools/
- you need to create a fake root dir like: $HOME/darwinroot copy at least the /System and /Frameworks and /usr directories (you may have to copy more than this) from your Apple or Darwin computer to $HOME/darwinroot
- now that you have these files make a folder in $HOME/darwinroot called cross. where ever you installed the odcctools you need to make links for the cross tools to be more fpc friendly. there are a bunch of files from odcc tools called powerpc-apple-darwin-* you need to make links (or rename them) so powerpc-apple-darwin-ld becomes powerpc-darwin-ld, do the same for *-ar and *-as.
- now you are ready to crosscompile fpc. basically you need to have the fpc source and have a terminal open there.
$PATH=$PATH:$HOME/darwinroot/cross (or whereever you made the symlinks)
make all TARGET_OS=darwin TARGET_CPU=powerpc OPT="-Xd -Fl/$HOME/darwinroot/usr/lib"
if that succeded you can install it to whereever you want with:
make install TARGET_OS=darwin TARGET_CPU=powerpc PREFIX=/cross/fpc
now copy the file ./compiler/ppccross somewhere you will be able to find it as it's the compiler you'll need to build powerpc programs
- configure your /etc/fpc.cfg file.
add a section like this:
#IFDEF powerpc -Fu/cross/fpc/lib/fpc/$fpcversion/units/$fpctarget/ -Fu/cross/fpc/lib/fpc/$fpcversion/units/$fpctarget/rtl -Fu/cross/fpc/lib/fpc/$fpcversion/units/$fpctarget/* -k-systemroot $HOME/darwin/cross #ENDIF
whenever you want to crosscompile you have to have ppccross and the symlinks to powerpc-darwin-* in the PATH and you should be able to just do ppccross someprogie.pas and it will create a darwin executable.
I may have missed some things (or most everything) as it's been a while since I did this.
This is less trivial, there is some info in the buildfaq
Detailed information may be found in Cross-compilation from Win32 to GO32v2.
From Darwin (Mac OS X) i386
from i386 to powerpc
- Cross binutils
First check if you already have the files powerpc-darwin-ld and powerpc-darwin-as:
$ which powerpc-darwin-ld $ which powerpc-darwin-as
If you have these files skip the creation of the symlinks and go to the "Compile FPC" heading.
Actually, the "normal" binutils can be used, since they are universal. Therefore, simple symlinks are enough:
$ sudo ln -s /usr/bin/as /usr/bin/powerpc-darwin-as $ sudo ln -s /usr/bin/ld /usr/bin/powerpc-darwin-ld
The symlinks can be in any other directory, as long as it is in your $PATH (for example /sw/bin when installing through fink).
- Compile FPC:
$ cd fpc/compiler $ make cycle CPU_TARGET=powerpc
This creates the powerpc compiler (fpc/compiler/ppcppc) and the units of the rtl.
In order to create powerpc binaries no actual crosscompiler is needed. The powerpc fpc and ppcppc run fine on IntelMacs using Rosetta.
More test and docs are needed for parallel installation of both and usage.
If there are missing units, check your config file, $HOME/.fpc.cfg or /etc/fpc.cfg or /sw/etc/fpc.cfg You may have to add something like or where ever your units are located.
-Fu/usr/local/lib/fpc/lib/fpc/$fpcversion/units/$fpctarget/ -Fu/usr/local/lib/fpc/lib/fpc/$fpcversion/units/$fpctarget/rtl -Fu/usr/local/lib/fpc/lib/fpc/$fpcversion/units/$fpctarget/*
Reminder: Universal binaries are created from the individual (i386 and powerpc) binaries using lipo.
To Windows and Linux (32 bit)
The package manager fink has packages for crosscompiling to windows and linux (32 bit).
$ fink install fpc-win32
$ fink install fpc-i386-linux
install the crosscompilers.
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 Unix to Windows and not the other way around?
The main reason for this is that generating unix binaries on a foreign platform (another unix or even Linux distro included) is more complicated.
The main problems are:
- You need libraries on the host computer (the computer you are crosscompiling from)
- There is not one such set libraries as a result of more complex and dynamic Unix versioning
- A lot more (linker) parameters and tweaking is required, which are hard to explain for a general case.
If you still persist after this warning, please have a look at the crossnotes document mentioned further up, or the buildfaq.
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