隨著開源軟體的興起及這些解決方案在創建複雜系統中的接受度,開發能夠無縫運行於多種硬體平台的應用程式的能力變得極為重要。不斷需要在一種架構上開發軟體,但又能在其他目標架構上執行這些軟體。達成此目的的一種常見技術是對目標架構進行交叉編譯。
交叉編譯在嵌入式系統中非常重要,這些系統的目的是在像 ARM 和 PowerPC 板這樣的專用硬體上運行應用程式。這些系統資源有限,因此直接編譯並不是一個選項。因此,開發者將利用通用的 x86 架構作為主機,並使用針對目標硬體的工具鏈,生成與目標硬體相容的二進制檔案。
本文涵蓋了一個案例研究,其中對 PowerPC 進行了開源套件的交叉編譯。文章將涵蓋所使用的工具和工具鏈的詳細資訊,以及如何為此架構實現交叉編譯的逐步教程。
T此問題陳述
給定一個具有PowerPC架構的目標板,目的是為這個板添加L3路由能力。為此,考慮了一個流行的開源路由協議套件,FRRouting(FRR)。
FRR 是一套協議組合,使任何 Linux 機器能夠像一個 完整的 路由器一樣運作。它已經為 amd64、arm64、armhf、 和 i386 打包,但 不 支持 PowerPC。 這 需要 FRR 的交叉編譯。
Build host | target host | |
---|---|---|
CPU 架構 |
x86_64 |
Powerpc(32位) |
作業系統 |
Ubuntu 18.4 |
QorIQ SDK |
中央處理器 |
12 |
2 (e5500) |
隨機存取記憶體 |
12GB |
1GB |
Table 1. 建置和目標平臺之間的差異
The Cross-Compilation Journey
交叉編譯有兩個主要階段:
配置建置環境和預編譯工具鏈
1. 在環境中安裝所需的建置工具。常見的建置工具包括 autoconf、make、cmake、build-essentials、pkg-config、libtool 等。
2. 設置特定於目標主機環境的預編譯工具鏈。CPU/板卡供應商提供其自己的架構特定工具鏈。目標板卡特定的工具鏈是從供應商的產品網站獲得的。
3. 工具鏈附帶一個環境文件,用於設置交叉編譯所需的環境變數,如 CC、GCC、PKG_CONFIG_PATH 等。編輯環境文件 /opt/fsl-qoriq/2.0/environment-setup-ppce5500-fsl-linux
,並根據工具鏈目錄的路徑更新變數的路徑。
export SDKTARGETSYSROOT=/opt/fsl-qoriq/2.0/sysroots/ppce5500-fsl-linux
export PATH=/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/../x86_64-fslsdk-linux/bin:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc-fsl-linux:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc-fsl-linux-uclibc:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc-fsl-linux-musl:$PATH
export CCACHE_PATH=/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/../x86_64-fslsdk-linux/bin:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc-fsl-linux:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc-fsl-linux-uclibc:/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc-fsl-linux-musl:$CCACHE_PATH
export PKG_CONFIG_SYSROOT_DIR=$SDKTARGETSYSROOT
export PKG_CONFIG_PATH=$SDKTARGETSYSROOT/usr/lib/pkgconfig
export CONFIG_SITE=/opt/fsl-qoriq/2.0/site-config-ppce5500-fsl-linux
export PYTHONHOME=/opt/fsl-qoriq/2.0/sysroots/x86_64-fslsdk-linux/usr unset command_not_found_handle
export CC="powerpc-fsl-linux-gcc -m32 -mhard-float -mcpu=e5500 --sysroot=$SDKTARGETSYSROOT"
export CXX="powerpc-fsl-linux-g++ -m32 -mhard-float -mcpu=e5500 --sysroot=$SDKTARGETSYSROOT"
export CPP="powerpc-fsl-linux-gcc -E -m32 -mhard-float -mcpu=e5500 --sysroot=$SDKTARGETSYSROOT"
export AS="powerpc-fsl-linux-as "
export LD="powerpc-fsl-linux-ld --sysroot=$SDKTARGETSYSROOT"
export GDB=powerpc-fsl-linux-gdb
export STRIP=powerpc-fsl-linux-strip
export RANLIB=powerpc-fsl-linux-ranlib
export OBJCOPY=powerpc-fsl-linux-objcopy
export OBJDUMP=powerpc-fsl-linux-objdump
export AR=powerpc-fsl-linux-ar
export NM=powerpc-fsl-linux-nm
export M4=m4
export TARGET_PREFIX=powerpc-fsl-linux-
export CONFIGURE_FLAGS="--target=powerpc-fsl-linux --host=powerpc-fsl-linux --build=x86_64-linux --with-libtool-sysroot=$SDKTARGETSYSROOT"
export CFLAGS=" -O2 -pipe -g -feliminate-unused-debug-types"
export CXXFLAGS=" -O2 -pipe -g -feliminate-unused-debug-types"
export LDFLAGS="-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed"
export CPPFLAGS=""
export KCFLAGS="--sysroot=$SDKTARGETSYSROOT"
export OECORE_DISTRO_VERSION="2.0"
export OECORE_SDK_VERSION="2.0"
export ARCH=powerpc
export CROSS_COMPILE=powerpc-fsl-linux-
解析預編譯工具鏈中的依賴關係
每個軟體都有其特定的依賴關係(工具/庫),這些依賴關係需要在交叉編譯之前解決。
根據目標架構中這些工具/庫的可用性,有兩個選擇來解決它們。要麼直接從可用的套件安裝它們,或者也從源碼進行交叉編譯。
針對FRR編譯,libpcre2、libyang、clippy、libelf和json-c庫需要從源碼編譯。除此之外,protobuf和libcap庫套件可用於PPC(PowerPC)架構,可以直接安裝到工具鏈中。
1. 從套件安裝庫
針對目標架構可用的庫套件可以通過兩種方式安裝到工具鏈的sysroot中:
- 第一種方法使用基於 Ubuntu/Debian 的
dpkg-deb
工具來直接安裝 Debian 套件,如下所述:Shell$ dpkg-deb -x <pkg_name>.deb <toolchain_directory_path>
# libcap 的示例:
$ wget http://launchpadlibrarian.net/222364908/libcap-dev_2.24-12_powerpc.deb
$ dpkg-deb -x libcap-dev_2.24-12_powerpc.deb /opt/fsl-qoriq/2.0/sysroots/ppce5500-fsl-linux/
注意:
- 下載所有依賴包並按順序安裝。
- 庫包可能會安裝到不同的目錄結構中。根據工具鏈將這些庫文件複製到正確的目錄。
- 在第二種方法中,debian/rpm 套件被提取並手動放置到工具鏈目錄路徑,如下所述:
- 要提取 debian 套件,請使用
ar
和tar
工具,如下所示:純文本$ ar -x <package>.deb
$ tar -xJf data.tar.xz
注意: 此方法適用於不支持
dpkg-deb
的系統。 - 要提取 rpm 套件,請使用
rpm2cpio
工具,命令如下:純文本$ rpm2cpio <package>.rpm | cpio -idmv
-
使用 libcap 的包提取和文件放置示例:
Shell# 提取 .deb 套件
$ ar -x libcap-dev_2.24-12_powerpc.deb
# 會提取三個文件 (control.tar.gz, data.tar.xz, debian-binary)
$ ls
control.tar.gz data.tar.xz debian-binary libcap-dev_2.24-12_powerpc.deb
# data.tar.xz 包含程序文件
# control.tar.gz 包含套件的元數據
# debian-binary 包含 deb 文件格式的版本
# 解壓 data.tar.xz 以提取程序文件。
$ tar -xJf data.tar.xz
# 注意:rpm2cpio <package>.rpm 將直接提取程序文件。
# 對所有依賴的 debian 或 rpm 套件在相同路徑下執行相同操作,這將提取所需的所有程序文件和符號鏈接,並保持相同的目錄結構。
# 提取的文件應該複製到工具鏈目錄中的 /usr 目錄,與已有的文件並排放置。
$ cp usr/include/sys/capability.h /opt/fsl-qoriq/2.0/sysroots/ppce5500-fsl-linux/usr/include/sys/
-
要驗證套件/庫是否成功安裝,請運行以下命令:
Shell# 確保從工具鏈的環境文件中導出 PKG_CONFIG_PATH 變數
$ pkg-config --list-all | grep <package_library_name>
注意: 如果尚未安裝
pkg-config
,請安裝它。
- 要提取 debian 套件,請使用
2. 交叉編譯庫
庫套件不適用於目標架構,並且是從源碼編譯的。在開始編譯之前,請加載與工具鏈一起打包的環境文件,以設置交叉編譯所需的所有必要參數。
$ source <env_file_path>
請按照庫的README文件中給出的編譯步驟進行。此外,請在構建過程步驟中設置以下參數:
- 在運行
./configure
腳本時設置--host參數
注意:
- <target_host_parameter>為正在構建該庫/工具的系統。它可以在工具鏈的環境文件中找到。它是在$CC、$LD等中找到的常見前綴。
- 將有兩種類型的依賴庫。一種僅在編譯過程中需要,另一種是在目標主機上執行時的依賴要求。相應設置
--host參數
。
- 在使用 “make install” 來構建依賴庫時,將 DESTDIR 設置為工具鏈的 sysroot 目錄。
Shell
$ make DESTDIR=<toolchain_directory_path> install
範例:
$ make DESTDIR=/opt/fsl-qoriq/2.0/sysroots/ppce5500-fsl-linux/ install
結論
系統架構、庫、依賴和工具鏈的差異使跨編譯成為一種複雜的技術。為了簡化複雜性,本文揭示了跨編譯的各個階段。本文以FRR和PowerPC作為所需軟件和目標硬件的示例。然而,本文中涵蓋的步驟提供了在特定硬件上跨編譯任何軟件的合理策略。環境設置、工具鏈和依賴將根據需求而變化。
Source:
https://dzone.com/articles/heterogeneity-computing-environments-cross-compilation