Articles tagués “build

Activer la compilation multicœur dans Eclipse CDT

Mon premier article sur ce blog expliquait comment dire à make d’utiliser plusieurs cœurs lors de la compilation. Il suffit d’utiliser l’option -j pour spécifier le nombre de jobs pouvant s’exécuter en parallèle. Si vous utilisez Eclipse CDT et son builder interne, il existe aussi une option activer la compilation multicœur. Je l’ai trouvé par hasard aujourd’hui, elle est dans les propriétés du projet puis C/C++ Build et Behavior :

eclipse-compilation-multicoeur

J’ai étonné que cette option ne soit pas cochée par défaut et j’ai bien sûr immédiatement testé ça. Mon projet n’est pas encore très gros, il n’a que 78 fichiers. En l’activant, je suis passé de 31s.792 ms à 13s.114 ms pour le builder. Wouhou !

Publicités

Créer son propre archétype Maven

Aujourd’hui, j’ai enfin pris le temps de voir comment créer son propre archétype Maven. L’idée m’était venue en octobre, notamment avec la lecture de cet article, Maven pour les nuls… les archetypes. Avoir son propre archétype permet de créer un nouveau projet en respectant une structure donnée très simplement. Il est ainsi possible d’uniformiser les développements au sein de l’entreprise en fournissant un modèle qui sera commun à tous les projets. Pour cette expérimentation, j’ai choisi de créer un modèle de projet avec une structure ressemblant à celle que pourrait avoir un projet en C sur MCU et dont l’artéfact généré serait un zip contenant l’intégralité du projet. Je travaille dans Eclipse Mars pour plus de faciliter mais vous pourriez très bien faire la même chose avec un éditeur de texte et la ligne de commande.

Création du modèle de projet

La première étape est de créer un projet tel que j’aimerais que Maven le génère avec mon archétype. Une fois cette coquille créée, je demanderai à Maven de générer l’archétype à partir de ce modèle (template, en anglais). Voici à quoi ressemble mon projet :

maven - archetype - 1 - template

La seconde étape est la personnalisation du fichier pom.xml pour générer non pas un jar mais un zip du projet. Pour cela, il faut utiliser le plugin Assembly de Maven. En suivant les conseils de la section Usage, j’ai rajouté l’utilisation de ce plugin, j’ai choisi le mode project et j’ai demandé à ce que la cible qui va bien d’Assembly soit appelée lors de la phase package du projet. Enfin, j’ai changé le type de packaging du projet de jar vers pom pour ne plus générer de jar mais uniquement le zip d’Assembly. Voici le pom.xml :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gradot</groupId>
    <artifactId>mcu-project-template</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>project</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Création du projet Maven de l’archétype

À ce state, je possède donc un modèle de projet avec la structure et le packaging souhaités. En exécutant mvn package sur le projet, on constate en effet que le dossier de sortie target contient bien 3 archives (zip, tar.gz, targ.bz2). Il faut donc maintenant créer le projet Maven de l’archétype en lui-même, à partir de ce projet template, grâce à la commande mvn archetype:create-from-project. J’ai essayé de le faire directement avec un launch configuration d’Eclipse mais j’ai obtenu l’erreur suivante :

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:2.4:
create-from-project (default-cli) on project mcu-project-template: 
${maven.home} is not specified as a directory: 
'/home/pgradot/Documents/workspace-mars/mcu-project-template/EMBEDDED'. -> [Help 1]

Cela semble être dû à un bug de l’intégration de Maven dans Eclipse. La solution de contournement est simple :  exécuter la commande via le terminal. Le projet Maven de l’archétype est alors disponible dans target/generated-sources/archetype. Pour plus de facilité pour la suite, j’ai créé un projet Eclipse en utilisant une non-default location pointant vers l’emplacement du projet Maven de l’archétype :

maven - archetype - 2 - create eclipse project

Enfin, j’ai rajouté la nature Maven au projet Eclipse en faisant un clic-droit puis Configure / Convert to Maven project. On peut maintenant regarder le contenu de l’archétype et notamment retrouver les fichiers de notre projet template :maven - archetype - 3 - archetype content

Hic ! Les dossiers vides ne sont pas gardés lors de la génération de l’archétype…

Publication et utilisation de ce nouvel archétype

Pour publier l’archétype et ainsi le rendre disponible, il suffit d’appeler la cible install du projet (ou deploy, si les dépôts sont configurés) et l’artéfact de l’archétype se retrouve dans le dépôt local de Maven :

$ ls -l /home/pgradot/.m2/repository/com/gradot/mcu-project-template-archetype
/1.0.0-SNAPSHOT/
total 20
-rw-rw-r-- 1 pgradot pgradot   96 mai   10 08:34 m2e-lastUpdated.properties
-rw-rw-r-- 1 pgradot pgradot  726 mai   10 08:30 maven-metadata-local.xml
-rw-rw-r-- 1 pgradot pgradot 3241 mai   10 08:30 mcu-project-template-archetype
-1.0.0-SNAPSHOT.jar
-rw-rw-r-- 1 pgradot pgradot  988 mai   10 08:24 mcu-project-template-archetype
-1.0.0-SNAPSHOT.pom
-rw-rw-r-- 1 pgradot pgradot  238 mai   10 08:30 _remote.repositories

Je peux maintenant créer un nouveau projet dans Eclipse et demander à Maven d’utiliser mon nouvel archétype (il faut penser à cocher qui va bien la case si l’archétype a été buildé en snapshot, ce qui est le cas ici) :maven - archetype - 4 - create projet

Pour finir je peux constater que j’obtiens un projet semblable à mon projet template (aux dossier vides près… ) et qui se package comme il faut !

maven - archetype - 5 - result


Builder un projet Keil uVision en ligne de commande

J’utilise souvent Keil uVision (4 et 5) dans le cadre du travail. Aujourd’hui, j’ai souhaité pouvoir builder mon projet Keil depuis Eclipse pour pouvoir automatiser le déploiement de mon applicatif sur la carte. Il y a plusieurs étapes dans ce processus :

  1. Compiler mon application Java pour générer un fichier objet à destination de Keil.
  2. Builder le projet Keil pour obtenir un fichier exécutable ELF.
  3. Découper mon fichier ELF en deux fichiers binaires, un pour la flash interne, l’autre pour la flash externe.
  4. Programmer ma carte avec ces 2 fichiers binaires grâce au ST-Link Utility. Cette étape est en fait double car il faut programmer la mémoire interne puis la mémoire externe en sélectionnant à chaque fois le bon fichier.

La première étape est un bête launch configuration d’Eclipse. Les étapes 3 et 4 étaient déjà automatisées grâce à des scripts Ant. Il me restait donc cette étape 2 qui m’obligeait à quitter Eclipse pour aller dans Keil et à cliquer sur le bouton Build.

Pour automatiser cela, il suffisait de trouver la bonne ligne de commande pour appeler Keil et lui dire de builder mon projet. Le site de Keil dédie une page à l’utilisation en ligne de commandes : Keil uVision User’s Guide: Command Line. J’avais donc besoin de l’option -b pour demander de builder le projet. Mon projet ne contient qu’une seule target mais dans le doute (ou histoire de faire bien), je l’ai quand même précisé. La target Ant résultante ressemble à ceci (les noms des propriétés sont explicites, je ne pense pas avoir besoin de vous les montrer) :

<target name="build" description="build Keil project">
	<echo>Building Keil project...</echo>
    <exec executable="${keil.dir}/UV4/UV4.exe">
    	<arg line="-b ${keil.uvprojfile} -t&quot;${keil.target}&quot;"/>
    	<!-- You may add the -j0 option to the above argument line to hide Keil's UI -->
    </exec>
</target>

J’ai eu un problème dont la résolution mérite d’être retenue. Lors de l’appel à ce script, tous les fichiers du projet étaient recompilés même si rien n’avait changé. Normalement, c’est l’option -r qui devrait avoir cet effet. Cette discussion sur le forum Keil m’a aidé à résoudre le problème. La personne avait un problème similaire car le fichier de dépendance de son projet était en lecture seule dans le gestionnaire de sources. Il se trouve que mon projet était dans un dépôt Git et donc ce fichier était versionné, mais il n’était pas en lecture seule. Je l’ai ajouté à l’ignore list et le problème a disparu.

J’avais presque fini : il ne me restait plus qu’à faire un launch group dans Eclipse pour enchainer mes 3 launch configurations (1 programme Java et 2 programmes Ant). J’ai mis un petit moment à comprendre qu’il me fallait choisir Wait until terminated pour empêcher les 2 scripts Ant de s’exécuter en parallèle après avoir sagement attendu que l’application Java soit exécutée complètement.

build keil - launch groupEt voilà ! Je builde un 2 clics maintenant 🙂

J’en profite pour vous dire de toujours automatiser au maximum vos builds ! On a souvent l’impression que trouver un moyen d’automatiser va être plus long que le temps cumulé à réaliser les étapes manuellement. On se dit qu’après tout, on ne devrait pas le faire si souvent, que le projet ne devrait pas être trop long et que ce sera supportable. C’est faux ! Au-delà du fait que réaliser plusieurs étapes manuellement est atrocement pénible, c’est un risque de se tromper et perdre du temps. Ensuite, vous passerez plus de temps que vous ne le pensez à builder à la main. Enfin, ce que vous avez fait pour de précédents projets sera sûrement utilisé pour les projets suivants et vous passerez de moins en moins de temps à automatiser. J’ai souvenir d’un projet où, au bout d’un mois, j’ai écrit un script pour automatiser un processus similaire à celui décrit plus haut, où tout était manuel : ça a changé ma vie et j’ai regretté de ne pas l’avoir plus tôt !

N’hésitez plus, scriptez, automatisez, simplifiez vous la vie !