Un développeur parvient à faire fonctionner du code Swift sur Android
en attendant la sortie de Swift sous licence open source

Depuis la sortie de Swift, le nouveau langage de développement d’Apple, nombreux sont ceux qui ont tourné le dos à Objective-C. Étant considéré comme le successeur de ce dernier, Swift a gravi les échelons dans les classements et fait l’objet d’apprentissage de la part de nombreux développeurs.

Aussi, pour ouvrir son langage à plus de contributeurs, Apple a annoncé à la dernière conférence WWDC 2015 que Swift allait passer au format open source d’ici la fin de l’année. Communiqué qui a renforcé l’attrait des développeurs vers ce langage considéré par Apple comme le prochain grand langage de programmation qui servira à créer des applications et faire la programmation système pendant les 20 années à venir.

En attendant la sortie de Swift sous licence open source, un développeur s’est lancé dans un exercice assez intéressant et est parvenu à faire tourner du code Swift sur Android. Pour y arriver, ce dernier a été aidé par les caractéristiques intrinsèques de Swift.

Il faut rappeler que Swift a été construit afin d’être compatible avec l’environnement de développement intégré (EDI) Xcode. Dans cet EDI, le compilateur utilisé est la machine virtuelle de bas niveau LLVM (Low Level Virtual Machine). Une des particularités de ce compilateur est qu’il permet de créer un générateur de code pour plusieurs types d’architectures et des optimiseurs de compilation indépendants de la plate-forme sur laquelle et de tout langage.

Ainsi donc, au lieu de générer du code ciblant une architecture spécifique, LLVM génère d’abord du code assembleur, puis convertit ce dernier afin qu’il soit utilisé sur l’architecture souhaitée. En profitant de cette caractéristique modulaire, le développeur est parvenu à réutiliser le code binaire généré avec Swift afin de l’utiliser sur Android. Pour ce faire, il est passé par les différentes étapes suivantes :

Code du fichier Hello World
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
// hello.swift
print("Hello, world!");

Instruction pour compiler le fichier Hello World
Code : Sélectionner tout - Visualiser dans une fenêtre à part
$ $SDK/usr/bin/swiftc -emit-object hello.swift

Contenu du fichier objet compilé hello.o
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ nm hello_swift.o
                 U __TFSSCfMSSFT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS
                 U __TFSs27_allocateUninitializedArrayurFBwTGSaq__Bp_
                 U __TFSs5printFTGSaP__9separatorSS10terminatorSS_T_
                 U __TIFSs5printFTGSaP__9separatorSS10terminatorSS_T_A0_
                 U __TIFSs5printFTGSaP__9separatorSS10terminatorSS_T_A1_
0000000000000140 S __TMLP_
0000000000000100 S __TMaP_
                 U __TMdSS
                 U __TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__
                 U __TZvOSs7Process5_argcVSs5Int32
                 U _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func6
                 U _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token6
0000000000000000 T _main
                 U _swift_getExistentialTypeMetadata
                 U _swift_once
Ensuite, il a fourni le code objet à l’éditeur de liens afin de générer l’exécutable.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
$ ld -arch x86_64 -o hello hello.o
     -L$SDK/usr/lib/swift/macosx
     -lSystem -lswiftCore

$ DYLD_LIBRARY_PATH=$SDK/usr/lib/swift/macosx ./hello
Hello, world!
Il faut souligner que lorsque le compilateur Swift effectue la compilation, il génère dans un premier temps une représentation intermédiaire du code Swift, puis traduit cette représentation intermédiaire en code machine x86_64.

En continuant, le développeur a généré un fichier ARM qui est le format binaire utilisé sur Android. Voici le code utilisé pour générer le code binaire.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
$SDK/usr/bin/swiftc
  -parse-as-library # We don't need a "main" function
  -target armv7-apple-ios9.0
  -emit-ir
  add.swift
  | grep -v "^!" # Filter-out iOS metadata
  > add.ll
À partir du code intermédiaire obtenu, le développeur a généré un fichier objet ARM ELF en s’appuyant sur le compilateur statique dans LLVM. Voici le code exécuté pour obtenir le fichier objet.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
$NDK/toolchains/llvm-3.5/prebuilt/darwin-x86_64/bin/llc
  -mtriple=armv7-none-linux-androideabi
  -filetype=obj
  add.ll

Enfin, il a créé un package pour être utilisé dans une application Android. Pour cela, il a utilisé le framework Java JNI Bridge et écrit le code en C.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// jni-bridge.c

// Let's work around Swift symbol mangling
#define SWIFT_ADD _TF3add13addTwoNumbersFTVSs5UInt86secondS0__S0_

uint8_t SWIFT_ADD(uint8_t, uint8_t);

jstring jni_bridge(JNIEnv * env, jobject thiz ) {
  uint8_t a = 123;
  uint8_t b = 45;
  uint8_t c = SWIFT_ADD(a,b);

  char result[255];
  sprintf(result, "The result is %d", c);

  return (*env)->NewStringUTF(env, result);
}
Le tout a été regroupé dans une bibliothèque partagée et finalement le fichier objet a été compilé dans une application Android.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
$NDK_GCC/bin/arm-linux-androideabi-ld
  add.o
  jni_bridge.o
  -shared # Build a shared library
  -lc # We'll need the libc
  -L$NDK/platforms/android-13/arch-arm/usr/lib
Ci-dessous le résultat final sur Android.

Nom : demo.png
Affichages : 7065
Taille : 19,8 Ko

Il est bon de savoir que le code Swift utilisé sur Android ne requiert pas de bibliothèque Swift pour être exécuté, d’où la relative facilité dans sa mise en œuvre. Pour ceux qui souhaitent tirer profit de cette application, l’auteur du projet l’a mise à la disposition du public sur GitHub.

Télécharger la démo de l'application Hello World sur GitHub

Source : Page de présentation du projet

Et vous ?

Que pensez-vous de ce projet ?

Voir aussi

Forum langages de programmation