Cross compiling/zh TW

From Lazarus 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程式就會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