Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » [Tutoriel] Compiler des add-ins avec CMake (fxSDK)
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

[Tutoriel] Compiler des add-ins avec CMake (fxSDK)

Posté le 29/01/2021 15:29

Ce topic fait partie de la série de topics du fxSDK.

Ce tutoriel explique les bases de CMake et montre comment l'utiliser avec le fxSDK pour compiler des add-ins. L'objectif de ce tutoriel est de donner aux développeurs d'add-ins une compréhension minimale de la compilation de projets, pour vous permettre de maintenir le code lors des évolutions du fxSDK. C'est à la fois un tutoriel à lire de haut en bas et une référence à venir consulter quand vous aurez un doute dans la gestion de vos programmes.

Le fxSDK a longtemps utilisé un Makefile simple pour compiler les projets. Mais cela avait plusieurs inconvénients, essentiellement parce que les personnes débutant avec les add-ins n'avaient (à juste titre) pas envie ou pas le temps d'apprendre à le maîtriser, ce qui rendait son utilisation et sa mise à jour difficile. Le support de CMake a été introduit avec le fxSDK 2.3 pour résoudre ce problème, car il est plus accessible pour vous et bien plus pratique à maintenir pour moi.

Dans ce tutoriel, nous allons voir :

Les fichiers et commandes utilisées pour compiler avec CMake
La syntaxe du langage CMake
Les sources, cibles et dépendances d'un système de compilation
Utiliser des options de compilation et des bibliothèques
La gestion des assets avec fxconv, les g1a et g3a
Un système minimal fonctionnel
L'add-in par défaut du fxSDK, pas-à-pas
Conclusion

C'est parti !


Les fichiers et commandes utilisées pour compiler avec CMake

Le fichier principal qui décrit comment votre add-in doit être compilé est CMakeLists.txt. Tout comme le Makefile qu'il remplace, c'est un fichier qui décrit quelles sont les sources, les cibles, et les options.

La commande cmake lance CMake, qui va lire CMakeLists.txt et générer un dossier de compilation avec un Makefile contenant les instructions (CMake ne compile pas lui-même). Une fois que c'est fait, on peut lancer make dans ce dossier pour compiler le projet.

Le dossier de compilation doit absolument être séparé, et du coup le dossier d'un add-in ressemblera généralement à ça (c'est par exemple le cas du projet par défaut du fxSDK) :

MonAddIn
├── assets-cg
│   └── ... (les assets)
├── assets-fx
│   └── ... (les assets)
├── build-cg
│   └── ... (les fichiers compilés)
├── build-fx
│   └── ... (les fichiers compilés)
├── CMakeLists.txt
└── src
    └── ... (les sources)

Le dossier build-fx est créé par CMake quand on compile pour Graph mono, et le dossier build-cg quand on compile pour Graph 90+E.

En principe, on peut lancer CMake avec la commande « cmake . -B build » pour compiler le projet situé dans le dossier courant (.) et stocker les fichiers compilés dans le dossier build. Mais, dans le cas de la calculatrice, il faut ajouter quelques informations en plus :

• D'abord il faut indiquer que le compilateur est sh-elf-gcc, avec quelques options ;
• Et ensuite comme le fxSDK fournit des modules pour vous faciliter la tâche, il faut indiquer où les trouver.

Le fxSDK est programmé pour appeler cmake avec les bonnes options dans la commande fxsdk build-fx. S'il remarque que vous avez un CMakeLists.txt mais pas de dossier de compilation, il lance CMake puis make (pour les curieux, la commande complète est là). Si le dossier de compilation existe déjà, il lance juste make. Du coup dans vos projets vous n'aurez souvent besoin que de ces deux commandes.

# Compiler pour Graph mono
% fxsdk build-fx
# Compiler pour Graph 90+E
% fxsdk build-cg

Sur ce, voyons voir comment CMakeLists.txt fonctionne et comment on peut compiler un projet avec.


La syntaxe du langage CMake

CMakeLists.txt est une sorte de programme qui décrit votre projet en appelant des fonctions ou des modules. La syntaxe est la même pour tous les appels, et c'est quelque chose comme ça :

nom_de_la_fonction(arg1 arg2 OPTION ARGUMENT valeur OPTION ...)

Par exemple, la fonction install() permet de spécifier des fichiers à installer. Un appel peut ressembler à ça :

install(FILES lib1.h lib2.h DESTINATION "${FXSDK_COMPILER_INSTALL}/include")

Il y a deux arguments dans cet appel :
• D'abord FILES lib1.h lib2.h, qui indique la liste des fichiers à installer.
• Et ensuite DESTINATION "${FXSDK_COMPILER_INSTALL}/include", qui indique où on les installe.

L'équivalent en Python aurait des arguments nommés et ressemblerait à ça :

install(files=["lib1.h","lib2.h"], destination=f"{FXSDK_COMPILER_INSTALL}/include")

FILES et DESTINATION sont des « mots-clés » de la fonction install(). Pour pouvoir lire la commande, il faut savoir quels sont les mots-clés pour découper au bon endroit. En général ce n'est pas difficile c'est les mots tout en majuscules ; la liste exacte est donnée dans la documentation de install(). Si vous avez un bon éditeur de texte, il les colorera automatiquement pour vous aider.

Pour prendre un autre exemple, la fonction find_package() permet de rechercher une bibliothèque ou un outil sur l'ordinateur qui effectue la compilation. Un appel ressemblera à ça :

find_package(Gint 2.1 REQUIRED)

Ici il y a trois arguments :
• D'abord le nom du paquet, « Gint », qui est toujours à la première place ;
• Ensuite la version « 2.1 », qui doit être à la deuxième place si on l'indique ;
• Et enfin l'option REQUIRED, indiquant que si gint n'est pas trouvé on veut émettre une erreur.

En Python, ça ressemblerait à ça :

find_package("Gint", "2.1", required=True)

Ces deux exemples montrent les quatre types d'arguments qu'on peut trouver dans les fonctions :
• Les arguments positionnels sont à une position fixe, et on donne directement la valeur : « Gint ».
• Les options sont des mots-clés pour activer ou désactiver des options : « REQUIRED ».
• Les arguments simples sont formés d'un mot-clé suivis d'une seule valeur : « DESTINATION un_dossier ».
• Les arguments multiples sont formés d'un mot-clé suivi d'une ou plusieurs valeurs : « FILES lib1.h lib2.h ».

Toutes les données sont des chaînes de caractères, mais quand il n'y pas de caractères spéciaux on n'est pas obligés de mettre les guillemets. On pourrait écrire "FILES" par exemple mais c'est plus léger d'éliminer les guillemets et d'écrire FILES. Les points, slashs et autre caractères qu'on trouve habituellement dans les noms de fichiers peuvent être utilisés sans guillemets. Personnellement j'en mets surtout quand il y a des variables à substituer dans la chaîne de caractères, par exemple dans "${FXSDK_COMPILER_INSTALL}/include". La notation ${VAR} sert à insérer la valeur d'une variable.

Au passage, on peut utliser # pour ajouter des commentaires qui continuent jusqu'à la fin de la ligne.

Avec ça vous devriez pouvoir déchiffrer les CMakeLists.txt sans trop de problèmes. On peut du coup s'attaquer au plat de résistance.


Les sources, cibles et dépendances d'un système de compilation

Les sources, les cibles (“targets” en anglais), et les dépendances sont trois grands concepts de tout système de compilation. Le but de la compilation est de compiler les sources pour produire les cibles, et de surveiller les dépendances pour recompiler le projet quand des changements sont faits.

Typiquement, dans un add-in écrit en C :
• La cible est l'add-in final (le fichier .g1a ou .g3a).
• Les sources sont les fichiers C que l'on veut compiler.
• Les dépendances sont les fichiers C ainsi que les fichiers d'en-tête (les .h).

Le processus complet consiste à compiler les fichiers C pour produire l'add-in, et si une dépendance (un fichier C ou un en-tête) change, on recompile les fichiers C impactés (ceux qui ont changé ou qui incluent un en-tête qui a changé).

Déclarer les cibles, les sources et les dépendances est le travail principal de votre CMakeLists.txt. En général vous n'avez pas besoin d'indiquer comment appeler GCC pour compiler puisque CMake sait déjà faire et le fxSDK a fourni les détails spécifiques à la calculatrice : il vous suffit de nommer les fichiers à compiler.

Déclarer les cibles et les sources

Dans CMake, il y a trois types de cibles et chacun a une fonction servant à le déclarer.
• Des exécutables : typiquement des logiciels ou des add-ins. On en crée avec add_executable().
• Des bibliothèques que vous pouvez réutiliser dans des exécutables. On en crée avec add_library().
• Des cibles personnalisées, pour tout le reste. On en crée avec add_custom_target().

Vous pouvez voir que le prototype de add_executable(), si on ignore les options utilisées plus rarement, est le suivant.

add_executable(<name> [source1] [source2 ...])

Le <name> est le nom de votre cible, il vous permet d'identifier la cible dans le reste de CMakeLists.txt. Par défaut, c'est aussi le nom du fichier exécutable. Il est entre chevrons donc c'est un argument obligatoire. Ensuite, il y a les sources ; les noms sont entre crochets donc elles sont facultatives (mais un exécutable vide ne sert à rien). Tous ces arguments sont positionnels, il n'y a pas de mot-clé ici.

Dans un add-in tout simple, on créerait le fichier exécutable avec une commande comme ci-dessous.

add_executable(MonAddin src/main.c)

Quasiment tout le système de compilation est contenu dans cette seule commande ! Pour que ça marche, il ne manque à indiquer que le fait de lier avec gint ou fxlib, et de générer le g1a/g3a (ce qui est fait par le fxSDK parce que CMake ne connaît pas ces formats). Je reviens sur ces points bientôt.

Pour une bibliothèque, c'est presque pareil. Voici par exemple ce que fait libprof pour Graph mono :

add_library(prof-fx STATIC libprof.c)

Ici j'ai utilisé l'option STATIC pour créer une « bibliothèque statique ». Sinon CMake serait tenté de créer une « bibliothèque dynamique », un autre genre courant sur ordinateur mais bien plus compliqué et qu'on n'a pas sur la calculatrice.

Dans l'ensemble le principe est le même, et là aussi CMake gère toute la suite. Si vous regardez le prototype de add_custom_target() vous verrez que c'est un peu plus compliqué, c'est parce que cette fois vous devez indiquer les commandes à lancer pour produire la cible. Vous n'en aurez que rarement voire jamais besoin.

Déclarer les dépendances

Les dépendances ce sont les fichiers qui impactent le résultat de la compilation (on dit que le résultat de la compilation dépend de ces fichiers). Chaque fois qu'une dépendance change, il faut recompiler pour s'assurer que le résultat est à jour.

Il y a plusieurs types de dépendances, souvent vous aurez affaire à une de celles-là :
• Les dépendances qui affectent la compilation d'un fichier C sont ce fichier C, les en-têtes qu'il incluent, les en-têtes que ces en-têtes incluent, et ainsi de suite.
• Les dépendances qui affectent la conversion d'un asset sont l'asset lui-même et ses métadonnées pour fxconv (j'y reviendrai).
• Les dépendances qui affectent l'add-in final, en plus des sources et des assets, sont les bibliothèques, le CMakeLists.txt, et quelques autres détails.

La bonne nouvelle c'est que CMake s'occupe tout seul de déclarer la plupart de ces dépendances ! On n'a que très rarement besoin de le faire à la main. En particulier, le mécanisme un peu compliqué utilisé dans les Makefile pour rechercher les en-têtes inclus et obtenir les dépendances est géré tout seul par CMake. Dans votre CMakeLists.txt vous n'aurez quasiment jamais besoin de mentionner vos fichiers d'en-tête, car CMake va automatiquement les rechercher lorsqu'il liste les dépendances.

Si jamais vous avez besoin de déclarer des dépendances supplémentaires, jetez un oeil à set_source_files_properties() et set_target_properties().

Comme vous pouvez le voir, la déclaration des sources, cible et dépendances ne demande pas beaucoup d'efforts en général. On va quand même s'attarder sur les options de compilation dont vous pourrez avoir besoin si votre projet grandit.


Utiliser des options de compilation et des bibliothèques

Lorsque vous compilez un programme, vous pouvez modifier le comportement de GCC de différentes façons : afficher plus de warnings ou moins de warnings, activer des optimisations, choisir la version exacte du langage C que vous utilisez... tout cela se fait avec des options de compilation.

Dans CMake, les options de compilation sont définies pour une cible à l'aide de la fonction target_compile_options() qui a le prototype (simplifié) suivant :

target_compile_options(<cible> <PUBLIC|PRIVATE|INTERFACE> <options...>)

Le premier arguent est la cible à laquelle les options vont s'appliquer. Le deuxième indique dans quel contexte les options doivent être utilisées :
PRIVATE active les options durant la compilation de la cible (le cas de base) ;
INTERFACE active les options durant la compilation de fichiers qui utilisent la cible (quand la cible est une bibliothèque) ;
PUBLIC fait les deux à la fois.

Et enfin, viennent les options sous la forme d'arguments en ligne de commande, par exemple -Wall pour activer (presque) tous les warnings, ou -O2 pour optimiser le vitesse du programme au niveau 2. Dans le projet par défaut du fxSDK, on a les options suivantes :

target_compile_options(myaddin PRIVATE -Wall -Wextra -Os)

Cela active les options -Wall, -Wextra et -Os, qui activent un bon paquet de warnings et l'optimisation vitesse/taille du programme. myaddin est le nom de la cible, celui qui est donné comme premier argument à add_executable().

Pour les bibliothèques, c'est similaire. La différence est qu'il faut commencer par les trouver, ce qu'on fait avec la fonction find_package(). Son prototype (simplifié) est le suivant :

find_package(<name> [version] [REQUIRED])

Le premier argument est le nom de l'outil qu'on cherche ; le second (optionnel) est la version qu'on l'on souhaite utiliser, et si l'option REQUIRED est activée mais l'outil n'est pas trouvé CMake échouera avec une erreur. Si une version plus récente mais compatible avec celle demandée est trouvée, elle sera utilisée. Par exemple, un add-in qui utilise gint avec des fonctionnalités de la version 2.1 pourra indiquer :

find_package(Gint 2.1 REQUIRED)

Le paquet fournit ses propres cibles, dans le cas de gint il fournit une cible Gint que l'on désigne en la préfixant du nom du paquet, ce qui donne Gint::Gint. Pour compiler votre programme avec, utilisez target_link_libraries() :

target_link_libraries(<cible> <bibliothèques...>)

Un exemple tout simple pour lier avec gint serait donc :

target_link_libraries(myaddin Gint::Gint)

Vous pouvez spécifier plus d'une bibliothèque d'un coup, et vous n'êtes pas obligés d'utiliser des cibles CMake : vous pouvez écrire directement -lsomelib ou donner le nom d'un fichier .a, ça convient aussi tout à fait.

Avec ça vous êtes parés pour accomplir à peu près toutes les tâches usuelles. Il nous reste un seul point supplémentaire spécifique aux add-ins sur la calculatrice à voir : la gestion des assets et la génération des fichiers g1a et g3a.


La gestion des assets avec fxconv, les g1a et g3a

Les assets (images, polices, maps, dialogues, et autres données de votre application) ne sont pas gérés par CMake d'une façon aussi directe que add_executable(). Le fxSDK fournit des outils pour que ça reste transparent pour vous, mais je vais profiter de l'occasion pour détailler un peu comment créer des parties personnalisées dans le système de compilation.

Un concept très utile de CMake des ces situations est les modules. Vous pouvez inclure des fichiers externes dans votre CMakeLists.txt, y compris des fichiers distribués hors du projet. Le fxSDK fournit notamment :
Fxconv.cmake pour déclarer des assets à convertir avec fxconv.
GenerateG1A.cmake et GenerateG3A.cmake pour générer des fichiers g1a et g3a pour des exécutables.

On inclut un module avec la fonction include() qui est aussi simple que :

include(<file|module>)

Par exemple, le module Fxconv.cmake peut être inclus de la façon suivante (parce que le fxSDK indique à CMake que le dossier où Fxconv.cmake est stocké contient des modules).

include(Fxconv)

Actuellement ce module définit un nouveau langage FXCONV pour les assets, dont la commande de compilation appelle fxconv, et fournit une fonction fxconv_declare_assets() qui vous permet de lister vos fichiers d'assets pour qu'ils soient traités correctement par CMake.

Concrètement, pour traiter un fichier d'asset il faut faire deux choses :
• Indiquer que son langage est FXCONV pour qu'il soit compilé avec fxconv et pas GCC ;
• Indiquer une dépendance de l'asset vers le fxconv-metadata.txt du même dossier.

La dépendence existe car fxconv-metadata.txt (le fichier qui remplace le système bancal utilisé dans project.cfg) modifie les paramètres de la conversion, donc le résultat. Si on change les métadonnées, il faut reconvertir l'asset même si le fichier source (par exemple une image ou une police) n'a pas changé.

Ces deux informations (le langage et les dépendances d'un fichiers source) sont des propriétés du fichier source dans CMake, et on peut les modifier avec set_source_files_properties(). Si vous êtes curieux, voici comment le module Fxconv modifie le langage et la dépendance.

Et en fait c'est tout ! Les assets sont maintenant traités dans des fichiers sources dans add_executable() ou add_library() et seront simplement compilés avec fxconv au lieu de GCC. On peut donc mélanger les fichiers C et les assets et écrire :

fxconv_declare_assets(assets-fx/example.png WITH_METADATA)
add_executable(myaddin src/main.c assets-fx/example.png)

La fonction fxconv_declare_assets() prend en paramètre une liste de fichiers d'assets. L'option WITH_METADATA ajoute la dépendance (c'est ce que vous voulez la plupart du temps).

Pour les fichiers g1a et g3a, c'est à peu près la même histoire, vous incluez le module et appelez la fonction qui convient pour générer un fichier g1a ou g3a après la compilation de votre exécutable.

include(GenerateG1A)
generate_g1a(TARGET <cible> [OUTPUT <fichier>] ...)

La cible est le nom de votre cible exécutable (le premier argument de add_executable()). OUTPUT permet de choisir le nom du fichier de sortie ; et ensuite viennent les options du g1a, toutes facultatives :

NAME <nom> pour indiquer le nom de l'add-in dans le menu SYSTEM ;
INTERNAL <nom interne> pour indiquer le nom interne (en général vous n'avez pas besoin de l'indiquer) ;
VERSION <MM.mm.pppp> pour donner la version du programme ;
DATE <YYYY.mmdd.hhmm> pour la date de compilation (la valeur par défaut est la date du jour) ;
ICON <image> pour choisir l'icône (qui doit être un fichier PNG de 30x19 pixels).

include(GenerateG3A)
generate_g3a(TARGET <cible> [OUTPUT <fichier>] ...)

Le fonctionnement pour les g3a est identique. Il y a un peu moins d'options car mkg3a ne donne pas accès à tous les détails :

NAME <nom> pour indiquer le nom de l'add-in. Le nom est aussi affiché sur le menu principal, mais parfois on n'en veut pas. Vous pouvez indiquer un nom vide en écrivant « NAME "" » pour que l'icône soit affichée sans texte par dessus.
ICONS <icone-unselected> <icon-selected> pour donner les icônes (deux images PNG de 92x64 pixels).

Voilà ce que ça donne dans le projet par défaut.

# Pour Graph mono
generate_g1a(TARGET myaddin OUTPUT "MyAddin.g1a" NAME "MyAddin"
  ICON assets-fx/icon.png)
# Pour Graph 90+E
generate_g3a(TARGET myaddin OUTPUT "MyAddin.g3a" NAME "MyAddin"
  ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)



Un système minimal fonctionnel

Avec ça, on peut maintenant compiler un add-in pour de vrai ! Voici le plus petit système de compilation d'add-in pour Graph mono avec CMake.

cmake_minimum_required(VERSION 3.18)
project(MyAddin)

include(GenerateG1A)
include(Fxconv)
find_package(Gint 2.1 REQUIRED)

fxconv_declare_assets(assets-fx/example.png)
add_executable(myaddin src/main.c assets-fx/example.png)

target_compile_options(myaddin PRIVATE -Wall -Wextra -Os)
target_link_libraries(myaddin Gint::Gint)

generate_g1a(TARGET myaddin OUTPUT "MyAddin.g1a" NAME "MyAddin"
  ICON assets-fx/icon.png)

Comme vous pouvez le voir, c'est simplement un combinaison de tout ce qu'on a vu jusqu'ici. Il n'y a que deux nouveautés dont il faut s'occuper au début de CMakeLists.txt : d'abord cmake_minimum_required() pour indiquer la version de CMake que vous suivez (les fonctions ont changé au cours du temps), et puis project() pour nommer le projet (on peut aussi donner sa version et indiquer les langages si besoin).

Vous pouvez coller ça dans votre CMakeLists.txt et lancer fxsdk build-fx, vous aurez votre MyAddin.g1a.


L'add-in par défaut du fxSDK, pas-à-pas

Le CMakeLists.txt que le fxSDK vous donne dans les nouveaux projets est un poil plus compliqué (il permet notamment de compiler pour Graph mono et Graph 90+E), alors voici les détails pas-à-pas ! Le début commence exactement comme on l'attend, en incluant les modules et gint.

# Configure with [fxsdk build-fx] or [fxsdk build-cg], which provide the
# toolchain file and module path of the fxSDK

cmake_minimum_required(VERSION 3.18)
project(MyAddin)

include(GenerateG1A)
include(GenerateG3A)
include(Fxconv)
find_package(Gint 2.1 REQUIRED)

Ensuite on définit quelques variables pour spécifier les fichiers sources, les assets communs Graph mono/Graph 90+E, les assets spécifiques à la Graph mono, et les assets spécifiques à la Graph 90+E.

set(SOURCES
  src/main.c
  # ...
)
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets
set(ASSETS
  # ...
)
set(ASSETS_fx
  assets-fx/example.png
  # ...
)
set(ASSETS_cg
  assets-cg/example.png
  # ...
)

Je n'ai pas encore parlé des variables même si quelques-unes sont utilisées dans les exemples précédents. C'est assez direct :
• On peut créer ou modifier une variable avec set() : set(<nom> <valeur>).
• On peut obtenir la valeur d'une variable avec ${nom} (en général entre guillemets pour ne pas être embêté s'il y a des espaces ou points-virgules dans les contenus).

Voici un exemple tout simple. message() est juste un print, c'est utile pour debugger :

set(MA_VARIABLE "du texte")
message("MA_VARIABLE contient ${MA_VARIABLE}")

Ce code affiche "MA_VARIABLE contient du texte" quand CMake est lancé.

Dans le projet, on utilise une fonctionnalité de set() qui permet de spécifier plusieurs valeurs pour faire une « liste » ; c'est une fausse liste, les valeurs sont juste séparées par des points-virgules.

set(SOURCES src/main.c src/game.c)
message("${SOURCES}") # -> affiche "src/main.c;src/game.c"

Ensuite on déclare les assets, comme précédemment.

fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)

Ici on ne met pas de guillemets autour des variables, c'est fait exprès : comme ça la liste sera « déroulée » en une liste d'arguments (un peu comme fonction(*liste) en Python). Si ça vous échappe ne vous inquiétez pas trop.

Ensuite, on crée la cible exécutable. C'est là qu'on voit apparaître des différences entre Graph mono et Graph 90+E. Ce dont il faut se souvenir c'est que le CMakeLists.txt sera exécuté deux fois : une fois pour Graph mono quand on utilise fxsdk build-fx, et une fois pour Graph 90+E quand on utilise fxsdk build-cg. Il n'y a donc besoin de se soucier que d'une seule plateforme à la fois, et le fxSDK indique laquelle avec deux variables :

FXSDK_PLATFORM vaut « fx » quand on compile pour Graph mono et « cg » quand on compile pour Graph 90+E.
FXSDK_PLATFORM_LONG vaut « fx9860G » quand on compile pour Graph mono et « fxCG50 » quand on compile pour Graph 90+E.

La deuxième est plus lisible mais la première est pratique dans certains cas. Par exemple, dans la cible exécutable qu'est notre add-in, on veut ajouter uniquement les assets de la platforme courante, ce qu'on peut faire élegamment avec FXSDK_PLATFORM.

add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os)
target_link_libraries(myaddin Gint::Gint)

Tout comme dans fxconv_declare_assets(), on passe les listes de sources et assets en argument (donc sans guillemets). ${ASSETS_${FXSDK_PLATFORM}} devient ${ASSETS_fx} ou ${ASSETS_cg} selon la plateforme pour laquelle on compile, ce qui permet de choisir élégamment la bonne liste d'assets. Les sources de la cible sont donc les fichiers C, les assets communs, et les assets spécifiques à la plateforme à laquelle on est en train de s'intéresser.

Ensuite on ajoute les options de compilation et on linke avec gint, rien d'inattendu ici.

if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
  generate_g1a(TARGET myaddin OUTPUT "MyAddin.g1a"
    NAME "MyAddin" ICON assets-fx/icon.png)
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
  generate_g3a(TARGET myaddin OUTPUT "MyAddin.g3a"
    NAME "MyAddin" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
endif()

Et enfin on génère un fichier g1a ou g3a. On utilise if() pour tester la plateforme, et on utilise generate_g1a() ou generate_g3a() selon le cas. La syntaxe du if n'est pas vraiment intuitive, on ne peut pas écrire des conditions avec ==, <= ou != comme dans les langages de programmation ; à la place il faut tester avec des mots-clés comme STREQUAL. C'est un peu comme test en bash (pour ceux qui connaissent). Dans l'ensemble, consultez la documentation en cas de doute.

Et voilà, vous savez maintenant comment CMakeLists.txt fonctionne dans votre add-in, et vous êtes équipé·e pour aborder sereinement sa modification pour répondre à vos besoins futurs.


Conclusion

CMake est un système de compilation riche et avec sa part de complexité, mais qui présente aux débutants des moyens simples et directs pour gérer la compilation de programmes. Dans ce tutoriel, on a vu comment un add-in pour la calculatrice pouvait se compiler avec CMake et le fxSDK, en couvrant tant le code source que les assets, les options de compilation, et l'utilisation de bibliothèques.

J'espère que ce tutoriel vous aura permis de comprendre et maîtriser votre système de compilation, et ainsi de vous faciliter la gestion de projet au cours des évolutions à la fois de vos programmes et des outils comme le fxSDK.


Kamrade Hors ligne Membre Points: 48 Défis: 0 Message

Citer : Posté le 14/02/2021 15:35 | #


Bonjour
J'ai fichier src d'un jeu (Gravity duck avec le nouveau Monocohrome lib compatible) mais il est sur Windowset j'ai wsl d'installer
Comment je fait pour y accéder à travers wsl?
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 14/02/2021 15:38 | #


Apparemment le disque Windows est visible depuis WSL dans le dossier /mnt. Là-dessus les tutoriels WSL t'aideront plus que moi... qui n'ai pas Windows et donc lis des tutoriels WSL pour essayer de répondre. xD
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Kamrade Hors ligne Membre Points: 48 Défis: 0 Message

Citer : Posté le 14/02/2021 15:41 | #


Ok
Potter360 Hors ligne Rédacteur Points: 1221 Défis: 2 Message

Citer : Posté le 14/02/2021 15:42 | #


cp /mnt/c/Users/utilisateur/Documents/dossier/gravityduck /chemin
Globalement, coder. Mal, mais coder.
Kamrade Hors ligne Membre Points: 48 Défis: 0 Message

Citer : Posté le 14/02/2021 16:00 | #


Merci
Gibroule Hors ligne Membre Points: 4 Défis: 0 Message

Citer : Posté le 03/01/2024 20:01 | #


Salut,
Tout d'abord je tenais à te remercier Lephenixnoir pour ton travail fantastique avec le fxsdk, gint et tous les outils que tu as développé. Cependant, je m'arrache les cheveux depuis 3 jours sur un problème avec CMake.
Depuis la version 3.24, la manière de déclarer FXCONV comme un nouveau langage ne fonctionne plus, disant qu'il faut utiliser la fonction enable_language(FXCONV). Je ne sais pas si c'est un bug de cmake ou pas puisque je n'ai rien trouvé à ce sujet, sur les forum ou le changelog...
J'ai essayer de le faire et de définir la variable CMAKE_FXCONV_COMPILER mais ça n'a pas non plus fonctionné.
Je tenais à savoir si ce problème est connu et s'il existe une solution.
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 03/01/2024 21:54 | #


Salut Gibroule ! Merci pour ton retour, ça me fait très plaisir que mes outils soient utiles.

Le problème est en effet connu, je m'en suis occupé avec ce commit en Août 2022. J'ai CMake 3.28 installé sur ma machine actuellement donc ça devrait marcher. Ce commit a été l'objet de la version 2.9.1 du SDK, et donc selon toute logique tu devrais l'avoir sur ta machine. Je croyais que je n'en entendrais plus parler.

Peux-tu me montrer un peu plus de détails sur ton installation, fxsdk --version ainsi qu'une copie des messages de CMake ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Gibroule Hors ligne Membre Points: 4 Défis: 0 Message

Citer : Posté le 03/01/2024 22:41 | #


Ah je comprends, étant sur archlinux, j'ai utilisé le dépôt mis à disposition par Dark Storm mais les paquets sont restés à la version 2.8.0. Je pense que je vais passer par gitea pour mon installation car je ne sais pas s'il sont encore maintenus.
Pour le message de cmake c'était :
-- The C compiler identification is GNU 11.2.0
-- The CXX compiler identification is GNU 11.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/sh-elf-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/sh-elf-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Gint: TRUE (found suitable version "2.8.0", minimum required is "2.8")
-- Configuring done (0.3s)
CMake Error in CMakeLists.txt:
  The language FXCONV was requested for compilation but was not enabled.  To
  enable a language it needs to be specified in a 'project' or
  'enable_language' command in the root CMakeLists.txt


-- Generating done (0.0s)
CMake Generate step failed.  Build files cannot be regenerated correctly.

Merci pour l'aide !
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 03/01/2024 23:10 | #


Ah en effet les dépôts de Dark Storm n'ont pas été mis à jour depuis un moment. Tu peux toujours utiliser GiteaPC ou compiler manuellement. Bon courage !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Gibroule Hors ligne Membre Points: 4 Défis: 0 Message

Citer : Posté le 03/01/2024 23:18 | #


Nickel alors, merci !

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 128 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd