5 ms·
> Then run ./build.py. This will use the bootstrapped 30cc-compiler to compile 30cc itself. It then again uses the 30cc-compiled compiler to compile 30cc once a
by yjftsjthsd-h 2y ago
> Then run ./build.py. This will use the bootstrapped 30cc-compiler to compile 30cc itself. It then again uses the 30cc-compiled compiler to compile 30cc once again. The final compiler is then stored as ./30cc.
Why isn't that also done by the Makefile? The only catch I could see is that you'd need to have it build to different output names, but that seems fine for what it is?
---
Also, I'm curious - did you find yourself having to constrain your use of C in order to make sure that the compiler could compile itself? Or does it implement everything you would use naturally anyways?
(And of course, congrats/bravo; super impressive:])
- __alexander 2y ago> Why isn't that also done by the Makefile? My guess is that some people would rather write Python code than dig into Make’s documentation. That said, ChatGPT is excellent at creating valid make files.
- anyfoo 2y agoOr just take a few moments to learn the basics about Makefiles. The thing about Makefiles is that simples ones at least are really easy to write, and read. Much simpler and quicker than a cumbersome python script, that will most likely do less with much more boilerplate code (e.g. dependencies), and be much harder to read. Of course, you may hit a point where you stretch your Makefile so much beyond its common capabilities that that no longer becomes true, but in my experience that point is pretty far away.
- aleph_minus_one 2y ago> The thing about Makefiles is that simples ones at least are really easy to write, and read. Much simpler and quicker than a cumbersome python script, that will most likely do less with much more boilerplate code (e.g. dependencies), and be much harder to read. Whether this is true or not depends a lot on from which programming culture/background you come.
- anyfoo 2y agoI honestly don't think so, and I think this is here is a prime example for proving that. For example, a Makefile that does the same job as the build.py script in this project would be significantly smaller, simpler, and easier to read in several metrics that I'd reasonably call "objective" to a certain degree. In fact, contrast the Makefile in that project: https://github.com/keyvank/30cc/blob/main/Makefile https://github.com/keyvank/30cc/blob/main/Makefile With the build.py script: https://github.com/keyvank/30cc/blob/main/build.py https://github.com/keyvank/30cc/blob/main/build.py You need to know very little about Makefiles to make immediate sense of what that Makefile is doing, whereas you need to know much more about python to still not immediately see what the build.py script is doing. In fact, you will probably just "guess" that the python script is supposed to do a similar job only from its name before that. And then the python script still does not do incremental builds at all! Again, if it gets more complex that can change, but this is far away from that. It takes 10 or so minutes to learn enough about Makefiles to be productive with them, from scratch.
- 3836293648 2y agoIt's is absolutely objectively true. Whether you already know it or not depends on your background
- deleted 2y ago[deleted]
- Tor3 2y agoA Makefile dependency: Left : right Left depends on the right. I don't think the ability to learn that concept is related to programming culture/background. What follows below that is what happens. Left : right cp right Left echo and so on. Left is now updated. The only tricky part of the above, and something I guess nobody has found any good reason for, is that the whitespace in front of the statements ('cp' in this case) has to be an actual tab, just spaces won't do. When it comes to the more "advanced" concepts (wildcards etc) there are slight differences between Make versions. And to bother with that is to get into the mindset which created the (argh) Automake and Autoconf systems (to begin with), so back in the day our company simply decided that we'll use GNU Make on every single system (we supported lots of various UNIX systems) and not bother with any of that (no SYSV Make, no BSD Make or anything), because GNU Make was and is available on anything and everything. Made life very simple back then.
- unclad5968 2y agoAs someone that learned C# and python before C and C++, to this day I couldn't explain to you how make rules work. Make is so unlike build tools from other languages that it doesn't surprise me someone would rather use python to bootstrap their compiler.
- anyfoo 2y agoIt is so trivial, it takes you 10 minutes to learn. Less even, here is an attempt: foo.o: foo.c clang -c -o foo.o foo.c This builds a file called foo.o, if foo.c is newer than foo.o. Imagine that there is an identical bar.o as well, that builds it from bar.c. fooexec: foo.o bar.o clang -o fooexec foo.o bar.o This links together foo.o and bar.o into a file called fooexec, if at least one of foo.o or bar.o is newer (which in turn means that any of its respective dependencies changed; e.g. change bar.c, and bar.o and then fooexec will rebuild). Now type this into the shell: make fooexec Congratulations! You have a fully built fooexec. Now change bar.c, type it again, and like magic, you have a rebuilt bar.o and fooexec. foo.o will stay put, it’s up to date! But of course all the .c -> .o rules look the same, so instead of writing a new one for every file, you'd use simple wildcards, and now the whole, entire Makefile is just: %.o: %.c clang -c -o $@ $< fooexec: foo.o bar.o clang -o fooexec foo.o bar.o Do $@ and $< look arcane at first glance? Yes. Is what they do simple, though? Also yes. (If your complaint is that you don't know what those "clang" lines do, then you don't know how to use the C compiler, and will have the same problem when writing a python script.) It pains me if that is not immediately obvious. And it pains me even more that someone would want to write a boilerplate heavy, complex python program, that rebuilds everything all the time, instead of just learning this very simple concept.
- IgorPartola 2y agoThis is an excellent explanation of make! The only thing I will add is the slightly more abstract thought that make is meant to build files out of other files based on timestamps of the source files. And the target files can themselves become source files, which means that you can build dependency graphs. Lastly, it has “caching” built in: if bar.o is newer than bar.c, don’t rebuild it. If it doesn’t exist or is older, do rebuild it. So when you change one file, you don’t recompile the entire damn tree. It also has “phony” targets that aren’t files. The canonical example of this is “clean” which basically just does something like rm -rf *.o fooexec This is what the JavaScript tooling people have been chasing for the past 15 years and can’t seem to grasp. Someone actually did build a make-based JS build system I believe but it never got popular because it wasn’t written in JavaScript.
- saghm 2y agoOn the other hand, I'd argue that the point where you've stretched it so far that it's more trouble than it's worth is basically impossible to see until you've gone beyond it.
- bluGill 2y agoIf make is too hard, ninja is simpler. Less powerful but in ways that rarely matter. I've written both by hand both are a little weird but not hard. Normally I use cmake these days (an aweful language but it works for hard problems)
- dbcurtis 2y ago> Also, I'm curious - did you find yourself having to constrain your use of C in order to make sure that the compiler could compile itself? Or does it implement everything you would use naturally anyways? That would be the "bootstrapping" process. Nearly a half-century ago I took a compiler lab class where we were given a working, but slightly lame, compiler, and were tasked with adding new, less lame, language features by bootstrapping. That is: 1) implement new feature without using the new feature, 2) using the compiler that results from step 1, re-implement the feature using the new feature, and compile again. 3) Repeat with more features until end of semester for best grade. Oh, and to the OP, well done!
- abirch 2y agoIt seems that a programmer making their own compiler is like a Jedi making their own lightsaber
- williamdclt 2y agoI guess the full bootstrapping process would start with writing a basic compiler in assembly?
- atq2119 2y agoThe full bootstrapping process starts with entering instructions in binary (or hex or octal) to build an assembler in the first place :)
- swiftcoder 2y agoThe full bootstrapping process starts with a soldiering iron and a reel of copper wire.
- pabs3 2y agoThat is correct the path chosen by the Bootstrappable Builds project indeed: https://bootstrappable.org/ https://bootstrappable.org/ https://lwn.net/Articles/983340/ https://lwn.net/Articles/983340/
- 2y ago
- keyvank 2y agoi think it just supports smth like 70% of C. I didn't bother supporting floating-point operators, or arrays (I mean, malloc and pointers are fine) or etc. I just wanted smth small and self-hosting!