Compiler giac avec emscripten

Librairie C++ de calcul formel/ C++ symbolic computation library

Modérateur : xcasadmin

vgu
Messages : 8
Inscription : mar. mai 14, 2024 5:17 pm

Compiler giac avec emscripten

Message par vgu » mer. mai 22, 2024 10:36 am

Bonjour

J'ai des difficultés de compilation... cette fois pour la version js/wasm

J'ai téléchargé les sources de giac pour la compilation avec emscripten ici https://www-fourier.univ-grenoble-alpes ... c_wasm.tgz

Je voulais utiliser la même version d'emscripten (1.38.41) que vous, malheureusement elle n'est plus disponible sur github: la plus ancienne disponible est à ce jour la 1.39.1(11/10/2019).

1.

La commande

Code : Tout sélectionner

emmake make giacwasm.js
donne l'erreur suivante:

Code : Tout sélectionner

shared:ERROR: BINARYEN_TRAP_MODE is not supported by the LLVM wasm backend
Je peux supprimer

Code : Tout sélectionner

-s "BINARYEN_TRAP_MODE='clamp'"
du Makefile dans CXXFLAGS et LDJSFLAGS (je ne sais pas ce que ça implique...)

Cette fois la compilation se lance mais

2.

Code : Tout sélectionner

./markup.h:32:1: error: unknown type name 'string'; did you mean 'std::string'?
./markup.h:33:45: error: unknown type name 'string'; did you mean 'std::string'?
./markup.h:34:1: error: unknown type name 'string'; did you mean 'std::string'?
./markup.h:35:1: error: unknown type name 'string'; did you mean 'std::string'?
./markup.h:36:1: error: unknown type name 'string'; did you mean 'std::string'?
Je corrige donc ./markup.h pour y ajouter le namespace std

3.

Cette fois, ça compile mais il y a un problème à la liaison :

Code : Tout sélectionner

wasm-ld: error: mpker.o: machine type must be wasm32
wasm-ld: error: gen1.o: machine type must be wasm32
wasm-ld: error: gen2.o: machine type must be wasm32
...
Je vois que ces objects sont liés à libpari. Il y a un ./pari/libpari.a dans les sources qui contient des objets .o au format LLVM IR bitcode.

Là, je suis bloqué. Si vous avez une suggestion, je suis preneur!

4.

Par ailleurs, j'ai préalablement compilé gmp comme indiqué dans le README de l'archive giac-emscripten et obtenu "a.out.js" et "a.out.wasm" ; est-ce que c'est utile ?

Pour infos, emcc -v me dit:

Code : Tout sélectionner

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.39.1
clang version 10.0.0 (/b/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-llvm-llvm--project f919be336583349d883ba0dfdb3b2479a190b67c)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/vivien/pr-src/giac-emscripten/emsdk-1.39.1/upstream/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64

parisse
Messages : 5771
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Compiler giac avec emscripten

Message par parisse » mer. mai 22, 2024 6:19 pm

Pour l'install de la version 1.38.41, vous avez fait emsdk install et emsdk activate?

Normalement il faut juste faire make dans le répertoire emgiac/giac, et ça devrait générer giacwasm.js. Il n'est pas nécessaire de recompiler de librairies, puisque l'archive tar contient des lib*.a.

Pour l'erreur avec libpari, le plus simple est probablement de désactiver le support de pari dans config.h et d'enlever pari/libpari.a de LIBS, mais le message d'erreur est un peu inquiétant, ça laisse craindre des problèmes aussi avec les autres librairies précompilées.

Chez moi, emcc -v renvoie

Code : Tout sélectionner

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.38.41
clang version 6.0.1 (/b/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-emscripten--core-emscripten--fastcomp--clang 98df4be387dde3e3918fa5bbb5fc43e1a0e1daac) (/b/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-emscripten--core-emscripten--fastcomp 1b4148f39a69c7fc62edadd85e4122b68694dfb7) (emscripten 1.38.31 : 1.38.31)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/parisse/emsdk/fastcomp/fastcomp/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
shared:INFO: (Emscripten: Running sanity checks)
ce qui est vraiment différent c'est la version de clang qui passe de 6 chez moi à 10 chez vous et peut expliquer les bugs rencontrés dans markup.h que je mets à jour.

vgu
Messages : 8
Inscription : mar. mai 14, 2024 5:17 pm

Re: Compiler giac avec emscripten

Message par vgu » jeu. mai 23, 2024 10:33 am

J'ai fini par trouver ce qui pose problème.

La lib précompilée dans giacwasm l'a été avec l'ancien backend de emscripten : "fastcomp".

Le changement s'est fait précisément entre la version 1.38 et 1.39 de emscripten fin 2019.

https://groups.google.com/g/emscripten- ... DszSPkAAAJ

Il est possible de forcer emscripten d'utiliser fastcomp en faisant

Code : Tout sélectionner

emsdk install latest-fastcomp
emsdk activate latest-fastcomp
à la place de

Code : Tout sélectionner

emsdk install latest
emsdk activate latest
Notez que le make se termine tout de même sur une erreur (pas bien grave) qui suppose l'existence d'un répertoire 'shared' à la racine !

Code : Tout sélectionner

/bin/cp xcas_ups.js /shared
/bin/cp: impossible de créer le fichier standard '/shared': Permission non accordée
Il ne me reste plus qu'à comprendre comment intégrer le composant giac.js (ou wasm ?), pour pouvoir utiliser les opérations symboliques et numériques ainsi que les conversions entre les expressions mathématiques en langage "calculatrice" et MathML.

Afin de ne pas me retrouver dans la même situation qu'avec les bindings java précompilés qui ne fonctionnent plus, je veux pouvoir recompiler entièrement la version emscripten à partir des sources, donc sans morceaux précompilés, et mettre ça dans un script qui compilera tout sans intervention manuelle. Pouvez-vous me dire:

- si la version de libpari que vous utilisez est bien (comme je le lis dans le Makfile.pari.emscripten) la 2.7.3 qu'on trouve ici https://pari.math.u-bordeaux.fr/pub/par ... 7.3.tar.gz ;
- quelle version de libgmp vous avez compilé pour pari.

Merci !

parisse
Messages : 5771
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Compiler giac avec emscripten

Message par parisse » jeu. mai 23, 2024 5:26 pm

Merci pour l'info, je vais rajouter ça dans le README.
Effectivement, j'ai rajouté des instructions dans le Makefile, afin d'automatiser la mise à jour du simulateur web de la calculatrice Numworks + Xcas, mais qui ne marchent que chez moi, ce n'est pas très propre...
Pour utiliser giacwasm.js, je vous suggère de regarder https://www-fourier.univ-grenoble-alpes ... se/giacjs/. En gros, il y a une fonction exportée de prototype C const char * caseval(const char *) qui est appelée en javascript par caseval de la variable UI dans giacsimple.js, elle évalue une chaine de caractère et renvoie le résultat. Et ça suffit pour Geogebra, donc ça devrait vous suffire également (sinon on peut toujours un peu adapter coté C, comme pour la Numworks qui utilise nws_caseval au lieu de caseval).
Pour compiler gmp, la version n'a pas trop d'importance, par contre de mémoire c'était assez difficile, il me semble que pour y arriver j'ai du d'abord compiler gmp dans une machine virtuelle 32 bits, sinon il y avait des problèmes pour cross-compiler avec emscripten. Pour pari, je ne sais plus quelle version j'ai utilisée, mais vous pouvez surement vous en passer (ça économisera quelques % sur giacwasm.js).
En tout cas avoir un script de build entièrement automatisé à partir des sources serait hautement utile!

parisse
Messages : 5771
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Compiler giac avec emscripten

Message par parisse » dim. mai 26, 2024 7:11 am

Ca n''a certainement pas d'impact pour votre projet, mais je le signale au cas où quelqu'un d'autre aboutit sur cette page, il y a un problème dans la version 1.38 de emscripten qui fait bugger la gestion de la 3d, il faut corriger SDL_Quit dans le fichier library_sdl.js fourni en mettant à la place:

Code : Tout sélectionner

	SDL_Quit: function() {
	_SDL_AudioQuit();
	var keyboardListeningElement = Module['keyboardListeningElement'] || document;
	keyboardListeningElement.removeEventListener("keydown", SDL.receiveEvent);
	keyboardListeningElement.removeEventListener("keyup", SDL.receiveEvent);
	keyboardListeningElement.removeEventListener("keypress", SDL.receiveEvent);
	// Module.print('SDL_Quit called (and ignored)');
	},

vgu
Messages : 8
Inscription : mar. mai 14, 2024 5:17 pm

Re: Compiler giac avec emscripten

Message par vgu » lun. mai 27, 2024 4:49 pm

En effet, je n'ai pas prévu d'utiliser de fonctions graphiques, en tous cas pour le moment.

J'arrive maintenant à compiler emgiac et à utiliser caseval (_caseval) dans le navigateur. Pour l'instant, je ne recompile pas pari, j'utilise donc la lib précompilée que vous avez mise dans les sources. (A ce propos, je n'ai pas trouvé comment compiler sans libpari comme vous le suggéreriez).

Par contre, je n'arrive pas à utiliser la fonction de conversion vers mathml. Je suppose qu'il s'agit de gen2mathml si je me fie à mon ancien code java. Mais je n'arrive pas à trouver ce que je dois exporter dans LDJSFLAGS. Si j'ajoute simplement '_gen2mathml' à EXPORTED_FUNCTIONS dans LDJSFLAGS, le compilateur me dit :

Code : Tout sélectionner

shared:WARNING: undefined exported function: "_gen2mathml"
pourtant GIACOBJS contient bien mathml.o

Si ça vous dit quelque chose ou que vous avez une idée de solution, je suis preneur.

Merci !

parisse
Messages : 5771
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Compiler giac avec emscripten

Message par parisse » mar. mai 28, 2024 4:48 pm

C'est un problème de linkage, gen2mathml est une fonction C++, elle est donc "manglée", ce qui ne facilite pas les échanges avec javascript, c'est pour cela que j'ai créé la fonction caseval déclarée comme extern "C" donc non manglée, et qui est générée dans les fichiers objets avec un _ en préfixe.
Mais de toutes façons vous ne pourrez pas accéder à des objets de type gen depuis javascript, on ne peut travailler qu'avec des chaines de caractères. La solution la plus simple est d'appeler la commande mathml() de giac à travers caseval.
Par exemple caseval("mathml(1/2+1/6)")

Sinon, vous avez réussi à recompiler GMP/MPFR/MPFI depuis les sources?

vgu
Messages : 8
Inscription : mar. mai 14, 2024 5:17 pm

Re: Compiler giac avec emscripten

Message par vgu » mar. mai 28, 2024 8:18 pm

Merci pour les explications pour mathml. Il me semblait bien qu'il y avait quelque chose comme dans ce genre.

Si je peux faire caseval("mathml(x)"), c'est parfait.

Niveau libs, non, pas encore. Puisque vous posez la question voilà où j'en suis:

- libmicropy ne m'est pas utile et tout a l'air de fonctionner correctement en ne liant pas la lib donc je n'ai pas fait d'effort dans ce sens.
- gmp c'est bon (grâce à votre petite doc)
- pari, c'est bon (grâce à ça : https://pari.math.u-bordeaux.fr/archive ... 00015.html)
- libmpfr, ça a l'air bon
- libmpfi me donne pas mal de fil à retordre. J'ai commencé par télécharger le tar.gz de la dernière version taguée sur leur dépôt de sources (mpfi-1.5.4.tar.gz) avant de me rendre compte que les erreurs de compilation étaient dus au fait qu'il manquait tout bonnement des fichiers dans l'archive (ce qui est confirmé dans un rapport de bug, mais n'a pas été corrigé)... J'utilise donc la version de leur branche master (sans savoir si c'est une version stable) mais je dois désactiver les tests de gmp et mpfr dans configure.ac pour que quelque chose se passe... mais pas jusqu'au bout:

Code : Tout sélectionner

libtool: compile:  /home/vivien/pr-src/giac-emscripten/build/emsdk-1.39.1/fastcomp/emscripten/emcc -DHAVE_CONFIG_H -I. -I.. -I.. -I/home/vivien/pr-src/giac-emscripten/build/gmp-6.3.0 -I/home/vivien/pr-src/giac-emscripten/build/mpfr-4.2.1/src -g -O2 -MT z_sub.lo -MD -MP -MF .deps/z_sub.Tpo -c z_sub.c  -o .libs/z_sub.o
z_sub.c:31:1: error: static declaration of 'mpfr_z_sub' follows non-static declaration
mpfr_z_sub (mpfr_ptr x, mpz_srcptr z, mpfr_srcptr y, mpfr_rnd_t rnd)
Une fois que tout compilera, il restera à voir si tout fonctionne effectivement ensemble dans giac...

Je documente tout sous forme d'un script shell qui compile tout de zéro comme je vous l'avais dit, que je mettrai sur le dépôt de source public de notre projet quand ça marchera. Lorsque ce sera le cas, j'essaierai d'utiliser des version récentes pour toutes les libs et pour emscripten.

Les versions que j'utilise

https://github.com/emscripten-core/emsd ... 9.1.tar.gz
https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
https://pari.math.u-bordeaux.fr/pub/par ... 5.5.tar.gz
https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.gz
https://gitlab.inria.fr/mpfi/mpfi.git révision b192f0871e63f5003e9914178c4a616597736663

A ce propos, pourriez-vous mettre un numéro de version sur vos fichiers tgz ? Pour le moment, je m'appuie dans mon script sur un sha256 pour être sûr que l'archive n'a pas changé afin qu'il n'y ait pas de surprise à la compilation mais s'il y avait, en plus, un numéro de version (ou une date), ça serait plus commode.

Répondre