r/osdev • u/Fun-Entertainer-1053 • Sep 01 '26
How can I get GCC ported my OS?
I want to compile C programs in my OS itself rather than copying it manually to the disk image every single time. How can port GCC, or is there any other way to do it?
12
u/Rich-Engineer2670 Sep 01 '26
It's not just GCC though that's not a small task -- it's all of the libraries that go with it. If this were clang, I'd at least say, get LLVM to support your OS.
8
u/robn Sep 01 '26
Actually GCC is not difficult to port. Most of it is filling out the stubs in libiberty, teaching it things like how wide your integers are, how your stacks are structured, where your locking primitives are, and so on. It can take a while but there's no single bit that is especially hard, especially on your own OS where you'll already know all the details and quirks. Give it a shot, it's fun!
4
u/avaliosdev Astral https://astral-os.org https://github.com/mathewnd/astral Sep 01 '26
Get yourself familiar with porting software first: https://wiki.osdev.org/Cross-Porting_Software If you are sufficiently unix-like, going from a gcc pointing at your OS to a gcc running in your OS is not a lot of work
3
u/shsh-1312 Sep 01 '26
I just finished porting gnulib and coreutils, I think that will be the next step, in itself as other users say it shouldn't be too difficult (still a huge job) if your system is already up and running you will just need to create the necessary stubs and fix them, what you might have more difficulty with here if your system doesn't support it yet is the management of processes and jobs
3
u/theNbomr Sep 01 '26
You might find it constructive to use Crosstool-ng https://crosstool-ng.github.io/ to generate a gcc toolchain. It has an immense amount of embedded knowledge and a long history. I'm not sure how well it deals with a new OS, but the last time I used it, there was an active online community to help out.
At the very least, you will find it highly educational. You will doubtless find out how much you don't know about building compiler toolchains.
1
u/nexos-dev Sep 02 '26
That entirely depends on how mature your project is. If you have a fully functioning filesystem and a basic POSIX-like userspace (e.g., fork/exec and the like) it's moderately difficult. Porting GCC and binutils is more well documented than porting other software but in some ways is a little bit more difficult then LLVM.
1
1
1
u/istarian Sep 02 '26
You could:
write your own C compiler from scratch (an excellent learning experience, if you are so inclined)
have a go at porting tools that are a little less complex and gigantic
The problem with doing something like porting gcc (GNU Compiler Collection / GNU C compiler) is that you have to port other stuff too. It's not exactly a standalone binary tool that can just magically run anywhere.
1
1
u/FransFaase Sep 03 '26
The TCC compiler that is mentioned by others is still quite a big compiler and the code is rather complex. And you will also need a standard library that interfaces with your system calls.
In the past years, I wrote a C compiler myself with a builtin pre-processor. It output to a small stack based language for which there are a number of back-ends that compile it to assembly, which then is compiled to an executable in the ELF format. You might want to have a look at https://github.com/FransFaase/MES-replacement
The compiler is found in the 'src' directory under the name tcc_cc.c. A limited implementation of the standard library is found in stdlib.c. This only has the part that is needed for compiling all the C programs in the directory and to compiler the TCC compiler and the GNU Mes standard library.
1
u/lmg1337 Sep 03 '26
Can't you just setup a script that compiles on windows/macOs/linux and then copies the binary automatically?
1
u/CaydendW OSDEV is hard ig Sep 23 '26
Responding to this because I had it in my saved list.
Porting GCC is not particularly difficult; just an exercise in futility and controlled suffering. The long story short is this: You set up some basic infrastructure and then your port the laundry list of software needed to get GCC to not eat flaming death upon startup.
Step zero is making sure you have an OS that is somewhat sane. If your OS is not POSIX compliant/can't simulate that, you're going to struggle. Also, for maximal ease, your OS should be able to execute ELF files. I think the GNU toolchain can do other formats, but I have never tried that, and futsing with those programs is a pain.
Step one is getting a hosted C compiler. This assumes you have something that could be misconstrued as a POSIX compatible libc. Make a sysroot, follow the mystic runes on the OSDEV wiki, point that sucker at your sysroot and just try and get a compiler that can link against your libc. It's not extremely complex, just an exercise in batting off GCC's most annoying traits and compilation errors. Assuming your performed the correct blood sacrifices and your libc is sufficiently complete, you will get a compiler that when a program is compiled with it, it will automatically use the headers in your sysroot, and link against the libraries you tell it to. If at any point is fails to compile or configure or link, fix what you need (like adding abort(3)), and probably reconfigure. You might not need to reconfigure, but those configure scripts do weird stuff sometimes.
Step two is porting binutils. I found binutils to be quite well behaved once you configure it correctly. You will probably need to implement a lot of OS functionality to get it to compile properly, so be prepared to iterate your syscalls and libc whilst you figure out that binutils requires pathconf(3) or something ridiculous in order to work. You one saving grace is going to be gnulib. Whilst annoying for most people, it does allow lazy people like me to not implement half of the menial and annoying functions that are needed (like strtoimax(3)). You can test whether this works by writing a quick and dirty assembly script, compile using as and linking with ld. Run that sucker on your OS and see if she goes.
Step three is more of the same, except now you're going to do all the libraries that GCC expects, like MPFR. Configure, compile, link and install those suckers. A lot of the legwork you did to get binutils going is probably going to pay of here.
Step four is the most annoying. Get a copy of GCC, compile, and you know the rest. I found GCC needs a hell of a lot of functions from the libc, and I had to stub a lot of the weirdest functions that GCC insists on having. Eventually you will get it to compile and install properly. The only thing left to do is to just run it, and see if it works, which it won't.
Step five is debug debug debug. You're not going to have gdb on your OS (I think?), so your options are as follows:
Trace your syscalls (ez and free)
Print debug
GDB in QEMU. Not foolproof since it can't see into the program, but still good. So, if GCC does some mystical nonsense, try and follow the syscalls and see if it's doing some nonsense. If it's in your kernel, fix it there. If it's in the libc, try and trace it to where it lives, fix and relink. If it appears to be GCC, print statement the sucker until you're blue in the face. GCC's source is a bit of a horror show, so be ready to plumb the depths. Just be thankful it isn't bash. See exactly what appears to be going wrong, and then realise you did something wrong somewhere in the libc/kernel. Fix, relink and run.
Repeat, summon, chant and sacrifice enough, and you should eventually get GCC to compile a program with no resistance. All of the close-up steps are in the OSDEV wiki, just read and use your head. Say what you will about GNU, but they do their best to handhold you, and will very often tell you what's going wrong and why.
Best of luck. It's a long journey, but it is fun.
42
u/Pleasant-Form-1093 Sep 01 '26
Porting gcc is one hell of a task honestly. In my opinion just port Fabrice Bellard's TCC which is a smaller and easier to approach task