6 ms·
The Makefile shown in the article is simultaneously not complicated and also over-complicated. I feel like most Make users don't understand Make very well (espe
by __david__ 9y ago
The Makefile shown in the article is simultaneously not complicated and also over-complicated. I feel like most Make users don't understand Make very well (especially the ones that complain really loudly about it).
Here's a couple examples:
1. The "%.o: %.c" line is a huge code smell for Makefiles. You shouldn't ever write that line—it's built in!
2. Mentioning .h files in the Makefile. Don't. Go look up the `-MMD` flag in your C compiler. Clang, gcc and many other C compilers support it. Add that and a "-include *.d" line in the Makefile and you'll have great dependency support.
Everything else in that makefile is just setting variables. It's made overly complicated by the directory junk, but I'm failing to see the problem.
- beefhash 9y ago> Clang, gcc and many other C compilers support it. Add that and a "-include *.d" line in the Makefile and you'll have great dependency support. Doesn't that sacrifice portability, though? Is this method portable between GNU make and FreeBSD make and OpenBSD make?
- Tomte 9y agoWhy wouldn't it? the *.d files are file snippets in regular make syntax. The special handling is in the compilers: they emit make file parts!
- beefhash 9y agoBecause "-include" is a non-standard[1,2] extension. "include" is standard POSIX behavior[1] but (1) does not seem to support wildcards and (2) errors if the file does not exist, which it never will on initial build. From a glance at the man pages, OpenBSD make does support -include[2], but FreeBSD make does not[3]. [1] cf. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ma... [2] https://man.openbsd.org/make https://man.openbsd.org/make [3] https://www.freebsd.org/cgi/man.cgi?make https://www.freebsd.org/cgi/man.cgi?make
- pja 9y agoFrankly at this point in time, when people say "Make" they mean GNU Make. Unix distributions that wish to remain stuck in the 1980s with their original BSD Make are welcome to do so, but no sane developer is going to use BSD Make for a build system written any time in the last 25 years unless they have to.
- _wp_ 9y agoCould you provide an equivalent Makefile to the one written in the article to demonstrate best practices?
- danaliv 9y agoI am by no means a make expert but this is how I would write it: CC = clang CFLAGS += -Wall -Wextra libs = -lm objs = hellomake.o hellomake: $(objs) $(CC) $(CFLAGS) -o $@ $(objs) $(libs) .PHONY: clean clean: rm -f hellomake *.o *.d deps := $(objs:.o=.d) %.d: %.c $(CC) $(CFLAGS) -MM -MF $@ $< -include $(deps) The first two lines tell us which compiler we're using and set up some extra compiler warnings. Then we specify which libraries we use (it's a matter of taste whether this is a variable or just spelled out later) and the names of our object files. The first target, hellomake, is our executable. This is the default target, so it's the one that'll be built if we run make with no arguments. It runs the C compiler with the flags we specified earlier. Its dependencies are the object files, which means they'll be built automatically and rebuilt when their dependencies change. As noted, there is a built-in rule to build the object files from the C source using our CC and CFLAGS. We don't need to tell make how to do that. The next target, clean, is a "phony" target—it doesn't refer to a file. Normally a make target tells make how to build a file. A phony target, in contrast, is really just a shell script that doesn't produce any file output. This one deletes all the build products. The remaining lines set up the dependency tracking for headers. This makes it so that a change in a header file will trigger a rebuild of any source that includes it. We begin by making a list of files by copying the list of object files and swapping in ".d" for the ".o" file extension. Next is a rule that tells how to build a .d file from a .c file. This rule runs the C compiler and tells it to output a dependency tracking file. The last line says to include each of the .d files in the Makefile. (The .d files contain Makefile syntax to specify the header dependencies.) I omitted the IDIR and ODIR and such because in a project of this size I wouldn't bother putting includes and object files in separate directories from the source. I hope that helps. I know make can seem outdated and weird but I think it really can be simple once you learn a few things about how it works. Hopefully this will get you started in that direction!
- jwilk 9y ago
- skohan 9y ago> I feel like most Make users don't understand Make very well (especially the ones that complain really loudly about it). But the question is whether this is Make's fault for being incomprehensible, or the User's fault for being lazy. The thing is virtually any system or tool can be understood with enough practice, but just because there is someone out there who can use it well does not mean it's not poorly designed. Both C and Make are decades-old technologies, but most people can read a C file without much experience and intuitively understand what is going on. The same is not true for Makefiles.
- avip 9y agoSure but if all things were kept intuitive, well-specified and simple, no one would have paid us six-figs to maintain it. It's part of the guild protection.
- sureaboutthis 9y agoYou can also create a point and click gui mechanism and brag about how wonderful it is, too, but it wouldn't be 'make' or be as capable, well-rounded, flexible, encompassing, etc. 'make' exists for what it's capable of doing and it must be so as it's used in every piece of software and operating sytem everywhere.
- Qwertious 9y ago>'make' exists for what it's capable of doing and it must be so as it's used in every piece of software and operating sytem everywhere. So it's extremely popular/widespread, therefore it must be good, and therefore you should use it (thereby making it even more popular/widespread)? I really hope that you poorly worded that/I'm grossly misunderstanding you because otherwise, your logic is batshit insane.
- sureaboutthis 9y agoYou are then suggesting that make is not popular and widespread because it's "good". I am saying that, when given the choice, most operating systems and software use 'make' as evidence.
- endymi0n 9y ago> I feel like most Make users don't understand Make very well (especially the ones that complain really loudly about it). This is the very same narrative that vim users proclaim: "It's totally not complex if you took some years to learn your tools" — while simply not realizing that the whole Make syntax is a pile of clunks and hacks and stopgaps and bandaids that has a super steep learning curve and looks like incomprehensive gibberish to the uninitated eye. And most of that needlessly so IMHO. It shouldn't be hard to find a better, well designed syntax with sane defaults, stricter rules with typing and linting, less surprises (tabs, I'm looking at you) that's overall much less scary for newcomers — as well as less taxing for "expert casual" users like me. (I still go for my coworkers and Stack Overflow regularly if I have to fix one and I'm a fucking CTO with 10 years of dev experience) Make's only reason for survival is its ubiquity. No matter which terminal you boot up, it's just there, that's why we use it too, and I hate it every day. I think none of the alternatives (cmake, Jam, Gradle, Maven, grunt etc. etc.) has really succeeded as a cross-platform, cross-ecosystem solution that's both an approachable, simple and usable version of a DAG execution engine that's usable for lots of situation. So the situation will probably stay like with vim and the QWERTY keyboard, the status quo pretty bad, but everyone's too used to it to go for something better.
- xfer 9y agoMaybe you should point to a better editor(or design one if you can) in vim case than simply claiming everyone is using it because they are used to it.
- monob 9y ago>This is the very same narrative that vim users proclaim Sounds like a solid reason why makefiles are great to me then. Vim is so good it finally is letting emacs-OS have a real editor.
- dwc 9y ago> This is the very same narrative that vim users proclaim: "It's totally not complex if you took some years to learn your tools" Something interesting I see more often than not when someone I know decides to try out vim: They know I'm a vim user so they ask me for good tutorials and I tell them there are lots out there but they should start by running vimtutor (included with vim). Takes around 15-20 minutes to work through the interactive lessons and gives you all the basics of movement and editing. A day or so later I ask how it's going and the answer is usually that they're struggling with vim, so I ask if they ran vimtutor. Usually nope, or they started it but quit after a minute or two. Why would one switch to a tool with a different paradigm, ask for and get a tutorial recommendation, and then ignore the advice of spending less than 1/2 hour on a tutorial that ships with the tool? sigh
- yodsanklai 9y ago"The "%.o: %.c" line is a huge code smell for Makefiles. You shouldn't ever write that line—it's built in!" Does it hurt to write it though? It makes the makefile more readable for people who don't know it's built-in. Besides, it's only built-in for ".c". I prefer to keep it in order to have a generic Makefile I can adapt to other programming languages.
- exDM69 9y agoEither you should not write it, or disable all built-in rules of Make with a flag. Doing both is asking for trouble. Make has lots of built-in rules for lots of languages, C, C++, Fortran, Lex, Yacc, etc.
- qznc 9y agoThe Make problems I know [0] are: * Recursive Make Considered Harmful * Changes to the Makefile do not implicitly trigger rebuilds * Dependencies on directories is not really possible * Lots of output by default * Rules with multiple output files are not really possible * can't handle spaces in pathnames [0] https://github.com/qznc/annoying-build-systems#make-alone https://github.com/qznc/annoying-build-systems#make-alone
- snarfy 9y agoSome more: * Change tracking entirely depends on modified timestamps instead of something more robust like checksums. * Makefiles are always platform specific. Make executes commands based on a dependency graph, but it has no commands of its own. You either write multiple makefiles or you build everything in a bash environment.
- qznc 9y agoDo you have a good link/example, why timestamps are bad? I think in the context of Make it is ok. If you rely on checksums, you must implicitly assume that all commands you execute are idempotent. That assumption easily breaks.
- snarfy 9y agoI don't have a link, but one reason to prefer checksums is if you have intermediary steps that produce artifacts, possibly binary input to another step, that may or may not need to actually be built.
- oriolid 9y agoWhen I worked with Clearcase (which is terrible in many ways, this is just one), one of its nice features was that it changed file timestamp to the timestamp of commit, not the timestamp it was changed on developer's machine. The commit timestamp may be after previous commit but also before the compiled object file. Because of this, the only way to do a reliable build was to start from scratch. Which took 45 minutes. Ceterum censeo, Clearcase must be destroyed.
- falsedan 9y ago> I feel like most Make users don't understand Make very well This indicates that make is hard to understand. I've been using it for a while and I still struggle to grok concepts like order-only prerequisites.
- mannykannot 9y agoRe -MMD: without automated dependency discovery, make was half a tool: if a dependency was omitted, it might do a less-than minimal job of rebuilding, introducing regressions into the build output that did not exist in the source. For this reason, make was quite often used in an unconditional manner, and if you are doing that, you can get the same result more simply and clearly (and without surprises) with a procedural shell script. It is surprising how long it took for that gap in capabilities to be closed.
- JdeBP 9y agoIt is not completely closed. * https://news.ycombinator.com/item?id=15060146 https://news.ycombinator.com/item?id=15060146