2 April 2022

Compiling Giac via MSYS2/CLANG32

It is a great honor that the GeoGebra Team allowed me to show some technical updates in the frame of the GeoGebra Community Gathering March 2022. It was organized online on the 31st of March. I managed to describe three topics, but for the fourth one, “Compiling Giac via MSYS2/CLANG32” I could not reserve enough time. This blog entry explains some ideas on this topic.

Giac is the embedded computer algebra system in GeoGebra. It is developed by the French mathematician Bernard Parisse, a researcher of Institut Fourier in Grenoble, France. During the last years a couple of young programmers at GeoGebra joined his work a bit, at least in fighting against various platforms and compilers. To name just a few, Zbyněk Konečný, Balázs Bencze and Ágoston Sütő worked quite a lot on this field.

Since Giac is written in C++, it is possible to use it in an embedded way on various platforms including Java (on Windows, Mac and Linux), Android or iOS. The embedding is, however, far from being straightforward: it requires experts who are ready to address technical challenges. One of those challenges is to compile Giac for Java on Windows: the current official way how we do it is to maintain an Ubuntu Linux 20.04 system that compiles Giac via a cross-compiler called g++-mingw-w64-i686. Here g++ stands for the GNU C++ compiler (or, more precisely, the C++ frontend of the GNU Compiler Collection, also known as GCC), mingw-64 refers to a Windows based runtime environment for GCC, and i686 is a “flavor” that is used to produce executable code for 32-bit architectures.

One of our power users recently faced some issues when using some exotic computer algebra code – a crash occurred, but only on Windows. Unfortunately, we were unable to reproduce the bug on other platforms. Even worse, for the g++-mingw-w64-i686 platform we do not even have satisfactory ways to debug the code.

Trying a newer toolchain

A toolchain is a set of programs that help compiling your code for a given platform. In this point of view, g++-mingw-w64-i686 is a toolchain that creates executable code for the 32-bit Windows platform. There are other toolchains available that offer similar functionality, but based on different software or different settings.

After a remarkable amount of work (that is, months, with a remarkable amount of breaks) I managed to find a way to compile Giac for Java/Win32. During the last months I learned that there is a very diligent and motivated team who work very hard on providing the best toolchain creating Windows executables based on a Linux-like command line framework. These guys are the MSYS2 team.

MSYS2 is a complicated system. My biggest confusion was that it provides several environments like MSYS, MINGW64, UCRT64, CLANG64, MINGW32, CLANG32 and CLANGARM64. If you are new to MSYS2, the first steps are rather difficult when learning which environment fits you the most. For me, different C++ (or C) projects needed different environments because each environment supports just a partial set of the well-known libraries under Linux. For example, porting Tarski to Windows I first selected the MSYS environment and achieved acceptable results, but later I chose CLANG64 that seemed to be able to create more stable Java DLLs. On the other hand, for GNU Aris the MINGW64 environment was the winner.

My friend and colleague Noah Dana-Picard – a power user of GeoGebra Discovery – reported that some of his students in Jerusalem, Israel, have difficulties in installing the Java/Win64 version of GeoGebra Discovery. I always thought that nowadays nobody uses 32-bit Windows or 32-bit Java anymore. But it turned out that I was wrong. It was just recently, end of 2021. So I quickly had a look at the MSYS2 project – I was optimistic to find another environment I could use. Unfortunately, the CLANG32 environment was in a very early stage that time. But coming back later, by the end of December, CLANG32 was already up-to-date enough to help me creating a fully functional variant of GeoGebra Discovery that runs on Java/Win32. I had, as always, many difficulties on finalizing the DLL, but I got very prompt and useful help from the MSYS2 team on their Discord communication platform. I am especially grateful to Jeremy Drake, Biswapriyo Nath and Christoph Reiter who explained me several important details how MSYS2 works under the hood. Many details were shown me on Christmas Eve – I just wanted to ask a question and wait for the answer after the holidays, but they apparently solved my question within an hour. That was an exceptionally kind way how they handled a user request.

Using my experiences from other projects

Porting Giac to the MSYS2/CLANG32 environment was a simpler story because I had the former experiences with the other projects. Mike (our project leader and chief technology officer at GeoGebra) asked me to focus on Java/Win32 since our users in several schools may have similar problems of old computers or old software. Finally, a CLANG32 build is available now, and, what is more, it is automatically compiled on each source code change (more precisely, on each git push) in my own GitHub repository of Giac. My own repo is a fork of GeoGebra's official Giac repository, but mine contains the required extra code – it is, of course, synchronized quite regularly to be up-to-date with the mainstream version.

GitHub's automated build feature is an extremely useful way to keep your source code tested. To explain it in a nutshell: you only need to maintain a configuration file that explains which platforms are to be compiled and exactly how. To have a quick overview, I copy the MSYS2/CLANG64 part here:
name: build test

on: [push]

jobs:

 windows_msys2_clang64-native-cmake:
    runs-on: windows-latest
    defaults:
      run:
        shell: msys2 {0}
    steps:
    - uses: actions/checkout@v1
    - name: prerequisites
      uses: msys2/setup-msys2@v2
      with:
        msystem: CLANG64
        update: true
        install: >-
          base-devel
          mingw-w64-clang-x86_64-cc
          mingw-w64-clang-x86_64-cmake
          mingw-w64-clang-x86_64-make
    - name: build
      run: mkdir cbuild && cd cbuild && CC=clang CXX=clang++ cmake -G "MinGW Makefiles" .. && mingw32-make

I copied the CLANG64 variant in this blog because the CLANG32 environment is not yet production ready on GitHub at the moment. So, one needs to do some file system hacks to set up MSYS2/CLANG32 first, and then update the packages, and finally install the necessary packages mingw-w64-clang-i686-cc, mingw-w64-clang-i686-cmake and mingw-w64-clang-i686-make for Win32. The Java related files are already available as pre-compiled packages in the Giac repository (these include native versions of GMP and MPFR, this is a standard way how we do this at GeoGebra).

The final player in this story is CMake. I would not say that I chose it because of its simplicity or platform transparency – it was just an attempt and it worked after an acceptable amount of headache. CMake has a convenient learning curve: you can start simple things quite easily, but for complex projects you need to master it. I am somewhere between the beginner and intermediate level now.

To make this long story short: Our user's problem with the crash has been solved with the new toolchain. However, we still need some work to integrate the new toolchain in the production process. Hopefully, this can be addressed soon.

The most important benefit of this change will be that we will manage to unify some platforms and their testing. We can rid of the difficulty of debugging the Java/Win32 platform that was done in a sort of voodoo way, and we will be able to test the native CLANG64/CLANG32 executables inside a modern debugger instead.

Giac is available on many platforms. My GitHub fork currently supports 11 different platforms – each runs a different piece of code of the GitHub action. You may be interested how GitHub informs me after a successful run of compilation for all the 11 platforms. It was fun to put this testing system together, however, the maintenance of so many platforms seems to be quite difficult for the long term. So – unification and simplification remain very important issues!


Entries on topic technical developments

  1. Embedding realgeom in GeoGebra (9 July 2021)
  2. Web version of Tarski (1 October 2021)
  3. Developing Giac with Qt Creator on Windows (24 January 2022)
  4. Compiling Giac via MSYS2/CLANG32 (2 April 2022)
  5. Terminals on the web (28 June 2022)
  6. Torus puzzle (15 April 2023)
  7. Tube amoeba (16 April 2023)
  8. XaoS in WebAssembly (30 August 2023)
  9. Debut of GNU Aris in WebAssembly (11 November 2023)
  10. JGEX 0.81 (in Hungarian) (10 December 2023)
  11. xaos.app (2 January 2024)
  12. Compiling and running bibref-qt on Wine (22 August 2024)

Zoltán Kovács
Linz School of Education
Johannes Kepler University
Altenberger Strasse 69
A-4040 Linz