Good Makefiles (2018)
glouw.comYou shouldn't hard-code gcc. make has an implicit CC variable for this: https://www.gnu.org/software/make/manual/html_node/Implicit-...
Your makefile will then work on systems without gcc, and it is also easier to override it, ie:
make CC=clang> You shouldn't hard-code gcc.
You should unless you've committed to writing portable code. If you're using GCC specific features then using CC would imply a false level of compatibility.
In this case they are using gcc specific features "-MMD -MP -MT".
I just tested and this Makefile works fine with clang, except that -flto should be added to LDFLAGS.
In fact I believe it should be there for gcc too, according to https://gcc.gnu.org/wiki/LinkTimeOptimization so perhaps this is a bug in the Makefile?
Flushing out issues like this is another reason to commit to writing portable code (and build systems), as you put it.
or just rely on the /usr/bin/cc symbolic link
Not every system that can use Makefiles has a C compiler at /usr/bin/cc
we shouldn't hardcode the path but I would assume that most unixes with a C compiler will have a cc symlinked somewhere in the $PATH
Okay, and what if someone wants to cross-compile?
Make is a great tool. I mostly use it to remember repetitive tasks, like running python tests, not as a build system. Works even better for this. What annoys me deeply is that gnu make isn’t available on windows, e.g git bash.
The one fatal flaw is it's inability to handle whitespace in paths. How do you avoid that problem?
I really don't know the first thing about C or makefiles o anything related, but I was browsing the code out of general curiosity and I have a question.
Would this code benefit from better variable names or is it just that I don't know the domain and this is good understandable code? I'm honestly curious.
This happens a lot with C code examples here.
I think that most code benefits from better variable names. For ease of typing and for historical reasons, abbreviated variable names are in the C and makefile domain:
BIN = BINary executable
SRCS = SouRCe fileS
OBJS = OBJect fileS
DEPS = DEPendency fileS
CFLAGS = C compiler FLAGS passed as arguments to the C compiler
LDFLAGS = linker or Link eDitor FLAGS passed as arguments to the linker
I would say that the variable naming in the linked Makefile follows the usual conventions. Sure it could benefit - but at the cost of confusing readers who are accustomed to those conventions.
Most of the variables here have standard names that show up in most makefiles.
There's a larger discussion on this topic at https://news.ycombinator.com/item?id=19052830.
For lots of things, and especially if you stick to the Unix Philosophy or Suckless Philosophy, this Makefile is all you need. I personally add ‘install’, ‘uninstall’, ‘clean’, and ‘superclean’ targets to my projects but this is a really great start.
I understand there's lots of build systems out there with better scripting languages, but is there anything else that can challenge make for simplicity and portability (although I guess you could export Makefiles)?
What about CMake?
Right, CMake seems like a more than adequate replacement. Then it becomes a question of why so many people are still writing Makefiles by hand.
Unfortunately, the reality is never as simple as that. Your makefile will grow like a tumour once your project grows: Specific dependencies, OS and compiler related flags and switches, special folder structures, etc etc.
It's a terrible Makefile