[DEV] Compiler et optimiser FileZilla pour son CPU

Aujourd'hui, nous vous proposons une petite actualité dédiée aux amoureux du développement et de la programmation. FileZilla est un client FTP (et FTPS/SFTP) assez bien connu, bénéficiant de nombreuses options et doté d’une excellente ergonomie. Logiciel open source, FileZilla est disponible pour de nombreuses plateformes. Des fichiers binaires « génériques » pour Linux, Windows et Mac OS X peuvent d’ailleurs être téléchargés gratuitement dans notre logithèque.

Les sources de FileZilla étant disponibles, nous allons tenter de le compiler en essayant de l’optimiser pour notre propre processeur. Ce qui veut au passage signifier que la version de FileZilla que nous allons obtenir pourrait ne pas fonctionner sur d’autres ordinateurs…

L’environnement de développement

Plusieurs choix sont possibles en ce qui concerne l’environnement de développement, nous avons choisi MinGW (Minimalist GNU for Windows), une adaptation sur plateforme Win32 des logiciels de développement et de compilation du GNU (GCC - GNU Compiler Collection), et MSYS (Minimal SYStem), un environnement en ligne de commande servant de support aux outils de développement MinGW.

Commençons donc par télécharger MinGW, puis installons-le en choisissant « download latest repository catalogue » afin d'utiliser les dernières versions des outils. Ne pas oublier de cocher « C Compiler », «  C++ Compiler » et « MinGW Developer ToolKit » (qui comprend MSYS), nous allons en avoir besoin…

Lancer enfin MinGW Shell. L'invite de commande nous place dans /home/<Utilisateur> par défaut (qui se trouve en réalité dans <lecteur>/MinGW/msys/1.0/home/<Utilisateur>).

Sources et pré-requis

Nous allons tout d’abord installer deux outils qui ne sont pas livrés par défaut, mais qui seront nécessaires par la suite : wget et unzip (commandes à taper ou à copier-coller dans l'invite de commande MSYS/MinGW) :

mingw-get install msys-wget
mingw-get install msys-unzip

Nous allons ensuite définir certaines variables, afin d’activer certaines optimisations permises par le compilateur (O2), de lui demander d'utiliser les instructions SSE pour les opérations flottantes et de doubler le nombre de registres utilisables (mfpmath=both), et enfin de générer du code optimisé pour le processeur de l’ordinateur en particulier (march=native). Ceci activera également les différents jeux d’instruction supportés par le processeur (MMX, SSE, SSE2, SSE3… selon le cas).

Notez que nous n’utilisons pas les flags O3 et fomit-frame-pointer, ceux-ci aboutissant dans le cas précis de FileZilla à du code non fonctionnel. D’autres optimisations sont bien entendu possibles (fgcse-sm, fgcse-las, floop-optimize2, ftree-loop-linear, ftree-loop-im, ftree-loop-ivcanon, …), nous laissons la possibilité aux plus courageux d’entre vous de les tester !

arch_flags="-march=native -O2 -pipe -mfpmath=both -ffast-math"
export CFLAGS="-w $arch_flags"
export CXXFLAGS="-w $arch_flags"
export CPPFLAGS="-I/local/include"
export LDFLAGS="-L/local/lib"
export OBJCFLAGS="$arch_flags"
export OBJCXXFLAGS="$arch_flags"
export PKG_CONFIG_PATH=/local/lib/pkgconfig

Récupérons maintenant certaines bibliothèques indispensables pour compiler FileZilla (glib, pkg-config, gettext-runtime, zlib, zlib-dev) :

wget http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.8-1_win32.zip
wget http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.26-1_win32.zip
wget http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip
wget http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/zlib-dev_1.2.5-2_win32.zip
wget http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/zlib_1.2.5-2_win32.zip

Il ne reste plus qu’à les décompresser au bon endroit (répondre [N]one à la question demandant si on remplace le fichier) :

unzip pkg-config_0.25-1_win32.zip -d /mingw
unzip glib_2.28.8-1_win32.zip -d /mingw
unzip zlib-dev_1.2.5-2_win32.zip -d /mingw
unzip zlib_1.2.5-2_win32.zip -d /mingw
unzip gettext-runtime_0.18.1.1-2_win32.zip -d /mingw

Récupérons enfin les sources de FileZilla et des bibliothèques nécessaires (libidn, GMP, nettle, gnuTLS, sqlite3 et wxWidgets) :

wget http://sourceforge.net/projects/filezilla/files/FileZilla_Client/3.5.3/FileZilla_3.5.3_src.tar.bz2
wget ftp://ftp.gnu.org/gnu/libidn/libidn-1.24.tar.gz
wget ftp://ftp.gmplib.org/pub/gmp-5.0.4/gmp-5.0.4.tar.bz2
wget http://www.lysator.liu.se/~nisse/archive/nettle-2.4.tar.gz
wget ftp://ftp.gnutls.org/pub/gnutls/gnutls-3.0.14.tar.xz
wget http://www.sqlite.org/sqlite-autoconf-3071000.tar.gz
wget http://prdownloads.sourceforge.net/wxwindows/wxWidgets-2.8.12.tar.bz2

Compiler FileZilla

Commençons par décompresser les sources de libidn 1.24, puis passons à la compilation de cette bibliothèque permettant d’encoder et de décoder les noms de domaines internationalisés.

tar -xvzf libidn-1.24.tar.gz
cd libidn-1.24
configure --prefix=/local --disable-shared --enable-static --disable-nls --enable-threads=win32 --disable-gtk-doc-html
make -j2
make install
cd ..

Passons à Nettle 2.4, une bibliothèque d’encodage de bas niveau nécessaire aux dernières versions de gnuTLS :

tar -xvzf nettle-2.4.tar.gz
cd nettle-2.4
configure --prefix=/local --disable-openssl --enable-shared
make -j2
make install
cp libhogweed-2-1.dll libnettle-4-3.dll /local/bin
cd ..

Continuons avec GnuTLS 3.0.14 (les versions plus récentes 3.0.15, .16 et .17 posent problème), une implémentation des protocoles SSL et TLS. Attention, l’utilisation de « make –j2 » (ou tout autre compilation en parallèle) peut parfois poser problème, nous nous contenterons donc de « make » :

tar -xvJf gnutls-3.0.14.tar.xz
cd gnutls-3.0.14
configure --prefix=/local --disable-shared --enable-static --disable-nls --disable-guile --disable-gtk-doc-html --enable-threads=win32
make
make install
cd ..

Au tour de wxWidgets 2.8, une bibliothèque graphique que l’on peut considérer comme une vraie boîte à outil de programmation d’interfaces graphiques :

tar -xvjf wxWidgets-2.8.12.tar.bz2
cd wxWidgets-2.8.12
configure --prefix=/local --enable-unicode --disable-shared --with-msw -with-zlib
make -j2
make install
cd ..

C’est au tour de SQLite3. Attention, cette bibliothèque n’est pas compatible avec le flag « ffast-math ». Il faut donc modifier certaines variables avant de lancer la compilation :

arch_flags="-march=native -O2 -pipe -mfpmath=both"
export CFLAGS="-w $arch_flags"
export CXXFLAGS="-w $arch_flags"
tar -xvzf sqlite-autoconf-3071000.tar.gz
cd sqlite-autoconf-3071000
configure --prefix=/local --disable-shared --enable-static
make -j2
make install
cd ..

Enfin, il ne reste plus qu’à compiler FileZilla. Attention, le flag « mfpmath=both » ne semble pas compatible, il va donc falloir se contenter de « mfpmath=sse » :

arch_flags="-march=native -O2 -pipe -mfpmath=sse –ffast-math"
export CFLAGS="-w $arch_flags"
export CXXFLAGS="-w $arch_flags"
tar -xvjf FileZilla_3.5.3_src.tar.bz2
cd fileZilla-3.5.3
configure --prefix=/local --with-tinyxml=builtin
make -j2
make install

On en profite pour retirer les symboles nécessaires au débogage des différents fichiers compilés. Cela permet de réduire sensiblement leur poids :

strip src/interface/.libs/filezilla.exe
strip src/putty/.libs/fzsftp.exe
strip src/putty/.libs/fzputtygen.exe
strip src/fzshellext/.libs/libfzshellext-0.dll
cp src/interface/.libs/filezilla.exe src/putty/.libs/fzsftp.exe /local/bin
cp src/putty/.libs/fzputtygen.exe src/fzshellext/.libs/libfzshellext-0.dll /local/bin
cd ..

Et voila ! Le fichier filezilla.exe optimisé ainsi que les différents fichiers nécessaires à son exécution se trouvent dans le répertoire /local (soit dans <lecteur>/MinGW/msys/1.0/local).

Créer le fichier d’installation

Pour ceux qui veulent aller plus loin, il est possible de créer un fichier d’installation contenant tous les fichiers indispensables au bon fonctionnement de votre version de FileZilla. Pour cela, il convient tout d’abord de télécharger et d’installer NSIS. Attention, il faut prendre la version Unicode.

Le fichier .nsi servant à générer le fichier d’installation se trouve dans /home/<utilisateur>/ filezilla-3.5.3/data/. Il va falloir le modifier…

Ouvrir le fichier install.nsi avec votre éditeur de texte favori, puis rajouter dans la section « "FileZilla Client" SecMain », sous « File "..\src\interface\${LT_EXEDIR}FileZilla.exe" », les lignes suivantes :

File "..\..\nettle-2.4\libhogweed-2-1.dll"
File "..\..\nettle-2.4\libnettle-4-3.dll"
File "..\..\..\..\..\..\bin\zlib1.dll"

De la même façon, cherchez la section « "Uninstall" » et sous « Delete "$INSTDIR\filezilla.exe" » rajoutez :

Delete "$INSTDIR\libhogweed-2-1.dll"
Delete "$INSTDIR\libnettle-4-3.dll"
Delete "$INSTDIR\zlib1.dll"

Enregistrez les modifications. Il ne reste plus qu’à faire un clic droit sur le fichier install.nsi et de choisir « Compile NSIS Script » dans le menu contextuel. Si tout se passe bien vous devriez obtenir un fichier d’installation nommé « FileZilla_3_setup.exe ». Et voila !

Note 1 : Il se peut que la compilation échoue à l’étape configure, le script indiquant un problème avec le compilateur. Il arrive parfois que le fichier de test compilé lors de cette étape, nommé a.exe, soit immédiatement effacé par certains antivirus…

Note 2 : Les différentes commandes successives ont été décomposées dans cet article pour améliorer la clarté de l’ensemble. Mais il est bien entendu possible de réaliser toutes ces étapes les unes à la suite des autres en utilisant « && ».

Un problème, une remarque ou une idée ? N'hésitez surtout pas à laisser un commentaire !

Posez une question dans la catégorie Les news : vos réactions du forum
Cette page n'accepte plus de commentaires
23 commentaires
    Votre commentaire
  • job31
    Rien pigé, mais très content de voir ce genre de contenu sur ppc.
    :jap:
    2
  • Yannick G
    Anonymous a dit :
    Rien pigé, mais très content de voir ce genre de contenu sur ppc.
    :jap:


    Pour faire très (très) court, c'est juste "comment faire pour créer sa propre version de FileZilla (version win32) optimisée pour tirer le meilleur de son processeur" :D

    Si ça plait, on va essayer de faire ça un peu plus souvent :)
    (le premier c'était Compiler VLC pour les CPU Atom)
    1
  • baud10
    Article intéressant, mais a mon avis l'exemple est assez mal choisi, un client FTP n'est pas spécialement gourmand en CPU, le gain apporté sera strictement nul... Cela aurait été plus intéressant sur d'autres logiciels CPU-vores, tels que Firefox...
    1