VIII. Compiler et exécuter un programme▲
VIII-A. Introduction▲
Le code que nous avons écrit jusqu'à présent n'est rien de plus que du texte que nous autres, humains, pouvons lire. Bien que ce ne soit pas vraiment de la prose pour nous, c'est encore pire pour votre Mac. Il ne peut rien en faire du tout ! Un programme spécial, appelé compilateur, est nécessaire pour convertir votre code de programmation en un code d'exécution qui pourra être exécuté par votre Mac. C'est le rôle de l'environnement de programmation gratuit Xcode d'Apple. Vous devrez avoir installé Xcode depuis le disque fourni avec votre exemplaire de Mac OS X. En tout cas, vérifiez que vous avez la dernière version, que vous pouvez télécharger depuis la section développeur du site d'Apple à http://developer.apple.com (enregistrement gratuit requis).
VIII-B. Créer un projet▲
Maintenant, lancez Xcode, que vous trouverez dans le dossier Applications du dossier Developer (Développeur). La première fois, il vous posera quelques questions. Acceptez les suggestions par défaut, elles sont excellentes, et vous pourrez toujours les changer ultérieurement, si vous le souhaitez, au moyen des « Preferences » (Préférences). Pour vraiment bien démarrer, choisissez New Project (Nouveau projet) dans le menu Fichier. Une fenêtre de dialogue s'affiche, contenant une liste des types de projets possibles.
L'assistant d'Xcode vous permet de créer de nouveaux projets.
Nous voulons créer un programme très simple en Objective-C, sans GUI (Interface Graphique Utilisateur), donc faites défiler vers le bas jusqu'à sélectionner Foundation Tool (Outil de création) dans la section Command Line Utility (Utilitaire de ligne de commande).
Définir le nom et l'emplacement du nouveau projet.
Entrez un nom pour votre application, tel que "justeunessai". Choisissez un emplacement où enregistrer votre projet, puis cliquez sur Terminer.
Le projet que nous nous apprêtons à créer peut être exécuté depuis le Terminal. Si vous vous sentez en mesure de le faire, et souhaitez éviter des tracas, assurez-vous que le nom de votre projet ne se compose que d'un mot. De même, il est de coutume de ne pas faire commencer par une majuscule les noms de programmes lancés par le terminal. D'autre part, les noms de programmes ayant une interface utilisateur graphique devront commencer par une majuscule.
VIII-C. Explorer Xcode▲
Maintenant, vous vous trouvez face à une fenêtre que vous verrez très souvent en tant que programmeur. La fenêtre comporte deux cadres. À gauche il y a le cadre "Groups & Files (Groupes & Fichiers)" permettant d'accéder à tous les fichiers composant votre programme. Actuellement il n'y a en pas trop, mais ultérieurement, lorsque vous créerez des programmes multilingues avec GUI, c'est là que les fichiers de votre GUI et les différentes langues pourront être trouvés. Les fichiers sont regroupés et conservés dans des dossiers, mais ne recherchez pas ces dossiers sur votre disque dur. Xcode fournit ces dossiers virtuels ("Groups") à seules fins d'organiser votre bazar.
Dans le cadre de gauche nommé Groupes et Fichiers, ouvrez le groupe justeunessai pour atteindre le groupe intitulé Source. Dans celui-ci, il y a un fichier nommé justeunessai.m [1]. Vous vous souvenez que chaque programme doit contenir une fonction appelée main() ? Eh bien, c'est le fichier qui contient cette fonction main(). Plus loin dans ce chapitre, nous le modifierons pour y inclure le code de notre programme. Si vous ouvrez justeunessai.m en double-cliquant sur son icône, vous aurez une agréable surprise. Xcode vous a déjà créé la fonction main().
//[1]
#
import
<Foundation/Foundation.h>
int
main (
int
argc, const
char
*
argv[]) //[1.2]
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init]; //[1.4]
// insérez votre code ici...
NSLog
(
@"Bonjour, tout le monde !"
);
[pool drain]; //[1.7]
return
0
;
}
Jetez un coup d'œil au programme et cherchez-y des choses connues. Vous verrez :
- la déclaration d'importation requise pour des fonctions telles que NSLog(), commençant par un dièse ;
- la fonction main() ;
- les accolades qui contiendront le corps de notre programme ;
- un commentaire, qui nous invite à mettre notre code à cet endroit ;
- une déclaration NSLog() pour afficher une chaîne à l'écran ;
- la déclaration return 0;.
Il y a aussi deux ou trois choses que vous ne connaîtrez pas :
- deux curieux arguments entre les parenthèses de la fonction main() [1.2] ;
- une déclaration commençant par NSAutoreleasePool [1.4] ;
- une autre déclaration contenant les mots pool et drain [1.7].
Personnellement, je ne suis pas très ravi quand des auteurs de livre me présentent du code plein de déclarations inconnues en me promettant que tout s'éclaircira plus tard. Pour sûr. C'est la raison pour laquelle j'ai changé mes habitudes en vue de vous familiariser avec la notion de «fonctions» afin que vous ne soyez pas confronté à de trop nombreux nouveaux concepts.
Vous savez déjà que les fonctions sont un moyen d'organiser un programme, que chaque programme a une fonction main(), et à quoi ressemble une fonction. Cependant, je dois admettre que, pour l'instant, je ne peux pleinement expliquer tout ce que vous voyez dans l'exemple [1]. Je suis vraiment désolé de devoir vous demander d'ignorer, pour le moment, ces déclarations ([1.2, 1.4 et 1.7]). Il y a d'autres choses du langage Objective-C avec lesquelles vous devez d'abord vous familiariser, afin de pouvoir écrire de petits programmes. La bonne nouvelle est que vous avez déjà passé deux chapitres difficiles, et que les trois chapitres à venir sont assez faciles. Ensuite, nous devrons à nouveau faire face à des choses plus difficiles.
Si vous ne souhaitez vraiment pas rester sans explication, en voici le résumé.
Les arguments de la fonction main() sont nécessaires pour exécuter le programme depuis le Terminal. Votre programme occupe de la mémoire. De la mémoire que d'autres programmes souhaiteront utiliser lorsque vous en aurez fini avec lui. En tant que programmeur, c'est à vous de réserver la mémoire dont vous avez besoin. Tout aussi important, vous devez restituer la mémoire quand vous en avez fini. C'est ce à quoi servent les deux déclarations contenant le mot "pool".
VIII-D. Build and Go (Compiler et exécuter)▲
Exécutons le programme fourni par Apple [1]. Tout d'abord nous devons ouvrir la fenêtre Console, se trouvant dans le menu Run (Exécuter), pour voir les résultats. Puis pressez sur l'icône du deuxième marteau étiquetée "Build and Go" pour construire (compiler) et exécuter l'application.
Le programme est exécuté et les résultats sont affichés dans la fenêtre Console, avec quelques informations supplémentaires. La dernière phrase indique que le programme a quitté (s'est arrêté) sur return 0. Là, vous voyez la valeur zéro qui est retournée par la fonction main(), comme indiqué au chapitre 3 [7-9]. Donc, notre programme est parvenu à la dernière ligne et ne s'est pas arrêté prématurément. Jusqu'ici, tout va bien !
VIII-E. Boguer▲
Revenons à l'exemple [1], et voyons ce qui se passe s'il y a un bogue dans le programme. Par exemple, j'ai remplacé la déclaration NSLog() par une autre, mais ai "oublié" le point-virgule indiquant la fin de la déclaration.
//[2]
#
import
<Foundation/Foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
// insérez le code ici...
NSLog
(
@"Julia est mon actrice favorite"
) //Oups, j'ai oublié le point-virgule !
[pool drain]; //[2.9]
return
0
;
}
Pour construire l'application, pressez sur l'icône de construction dans la barre d'outils. Un cercle rouge apparaît devant la déclaration [2,9].
Si vous cliquez dessus, la ligne en dessous de la barre d'outils donne une brève description du grief :
error
:
parse error before "drain"
(
erreur : erreur de syntaxe avant "drain"
)
L'analyse syntaxique est l'une des premières choses que fait un compilateur : il parcourt le code et vérifie s'il peut comprendre chaque ligne. Pour l'aider à comprendre la signification des différentes parties, c'est à vous de fournir des indices. Ainsi, pour la déclaration d'importation [2.1], vous devez mettre un signe dièse (#). Pour indiquer la fin d'une instruction [2.8], vous devez mettre un point-virgule. Quand le compilateur arrive à la ligne [2.9], il remarque que quelque chose ne va pas. Toutefois, il ne se rend pas compte que le problème ne s'est pas produit dans cette ligne, mais dans la ligne où le point-virgule est manquant. La grande leçon ici est que si le compilateur essaie de donner un commentaire judicieux, le commentaire n'est pas nécessairement une description précise du vrai problème, et que la position dans le programme n'est pas nécessairement le véritable emplacement de l'erreur (mais elle sera probablement très proche).
Corrigez le programme en rajoutant le point-virgule et exécutez de nouveau le programme pour être sûr qu'il marche bien.
VIII-F. Notre première application▲
Prenons maintenant le code du dernier chapitre, et intriquons-le dans le code fourni par Apple [1], ce qui donne l'exemple [3].
//[3]
#
import
<Foundation/Foundation.h>
float
cercleAire
(
float
leRayon); // [3.3]
float
rectangleAire
(
float
largeur, float
hauteur); // [3.4]
int
main (
int
argc, const
char
*
argv[]) // [3.6]
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
int
imageLargeur;
float
imageHauteur, imageAire,
cercleRayon, cercleSurfaceAire;
imageLargeur =
8
;
imageHauteur =
4.5
;
cercleRayon =
5.0
;
imageAire =
imageLargeur *
imageHauteur;
cercleSurfaceAire =
cercleAire
(
cercleRayon);
NSLog
(
@"Aire de l'image : %f. Aire du cercle : %10.2f."
,
imageAire, cercleSurfaceAire);
[pool drain];
return
0
;
}
float
cercleAire
(
float
leRayon) // [3.22]
{
float
lAire;
lAire =
3.1416
*
leRayon *
leRayon;
return
lAire;
}
float
rectangleAire
(
float
largeur, float
hauteur) // [3.29]
{
return
largeur*
hauteur;
}
Prenez votre temps pour être sûr de bien comprendre la structure du programme. Nous avons les en-têtes de fonction [3.3, 3.4] de nos propres fonctions cercleAire() [3.22] et rectangleAire() [3.29] avant la fonction main() [3.6], comme il se doit. Nos propres fonctions se trouvent en dehors des accolades de la fonction main() [3.5]. Nous avons mis le code du corps de la fonction main() là où Apple nous a dit de le mettre.
Lorsque le code est exécuté, nous obtenons la sortie suivante :
Aire de l'image: 36.000000. Aire du cercle : 78.54.
justeunessai a quitté avec l'état 0.
VIII-G. Déboguer▲
Pour un programme plus compliqué, il devient plus difficile de le déboguer. Si jamais vous voulez découvrir ce qui se passe à l'intérieur du programme pendant qu'il tourne, Xcode rend cela facile à faire. Il suffit de cliquer dans la marge grise à gauche des déclarations dont vous souhaitez connaître les valeurs des variables. Xcode va insérer un "point d'arrêt" représenté par une flèche bleue :
Bien noter que vous verrez les valeurs des variables d'avant que cette déclaration donnée ne soit exécutée ; donc, souvent, vous devrez mettre le point d'arrêt sur la déclaration suivant celle qui vous intéresse.
Maintenant, maintenez la souris enfoncée tout en cliquant sur le deuxième bouton de marteau de la barre d'outils, et un menu se déroulera.
Qui peut se traduire par :
Pour suivre ce qui se passe, vous devrez ouvrir les fenêtres Console et Debugger (Débogueur) du menu Run (Exécuter). La console affiche un texte de ce genre :
[Session started at 2009-06-03 15:48:02 +1000.]
Loading program into debugger?
GNU gdb 6.3.50-20050815 (Apple version gdb-956) (Wed Apr 30 05:08:47 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".tty /dev/ttys000
Program loaded.
sharedlibrary apply-load-rules all
run
[Switching to process 86746 local thread 0x2d03]
Running?
Ce qui peut se traduire par :
[Session commencée le 03/06/2009 à 15:48:02 +1000.]
Chargement du programme dans le débogueur...
GNU gdb 6.3.50-20050815 (version gdb-956 d'Apple) (Mer 30 Avril 05:08:47 UTC 2008)
Copyright 2004 Free Software Foundation, Inc
GDB est un logiciel libre, couvert par la Licence publique générale GNU, et vous êtes invité à en modifier et/ou à en distribuer des exemplaires sous certaines conditions.
Taper "show copying" pour voir les conditions.
Il n'y a absolument aucune garantie concernant GDB. Taper "show warranty" pour plus de détails.
Ce GDB a été configuré en tant que "i386-apple-darwin".tty /dev/ttys000
Programme chargé.
bibliothèque partagée apply-load-rules complète
Exécuter
[Bascule sur le processus 86746 fil local 0x2d03]
Exécution ?
Ceci nous montre que notre application a été compilée et lancée, et que le débogueur s'est chargé dedans.
La fenêtre Debugger (Débogueur) devrait ressembler à cela :
Le débogueur de Xcode vous permet d'exécuter le programme pas à pas et d'examiner les variables.
Le programme s'exécutera jusqu'à ce qu'il atteigne le premier point d'arrêt. Si vous examinez le panneau supérieur droit de la fenêtre, vous pourrez voir les valeurs des différentes variables. Toutes les valeurs définies ou modifiées depuis le dernier point d'arrêt sont affichées en rouge. Pour poursuivre l'exécution, utilisez le bouton Continue/Continuer. Le débogueur est un puissant outil. Jouez dessus un moment afin de vous familiariser avec.
VIII-H. Conclusion▲
Nous possédons maintenant tout ce qu'il faut pour écrire, déboguer et exécuter de simples programmes pour Mac OS X.
Si vous ne souhaitez pas créer de programmes avec interface utilisateur graphique, la seule chose qu'il vous reste à faire est d'accroître vos connaissances en Objective-C afin de vous permettre de développer des programmes non graphiques plus sophistiqués. C'est précisément ce que nous ferons dans les prochains chapitres. Après cela, nous plongerons dans les applications avec GUI. Lisez la suite !