gint : un noyau pour développer des add-ins
Posté le 20/02/2015 17:30
Ce topic fait partie de la série de topics du fxSDK.
En plus des options de programmation intégrée comme le Basic Casio ou Python, la plupart des calculatrices Casio supportent des
add-ins, des programmes natifs très polyvalents avec d'excellentes performances. Les add-ins sont généralement programmés en C/C++ avec l'aide d'un ensemble d'outils appelé SDK.
Plusieurs SDK ont été utilisés par la communauté avec le temps. D'abord le
fx-9860G SDK de Casio avec fxlib pour Graph monochromes (plus maintenu depuis longtemps). Puis le
PrizmSDK avec libfxcg pour Prizm et Graph 90+E (encore un peu actif sur Cemetech). Et plus récemment celui que je maintiens, le
fxSDK, dont gint est le composant principal.
gint est un unikernel, ce qui veut dire qu'il embarque essentiellement un OS indépendant dans les add-ins au lieu d'utiliser les fonctions de l'OS de Casio. Ça lui permet beaucoup de finesse sur le contrôle du matériel, notamment la mémoire, le clavier, l'écran et les horloges ; mais aussi de meilleures performances sur le dessin, les drivers et la gestion des interruptions, plus des choses entièrement nouvelles comme le moteur de gris sur Graph monochromes.
Les sources de gint sont sur la forge de Planète Casio :
dépôt Gitea Lephenixnoir/gint
Aperçu des fonctionnalités
Les fonctionnalités phares de gint (avec le fxSDK) incluent :
- Toutes vos images et polices converties automatiquement depuis le PNG, sans code à copier (via fxconv)
- Un contrôle détaillé du clavier, avec un GetKey() personnalisable et un système d'événements à la SDL
- Une bibliothèque standard C plus fournie que celle de Casio (voir fxlibc), et la majorité de la bibliothèque C++
- Plein de raccourcis pratiques, comme pour afficher la valeur d'une variable : dprint(1,1,"x=%d",x)
- Des fonctions de dessin, d'images et de texte optimisées à la main et super rapides, surtout sur Graph 90+E
- Des timers très précis (60 ns / 30 µs selon les cas, au lieu des 25 ms de l'OS), indispensables pour les jeux
- Captures d'écran et capture vidéo des add-ins par USB, en temps réel (via fxlink)
Avec quelques mentions spéciales sur les Graph monochromes :
Un moteur de gris pour faire des jeux en 4 couleurs !
La compatibilité SH3, SH4 et Graph 35+E II, avec un seul fichier g1a
Une API Unix/POSIX et standard C pour accéder au système de fichiers (Graph 35+E II seulement)
Et quelques mentions spéciales sur les Graph 90+E :
Une nouvelle police de texte, plus lisible et économe en espace
Le dessin en plein écran, sans les bordures blanches et la barre de statut !
Un driver écran capable de triple-buffering
Une API Unix/POSIX et standard C pour accéder au système de fichiers
Galerie d'add-ins et de photos
Voici quelques photos et add-ins réalisés avec gint au cours des années !
Arena (2016) — Plague (2021)
Rogue Life (2021)
Momento (2021)
Communication avec le PC (cliquez pour agrandir)
Utiliser gint pour développer des add-ins
Les instructions pour installer et utiliser gint sont données dans les divers tutoriels recensés dans le
topic du fxSDK. Il y a différentes méthodes de la plus automatique (GiteaPC) à la plus manuelle (compilation/installation de chaque dépôt). Le fxSDK est compatible avec Linux, Mac OS, et marche aussi sous Windows avec l'aide de WSL, donc normalement tout le monde est couvert
Notez en particulier qu'il y a des
tutoriels de développement qui couvrent les bases ; tout le reste est expliqué dans les en-têtes (fichiers
.h) de la bibliothèque que vous pouvez
consulter en ligne, ou dans les ajouts aux changelogs ci-dessous.
Changelog et informations techniques
Pour tester les fonctionnalités et la compatibilité de gint, j'utilise un add-in de test appelé gintctl (
dépôt Gitea Lephenixnoir/gintctl). Il contient aussi une poignée d'utilitaires d'ordre général.
Ci-dessous se trouve la liste des posts indiquant les nouvelles versions de gint, et des liens vers des instructions/tutoriels supplémentaires qui accompagnent ces versions.
Anecdotes et bugs pétés
Ô amateurs de bas niveau, j'espère que vous ne tomberez pas dans les mêmes pièges que moi.
TODO list pour les prochaines versions (2023-04-03)
gint 2.11
- Changements de contextes CPU. À reprendre du prototype de threading de Yatis pour permettre l'implémentation d'un véritable ordonnanceur. Demandé par si pour faire du threading Java.
- Applications USB. Ajouter le support de descripteurs de fichiers USB. Potentiellement pousser jusqu'à avoir GDB pour debugger.
- Support de scanf() dans la fxlibc. Codé par SlyVTT, plus qu'à nettoyer et fusionner.
Non classé
- Regarder du côté serial (plus facile que l'USB) pour la communication inter-calculatrices (multijoueur) et ultimement l'audio (libsnd de TSWilliamson).
- Un système pour recompiler des add-ins mono sur la Graph 90+E avec une adaptation automatique.
- Support des fichiers en RAM pour pouvoir utiliser l'API haut-niveau sur tous les modèles et éviter la lenteur de BFile à l'écriture quand on a assez de RAM.
Citer : Posté le 25/04/2021 18:24 | #
Dans mon CMakeLists j'ai modifié par
Mais j'ai exactement le même problème
Citer : Posté le 25/04/2021 18:28 | #
Faut que tu m'excuses parce que je suis un peu à côté de mes pompes aujourd'hui, alors que ce serait bien plus simple pour toi d'avoir les explications détaillées. En voilà des détails.
Tu es sans doute familier avec le principe des en-têtes ; quand on a du code dans plusieurs fichiers les fichiers sont compilés chacun de leur côté, sans savoir ce qu'il y a dans les autres fichiers. Évidemment ça pose dans problème quand tu veux appeler une fonction ou utiliser une variable qui est dans un autre fichier. Pour cette raison, on a les en-têtes .h dont le rôle est simplement de faire la publicité de ce qui existe dans d'autres fichiers.
Pour les bibliothèques, c'est pareil : les bibliothèques comme OpenLibm sont déjà compilées à l'avance, et donc ton programme n'aurait aucun moyen de savoir ce que OpenLibm propose comme fonctions s'il n'y avait pas un en-tête qui est là pour le lui dire. C'est exactement ce à quoi <openlibm.h> sert.
Cependant les en-têtes ne font que la publicité et ne fournissent pas le code. Dans le cas de plusieurs fichiers dans ton projet, c'est les autres fichiers .c qui fournissent le code. Dans le cas d'une bibliothèque, c'est une archive .a qui est installée dans le compilateur qui fournit le code.
Pour utiliser une bibliothèque, il y a donc deux étapes :
1. Il faut avoir les en-têtes sous la main pour vérifier que ton programme appelle des fonctions qui existe et avec les bons paramètres.
2. Il faut avoir l'archive .a pour récupérer le code de la bibliothèque et le mettre dans ton add-in à la fin de la compilation.
Dans CMake, la commande target_include_directories() nomme un dossier dans lequel il y a des en-têtes qui t'intéressent (après avoir dit pour quel programme tu en avais besoin et un petit PRIVATE que je détaille pas). La ligne que je t'ai passée tout-à-l'heure nomme le dossier qui contient openlibm.h (et d'autres en-têtes comme openlibm_complex.h) et cela permet au compilateur de compiler tes fichiers en sachant ce qu'il trouvera dans l'archive .a d'OpenLibm.
Il faut cependant une autre commande pour aller chercher l'archive, et celle-ci c'est target_link_libraries(). Il y a plusieurs façons de spécifier des bibliothèques à utiliser dans CMake, mais dans notre cas la bonne c'est -lopenlibm (encore une fois après nommé le programme qui en a besoin et un petit PRIVATE). Voici un exemple dans gintctl. Tu as déjà une commande target_link_libraries() dans ton CMakeLists.txt et donc tu peux simplement ajouter -lopenlibm à la fin.
Souviens-toi qu'il y a bien deux étapes : d'abord les en-têtes, ensuite la bibliothèque à proprement parler. Si des en-têtes te manquent, tu as des erreurs comme "openlibm.h: No such file or directory", et si la bibliothèque te manque tu as des erreurs comme "undefined reference to _cos". C'est du très classique, donc si tu arrives à garder ça en tête tu pourras assez facilement comprendre les erreurs qui te tomberont dessus la prochaine fois que ton dealer local de programmes oubliera de te donner les instructions complètes.
Citer : Posté le 25/04/2021 18:36 | #
D'accord, je comprends mieux désormais, merci pour l'explication complète
C'est bon ça fonctionne !
Donc pour utiliser LibImg faudra faire pareil
A moins que je sois passé à côté, il serait bien de garder toutes ces remarques de côté.
En tant qu'utilisateur lamba qui découvre tout ça il y a de nombreuses questions que je me pose.
Par exemple, je n'ai pas trouvé de liste donnant toutes les fonctions dans gint et tout
Je ne pense être le seul à avoir ou avoir eu besoin de cos et sin avec le fxsdk
Merci à vous
Citer : Posté le 25/04/2021 18:38 | #
Les fonctions de gint sont détaillées dans les en-têtes (c'est expliqué dans le tutoriel). Une liste complète ce serait trop indigeste, il y en a des dizaines et des dizaines. ^^"
Citer : Posté le 25/04/2021 18:39 | #
Nouveauté dans gint 2.4.0 (à venir) : GINT_CALL. (Sera mentionné dans le changelog pour gint 2.4)
Si vous avez déjà utilisé un timer ou gint_switch(), alors vous avez déjà passé à gint une fonction en paramètre d'une fonction. En général, on fait ça pour que gint appelle la fonction plus tard ; dans le cas d'un timer c'est quand le timer arrive au bout, dans le cas de gint_switch() c'est une fois qu'on est revenus à l'OS. Dans gint 2.4 d'autres situations de ce genre sont ajoutées, comme à la fin d'un transfert USB (le module USB est encore en développement et ne sera pas fini avec gint 2.4).
Le problème c'est que compte tenu de la façon dont le langage C est fait, pour appeler une fonction de façon fiable il faut connaître le nombre et le type de ses arguments, et donc ces fonctions de gint ont tendance à fixer ça pour vous. Par exemple :
• Dans gint_switch(), la fonction doit être void fonction(void) : aucun paramètre et aucune valeur de retour.
• Dans timer_setup(), la fonction doit retourner un int, et peut prendre au plus un paramètre qui est un pointeur ou un int.
Tout ça c'est bien limitant, et j'ai eu plusieurs fois des retours que c'est casse-pieds de devoir passer par des variables statiques ou globales. Je suis bien d'accord.
Pour améliorer cette situation, dans gint 2.4 j'ai ajouté un mécanisme appelé GINT_CALL qui offre plus de possibilités (jusqu'à 4 arguments et plus de types autorisés), et qui est future-proof. Comme ça, vos programmes seront plus facile à écrire, et si dans le futur j'arrive à vous donner plus de liberté sur le nombre et le type des arguments alors ça se fera de façon transparente pour vous.
Comment ça marche en pratique ? La macro GINT_CALL() enregistre la fonction et les valeurs à passer en paramètre et renvoie une structure que gint peut ensuite utiliser pour réaliser l'appel. Par exemple, imaginons qu'on a une fonction save_game() qui utilise BFile :
path: Nom du fichier où enregistrer la partie
world: État du monde
play_time: Temps de jeu de la partie
-> Renvoie 0 en cas de succès, 1 en cas d'erreur. */
int save_game(uint16_t const *path, struct world *world, unsigned int play_time)
{
// ...
}
Pour appeler cette fonction, il faut d'abord sortir de gint, avec gint_world_switch() (anciennement gint_switch(), voir ci-dessous). Ça va donner ça :
gint_world_switch(GINT_CALL(save_game, u"\\\\fls0\\savegame.bin", (void *)&world, play_time));
Comme vous pouvez le voir, on indique à GINT_CALL la fonction, puis les arguments ensuite. Notez bien qu'il n'y a pas de parenthèses après le nom de la fonction parce qu'on ne l'appelle pas tout de suite, c'est gint qui l'appellera plus tard !
Voici ce que vous avez le droit de faire.
La fonction a le droit de prendre jusqu'à 4 arguments (donc 0, 1, 2, 3 ou 4 arguments).
Les arguments doivent tous faire 4 octets. Vous avez droit aux int, float, aux types entiers 32-bit et aux pointeurs vers à peu près tous les types classiques. Vous n'avez pas droit aux char, short, aux entiers 64-bit ou aux double.
La fonction peut renvoyer une valeur d'un type autorisé pour les arguments, ou rien.
Ne vous inquiétez pas trop si vous avez des doutes, si vous vous trompez les compilateur donnera une erreur. Si votre programme compile alors vous pouvez être sûr·e que l'appel est correct.
Il y a quelques astuces pour utiliser plus de types :
Pour utiliser un char ou un short, castez en int et faites prendre un int à la fonction. Par exemple GINT_CALL(ma_fonction, (int)mon_char).
Pour utiliser un pointeur vers un type personnalisé comme une structure, castez en void * (le type universel de tous les pointeurs). La fonction n'a pas besoin de prendre un void *, vous pouvez laisser le type original. Par exemple GINT_CALL(ma_fonction, (void *)&world).
Pour plus de types, passez un pointeur vers une structure contenant vos arguments.
L'exemple ci-dessus montre le passage d'un uint16_t * (le nom du fichier), qui est un type supporté tout seul, d'un pointeur vers une structure, que l'on caste en void *, et d'un int.
Je tiens à ce que les anciennes fonctions comme gint_switch() ou timer_setup() continuent de marcher, mais je ne pouvais pas modifier leur prototype de façon à accepter à la fois les fonctions comme avant, et le GINT_CALL(). Du coup j'ai créé d'autres fonctions qui deviendront les «bonnes» fonctions à utiliser, et les autres je les laisse tranquilles jusqu'à gint 3.
• gint_world_switch() remplace gint_switch(), c'est une partie du nouveau groupe gint_world_* que j'ai ajouté en modifiant les drivers.
• timer_configure() remplace timer_setup(), ça c'est juste un renommage.
• rtc_periodic_enable() remplace rtc_start_timer() pour mieux coller au nom de la fonctionnalité (le nom précédent est confus parce que les ETMU sont techniquement des « timers RTC »).
Les anciennes fonctions sont dépréciées et le compilateur vous dira de changer (ce que vous devez faire). Les autres continuent d'exister seulement pour permettre aux programmes écrits avant cette mise à jour de recompiler avec les versions récentes de gint.
J'ai trouvé ce mécanisme très agréable à utiliser, et j'espère que vous aussi. o/
Citer : Posté le 25/04/2021 19:49 | #
Intéressant. Je sens que j'y reviendrai à un moment et que je relirai ça avec attention
Sinon, j'ai trouvé où sont toutes les fonctions disponibles, c'est dans Gint/include. Je vois désormais ce que l'on peut utiliser
D'ailleurs en voulant utiliser memcpy en ayant #include <gint/std/string.h> j'ai ce message d'erreur, j'ai l'impression que c'est de ton côté que ça se joue ça...
11 | void *memcpy(void * restrict dest, void const * restrict src, size_t n);
Citer : Posté le 27/04/2021 14:48 | #
Ça devrait être bon, désolé. Le statut du mot-clé restrict n'est pas très clair en C++, visiblement il faut l'écrire __restrict. J'ai fait ça partout où c'était nécessaire.
Citer : Posté le 27/04/2021 15:54 | #
Nouvelle version : gint 2.4.0
Release associée du fxSDK : fxSDK 2.4.0
Les changements depuis la version 2.3.1 se sont un peu accumulés, donc j'ai décidé de publier une nouvelle version maintenant (au lieu d'attendre le driver USB) pour pas que la transition ne pose trop de problèmes. Il y a quelques incompatibilités avec la version précédente, mais honnêtement c'est des trucs dont personne ne se sert donc ça devrait poser de problèmes à personne.
Éléments majeurs
• Ajouté un allocateur de tas personnalisé. Cela permet d'étendre malloc() avec des régions mémoire (« arènes ») personnalisées en plus du tas déjà fourni par l'OS. Les arènes gérées par gint fournissent des statistiques détaillées sur la consommation mémoire. Une arène est créée automatiquement sur toute la région de RAM utilisateur qui n'est pas déjà utilisée par le segment de données, la VBR ou la pile ; cela représente ~4 kio sur Graph mono SH3, ~14 kio sur Graph mono SH4, et jusqu'à 500 kio sur Graph 90+E.
• Ajouté une interface appelée « keydev » pour gérer les périphériques d'entrée. keydev fournit des événements (comme avant) et des transformations : combiner SHIFT+touche pour former d'autres touches, répéter des touches, et quelques autres. C'est essentiellement ce que faisait getkey() avant, sauf que (1) on peut changer les transformations à la volée, et (2) il y a quelques options en plus (comme SHIFT+touche en gardant SHIFT pressé). Le plus important c'est que ça permettra d'enregistrer les saisies ou même de créer un clavier virtuel pour rejouer une saisie enregistrée (démo) ou récupérer des touches pressées sur l'ordinateur par USB (contrôle à distance).
• Remanié le système de drivers pour intégrer la gestion des mondes, pour mieux coller à ce que Yatis a fait avec son hyperviseur qui honnêtement est bien plus propre que l'ancien truc. Tous les détails sont ici.
• Ajouté un mécanisme appelé GINT_CALL() pour gérer les callbacks de timer, les switchs, et d'autres fonctions asynchrones. Ce nouveau système vous permet d'avoir plus d'arguments aux callbacks et avec des types plus variés. Explications et instructions.
Il n'était pas possible de modifier les prototypes des anciennes fonctions pour utiliser GINT_CALL() sans casser le code existant, donc j'ai choisi de remplacer les fonctions et d'en profiter pour améliorer le nommage.
gint_switch() devient gint_world_switch(), une fonction du groupe gint_world que j'ai ajouté en modifiant le système de drivers.
timer_setup() devient timer_configure() (je ne sais pas pourquoi j'ai utilisé « setup » au début, ça n'a pas trop de sens).
rtc_start_timer() et rtc_stop_timer() deviennent rtc_periodic_enable() et rtc_periodic_disable() pour bien appuyer le fait que c'est l'interruption périodique et pas les timers RTC (« ETMU »), qui ont été découvert sous ce nom bien après que j'aie nommé ces fonctions la première fois.
Nouvelles fonctionnalités
• Ajouté %f, %e et %g à toutes les fonctions qui supportent les formats à la printf(), pour afficher les float et les double. Cette fonctionnalité utilise l'algorithme Grisu2b de Florian Loitsch (voir à la fin de sa page perso). Pour rappel les fonctions mathématiques sont fournies par OpenLibm, qui est donc maintenant une dépendance.
• Ajouté une fonction rtc_ticks() qui fait exactement comme RTC_GetTicks().
• Ajouté les fonctions asprintf() et vasprintf() qui allouent une chaîne de caractères de la bonne taille avec malloc() et la renvoient. Notez que le format est calculé deux fois : une fois pour obtenir la taille, et une fois après avoir alloué pour générer la chaîne.
• Ajouté les fonctions strchr(), strrchr() et strchrnul().
• Ajouté un paramètre à dtext_opt() pour limiter le nombre de caractères à afficher. Ça permet d'afficher des sous-chaînes. Le paramètre est ajouté automatiquement par une macro s'il n'est pas spécifié, donc les anciens programmes restent compatibles.
• Ajouté une fonction dnsize() qui fait comme dsize() mais peut s'arrêter au milieu de la chaîne.
• Ajouté une fonction drsize() qui fait l'inverse de dnsize() : on spécifie combien de pixels de largeur on a et elle indique combien de caractères peuvent être dessinés sans dépasser.
• Ajouté une fonction dfont_default() qui renvoie la police par défaut de gint.
• Ajouté une fonction keysc_set_scan_frequency() qui permet de changer la vitesse de scan du clavier à l'exécution au lieu de le faire à la compilation (avant c'était un paramètre de compilation de gint).
• Ajouté une fonction mmu_uram_size() qui indique combien de mémoire est mappée à 0x08100000.
• Ajouté une définition pour off_t et les détails des types de fichiers dans BFile_FileType (merci Yatis!).
Changements
• Déplacé la VBR à la fin de la zone de RAM utilisateur sur fx-9860G (au lieu d'à la fin des 8 premiers kio), pour permettre de placer un tas au milieu.
• Amélioré la compatibilité Mac OS des scripts, c'est encore expérimental mais globalement ça marche (merci Ninestars ).
Citer : Posté le 27/04/2021 19:44 | #
Et bien plein de nouveautés !
Content que le %f soit désormais géré, j'étais en train de l'écrire sans savoir que ce n'était pas géré
Comment il faut s'y prendre pour faire une mise à jour de gint (ou fxsdk) ?
cd gint
fxsdk build-fx
Citer : Posté le 27/04/2021 19:46 | #
Si tu utilise giteapc, giteapc install -u fxsdk gint
Citer : Posté le 27/04/2021 20:01 | #
J'ai oublié de préciser mais il faut activer le point-flottant explicitement (pour différentes raisons pas tant au runtime qu'à la compilation).
kprint_enable_fp(); // <- Ceci active %f, %e, et %g
Pour mettre à jour gint, tu peux juste faire :
% fxsdk build-cg install
Et ensuite recompiler ton add-in. Le "git pull" récupère la dernière version sur ta branche actuelle, qui est normalement master, et chaque version sur master est une release (ici donc c'est 2.4.0). Pour recompiler ton add-in tu peux faire juste fxsdk build-cg normalement, mais en cas de doute tu peux faire fxsdk build-cg -B qui force une recompilation complète (c'est utile dans d'autres situations d'ailleurs).
Note que si tu as des libs qui utilisent gint, comme libprof ou libimg, il faut aussi les mettre à jour. C'est un peu fastidieux, c'est une des motivations qui m'a fait écrire GiteaPC.
Pour info Darks, GiteaPC ne marche pas sous MacOS parce que bien sûr rien ne marche directement sous MacOS, et je n'ai pas trop de quoi tester. Je demanderai à quelqu'un un jour.
Citer : Posté le 28/04/2021 22:17 | #
Salut,
j'ai un problème avec la mise à jour du fxsdk et de gint.
Lorsque je lance la commande giteapc install -u fxsdk (ou gint), la compilation rate avec l'erreur suivante :
-- Checking for module 'udisks2'
-- No package 'udisks2' found
CMake Error at /usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:493 (message):
A required package was not found
Call Stack (most recent call first):
/usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:677 (_pkg_check_modules_internal)
CMakeLists.txt:13 (pkg_check_modules)
-- Configuring incomplete, errors occurred!
See also "/home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build/CMakeFiles/CMakeOutput.log".
gmake: *** [giteapc.make:12 : configure] Erreur 1
error: error 2 in command: gmake -f giteapc.make configure
J'ai pourtant bien le paquet libudisks2-0 d'installé, mais une chose à souligner est que je suis à ce jour sur un live usb persistent avec ubuntu 20.10 (c'est pour ça que mon $USER est ubuntu), car je n'ai pas réussi la compilation avec la version précédente sur mon système habituel (j'utilise Pop-os, mais c'est un dérivé d'Ubuntu, Debian, etc..., et je n'ai pas non plus réussi avec une installation normale d'Ubuntu 20.10).
J'avoue ne comprendre ni les subtilités de la compilation avec cmake, ni pourquoi le paquet n'est pas détecté.
Si quelqu'un à une idée, je suis preneur.
PS : La commande cat /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build/CMakeFiles/CMakeOutput.log | grep udisk2 ne renvoie rien.
Citer : Posté le 28/04/2021 22:20 | #
Puisque la compilation du fxSDK et de gint est un problème pour l'instant, ce que tu peux faire c'est simplement utiliser la configuration noudisks2 du fxSDK qui désactive les fonctionnalités qui utilisent UDisks2 (c'est-à-dire la fonction de fxlink pour envoyer rapidement un fichier sur une Graph 35+E II ou Graph 90+E).
Avec cette configuration le fxSDK ne demandera pas le module UDisks2 à CMake, ce qui devrait te permettre de te concentrer sur le principal.
Citer : Posté le 28/04/2021 22:27 | #
Merci beaucoup, c'est vrai que je l'avais lu mais n'y avait pas pensé (j'ai une graph 35+E).
Ceci dit, je viens de tester, et j'ai exactement la même erreur :
-- Checking for module 'udisks2'
-- No package 'udisks2' found
CMake Error at /usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:493 (message):
A required package was not found
Call Stack (most recent call first):
/usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:677 (_pkg_check_modules_internal)
CMakeLists.txt:13 (pkg_check_modules)
-- Configuring incomplete, errors occurred!
See also "/home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build/CMakeFiles/CMakeOutput.log".
gmake: *** [giteapc.make:12 : configure] Erreur 1
error: error 2 in command: gmake -f giteapc.make configure
Citer : Posté le 28/04/2021 22:32 | #
Oups, la configuration n'est jamais arrivée sur le dépôt à cause d'un quirk de gitignore. Désolé !
J'ai poussé ce qu'il fallait sur la branche dev, tu peux réessayer comme ça.
Citer : Posté le 28/04/2021 22:37 | #
Merci... pour de vrai cette fois, par contre il y a encore une autre erreur :
make[3] : on entre dans le répertoire « /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build »
Scanning dependencies of target fxg1a
make[3] : on quitte le répertoire « /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build »
make[3] : on entre dans le répertoire « /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build »
[ 60%] Building C object CMakeFiles/fxg1a.dir/fxg1a/dump.c.o
[ 66%] Building C object CMakeFiles/fxg1a.dir/fxg1a/edit.c.o
[ 73%] Building C object CMakeFiles/fxg1a.dir/fxg1a/file.c.o
[ 80%] Building C object CMakeFiles/fxg1a.dir/fxg1a/icon.c.o
[ 86%] Building C object CMakeFiles/fxg1a.dir/fxg1a/main.c.o
[ 93%] Building C object CMakeFiles/fxg1a.dir/fxg1a/util.c.o
[100%] Linking C executable fxg1a
/usr/bin/ld : ne peut ouvrir le fichier de sortie fxg1a : est un dossier
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/fxg1a.dir/build.make:161 : fxg1a] Erreur 1
make[3] : on quitte le répertoire « /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build »
make[2]: *** [CMakeFiles/Makefile2:134 : CMakeFiles/fxg1a.dir/all] Erreur 2
make[2] : on quitte le répertoire « /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build »
make[1]: *** [Makefile:130 : all] Erreur 2
make[1] : on quitte le répertoire « /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build »
gmake: *** [giteapc.make:15 : build] Erreur 2
error: error 2 in command: gmake -f giteapc.make build
Désolé si mes messages sont difficiles à lire vu que je cite pas mal de lignes du terminal.
edit : au temps pour moi, j'ai mal orthographié udiskS quand j'ai cherché les paquets en lien avec apt, et il semblerait qu'avoir installé le paquet libudisks2-dev ait résolu le problème de udisks2. Pour autant l'erreur de ld subsiste.
Citer : Posté le 28/04/2021 22:55 | #
Alors ça c'est un truc dommage. En fait dans ton dossier fxSDK clôné par GiteaPC, tu as les restes d'une compilation précédente et ils te gênent. Il faudrait que je trouve un moyen de les nettoyer proprement (mais pas à tous les coups, en général on veut pas le nettoyer).
Sans se casser trop la tête, tu peux les supprimer avec cette commande et recommencer.
# ou bien
% rm -rf /home/ubuntu/.local/share/giteapc/Lephenixnoir/fxsdk/build
Citer : Posté le 28/04/2021 22:58 | #
Nickel, la mise à jour de gint et du fxsdk s'est passée sans encombres.
Citer : Posté le 28/04/2021 23:00 | #
Ouf ! Merci de ta patience.
Citer : Posté le 30/04/2021 18:49 | #
Voici une update (attendue, on m'a fait comprendre !) pour @RDP.
Screenshots en temps réel ! Chaque fois que j'appuie sur OPTN un screenshot est fait, et fxlink enregistre (actuellement) les données dans un fichier. À la fin de la vidéo, je convertis le fichier en image et pouf tout y est.
(Si vous ne voyez rien pendant les 10 premières secondes, pas grave.)
J'ai fait suffisamment avancer fxlink pour avoir un mini-protocole personnalisé dans lequel on peut envoyer des messages en plusieurs parties et spécifier une « application » et un « type » pour le message. Le but du type c'est de pouvoir traiter différemment le texte (affiché sur la console, comme un chat), des logs (enregistrés dans un fichiers), des screenshots (convertis en PNG à la volée), etc.
L'idée de l'application c'est de pouvoir étendre facilement fxlink pour faire d'autres choses avec. Mettons que je veux recevoir une structure par USB et la convertir en JSON pour résumer les benchmarks de gintctl. Je peux envoyer un message avec comme application "gintctl", et fxlink appellera un programme avec un nom prédéterminé du style fxlink-handler-gintctl en lui passant les messages sur la lib standard.
Du coup, côté add-in, je peux faire :
1. usb_open(&usb_ff_bulk) (c'est le nom de l'interface qui fournit le protocole pour fxlink)
2. usb_fxlink_fill_header(&header, "gintctl", "perf-report", 256) (application "gintctl", type "perf-report", taille 256 octets)
3. Envoyer les données par l'API USB (2-3 appels de fonction)
4. usb_close() (facultatif)
Et le protocole consiste en :
1. Écrire un programme fxlink-handler-gintctl qui lit la structure sur l'entrée standard et produit le JSON dans un fichier
2. Lancer fxlink puis lancer l'application (ou dans l'ordre inverse, peu importe)
3. Dès que le transfert se fait fxlink appelle le script qui convertit et sauvegarde tout instantanément
Notez que le côté add-in est un peu plus simple pour les messages par défaut, par exemple les étapes 2 et 3 peuvent être raccourcies en un usb_fxlink_screenshot() qui compacte le tout.
Voilà voilà ça vous donne une idée de ce à quoi l'API ressemblera.
Citer : Posté le 30/04/2021 18:57 | #
j'attends l'update avec l'USB,
ma patience craque