diff options
-rw-r--r-- | content/bootstrapGcc/12_gcc_backported_works.md | 193 | ||||
-rw-r--r-- | content/bootstrapGcc/13_tcc_to_gcc.md | 243 | ||||
-rw-r--r-- | content/bootstrapGcc/14_g++4.6.4.md | 185 |
3 files changed, 621 insertions, 0 deletions
diff --git a/content/bootstrapGcc/12_gcc_backported_works.md b/content/bootstrapGcc/12_gcc_backported_works.md new file mode 100644 index 0000000..9747c41 --- /dev/null +++ b/content/bootstrapGcc/12_gcc_backported_works.md @@ -0,0 +1,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. diff --git a/content/bootstrapGcc/13_tcc_to_gcc.md b/content/bootstrapGcc/13_tcc_to_gcc.md new file mode 100644 index 0000000..0d3bcde --- /dev/null +++ b/content/bootstrapGcc/13_tcc_to_gcc.md @@ -0,0 +1,243 @@ +Title: TinyCC to GCC gap is slowly closing +Date: 2024-05-02 +Category: +Tags: Bootstrapping GCC in RISC-V +Slug: bootstrapGcc13 +Lang: en +Summary: The sidetrack we took in the past started to give us some good news. + Here there are some. + +In [previous episodes we talked about getting +sidetracked](/bootstrapGcc11.html) and we mentioned we needed to build Musl +because we had limitations in our standard library. We didn't explain them in +detail and I think it's the moment to do so, as many of the changes we proposed +there have been tested and upstreamed, and explain the ramifications that +process had. + +#### Symptoms + +TinyCC and our MeslibC are powerful enough to build Binutils. But not enough to +make some of the programs, like GNU As, work. + +MeslibC is supersimple, meaning it doesn't really implement some of the things +you might consider obvious. One of the best examples is `fopen`. Instead of +returning a fresh `FILE` structure, in MeslibC `fopen` simply returns the +underlying file descriptor, as returned by the kernel's `open` call. This is +not a big problem, as the `fread` and `fclose` provided with MeslibC are +compatible with this behaviour, but there's a very specific case where this is +a problem. In GNU As, if no file is given as an input, it just tries to read +from standard input, and it fails, saying there was no valid file descriptor. +Why? Let's read the code GNU As uses to read files (`gas/input-file.c`): + +``` clike +/* Open the specified file, "" means stdin. Filename must not be null. */ + +void +input_file_open (const char *filename, + int pre) +{ + int c; + char buf[80]; + + preprocess = pre; + + gas_assert (filename != 0); /* Filename may not be NULL. */ + if (filename[0]) + { + f_in = fopen (filename, FOPEN_RT); + file_name = filename; + } + else + { + /* Use stdin for the input file. */ + f_in = stdin; + /* For error messages. */ + file_name = _("{standard input}"); + } + + if (f_in == NULL) + { + as_bad (_("can't open %s for reading: %s"), + file_name, xstrerror (errno)); + return; + } + + c = getc (f_in); + /* ... Continues ...*/ +``` + +If MeslibC uses file descriptor integers as `FILE` structures, it's not hard to +detect the problem in the example. For the cases where the selected filename is +empty (no file to read from) `filename[0]` will be false (`\0` character), and +`f_in` will be set to `stdin`. That should normally mean some `FILE` structure +with an internal file descriptor of value `0`, the one corresponding to the +standard input. As the structure is not `NULL` the error message below won't +trigger. As I just explained, MeslibC uses kernel's file descriptors instead of +`FILE` structures so `stdin` in MeslibC is just `0`, which is equal to `NULL` +for the compiler, so the error message is triggered and the execution stops. + +MeslibC's clever solution for filenames is simply failing due to the fact that +C has no error types, and errors are signalled in the standard library using +`NULL`. + +This is just a simple case to exemplify how MeslibC affects our bootstrapping +chain, but there are others. For example, MeslibC can't `ungetc` more than once +because that was enough for the bootstrapping as it was designed for x86, but +as we moved to a more recent binutils version (the first one supporting +RISC-V), that became an obstacle, and it's preventing us from running GNU As. + +Of course, all of these problems could be fixed in MeslibC, but in the end the +goal of MeslibC is not to be a proper C standard library implementation, but a +helper for the bootstrapping of more powerful standard libraries that already +exist. These problems, and some others we also found, are just drawing the line +of *when* do we need to jump to a more mature C standard library in our chain. +Looks like binutils is where that line is drawn. + +#### Musl + +The bootstrapping chain as conceived in Guix uses GLibC, as Guix is a GNU +project, but we found Musl to be a more suitable C standard library for these +initial steps as it is simple an easy to build while keeping all the +functionality you might expect from a proper C standard library. + +We ran into some issues though, as upstream TinyCC's RISC-V backend wasn't +ready to build it. + +First of all, TinyCC's RISC-V backend had no support for Extended ASM, so I +implemented it and sent it upstream. + +Once I did that we built Musl and we realized we had issues in some functions. +The problem was the Extended Asm implementation was not understanding the +constraints properly and those parameters marked as read and write were not +considered correctly. I talked with Michael, the author of that piece of code, +because I didn't understand the behaviour well. He guided me a little and I +proceeded to fix it in all architectures. + +Still, we couldn't build Musl because it was using some atomic instructions +that were not implemented in TinyCC's RISC-V assembler and we decided to avoid +them, patching around them in Musl. They happened to be important for memory +allocation (LOL) so I decided to implement them in TinyCC's assembler and push +the changes upstream. I implemented `lr` (load reserved), `sc` (store +conditional) and extended `fence`'s behaviour to match what the GNU Assembler +(the reference RISC-V assembler) would do. + +Still this wasn't enough for Musl to build properly as TinyCC's RISC-V backed +was not implemented as a proper assembly but as instructions in human readable +text. RISC-V is a RISC architecture and makes a heavy use of pseudoinstructions +to ease the development of assembly programs. Before all this work, TinyCC +only implemented simple instructions and almost no pseudoinstruction expansion. + +Also, its architecture couples argument parsing with relocation generation and +it doesn't really help to implement pseudoinstructions with variable argument +count or default values. I added enough code to avoid falling in the problems +this design decision had and pushed everything upstream. The list includes +support for many pseudoinstructions, proper relocation use for several +instruction families like `jal` and branches, and some other things. In the +end, we do not have a fully featured assembler yet, but we do have enough to +build the simple code we find in a C standard library like Musl. In fact, even +using the syntax that any RISC-V assembler would expect, as I explained in +more detail [here](/bootstrapGcc11.html). + +#### Meslibc + +Once all those changes are finally applied to TinyCC, we can remove the weird +split we needed to do in MeslibC to support make it match the TinyCC assembly +syntax, so I did that. Less code, less problems. + +Also my colleague Andrius added a `realpath` stub, to make us able to build +upstream TinyCC without having to patch the places where `realpath` was used in +it. `realpath` is not a simple function to implement, and it's not critical in +TinyCC. Again MeslibC doesn't need to be perfect, only let us start building +everything. + +#### TinyCC + +With all those changes coming to MeslibC and the ones we upstreamed, we now +don't need to patch on top of upstream TinyCC, so all our small changes on top +of it are dropped now. Less code, less problems. + +We could have kept these changes for ourselves, but sharing them is not only +easier, but also better for everyone. The following is the complete list of +changes I upstreamed to TinyCC, a project that we are not really part of, but +this is what we do and what we believe in. + +* `0aca8611` fixup! riscv: Implement large addend for global address +* `8baadb3b` riscv: asm: implement `j offset` +* `15977630` riscv: asm: Add branch to label +* `671d03f9` riscv: Add full `fence` instruction support +* `c9940681` riscv: asm: Add load-reserved and store-conditional +* `0703df1a` Fix Extended Asm ignored constraints +* `6b3cfdd0` riscv: Add extended assembly support +* `e02eec6b` riscv: fix jal: fix reloc and parsing +* `02391334` fixup! riscv: Add .option assembly directive (unimp) +* `cbe70fa6` riscv: Add .option assembly directive (unimp) +* `618c1734` riscv: libtcc1.c support some builtins for \_\_riscv +* `3782da8d` riscv: Support $ in identifiers in extended asm. +* `e2d8eb3d` riscv: jal: Add pseudo instruction support +* `409007c9` riscv: jalr: implement pseudo and parse like GAS +* `8bfef6ab` riscv: Add pseudoinstructions +* `8cbbd2b8` riscv: Use GAS syntax for loads/stores: +* `019d10fc` riscv: Move operand parsing to a separate function +* `7bc0cb5b` riscv: Implement large addend for global address + +#### Bootstrappable TinyCC + +During the bootstrapping process we detected new issues and one of them was so +deep it took pretty long to detect and solve. + +Most of the programs we were building with our Bootstrappable TinyCC worked: +GZip, Make... But we reached a point were we needed to rebuild upstream TinyCC +with Musl, in order to start using Musl to build the next programs. It didn't +work. + +We had a really hard time finding the problem behind this because it appeared +too far in the chain to be easy. The process goes like this. + +We use Mes to build our very first Bootstrappable TinyCC, which compiles itself +several times (6), until it reaches its final state. That then builds upstream +TinyCC and with that we build TinyCC again this time using Musl as its standard +library. We found this last one was unable to build simple files and we started +digging. + +We realized TinyCC was using sign extension in `unsigned` values, and that was +messing up with the next TinyCC, making it unable to build programs correctly. +Researching this deeply we found the problem was in the `load` function of +TinyCC but a TinyCC built with GCC didn't have this problem. The only option +was that the Bootstrappable TinyCC had the bug that was later affecting the +compilers compiled with it. + +Digging a little bit further I found the casts from Bootstrappable TinyCC had +some missing cases that I didn't backport properly but as I wasn't able to +understand them very well I decided to backport the full `gen_cast` function +from upstream to the Bootstrappable TinyCC. With that, the errors from TinyCC +were gone. + +It feels like an accidental trusting trust attack, yes. This is the kind of +things we have to deal with, and they are pretty tiring and frustrating to +find. + +#### The new Bootstrapping chain + +So, all of this brings us to the new bootstrapping chain. We need to make +things very different to the way Guix does them right now, because we are +skipping many steps (GCC 2.95, now we need Musl for Binutils...) so I started +[a project](https://github.com/ekaitz-zarraga/commencement.scm) to track how we +go forward in the bootstrapping chain (it's just a wip, for our tests, take +that in account). + +We had good and bad news in that regard. At the moment of writing we managed to +build up to the GCC 4.6.4 I added RISC-V support to, but the compiler is faulty +and it's unable to build itself again with the C++ support. + +I'm using non-bootstrapped versions of `flex` and `bison`, but those +shouldn't be hard to bootstrap either. I just didn't have the time to make them +from scratch. And I'm using a `bash` instead of `gash` because we had found a +blocking error in `gash` that is not letting us continue forward from Binutils. + +In any case, this means we are near from the next milestone: building GCC 4.6.4 +with TinyCC; and as we described in the previous post we already built GCC 7.5 +from GCC 4.6.4 so we solved the next already. + +After those, we would need to clean this new bootstrapping chain and talk with +Guix for its inclusion in there. I hope we can finish all this before hitting +the deadline that is silently approaching... diff --git a/content/bootstrapGcc/14_g++4.6.4.md b/content/bootstrapGcc/14_g++4.6.4.md new file mode 100644 index 0000000..9df600f --- /dev/null +++ b/content/bootstrapGcc/14_g++4.6.4.md @@ -0,0 +1,185 @@ +Title: Milestone – Bootstrapped GCC 4.6.4 for RISC-V +Date: 2024-05-17 +Category: +Tags: Bootstrapping GCC in RISC-V +Slug: bootstrapGcc14 +Lang: en +Summary: So yeah, we bootstrapped GCC 4.6.4 for RISC-V. We even have C++ + support! + +In latest posts we talked about many things: problems, our changes to other +projects and other things. Now it's time to actually talk about something we +actually *did*. + +But first, we fixed more extra things... This is a never ending story. + +### The things we need to deal with + +We have been trying to build GCC 4.6.4 with the backported RISC-V support using +TinyCC. We already did a GCC 4.6.4 that worked but we only tested it building +with a modern GCC. Building with a TinyCC with an incomplete backend that we +had to improve ourselves is not that obvious as it would be with the very well +established architecture like i386. + +We could build a minimal GCC, from TinyCC and Musl, but it didn't work. Me and +my colleague Andrius Štikonas detected and patched around a problem that we +still don't know where it is coming from ([we reported upstream][upstream]). +This is the only one we need to apply to GCC, as we fixed many things in +TinyCC. + +[upstream]: https://lists.nongnu.org/archive/html/tinycc-devel/2024-04/msg00028.html + +This simple patch was enough to build the whole GCC. Can you spot the +difference? + +We find this kind of problems making small reproducers that we tried to tweak, +and happened to work if we split things. + +``` diff +diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c +index d05f8149170..d4ef8de4813 100644 +--- a/gcc/tree-ssa-operands.c ++++ b/gcc/tree-ssa-operands.c +@@ -300,6 +300,7 @@ static inline void * + ssa_operand_alloc (unsigned size) + { + char *ptr; ++ int x; + + gcc_assert (size == sizeof (struct use_optype_d) + || size == sizeof (struct def_optype_d)); +@@ -334,8 +335,8 @@ ssa_operand_alloc (unsigned size) + gimple_ssa_operands (cfun)->operand_memory_index = 0; + } + +- ptr = &(gimple_ssa_operands (cfun)->operand_memory +- ->mem[gimple_ssa_operands (cfun)->operand_memory_index]); ++ x = gimple_ssa_operands (cfun)->operand_memory_index; ++ ptr = &(gimple_ssa_operands (cfun)->operand_memory->mem[x]); + gimple_ssa_operands (cfun)->operand_memory_index += size; + return ptr; + } +``` + +### We need to rebuild with Musl + +Once that very first GCC compiles, it's necessary to rebuild Musl with that +GCC, and use the new GCC+Musl combination to rebuild GCC, now adding the C++ +support we missed first time. + +This gives us several things: a more stable GCC and a better Musl, that is +compatible with GCC. + +If we don't do that, and we don't rebuild Musl, we see errors when building the +second GCC, the `genmddeps` program, which is created and run during build +process of GCC just fails. + +Also, we have to `--disable-bootstrap`, so rebuilding it is like doing the +GCC's bootstrap ourselves. + +### Backport Musl support to GCC 4.6.4 + +Next thing, remember from previous posts why we had to use Musl for our +process. First, because it's a fully-featured C standard library; second, +because it's simple and easy to build and, lastly, because we can't use GlibC: +the newest version we can build doesn't support RISC-V. + +The main problem we have with GCC 4.6.4 since we started with all this journey +is that 4.6.4 was written before our architecture, RISC-V, was invented, and +this also happened with Musl. + +Andrius detected some missing declarations during the compilation process of +the `libstdc++`, which happened because GCC was trying to use some GlibC +specific functions for the build we didn't have, as we were using Musl instead. + +Turns out GCC needs extra configuration for Musl, that was added after our +version was released, so I backported all that (not much) to GCC 4.6.4. Maybe I +missed something, but now we can build GCC 4.6.4 with C++ support, using Musl, +for RISC-V! + +### But it doesn't work! + +Right after building it, we tried to use it on a simple program: + +``` clike +#include<iostream> + +int main (int argc, char* argv[]){ + std::cout << "Hello World" << std::endl; + return 10; +} +``` + +But this returns a huge set of errors looking like: + +``` something +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L0 ': +(.text._ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKPi+0x3a): undefined reference to `operator new[](unsigned long)' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L15': +(.text._ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKPi+0x172): undefined reference to `operator delete[](void*)' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L11': +(.text._ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKPi+0x190): undefined reference to `__cxa_call_unexpected' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L0 ': +(.text._ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi+0x3a): undefined reference to `operator new[](unsigned long)' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L39': +(.text._ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi+0x1b4): undefined reference to `__cxa_call_unexpected' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L23': +(.text._ZNSi6ignoreEl+0x21c): undefined reference to `__cxa_end_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L24': +(.text._ZNSi6ignoreEl+0x22e): undefined reference to `__cxa_end_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.LEHB2': +(.text._ZNSi6ignoreEl+0x24c): undefined reference to `__cxa_begin_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L31': +(.text._ZNSi6ignoreEl+0x272): undefined reference to `__cxa_rethrow' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.LEHE2': +(.text._ZNSi6ignoreEl+0x27c): undefined reference to `__cxa_begin_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L30': +(.text._ZNSi6ignoreEl+0x29c): undefined reference to `__cxa_end_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L51': +(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x22c): undefined reference to `__cxa_end_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L52': +(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x23e): undefined reference to `__cxa_end_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.LEHB9': +(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x25c): undefined reference to `__cxa_begin_catch' +/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L59': +(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x282): undefined reference to `__cxa_rethrow' +collect2: ld returned 1 exit status +``` + +Again, Andrius detected there was a line in the huge logs we have that said we +were missing the `find` command. So we added it, and worked[^until-it-broke]. + +[^until-it-broke]: There's something weird in this case, if I do a change like + this one below it fails: + <!-- Using a markdown fenced code block here fails --> + + <pre class="language-diff"> + <code class="language-diff"> + (native-inputs `(("gcc" ,gcc-muslboot0) + ("libc" ,musl-boot) + - ("find" ,findutils) + ,@(modify-inputs (package-native-inputs gcc-muslboot0) + + (append findutils) + (replace "make" gnu-make-muslboot) + (delete "libc") + (delete "tcc")))) + </code> + </pre> + +### The thing built, and worked! + +So we managed to make it build and run, improving TinyCC in the process. Now +TinyCC can build Musl and GCC 4.6.4 (with a very small patch), and that GCC is +able to build itself, adding C++ support. And of course, the thing works! + +You can try if this thing worked, and see how, in the +[`commencement.scm`][commencement] project where I'm keeping track of all this. + +[commencement]: https://github.com/ekaitz-zarraga/commencement.scm/commit/9bbb1c61a87e206fb275c3040d0493beba6ae0fe + +### Next + +So yeah, success but this didn't end. Now we need to use that GCC to build GCC +7.5, and compile the world with it. + +Cross fingers. |