Construction d’une chaîne de compilation pour Android

Il existe plusieurs méthodes pour avoir une chaîne de compilation pour le système Android. Mais pourquoi une toolchain ? Android est un système d’exploitation basé sur le noyau Linux et dédié aux processeurs de type ARM (actuellement, c’est le cas). Il ne s’agit donc pas de processeurs « classiques » de type x86 ou ia64, et par conséquent, les chaînes de compilation fournies avec les distributions Linux ne sont pas adaptées, car elles ne peuvent générer que du code x86 ou ia64…

Avertissement : Pour l’instant, j’ai réussi à compiler un kernel qui boot, mais j’ai perdu la radio, j’ai seulement le wifi.
Cet article est donc présent surtout à des fins théoriques ou pour les plus persévérant à commencer les bidouilles de bas niveau :p.

Quelques chaînes de compilation pour architecture arm

  • Gentoo, avec son paquet crossdev. Actuellement non fonctionnel chez moi.
  • la chaîne de compilation pré-compilé fourni par le SDK d’Android. Actuellement non fonctionnel chez moi.
  • la chaîne de compilation fournie par crosstool-ng. La plus configurable, la plus chiante à mettre en place, mais la seule qui a marché.

Il est possible que les autres chaînes de compilation marchent parfaitement bien, j’ai juste du louper un truc sur les paramètres à passer… c’est dire que contrairement au monde x86, des architectures ARM, il y en a à la pelle et pas souvent compatibles entre elles (pas sans recompilation).

Cette article détaillera uniquement la dernière chaîne de compilation, qui a l’avantage d’avoir beaucoup de paramètres que l’on peut utiliser pour optimiser sa chaîne.

Les étapes décrites ci-dessous s’appliquent à Gentoo, mais peuvent s’appliquer à n’importe quel UNIX-like avec quelques modifications mineures.

# si ce n'est pas déjà fait, on installe git
emerge -v git

# récupération du kernel cyanogen
export KERNELDIR=/home/kernel-cyanogen
export CROSSTOOLDIR=/home/crosstool-ng
mkdir -p $KERNELDIR
cd $KERNELDIR
#git clone git://github.com/CyanogenMod/cm-kernel.git
# pour certains appareils htc dont le vision, un autre repo est utilisé
git clone git://github.com/CyanogenMod/htc-kernel-msm7x30.git
# aller boire un café, ça va prendre 10bonnes minutes...
#cd cm-kernel
cd htc-kernel-msm7x30
make headers_install ARCH=arm INSTALL_HDR_PATH=../kern_h/

# construction de la toolchain
echo 'sys-devel/ct-ng' >> /etc/portage/package.keywords
emerge -va ct-ng
eselect bashcomp enable ct-ng --global
mkdir -p $CROSSTOOLDIR
cd $CROSSTOOLDIR
# placez le fichier uClibc.config ici, depuis l'archive à télécharger
#mv XVilka-uClibc-msm7200a.config uClibc.config
ct-ng menuconfig

Ci-dessous les changements à effectuer pour le menuconfig de crosstool-ng

Paths and misc options --->
(1) Number of parallel jobs
Target options --->
Target Architecture (arm)
(armv7-a) Architecture level
(cortex-a8) Emit assembly for CPU
(vfpv3) Use specific FPU
(-O2) Target CFLAGS
Toolchain options --->
(android) Tuple's vendor string
Operating System --->
Target OS (linux)
Linux kernel version (2.6.37.6) // à adapter en fonction de la version du kernel du cyanogenmod
C compiler --->
[*] C++
[*] Java
C-library --->
C library (uClibc)
(uClibc.config) Configuration file
Threading implementation to use: (linuxthreads)

Et on retourne à la ligne de commande…

ct-ng build
# là on reprend une tasse de café

# récupération des sources du cyanogenmod
export CYANODIR=/home/cyanogen
cd $CYANODIR
repo sync
make adb
export PATH=/out/host/linux-x86/bin:$PATH

# compilation d'un nouveau kernel
export _XXCFLAGS=" -march=armv7-a -mtune=cortex-a8 -mfpu-abi=softfp -mfpu=vfpv3 -O2"
export PATH=~/x-tools/arm-android-linux-uclibcgnueabi/bin:$PATH
export CCOMPILER=~/x-tools/arm-android-linux-uclibcgnueabi/bin/arm-android-linux-uclibcgnueabi-
cd $KERNELDIR/htc-kernel-msm7x30
# branchez le téléphone au pc
adb pull /proc/config.gz .
zcat config.gz > .config
# menuconfig pour changer deux ou trois choses avant de compiler (à faire avec beaucoup de précautions)
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER menuconfig
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER oldconfig
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER -j`grep 'processor' /proc/cpuinfo | wc -l` all
cd $CYANODIR/device/htc/vision
mv kernel kernel.bak
mv modules/bcm4329.ko modules/bcm4329.ko.bak
ln -s $KERNELDIR/htc-kernel-msm7x30/arch/arm/boot/zImage kernel
ln -s $KERNELDIR/htc-kernel-msm7x30/drivers/net/wireless/bcm4329/bcm4329.ko modules/
cd $CYANODIR
. build/envsetup.sh && brunch cyanogen_vision-eng

Et voilà, plus qu’à flasher.

Tous les crédits vont à XVilka, pour avoir décrit sa méthode pour le milestone.

Voir aussi