Hi Chris, I notice that your makefile article  uses the macro name LDLIBS for -l options like -lm. That's reminiscent of GNU make's .c suffix rule : LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) .c: $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@ Do you know why they separate the -L flags in LDFLAGS vs -l flags in LDLIBS? I realize that GCC's linker has trouble if the -l flags precede the source file(s), but my question is why don't they put all the flags (both -L and -l) together into LDFLAGS and put that macro at the end? For instance, using this suffix rule: .c: $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) POSIX make  doesn't recognize LDLIBS in its default rules. And its .c suffix rule puts the LDFLAGS before the source name: .c: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< The clang compiler is fine with the -l flags going before the source file actually, which makes it work with the POSIX defaults. Do you know the background behind GNU's divergence? 1: https://nullprogram.com/blog/2017/08/20/ 2: https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html 3: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html#tag_20_76_13_09
> why don't they put all the flags (both -L and -l) together into > LDFLAGS and put that macro at the end? That's a really good question, and I don't know the reason behind it. As you pointed out, as long as the -L option precedes the corresponding -l option, I believe it shouldn't matter that -L comes later, even for gcc. I suspect it's a historical accident. Dynamic linking came relatively late, and along with it linker sensitivity to argument order (at least when invoked via some compilers). By convention, options go before file arguments so the POSIX make documentation put LDFLAGS first. However, with dynamic linking we needed some arguments passed after the source file names. Rather than override the established inference rules to put LDFLAGS last, introduce a new variable, LDLIBS, to hold just the arguments that must go last. Perhaps whoever decided to create LDLIBS thought moving LDFLAGS was too disruptive, and that introducing LDLIBS was a softer fix. Unfortunately this history predates GNU Make's use of source control, as LDLIBS first appears in a January 1992 commit titled "Initial revision". However, it turns out this isn't a GNU-ism! Digging around the Unix History Repository, I see LDLIBS makes its first appearance in April 1986 in BSD 4.3 (commit 7887d35c750). It's in its modern form: at the end of the command with a separate LDFLAGS. This predates GNU Make, which was announced in February 1988 and released in June 1988. So GNU Make was just following conventions established by BSD. It may just be rationalization, but I actually prefer that these are separate since they configure two different sorts of knobs. It's common for the default LDFLAGS to be empty, and LDLIBS populated with the necessary libraries. I can override LDFLAGS independently of LDLIBS, meaning I don't need to worry about preserving anything about LDLIBS: make LDFLAGS='-pie -Wl,-rpath=$HOME/.local/lib' CFLAGS='-fpie' I do want to override LDFLAGS on occasion, but I rarely want or need to override LDLIBS. Makefiles are also a little tidier with them separated.