Con l’avvento del software open-source e dell’accettazione di queste soluzioni nella creazione di sistemi complessi, diventa essenziale la capacità di sviluppare applicazioni in grado di funzionare senza problemi su diverse piattaforme hardware. C’è sempre la necessità di sviluppare il software su un’architettura ma avere la possibilità di eseguirlo su altre architetture di destinazione. Una tecnica comune per raggiungere questo obiettivo è la compilazione incrociata dell’applicazione per l’architettura di destinazione.
Cross-compilazioneè significativa nei sistemi embedded dove l’obiettivo è eseguire applicazioni su hardware specializzato come schede ARM e PowerPC. Questi sistemi sono limitati in risorse e quindi la compilazione diretta non è un’opzione. Pertanto, gli sviluppatori sfrutteranno l’architettura comune x86 come host e utilizzeranno toolchain specifiche per l’hardware di destinazione, generando binari compatibili con l’hardware di destinazione.
Questo articolo copre uno studio di caso similedove è stata eseguita la cross-compilazione di un pacchetto open-source per PowerPC. L’articolo coprirà i dettagli degli strumenti e delle toolchain utilizzate e un tutorial passo dopo passo su come è stata raggiunta la cross-compilazione per questa architettura.
The Dichiarazione del Problema
Dato un board di destinazione con architettura PowerPC, l’obiettivo era aggiungere capacità di routing L3 a questo board. A questo scopo, è stato preso in considerazione un popolare suite di protocolli di routing open-source, FRRouting (FRR).
FRR è una suite di protocolli che consente a qualsiasi macchina Linux di comportarsi come un router a pieno titolo. È confezionato per amd64, arm64, armhf, e i386 ma non per PowerPC. Questo ha reso necessaria la cross-compilazione di FRR.
Build host | target host | |
---|---|---|
Architettura CPU |
x86_64 |
Powerpc(32-bit) |
Sistema operativo |
Ubuntu 18.4 |
QorIQ SDK |
CPU |
12 |
2 (e5500) |
RAM |
12GB |
1GB |
Tabile 1. Differenza nella Build e nella piattaforma target
The Viaggio di Cross-Compilazione
Ci sono due fasi principali nella cross-compilazione:
Configurazione dell’Ambiente di Compilazione e Toolchain Pre-compilata
1. Installare gli strumenti di compilazione richiesti nell’ambiente. Gli strumenti di compilazione comuni includono autoconf, make, cmake, build-essentials, pkg-config, libtool, ecc.
2. Configurare la toolchain pre-compilata specifica per l’ambiente host di destinazione. I fornitori di CPU/Schede forniscono le proprie toolchain specifiche per l’architettura. La toolchain specifica per la scheda di destinazione è stata ottenuta dal sito web del produttore.
3. La toolchain viene fornita con un file di ambiente, che viene utilizzato per impostare le variabili di ambiente come CC, GCC, PKG_CONFIG_PATH, ecc., che sono necessarie per la cross-compilazione. Modificare il file di ambiente /opt/fsl-qoriq/2.0/environment-setup-ppce5500-fsl-linux
e aggiornare il percorso delle variabili rispetto al percorso della directory della toolchain.
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-
Risoluzione delle dipendenze in Toolchain pre-compilato
Ogni software ha il proprio set di dipendenze (strumenti/librerie), che devono essere risolte prima della cross-compilazione.
In base alla disponibilità dei pacchetti di questi strumenti/librerie nell’architettura di destinazione, ci sono due opzioni per risolverli. Installarli direttamente dai pacchetti disponibili o cross-compilarli anche dal sorgente.
Specifico per la compilazione di FRR, le librerie libpcre2, libyang, clippy, libelf e json-c devono essere costruite dal sorgente. Oltre a queste, i pacchetti delle librerie protobuf e libcap erano disponibili per l’architettura PPC (PowerPC), che possono essere installati direttamente nel toolchain.
1. Installazione di librerie dai pacchetti
I pacchetti delle librerie disponibili per l’architettura di destinazione possono essere installati nel sysroot del toolchain in due modi:
- Il primo modo utilizza lo strumento
dpkg-deb
basato su Ubuntu/Debian per installare direttamente i pacchetti Debian come indicato di seguito:Shell$ dpkg-deb -x <pkg_name>.deb <toolchain_directory_path>
#Esempio di 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/
Nota:
- Scarica tutti i pacchetti di dipendenza e installali in ordine.
- I pacchetti di libreria possono essere installati in una struttura di directory diversa. Copia quei file di libreria nelle directory corrette secondo la toolchain.
- Nel secondo modo i pacchetti debian/rpm vengono estratti e posizionati manualmente nel percorso della directory del toolchain come indicato di seguito:
- Per estrarre il pacchetto debian, utilizzare gli strumenti
ar
etar
come indicato di seguito:Testo normale$ ar -x <package>.deb
$ tar -xJf data.tar.xz
Nota: Questo metodo è utile per i sistemi senza supporto
dpkg-deb
. - Per l’estrazione del pacchetto rpm, utilizzare lo strumento
rpm2cpio
con il comando seguente:Testo normale$ rpm2cpio <package>.rpm | cpio -idmv
-
Esempio di estrazione del pacchetto e posizionamento dei file con libcap:
Shell# Estrai il pacchetto .deb
$ ar -x libcap-dev_2.24-12_powerpc.deb
# Saranno estratti tre file (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 contiene i file del programma del pacchetto
# control.tar.gz contiene i metadati del pacchetto
# debian-binary contiene la versione del formato del file deb
# Estrai data.tar.xz per estrarre i file del programma del pacchetto.
$ tar -xJf data.tar.xz
# NOTA: rpm2cpio <package>.rpm estrarrà direttamente i file del programma.
# Fai lo stesso per tutti i pacchetti debian o rpm dipendenti nello stesso percorso, questo estrarrà tutti i file del programma e i link simbolici richiesti nella stessa struttura della directory.
# I file estratti nelle directory usr/lib, usr/include e usr/bin dovrebbero essere copiati nella directory del percorso del toolchain /usr, insieme ai file già presenti.
$ cp usr/include/sys/capability.h /opt/fsl-qoriq/2.0/sysroots/ppce5500-fsl-linux/usr/include/sys/
-
Per verificare se i pacchetti/librerie sono stati installati con successo, eseguire il comando seguente:
Shell# Assicurati di esportare la variabile PKG_CONFIG_PATH dal file env del toolchain
$ pkg-config --list-all | grep <package_library_name>
Nota: Installare
pkg-config
se non è già installato.
- Per estrarre il pacchetto debian, utilizzare gli strumenti
2. Compilazione incrociata delle librerie
I pacchetti delle librerie non sono disponibili per l’architettura di destinazione e vengono compilati dalla sorgente. Prima di iniziare la compilazione, caricare il file di ambiente fornito con il toolchain per impostare tutti i parametri necessari richiesti per la compilazione incrociata.
$ source <env_file_path>
Seguire i passaggi di compilazione indicati nel file README della libreria. Inoltre, impostare i seguenti parametri nei passaggi della procedura di build:
- Imposta il parametro
--host
quando esegui lo script./configure
.Shell$ ./configure --host=<target_host_parameter>
# Esempio:
$ ./configure --host=powerpc-fsl-linux
Nota:
- <target_host_parameter> è il sistema per cui viene compilata la libreria/strumento. Può essere trovato nel file di ambiente della catena di strumenti. È un prefisso comune trovato in $CC, $LD, ecc.
- Ci saranno due tipi di librerie dipendenti. Una è richiesta solo per il processo di compilazione, e l’altra è un requisito di dipendenza per l’esecuzione sull’host di destinazione. Imposta il parametro
--host
di conseguenza.
- Quando si utilizza “make install” per costruire librerie dipendenti, impostare DESTDIR sulla directory sysroot della toolchain.
Shell
$ make DESTDIR=<toolchain_directory_path> install
Esempio:
$ make DESTDIR=/opt/fsl-qoriq/2.0/sysroots/ppce5500-fsl-linux/ install
Conclusione
Le differenze nelle architetture di sistema, nelle librerie, nelle dipendenze e nei toolchain rendono la cross-compilation una tecnica complessa da eseguire. Per semplificare le complessità, questo articolo svela le fasi della cross-compilation. FRR e PowerPC sono stati presi come esempi per il software desiderato e l’hardware di destinazione, rispettivamente. Tuttavia, i passaggi trattati in questo articolo forniscono una strategia ragionevole per la cross-compilation di qualsiasi software su un hardware specifico. Le impostazioni ambientali, il toolchain e le dipendenze varieranno in base ai requisiti.
Source:
https://dzone.com/articles/heterogeneity-computing-environments-cross-compilation