Cross compiling/zh CN

From Free Pascal wiki
Jump to navigationJump to search

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

前言

这是一个为新手写的简短的引言。接下来的章节将说明如何设置你的系统以进行交叉编译,这表示用一个计算机平台编译出用于不同平台的可执行程序——例如,在Linux平台上编译出在win32平台上的可执行程序(或者FreeBSD或Darwin等等)。既然这样,这个运行编译器的平台通常被称为“host”(上述的Linux就是个例子,在上述情况下,Linux就被称为host),而那个你希望你编译出的程序能得以运行的平台就称为“target”。Free Pascal是个编译器,基本原理就是将源代码翻译成可执行文件(机器语言)。这些可执行文件通常也包含了指示操作系统如何开始执行这个文件的信息(比如,入口点信息,段信息,重定位表等等)。再者可执行文件也可能提及特定系统上的APIs(应用程序接口)的信息,那就是为什么不同操作系统必须用不同实现的(但几乎同样的接口)运行时库。因此,这些可执行文件是平台相关的。Free Pascal本身并不需要什么设置。它能够为不同平台编译可执行文件。只需要告诉它要怎么干就行。

host和target运行于同样的CPU

FPC被设计以可以编译出适用于某种CPU的机器语言(因为不同CPU需要不同的机器语言),它也知道所有的被支持的平台(操作系统)上的,架构上的(CPU及其机器的体系结构)具体需要的,能用到的东西。这表示你可以用为运行于同一类CPU的不同程序使用同一个编译器执行交叉编译。

host和target运行于不同的CPU

如果你要编译出一个运行于不同CPU上的可执行文件,你需要一个特殊的交叉编译器,例如,运行于一种平台上的编译器,能够翻译出不同的适用于不同CPU上的机器语言(就FPC来说,这样一个交叉编译器同样能够为所有支持的平台和CPU架构编译出适用的可执行文件)。因此这个交叉编译器通常存放于同一个目录内作为本机的编译器。你可以自己编译出这样一个交叉编译器,或者你可以直接使用由FPC团队提供的已经为一些平台完成的发布版(这些平台通常用于移动平台,像arm-linux或者arm-wince,因为它们通常不会被作为host平台)。当你使用了 -P 参数后,FPC程序就会调用 -P 指定的target CPU架构的的编译器(本机编译器或者交叉编译器之一)。

汇编器和连接器

编译器只是一部分,我们需要汇编器和链接器。FPC仅仅为某些平台提供内嵌的汇编器和链接器,其他平台需要外部工具以提供支持。通常,这些工具不能够为不同平台编译出二进制文件。那就是为什么我们必须为每一个不同target平台使用不同的链接器‘ld’和汇编器‘as’。它们是binutils。

用于target的单元

装好了交叉编译工具后(这样的一个工具需要FPC RTL和其他为相应target平台编译好的单元文件)。例如,每种不同的target平台需要不同的system.ppu文件(系统单元)等等。这些单元文件要么是你自己为了target平台编译出来的,要么可能是官方为某个版本的FPC编译并发行的。

配置

你要设置你的FPC的配置文件,以使得交叉编译变得容易,你可以忘记所有无聊的细节问题。 对LCL(lazarus cpmponent library)也可以这样做(如果你用Lazarus)。然后你就可以为不同的target编译出Pascal程序了。编译出的可执行文件就可以拷贝到一台运行target的机器上,或者在模拟器上运行(例如:wine,bochs,xbox,vmware等等)。

基本步骤

有一些交叉编译时通常的步骤你必须做的:

  1. 有一个可运行于你的host平台的Free Pascal编译器。
  2. 你需要Free Pascal的源代码。
  3. 你要么从源码构建,要么从别人那儿获得运行你的host系统但却是为target系统设计的cross-binutils可执行文件。
  4. 有时,你需要一些target上的文件。

从Linux

到Linux

事先说明,以下文字说的是在linux(x86_64)上编译出linux(i386)程序。关于以运行于ARM的Linux为目标的编译(例如:Zaurus)应该可以在设置编译器为ARM编译程序找到。

如果你的64位的Linux发行版已经可以编译32位程序,那么事情就好办了。由于FPC的设计的缘故,你还得做两件事。

  • 首先检查你是否拥有两个文件:i386-linux-ld和i386-linux-as:
 bash $ which i386-linux-ld
 bash $ which i386-linux-as

如果你有这两个文件,那么你就可以跳过下面"Compile FPC"标题所说的内容。

我没有这两个文件所以我做了一对脚本:

#!/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 $@
  • 使它们可以被执行:
bash $ chmod +x /usr/bin/i386-linux-as
bash $ chmod +x /usr/bin/i386-linux-ld
  • 编译FPC:
bash $ make all CPU_TARGET=i386

然后:

bash $ su -c "make install CPU_TARGET=i386"

就这样了。之后如果必要,你还可以编辑你的 /etc/fpc.cfg 文件。

到Windows

关于用Lazarus做交叉编译的信息你可以在在Linux下为Win32交叉编译找到。

如果你在编译FPC的2.1.1版本或者或更新的分支版本,你可以这样做:

bash $ make all OS_TARGET=win32 CPU_TARGET=i386

然后

bash $ su -c "make crossinstall OS_TARGET=win32 CPU_TARGET=i386"

注意:为win64编译的话,用的命令是: make all OS_TARGET=win64 CPU_TARGET=x86_64

如此简单的原因是因为内部的链接器已经包含这个版本的FPC。

到Darwin或者macOS

  • 首先你需要拥有用于target平台的binutils。从下面这个站点下载odcctools(使用CVS)。根据他们的指示安装:http://www.opendarwin.org/projects/odcctools/
  • 你需要建一个虚假的根目录,就像:$HOME/darwinroot至少从你的苹果或Darwin(苹果的开源版本)系统拷贝/System和/Frameworks/usr目录(你可能必须拷贝更多东西)到$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.

type:

$PATH=$PATH:$HOME/darwinroot/cross (or whereever you made the symlinks)

type (iirc):

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.


从Windows

到Linux

这很简单,你可以在buildfaq看到相关信息。

到GO32v2

你可以在从Win32到GO32v2的交叉编译找到详细信息。

从Darwin(macOS)i386

从i386到PowerPC

  • 交叉binutils

首先检查你是否已经有了以下文件powerpc-darwin-ld和powerpc-darwin-as:

 $ which powerpc-darwin-ld
 $ which powerpc-darwin-as

如果你已经有了上述文件就可以跳过创建符号链接,直接跳到“编译FPC”标题。

事实上,“normal”binutils能够使用,因为它们是通用的。因此简单的符号链接就够了:

 $ sudo ln -s /usr/bin/as /usr/bin/powerpc-darwin-as
 $ sudo ln -s /usr/bin/ld /usr/bin/powerpc-darwin-ld

这些符号链接可以存其他目录,只要她们在你的$PATH(for example /sw/bin when installing through fink)环境变量中就可以了。

  • 编译FPC:
 $ cd fpc/compiler
 $ make cycle CPU_TARGET=powerpc

这样就能创建一个PowerPC编译器(fpc/compiler/ppcppc)和rtl的单元。

事实上,创建PowerPC的binaries不需要交叉编译器。使用Rosetta,powerpc fpc和ppcppc在IntelMacs上运行得很好。

关于两者的平行的安装和使用需要更多的测试和文档(希望你来做测试和写些文档吧)。

如果缺少单元文件,检查你的配置文件,$HOME/.fpc.cfg或者/etc/fpc.cfg或者/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.

到Windows和Linux(32位)

包管理器fink 已经包含为Windows和linux(32位)交叉编译的包了.

$ fink install fpc-win32

$ fink install fpc-i386-linux

安装交叉编译器。

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-nativent
fpc-cross-i386-netbsd
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-dragonfly
fpc-cross-x86-64-freebsd
fpc-cross-x86-64-linux
fpc-cross-x86-64-win64

Cross compile FAQ

为什么要交叉编译?

这样你就用不着为一个 操作系统/系统架构 开发一个程序或为另一个 操作系统/系统架构 编译而重启或切换你的电脑。

为什么是从UNIX到Windows而不是反过来?

主要的原因是因为为其他系统生成 binaries(另一个UNIX甚至是包括Linux发行版)是非常复杂的。 主要的问题是:

  1. 你在host上需要库文件。
  2. 没有一套库文件可以作为越来越复杂的,不断变化的UNIX版本的最终版本(你很可能要编译出一套新的适合的库来)。
  3. 总是需要更多(linker)参数和设置,这些东西在通常情况下很难描述明白。

如果你在这个警告后还是坚持这样做(从Windows到UNIX),请看一下crossnotes document mentioned further,或者buildfaq

我需要更多构建FreePascal的信息。哪儿可以找到?

有一个通用的pdf格式的FAQ关于如何构建和配置FPC: buildfaq