It should be noted that just specifically does something make was not designed for but is often conscripted into: it’s not a build tool, it’s a command runner.
So when you run a command it runs the dependencies then the commands, in full, every time.
I very much prefer that usually, because either the underlying tooling handles checking if all’s right or there is no such checking to do and it would be a problem.
But if you expect just to build your C project and handle not touching stuff which doesn’t need to be, you’ll be disappointed.
Yup! Two well-established alternatives are "rake", in the Ruby community, and "just" in the Rust community.
Rake is fully programmable in Ruby. Just is a bit less flexible, but it doesn't require learning Ruby, and it's quite pleasant to use.
Also, many people using rake already are often biased by how Rails uses it, but it's much more than that, and can easily be used as a make replacement, complete with freshness checks and rules.
There was an article specifically avout that on the interwebs but I can't find it anymore. These ones cover some bits as well, although they're a tad heavier on using Ruby code.
[0]: https://github.com/casey/just