[omegafail] Dlang et gint
Posté le 29/03/2022 00:25
Bonjour !
Le langage D est un langage inclut dans gcc depuis 2018.
D expose un subset "
Better C" permettant de l'utiliser sans son runtime et de linker dans un projet C. J'ai cru qu'il suffirait d'ajouter un argument à la compilation de
sh-elf-gcc-casio pour avoir l'option de programmer en D.
Et c'est ce que j'ai fait. Pour les utilisateurs Arch,
https://arch.middleearth.fr/pkgbuild/sh-elf-gcc-casio/PKGBUILD ligne 32 ajoutez
,d après C++ puis
makepkg -si.
Je crée un module simpliste, nommé
square.d, pour mes tests.
pure @nogc int square(int a) {
return a * a;
}
Cette fonction se connecte au cloud pour minter des NFTs.
Je compile maintenant
square.d avec mon installation de
gcc sur Linux :
$ gcc -fno-druntime -c -o square.o square.d
Aucune erreur, le module est bien compilé vers
square.o en Better C, sans dépendances vers son runtime ou sa librairie standard.
Je tente maintenant la même chose avec
sh-elf-gcc :
$ sh-elf-gcc -fno-druntime -c -o square.o square.d
d21: error: cannot find source code for runtime library file 'object.d'
d21: note: dmd might not be correctly installed. Run 'dmd -man' for installation instructions.
d21: note: config file: not found
Une erreur. Je ne comprend pas pourquoi j'ai une erreur de runtime manquant alors que
fno-druntime le désactive. Qu'ai-je fait pour mériter cela ? Déception, tristesse, dramatisation.
Mon questionnement : est-ce que c'est un bug de gcc et je perd ? Dois-je essayer de compiler
dmd pour sh-elf ?
(NB : je préfère crever) Est-ce que je rate quelque chose de flagrant ?
Je ne pense pas que quelqu'un ici ait l'envie ou la capacité de m'aider (j'ai jamais vu D de mentionné), mais je voulais créer ce topic de toute manière pour archiver ma petite tentative.
To be continued
Merci d'avoir lu. Je sais pas pourquoi vous vous infligez ça.
Citer : Posté le 29/03/2022 12:00 | #
TL;DR : Je suis pas allé au bout, mais ça a l'air possible.
Prenons les choses dans l'ordre - dmd est le compilateur D, il peut à lui tout seul générer des programmes assembleur (mais pour un nombre restreint de cibles qui n'inclut pas SuperH). gdc est un front-end D basé sur dmd qui produit du code pour GCC, ce qui signifie que dmd analyse le code D mais GCC produit le code assembleur (pour nous, SuperH). Y'a pareil avec LLVM, le frontend s'appelle d'ailleurs ldc.
dmd est donc nécessaire pour compiler des programmes avec gdc, mais il n'est pas question de le "compiler pour SuperH" (il produit du code pour GCC et GCC produit le SuperH). Et en fait il est déjà fourni avec GCC quand tu compiles avec --enable-languages=d.
Le problème que tu as actuellement c'est que -fno-runtime/-betterC n'est pas automatique ; la façon dont ça marche est que ça intègre une partie du runtime dans le programme. C'est transparent pour la calculatrice mais ça veut dire qu'il faut quand même avoir le runtime à un moment ! object.d est un des fichiers de libphobos, qui contient ledit runtime, et c'est ça qui te manque actuellement.
On peut d'ailleurs voir tout ce qui se passe si tu ajoutes le flag -v (verbose) à gdc (je suis pas trop NFT donc j'ai testé avec une fonction de cryptomining à la place) :
(...)
GNU D (GCC) version 11.2.0 (x86_64-pc-linux-gnu)
(...)
binary /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/d21
version v2.076.1
predefs GNU D_Version2 LittleEndian GNU_DWARF2_Exceptions GNU_StackGrowsDown GNU_InlineAsm D_LP64 D_PIC D_PIE assert D_BetterC all X86_64 D_HardFloat Posix linux CRuntime_Glibc CppRuntime_Gcc
parse increment
importall increment
import object (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include/d/object.d)
import core.internal.hash (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include/d/core/internal/hash.d)
import core.internal.traits (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include/d/core/internal/traits.d)
import core.internal.convert (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include/d/core/internal/convert.d)
semantic increment
semantic2 increment
semantic3 increment
code increment
function increment.increment
(...)
as -v --64 -o increment.o /tmp/ccHNKHgw.s
(...)
Tu peux voir que ça charge tous ces objets de include/d/core/internal. Faire pareil avec le sh-elf pour voir que ça plante au import object est laissé en exercice au lecteur.
Tous ces fichiers sont bel et bien fournis avec GCC quand tu cross-compiles :
Permissions Size User Date Modified Name
.rw-r--r-- 26k el 28 Jul 2021 gcc-11.2.0/libphobos/libdruntime/core/internal/convert.d
.rw-r--r-- 28k el 28 Jul 2021 gcc-11.2.0/libphobos/libdruntime/core/internal/hash.d
.rw-r--r-- 105k el 28 Jul 2021 gcc-11.2.0/libphobos/libdruntime/object.d
.rw-r--r-- 12k el 28 Jul 2021 gcc-11.2.0/libphobos/libdruntime/core/internal/traits.d
Le problème c'est que libphobos n'est pas compilée par défaut, et personne ne t'en donne trop les instructions parce que l'utilisation classique de D reste d'avoir le runtime installé sur la machine cible.
Il faut donc configurer pour l'avoir avec --enable-libphobos :
La compiler une fois le compilateur installé :
% make -j4 all-target-libgcc
% make install-strip-gcc
% make install-target-libgcc
% make all-target-libphobos
Là ça se complique un peu, le runtime D a beau être intégré au programme, il dépend quand même de la libc (si tu regardes les logs de compilation de libphobos il plante à sa dépendance libbacktrace avec "C compiler cannot create executables" parce que -lc manque). Il faut donc installer fxlibc dans le nouveau compilateur :
% cmake -B build-gdc -DFXLIBC_TARGET=gint -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sh.cmake -DCMAKE_INSTALL_PREFIX="$($PREFIX/bin/sh-elf-gcc -print-file-name=.)"
% make -C build-gdc install
# Ajustement du chemin d'install (fxlibc a pas compris que c'était dans le compilo)
% mv $($PREFIX/bin/sh-elf-gcc -print-file-name=.)/{lib/libc.a,}
# Plus une copie à un endroit temporaire pour libphobos
% mkdir -p $PREFIX/sh3eb-elf/lib
% cp $($PREFIX/bin/sh-elf-gcc -print-file-name=libc.a) $PREFIX/sh3eb-elf/lib/
On peut alors progresser sur libphobos :
Et pour l'instant ça plante parce qu'il faudrait linker avec gint pour que fxlibc soit complète (par exemple exit() appelle la fonction _Exit() de gint). En principe on s'en fout de créer des exécutables, on veut juste libbacktrace en dépendant de libphobos. Mais je ne sais pas si on peut sauter l'étape, ou comment linker gint avec fxlibc (peut-être en créant une méga-libc.a avec les deux).
Pour l'instant pas de barrière catastrophique, faudrait juste y passer plus de temps pour voir.
Citer : Posté le 29/03/2022 17:02 | #
Merci d'avoir essayé et partagé toutes ces informations Lephé ! Ça donne un peu d'espor d'avoir des explications rationnelles au problème que j'avais.
En supposant que le tout compile proprement dans le futur, dans quel ordre se ferait l'installation ? Sera-t-il possible de compiler gcc, puis gint et fxlibc avant de finir avec Phobos ?
Citer : Posté le 29/03/2022 19:05 | #
Oui c'est ça. Comme libstdc++-v3 en fait
Citer : Posté le 17/08/2022 17:44 | #
Pour information si quelqu'un se demande toujours :
Et pour l'instant ça plante parce qu'il faudrait linker avec gint pour que fxlibc soit complète (par exemple exit() appelle la fonction _Exit() de gint). En principe on s'en fout de créer des exécutables, on veut juste libbacktrace en dépendant de libphobos. Mais je ne sais pas si on peut sauter l'étape, ou comment linker gint avec fxlibc (peut-être en créant une méga-libc.a avec les deux).
Oui c'est ça. Comme libstdc++-v3 en fait
Pour libstdc++-v3 on ne fournit en fait pas gint, le fait que la link ne soit pas complet est pris dans la face et on continue de compiler quand même. Le configure peut s'en passer et on ne crée pas d'exécutables durant la compilation de la lib.
Pas le temps d'y retourner là tout de suite mais du coup il se peut que le problème avec libphobos soit un peu différent. Ça reste possible à première vue en tous cas.