Tuesday, March 31, 2026

the truth make doesn't want you to know.

 we all know GNU make utility, the beautiful build system that helps us build complex projects and saves time, and always it tracks dependencies!

and perhaps the latter is the most important one, it saves a lot of compilation time by not compiling the up-to-date targets, but how make actually tracks the dependencies of a specific target?

it's simpler than what you think, it's just timestamp comparison!


say we have a target main.out that relies on 1 dependency, main.c, what happens when you type make is this:

make reads Makefile, it finds you have a target called "main.out" (we'll assume it's the default target for now), it finds that this target relies on main.c files, and it goes and search for main.out, if it's not found, this means it should be made now, but if it's found, it compares the timestamp!
if the timestamp of main.out is earlier than that for main.c, this means main.c was changed and main.out wasn't updated correspondingly, so this triggers a new build.

if they were equal, this means main.out is up to date and doesn't need new building!

but.. what about the third case?
what if main.out was actually updated AFTER main.c, meaning that the timestamp of main.c is now less than that for main.out!

this came to my mind and I had nothing but to try it out!


so, I made this simple main.c file:

along with this simple Makefile:

then we'll run make, obviously make will make main.out for us so happily, and now the timestamp of main.out is similar to main.c, if we ran make again, it'll do nothing because there is nothing to do!


ok, let's make a simple change to main.c:



now we have just one new line, but when we save this file the timestamp will be updated and will become bigger than the timestamp of main.out, if we ran make again, it'll happily make the target, main.out, again, which is what we need!


now let's make another new change to main.c:



but before we rush and run make again, let's run this simple command: touch main.out
touch will update the timestamp of main.out, what does this mean?
now main.out's timestamp is a bit bigger than that for main.c!

despite make SHOULD build the target again, if you run make it'll do nothing and tell you:
make: `main' is up to date.


what does this mean?
make doesn't have a hidden git inside it to track the versions of a file, and it doesn't actually need, the idea behind it is as simple as our main.c... a timestamp comparison!
imagine that this simple idea gave us to build so complex project in way less time, imagine each time you try to build your project, the compiler compiles the exact same utility file that no one has changed since intel pentium processors, imagine this in the scale of a game engine or linux kernel for example!
all this would take way a lot time, and just with an idea a freshman can write the code for, we solved all these problems!

sometimes, it's not about a fantastic solution as much as it's about using the tools you already have!

No comments:

Post a Comment

any inappropriate comments will be deleted and the commenter will get blocked permanently unless I'm free to fuck him.

on behalf of the user, by the name of laziness

 people tend to see engineering as a mysterious field only the chosen people can specialize in, today, as a software engineer, I'll spoi...