Let's shuffle bits

Cross-Compilation pour windows

Contexte

Je souhaite compiler un programme pour windows mais je n'ai pas windows. Hors de question de virtualiser et puis j'aime mon confortable make. Ce sera donc de la cross-compilation.

Pour ajouter au délire, j'ai besoin des dépendances suivantes: SFML, Box2D, Boost et zlib.

La méthode décrite par la suite n'engage que moi, j'ai été surpris de voir que ça fonctionnait.

Vu qu'on va compiler des librairies et pour éviter d'en foutre partout, on va se créer un dossier genre "crossenv".

Les bons outils

La cross-compilation suppose d'utiliser un compilateur adapté à la cible. Dans le cas présent il s'agit de mingw, on s'empresse donc d'installer gcc-mingw et ses éventuelles dépendances.

Deux systÚmes de construction sont utilisés: CMake et autotools. Dans un cas comme dans un autre, il est possible de spécifier la chaine de compilation que l'on souhaite utiliser (compilateur, linker, etc).

CMake

CMake permet de définir une toolchain, on ne va pas se priver et on met ça dans toolchain-mingw32.cmake:

# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)

# which compilers to use for C and C++
SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres)

# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH  /usr/i686-w64-mingw32 [crossenv] )

# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Je n'ai rien inventé, ça vient du wiki cmake, il faut juste adapter les noms d'éxécutables.

C'est ensuite presque un plaisir de lancer la compilation de SFML avec ça:

cmake -DCMAKE_TOOLCHAIN_FILE=[crossenv]/Toolchain-mingw32.cmake -DCMAKE_INSTALL_PREFIX=[crossenv] ..

Il est important d'installer les librairies dans le dossier "crossenv" puisqu'on précise dans la toolchain que c'est là qu'il faut chercher. Et en plus c'est plus hygiénique.

MĂȘme procĂ©dure pour Box2D, j'ai juste eu Ă  changer un header (freeglut_internal je crois) car il ne me trouvait pas <Windows.h>: la casse lui posait problĂšme avec <windows.h> ça passe. Une fois compilĂ©, on installe les libs Box2D et les includes Ă  la main dans notre crossenv. C'est moche mais ça fonctionne. En mĂȘme temps on cherche Ă  compiler un truc pour windows, Ă  ce point lĂ  on peu bien copier/coller en mode bourrin.

Autotools

Il nous faut Ă©galement zlib, qui utilise autotools. Pas de problĂšme, autotools supporte Ă©galement la cross-compilation.

CC=i686-w64-mingw32-gcc AR="i686-w64-mingw32-ar s" RANLIB=i686-w64-mingw32-ranlib ./configure --prefix=[crossenv]
make
make install

C'est tout. Il faut juste faire gaffe au "i686-w64-mingw32-ar s", le make pleure sans l'option s.

Boost

Boost est un cas à part puisqu'utilisant un systÚme de compilation maison: bjam. On commence par éditer tools/build/v2/user-config.jam pour y mettre ça:

using gcc : 4.8 : i686-w64-mingw32-g++ ;

On se fend ensuite de la procédure normale:

bootstrap.sh --with-libraries=filesystem,system --without-icu
bjam toolset=gcc target-os=windows --prefix=[crossenv] threading=multi threadapi=win32 link=static -j 2 --layout=tagged install

Toutes nos dépendances sont compilées, on est content.

Compilation finale

Ça aurait pu ĂȘtre le titre d'un film mais si ça avait Ă©tĂ© le cas ça n'aurait probablement pas Ă©tĂ© intĂ©ressant. Parce qu'en fait ça se rĂ©sume Ă  ça:

cmake -DCMAKE_TOOLCHAIN_FILE=[crossenv]/toolchain-mingw32.cmake -DCMAKE_INSTALL_PREFIX=[chez toi ou chez moi] ..

Il reste encore un détail à régler, j'aimerais linker statiquement mon exécutable (bah oui, c'est pour windows toussa...). J'ai été bourrin jusqu'au bout en forçant le linkage statique de la SFML et en fillant les arguments suivants à la compilation de mon soft:

-DBUILD_SHARED_LIBS=false -DCMAKE_EXE_LINKER_FLAGS=-static

Conclusion

La cross-compilation pour windows c'est pas si terrible que ça. Je m'attendais Ă  pire. C'est pas encore tip-top (header Ă  bouger Ă  la main, linkage hasardeux) mais on arrive quand mĂȘme au rĂ©sultat attendu. Ayant tentĂ© de compiler sous windows, c'est quand mĂȘme plus simple de cross compiler. M'enfin, les goĂ»ts, les couleurs...