Title: GCC 4.6.4 with RISC-V support in Guix
Date: 2024-04-02
Modified: 2024-04-05
Category:
Tags: Bootstrapping GCC in RISC-V
Slug: bootstrapGcc12
Lang: en
Summary:
    We built GCC 4.6.4 with RISC-V support and C++ and all that and we made it
    run in Guix, finally.

Short post now, following what we did in [previous
episodes](/bootstrapGcc10.html) where we explained how to build it and
run it in Debian, now we can run it in Guix thanks to Efraim Flashner's help.

We didn't get rid of the GCC Bootstrapping issue we explained in that post
(comparing binaries and all that, you remember). But we patched around it
because the differences were minimal, and this is not going to be a production
compiler after all. If this causes trouble in the future, we'll fix it, but I
don't think it will (I've said this before...).

### How to use this thing

We provide a `guix.scm` file in [the repository][gcc] you can use for your own
packages. If you know Guix, that's probably all you need to know.

[gcc]: https://github.com/ekaitz-zarraga/gcc

In my case, I did some ugly testing on this thing, so I made another folder,
adjacent to the `gcc` project folder and made this[^ugly]:

[^ugly]: Oh yes, I said ugly. If you know Guix you'll understand what I mean.
    There are plenty of ways to do this clean, but I don't care. I'm ugly.

I added a `guix.scm` file:

``` scheme
(use-modules (gnu packages base)
             (gnu packages)
             (guix licenses)
             (guix gexp)
             (guix utils)
             (guix build-system gnu)
             (guix packages))

(load "../gcc/guix.scm")

(define-public my-hello
  (package
    (inherit hello)
    (source (local-file (string-append (dirname (current-filename)) "/hola.cpp")
              #:recursive? #t))
    (inputs (list gcc-mine))
    (arguments
      `(#:tests? #f
        #:phases (modify-phases %standard-phases
         (delete 'configure)
         (delete 'install)
         (replace 'build (lambda* (#:key outputs #:allow-other-keys)
            (let ((out (assoc-ref outputs "out")))
              (mkdir-p (string-append out "/bin"))
              (invoke "g++" "--version")
              (invoke "g++" "hola.cpp" "-o" (string-append out "/bin/hola"))))))))))
my-hello
```

And a `hola.cpp` file:

``` clike
#include<iostream>
int main (){
    std::cout << "Hola!\n";
    return 0;
}
```

Jumped into the folder and called this:

``` bash
guix build -f guix.scm --system=riscv64-linux-gnu -K
```

Which gave me something like this, but way longer (beware of the `BLABLABLAH`):

``` something
$ guix build -f guix.scm --system=riscv64-linux -K
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
substitute: updating substitutes from 'https://substitutes.nonguix.org'... 100.0%
substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
substitute: updating substitutes from 'https://bordeaux.guix.gnu.org'... 100.0%
The following derivation will be built:
  /gnu/store/niszn6sh1hd6hqwg0xjcw2q7q4lbjvbb-hello-2.12.1.drv
building /gnu/store/niszn6sh1hd6hqwg0xjcw2q7q4lbjvbb-hello-2.12.1.drv...

... BLABLABLAH ...

starting phase `build'
g++ (GCC) 4.6.4
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

phase `build' succeeded after 1.4 seconds
successfully built /gnu/store/niszn6sh1hd6hqwg0xjcw2q7q4lbjvbb-hello-2.12.1.drv
The following graft will be made:
   /gnu/store/hnvji18y322q408x3h6i0wafmd6hqmdf-hello-2.12.1.drv
applying 2 grafts for hello-2.12.1 ...

... BLABLABLAH ...

successfully built /gnu/store/hnvji18y322q408x3h6i0wafmd6hqmdf-hello-2.12.1.drv
/gnu/store/dbkz567v66ry813svva2j3lnmdchb5r5-hello-2.12.1
```

And that I could run (using Qemu binfmt magic):

``` bash
$ /gnu/store/dbkz567v66ry813svva2j3lnmdchb5r5-hello-2.12.1/bin/hola
Hola!
```

Let's use `file` command just in case:

``` bash
$ file /gnu/store/dbkz567v66ry813svva2j3lnmdchb5r5-hello-2.12.1/bin/hola
/gnu/store/dbkz567v66ry813svva2j3lnmdchb5r5-hello-2.12.1/bin/hola: ELF 64-bit
LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV),
dynamically linked, interpreter
/gnu/store/fpqqyym3w1ym24jr2xiwz94hjfgr5hjm-glibc-2.35/lib/ld-linux-riscv64-lp64d.so.1,
for GNU/Linux 2.6.32, stripped
```

No tricks here, it's a RISC-V file, and you can see up in the Guix output it
was built using GCC 4.6.4. That's what we promised, isn't it?

### Next

Next we need to connect this thing to the bootstrapping chain. It needs to be
built using TinyCC and it needs to be able to build a modern GCC that is more
stable.

With that, we might be able to build the whole RISC-V world.

Wish us luck.


#### Extra (added 2024-04-05)

In a similar fashion to the `my-hello` I shared as an example, I just tried
this:

``` scheme
(use-modules (gnu packages gcc)
             (ice-9 rdelim)
             (gnu packages)
             (guix licenses)
             (guix gexp)
             (guix utils)
             (guix build-system gnu)
             (guix packages))

(load "../gcc/guix.scm")

(define-public gcc-with-mine
  (package
    (inherit gcc-7)
    (inputs `(("gcc" ,gcc-mine) ,@(alist-delete "gcc" (package-inputs gcc-7))))
    (arguments (substitute-keyword-arguments (package-arguments gcc-7)
      ((#:phases phases)
       `(modify-phases ,phases
         (add-after 'unpack 'setenv
             ;; We don't want gcc-11:lib in CPLUS_INCLUDE_PATH, it messes with
             ;; libstdc++ from gcc-4.6.
             (lambda _
               (setenv "CPLUS_INCLUDE_PATH" (getenv "C_INCLUDE_PATH")))) ))))))

gcc-with-mine
```

And guess what? It worked.

This is really interesting because GCC 7.5 is the first one with official
RISC-V support. Being able to build it means from here we can follow the
existing bootstrapping chain and build the world. Also, GCC is a huge program
and, as I told you before, it does some checks during the build, building
itself twice and then comparing the resulting binaries to make sure it's
stable. Building an stable GCC that is also able to build itself means a lot.

At this point we can consider my GCC-4.6.4 backport is correct, and not only
that, our package definition is, too. In projects like this bootstrapping thing
it still feels weird when things just work, it makes you be suspicious... I'll
try to ignore that feeling and be happy, just for once.