Live data from Hacker News

Show HN: My C compiler compiled itself

github.com

61–70 of 130 posts

Re: Show HN: My C compiler compiled itself

#61
post #45

Earlier quoted context omitted.

> 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.

A 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…

> the (argh) Automake and Autoconf systems

The classic XKCD graph that plots life satisfaction against days-since-editing-xorg.conf could equally apply to days-since-thinking-about-autotools.

In fact one of the few times I've thought about autotools in the last decade was when a failing python-based build script inflicted similar frustration!

If I were forced to find one nice thing to say about autotools it would probably be that at least it doesn't assume an internet connection is always available, reliable and without cost.

Re: Show HN: My C compiler compiled itself

#62
post #49

Earlier quoted context omitted.

That is neat, but also super brittle, and full of abstraction leakiness, potentially leading to both false positives and negatives. Sounds like it would break down with ccache or distcc immediately, for example.

I never had any false negatives, they are basically impossible in this framework, except it does assume if a program, and all it's inputs are unchanged, the output is unchanged, so this is no good for programs which randomly produce different outputs. ccache can cause things to get built twice, because the first run it sees it tries to read a file, then later writes to it, so it knows something different might happen…

Fair!

Re: Show HN: My C compiler compiled itself

#63
post #45

Earlier quoted context omitted.

> 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.

A 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…

The story I have heard about why it must be a tab is that by the time the author of the original Make realised he didn't need to require a tab, he already had six users and didn't want to annoy them by breaking compatibility with the makefiles they'd written :-)

Re: Show HN: My C compiler compiled itself

#64
post #16

Earlier quoted context omitted.

Or 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 capabi…

As 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.

> Make is so unlike build tools from other languages

Interesting, I thought that "make" was like multiplication tables, something you learn very early one as it's a super simple tool. Also I assumed it was part of any unix 101 class, together with bash and command line stuff. But probably it shows my age. Most people don't have any reason to learn these tools nowadays.

Re: Show HN: My C compiler compiled itself

#65
post #57
post #54

Very cool, congratulations! I took a 2-second peek at the code, and just wanted to offer a small piece of advice that I think makes it better. Or two, really. Counting is hard. Instead of (this is from parser.c): apply_result *ret = (apply_result*)malloc(sizeof(apply_result)); apply the two common principles of DRY [1] and "don't cast the return value of malloc()" [2] and you get: apply_result *ret = malloc(sizeof *r…

This kind of condescending advice doesn't help anybody. Redundant casts, like redundant braces, white space, and a plethora of similar choices are stylistic more than anything else. If you really feel the need to give unsolicited coding style feedback maybe at least spend more than a few seconds looking at the code before you do so. Otherwise it's just rude.

Really? Wow. I had no idea, and I really tried to sound non-condescending.

I simply don't agree that redundant casts are something to be ignored, since they can be harmful and hide actual errors (the cast is a bit like `sudo make me a sandwich`, it makes the compiler do what you say which is not always a good idea).

I guess I believe that publicly posting code, and even writing a compiler for the language in question, kind of automatically marks you as interested in the language and open for ideas of usage and so on.

My apologies to the OP if you were offended. Thanks for the feedback, @gizmo.

Re: Show HN: My C compiler compiled itself

#66

> 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 your…

> 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 featu…

It seems that a programmer making their own compiler is like a Jedi making their own lightsaber

Re: Show HN: My C compiler compiled itself

#67
post #50
post #42

Earlier quoted context omitted.

> Do $@ and $ And yet, I still don't actually know what `$@` and `$ The problem is that "simple" is not the same as "intuitive" or "discoverable". Yes, I could probably put in the effort to go and find out these things, but why would you expect someone to be motivated to do that by someone telling you that it's "trivial" and it "pains" them as they explain things in a way that doesn't actually clarify things in a way…

One might ask how you learned C (or python, or anything else) in the first place, if you can't be bothered to learn what the very simple $ The rest is just... of course you can reimplement make, or a subset of it, in python, python is turing complete after all. But why? make isn't that arcane. I'm sorry it uses the weirdly looking $@ and $ This is trivial in the sense that it's a part of any build system worth its sa…

> One might ask how you learned C (or python, or anything else) in the first place, if you can't be bothered to learn what the very simple $The problem is, you typically don't need to touch Makefiles that often once they work (or fulfil a reasonable interpretation of "work"), so unless you're a distro packager or the project(s) you work on are sufficiently complex and large to warrant an entire FTE just for build tooling, chances are high you need to touch that stuff only once every few years, by which time almost everyone has to dig into the documentation yet again... made worse by the fact that Google's search quality has gone down the drain.

Re: Show HN: My C compiler compiled itself

#68
post #57
post #54

Very cool, congratulations! I took a 2-second peek at the code, and just wanted to offer a small piece of advice that I think makes it better. Or two, really. Counting is hard. Instead of (this is from parser.c): apply_result *ret = (apply_result*)malloc(sizeof(apply_result)); apply the two common principles of DRY [1] and "don't cast the return value of malloc()" [2] and you get: apply_result *ret = malloc(sizeof *r…

This kind of condescending advice doesn't help anybody. Redundant casts, like redundant braces, white space, and a plethora of similar choices are stylistic more than anything else. If you really feel the need to give unsolicited coding style feedback maybe at least spend more than a few seconds looking at the code before you do so. Otherwise it's just rude.

Giving feedback - solicited or not - is part of an engineer's job. Wether it's cosmetic feedback or not doesn't matter as cosmetics are also part of the job, although not everybody thinks so.

Re: Show HN: My C compiler compiled itself

#69
post #26

Earlier quoted context omitted.

As 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.

It 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 (wh…

I've written a good amount of makefiles (and even one rather complex one.. before replacing it with a thing written in an actually sane language, bootstrapped by a stripped down version of the makefile), and I still mix up $@ $ or whatever else my brain comes up with. And this is coming from someone deep into array languages, which have entire sets of unicode glyphs.

For how often one typically writes/looks at build scripts, remembering the specifics about makefiles is quite likely to not be worth the effort.

Makefiles start becoming incredibly awful if you want to do anything outside of pure computations in the separate targets. Making the target directory requires either putting the mkdir call in each separate built thing (awfully redundant), introducing a whole another rule (and still adding it as a dependency on every rule that'll be outputting to said directory), doing some recursive make, or running it outside of rules (but putting it under a proper if statement is likely pain). That's a bunch of awful solutions to something that really really really should just be a single calls to mkdir in any sane system.

Another horrifically awful thing is if you want some reused data across rules (e.g. pkg-config results, current OS/arch). You can put them as globals, but that'll make them be calculated always, even if no build target needs them, unless you put them under an if, which is again non-trivial to get the condition correctly for. This becomes super bad if you do recursive make stuff.

More generally, makefiles start out simple, but doing anything that's not strictly simple is gonna be pain, at the very least requiring looking at docs of a thing you'll probably never use again, and debuggability is also very low (amusingly, '-p' and '--debug' break on recursive make, seemingly losing some variables; and '-n' requires copying out & running the recursive call to get to the actually important part; and afaict none of those help with figuring out why a thing didn't build).

And you're completely SOL if you wanted to do things like reorder compilations based on how long they previously took, or want a nice display of currently-compiling things.

Re: Show HN: My C compiler compiled itself

#70
post #32

Earlier quoted context omitted.

Yes, this is quite important for C projects as it leads to subtle bugs. I also long for a way to let make detect a change of $CC (new build of the compiler itself) in the context of debugging a compiler against third party makefile projects.

I often use a Python program called 'fabricate', which basically checks every file a command opens, and re-runs the command if any touched file changes. I love it, and I hoped this would become the future of how build-systems are built -- you could automatically parallelise, rebuild, make clean, everything, just by tracking which files are read, and written. It does add a bit of overhead, but I'd be willing to pay th…

The 'tup' build system also works this way.
Post reply on HN