Cross Compilation pour NAS Synology

Dans cet article, nous allons nous intéresser à la cross compilation pour NAS Synology – encore appelée compilation-croisée. Pour démystifier le thème, rentrons sans plus tarder dans le vif du sujet.

Qu’est-ce que la cross compilation ?

La cross compilation est la possibilité de compiler des programmes à destination d’une architecture B à partir d’une architecture A. Concrètement, on peut imaginer de compiler un programme C/C++ à destination d’une machine Linux depuis Macintosh, ou encore – pour le cas qui nous intéresse – compiler un programme C/C++ à destination d’un NAS Synology.

Quel intérêt me direz-vous ? Un des avantages de cette manière de faire est que vous n’aurez pas à installer tous les outils de compilation sur votre NAS Synology (pas très sécurisé d’ailleurs…) mais uniquement sur votre machine de développement. L’autre avantage est celui de pouvoir compiler des paquets pour des architectures que vous ne possédez peut-être pas. Par exemple, fournir des paquets pour la plupart des différents modèles de NAS Synology sans pour autant les posséder tous.

Pré-requis

Pour suivre cet article, je vous propose d’activer les services ci-dessous sur votre NAS :

  • SSH : pour la connexion sécurisée à distance
  • SCP : pour la copie à distance d’un programme (sécurisée aussi)

Pour la partie SSH, allez dans le panneau de configuration de votre NAS, puis choisissez « Terminal & SNMP » :

Terminal

Activer le service SSH en indiquant un numéro de port. Je conseille de changer le numéro de port par défaut qui est 22. Par exemple indiquez 33 comme ci-dessous :

SSH

Pour la partie SCP, allez dans le partage de fichier « Services de fichiers » :

Service Fichier

Activez le service SFTP, comme ci-dessous, en indiquant aussi  un autre port que celui par défaut. Par exemple 55 comme ci-dessous :

SFTP

Enfin pour la partie développement, il vous faudra :

  • Choisir votre machine de développement : Macintosh / NUC sous Ubuntu / VirtualBox avec Ubuntu
  • Récupérer la toolchain correspondant à l’architecture cible, c’est à dire celle qui correspond à votre modèle de NAS (la toolchain correspond au kit de développement)

Cette partie va être détaillée par la suite, mais faisons d’abord un petit détour par le  Mac…

Cross compilation sur Macintosh

Il est tout à fait possible – même si cette idée peut paraitre étrange – de compiler un programme à partir d’une machine Macintosh pour obtenir un binaire pour Linux Ubuntu.

Dans mon cas, je possède le NAS Synology DS214Play qui est une architecture 32 bits à base d’Intel. Et la toolchain Linux 32 bits fonctionne pour ce modèle.

Si vous possédez ce type de NAS, faites l’essai : procurez-vous le compilateur GCC téléchargeable pour Mac via le lien suivant : http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux

Une fois l’installation du compilateur effectuée, ouvrez un Terminal et indiquez l’endroit où se trouve installé celui-ci :

$ export CC=/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-gcc

A partir de là, vous pouvez dorénavant faire de la cross compilation. Par exemple pour le portage de DKB Trace sur Synology, la commande configure suivante est utilisée pour indiquer la plateforme cible  et faire la compilation :

$ ./configure --host=i586-pc-linux
$ make

Pour connaitre le type de programme obtenu, il suffit d’utiliser la commande « file » sur l’exécutable produit :

$ file dkb-trace 
dkb-trace: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.0.0, not stripped

On voit bien ici qu’il s’agit d’un programme 32 bits pour l’architecture Intel Linux.

Maintenant si on repasse sur le compilateur gcc standard du Mac (installé par défaut dans /usr/bin/gcc), et qu’on recompile le programme DKB-Trace, voici ce qu’indique la commande « file » :

$ file dkb-trace 
dkb-trace: Mach-O 64-bit executable x86_64

On est repassé sur un exécutable 64 bits à destination du Mac 🙂

En bonus, voici les dépendances en terme de bibliothèques de DKB-Trace :

$ otool -L dkb-trace 
dkb-trace:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.51.1)

Aucune dépendance notoire, sauf une bibliothèque système standard du Mac… Ce qui nous arrange, car la gestion des bibliothèques externes est une autre histoire…

Voici donc le concept présenté, passons maintenant au plat de résistance…

cross-compile

Cross compilation sur Ubuntu

Voici comment utiliser Ubuntu afin de faire de la cross compilation pour son NAS Synology.

Différentes étapes sont nécessaires :

  • Connaitre la famille de son NAS Synology
  • Obtenir la toolchain
  • Préparer son environnement

Connaitre la famille de son NAS

Deux méthodes pour cela :

La méthode simple : rendez-vous sur la page Synology de correspondance entre modèle de NAS et architecture. Sélectionnez votre modèle et dans la colonne « Package Arch » vous devriez trouver l’architecture associée.

Par exemple pour mon DS214Play, il s’agit d’EvanSport :

DS214Play

La méthode plus complexe : connectez-vous via SSH à votre NAS. Pour cela utilisez l’adresse IP de votre interface d’administration :

adresse-ip

Dans un Terminal, lancez la commande ssh où « user » correspond à votre compte d’administration et « 33 » au port configuré précédemment :

ssh

Indiquez votre mot de passe pour accéder à notre NAS.

La commande « uname » suivante vous donnera le détail de votre architecture NAS:

uname

Vous pouvez voir à nouveau l’architecture « evansport ».

Obtenir la toolchain

Pour obtenir le kit de compilation pour votre NAS sous Linux, rendez-vous à la page Synology suivante en rapport avec le DSM 6.1 et choisissez la toolchain correspondant à la famille de votre NAS.

Pour mon DS214Play, il s’agit du kit de compilation Evansport suivant. Téléchargez et installez ce kit.

Préparer son environnement

Une fois la toolchain installée, indiquez sous le terminal Ubuntu les variables suivantes pour l’accès au kit de développement :

export CC=/usr/local/i686-pc-linux-gnu/bin/i686-pc-linux-gnu-gcc
export LD=/usr/local/i686-pc-linux-gnu/bin/i686-pc-linux-gnu-ld
export RANLIB=/usr/local/i686-pc-linux-gnu/bin/i686-pc-linux-gnu-ranlib
export CFLAGS="-I/usr/local/include"
export LDFLAGS="-L/usr/local/lib"
export LD_LIBRARY_PATH=/usr/local/lib

Remplacez « i686-pc-linux-gnu » par le nom de votre toolchain.

Compiler son programme

Si vous avez suivi l’article précédent sur autoconf/automake, je vous conseille de prendre le programme d’exemple et de le compiler comme ci-dessous :

./configure --host=i686-pc-linux
make

L’option « –host » indique la plateforme cible, ici i686-pc-linux.

Vérifier son programme

Afin de vérifier que votre programme a bien été compilé pour votre NAS, il suffit d’utiliser la commande file ci-dessous :

$ cd src
$ file hello_digitalbox 
hello_digitalbox: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.0.0, not stripped

C’est confirmé : votre exécutable est bien compilé pour une plateforme Linux 🙂

Pour le tester, il suffit de le transférer sur votre NAS via SCP, en indiquant le bon numéro de port ainsi que le nom de l’administrateur :

$ scp -P 55 ./hello_digitalbox user@192.168.1.22:.

Maintenant connectez-vous à votre NAS en entrant le mot de passe adéquate :

$ ssh user@192.168.1.22 -p 33

Il n’y a plus qu’à lancer le programme :

$ ./hello_digitalbox 
Hello Digital Box 7.0 !

Well done !

Votre premier programme en compilation croisée vient d’être réalisé.

compilation

Pour aller plus loin

Le cas donné en exemple est un cas simple sans besoin de bibliothèques externes. Des cas plus complexes se présentent lorsque des bibliothèques supplémentaires sont nécessaires à votre exécutable.

Comment les identifier ? Si jamais un programme est disponible pour Linux, il suffit d’utiliser la commande ldd pour obtenir les dépendances. Par exemple sur le programme Yafaray, les voici :

$ ldd ./yafaray-xml 
 linux-vdso.so.1 => (0x00007fffea7c3000)
 libyafaray_v3_core.so => /home/sadmin/Documents/C/yafaray/build/yafaray_v3/bin/./../lib/libyafaray_v3_core.so (0x00007f4244763000)
 libboost_system.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 (0x00007f424453c000)
 libboost_filesystem.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.58.0 (0x00007f4244324000)
 libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4243fa2000)
 libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4243d8b000)
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f42439c2000)
 libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f42437bd000)
 libxml2.so.2 => /usr/lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f4243402000)
 libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f4243158000)
 libboost_serialization.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.58.0 (0x00007f4242ef6000)
 libopencv_imgproc.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.2.4 (0x00007f4242a6b000)
 libopencv_core.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4 (0x00007f4242641000)
 libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4242337000)
 libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f424211a000)
 /lib64/ld-linux-x86-64.so.2 (0x0000563352777000)
 libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007f4241d85000)
 libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f4241b6b000)
 liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f4241949000)
 libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f4241723000)
 libtbb.so.2 => /usr/lib/x86_64-linux-gnu/libtbb.so.2 (0x00007f42414e6000)
 librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f42412de000)
 libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f424106c000)
 libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55 (0x00007f423f5b5000)
 libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f423f38b000)
 libxcb-dri3.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0 (0x00007f423f188000)
 libxcb-present.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-present.so.0 (0x00007f423ef85000)
 libxcb-sync.so.1 => /usr/lib/x86_64-linux-gnu/libxcb-sync.so.1 (0x00007f423ed7d000)
 libxshmfence.so.1 => /usr/lib/x86_64-linux-gnu/libxshmfence.so.1 (0x00007f423eb7a000)
 libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f423e94c000)
 libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f423e739000)
 libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f423e536000)
 libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f423e330000)
 libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f423e12d000)
 libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f423ddf3000)
 libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f423dbda000)
 libxcb-dri2.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0 (0x00007f423d9d4000)
 libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f423d7b2000)
 libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f423d5ac000)
 libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f423d39c000)
 libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f423d198000)
 libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f423cf91000)

On voit ici que beaucoup de bibliothèques sont nécessaires (libboost, libpng, libxml2, …).

Pour porter le programme sur votre NAS, il faudra donc au préalable cross-compiler chaque version de bibliothèque pour votre NAS, en commençant par les dépendances les plus fines. Autant dire que la tâche n’est pas aisée…

Certains kits de cross compilation pour Synology comme SPKSRC permettent de simplifier la gestion de ces dépendances (et de leur compilation). Ce sera l’occasion d’un article à venir.

Pour information, DKB Trace a été porté sur différentes versions de NAS Synology via SPKSRC, car il est beaucoup plus pratique que les outils officiels.

En attendant vous pouvez toujours chercher à cross compiler quelques logiciels simples sans trop de dépendances avec des bibliothèques externes pour vous familiariser au concept. 🙂

 

 

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s