summaryrefslogtreecommitdiff
path: root/content/bootstrapGcc/12_gcc_backported_works.md
blob: 9747c4131c4aa98be110179c073377f8b62b968d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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.