Live data from Hacker News

Using Make – writing less Makefile

text.causal.agency

21–30 of 200 posts

Re: Using Make – writing less Makefile

#21
post #16

The article reads I think an important thing to know about make(1) is that you don't need to write a Makefile to use it. There are default rules for C, C++ and probably Fortran. And then it goes against its own spirit... You don't need this: OBJS = foo.o bar.o baz.o foo: $(OBJS) $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ Just do: foo: foo.o bar.o baz.o It respects LDFLAGS and LDLIBS.

Lists of files are usually used more than once for more than one task. This would only make sense if the only rule that needed the list was that one that builds, no install/uninstall/package/modify/audit/hash/clean/etc, which is never the case. You also don't want to use globbing in place of an explicit list either.

Sure, I'm just pointing out you don't need to type out the C compiler invocation again.

  FOOOBJS = foo.o bar.o baz.o
  foo: $(FOOOBJS)

Re: Using Make – writing less Makefile

#22

Earlier quoted context omitted.

What sort of keyhole are you peering through that needs to reflow 72-character text lines?

A phone? Your comment is 3 lines for me.

Just checked; both my comment and TFA appear full width on my phone. Bog-standard Android.

Re: Using Make – writing less Makefile

#23
post #8

With gnu make you don't even need OBJs for a simple directory in which all the .c files are compiled: .SECONDEXPANSION foo: $$(patsubst %.c,%.o,$$(wildcard *.c)) $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ Admittedly you can end up with short, very general Makefiles that look like they were a Prolog program written in TECO. But the advantage is that they are general so don't need to be fiddled with as your project grows. I m…

Globbing is possible but unwise. You do want a variable with an explicit list of sources, even while trying to make things as automatic and dynamic as possible.

Re: Using Make – writing less Makefile

#24
post #16

The article reads I think an important thing to know about make(1) is that you don't need to write a Makefile to use it. There are default rules for C, C++ and probably Fortran. And then it goes against its own spirit... You don't need this: OBJS = foo.o bar.o baz.o foo: $(OBJS) $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ Just do: foo: foo.o bar.o baz.o It respects LDFLAGS and LDLIBS.

But the OBJS allows for an easy `clean` target, defined further down the article.

Personally, I'd have gone with

    foo: $(OBJS)
            $(CC) $(LDFLAGS) -o $@ $
to put all flag options first, then the output option, then using `$But that is somewhat idiosyncratic, and based on some half-remembered ideas of second-hand stories of how compilers used to process their command parameters back in the '90s (and before). Those ideas probably aren't relevant now (and may not have been entirely correct originally), so if the recipe in the original article works for the author, I'm not going to say they're "wrong" for doing it the way they did.

Re: Using Make – writing less Makefile

#26
post #8

With gnu make you don't even need OBJs for a simple directory in which all the .c files are compiled: .SECONDEXPANSION foo: $$(patsubst %.c,%.o,$$(wildcard *.c)) $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ Admittedly you can end up with short, very general Makefiles that look like they were a Prolog program written in TECO. But the advantage is that they are general so don't need to be fiddled with as your project grows. I m…

Using these and other similar features of GNU make it is possible to write a generic Makefile that works for any software project.

It appears that almost nobody reads the manual of GNU make, despite the fact that it is extremely instructive.

I have read the GNU make manual once, about 25 years ago. Then I have written a set of small Makefiles that I have used in all my software projects forever, until now, with only extremely small changes during the years, e.g. when new compiler options have appeared, or when I have added compilers for additional CPU targets or operating system targets or additional programming languages.

It is possible to make such generic Makefiles that will work in any software project.

For example, in the simplest case, when the source files are in a single directory and you use that directory also for building the project, copying a small template Makefile that includes the appropriate generic Makefile for the target CPU and operating system is enough so that "make" will identify all the kinds of source files that exist in the directory, generate the necessary dependence rules, invoke the appropriate compilers and build the executable.

For any more complex project, only a minimum of information needs to be added to the template Makefile. For instance, when the build is done in another directory than the one with sources, or when there are multiple directories with source files, a list of directories with source files must be added into the template Makefile. Lists of non-standard libraries, non-standard library directories and non-standard include directories may be added. Additional options can be specified, e.g. building a shared library, not an executable file.

Besides these, nothing specific to the project needs to be written. Adding or deleting source files or renaming source files do not need any changes in the Makefile, but after such changes a "make clean" is recommended.

Instead of this simple and obvious approach, more than 99% of the software projects that I have seen use absolutely horrible huge and unmaintainable Makefiles, or they use "make" replacements like "cmake", which are much worse than the traditional "make", so I fail to understand why anyone would want to use them.

Re: Using Make – writing less Makefile

#27
post #21

Earlier quoted context omitted.

Lists of files are usually used more than once for more than one task. This would only make sense if the only rule that needed the list was that one that builds, no install/uninstall/package/modify/audit/hash/clean/etc, which is never the case. You also don't want to use globbing in place of an explicit list either.

Sure, I'm just pointing out you don't need to type out the C compiler invocation again. FOOOBJS = foo.o bar.o baz.o foo: $(FOOOBJS)

Ah got it. Agreed.

Re: Using Make – writing less Makefile

#28
post #17

I like the man page format each post has on this website. A little hard to read, but very unique.

This is supposed to be functional, not art work. Make it legible; easy to digest. I guess it's fitting for a tool (make) that is also unergonomic by today's standards.

I wouldn't use this format myself either, but that's the fun with personal websites: you can do whatever you want. There's no law that says stuff needs to be functional. People who dislike it will just move on.

Re: Using Make – writing less Makefile

#29
post #8

With gnu make you don't even need OBJs for a simple directory in which all the .c files are compiled: .SECONDEXPANSION foo: $$(patsubst %.c,%.o,$$(wildcard *.c)) $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ Admittedly you can end up with short, very general Makefiles that look like they were a Prolog program written in TECO. But the advantage is that they are general so don't need to be fiddled with as your project grows. I m…

Globbing is possible but unwise. You do want a variable with an explicit list of sources, even while trying to make things as automatic and dynamic as possible.

Why would you want that?

In decades of programming in very varied environments I have never compiled any software project otherwise than by using globbing, so that I have never needed to waste time to write the name of any source file in a Makefile.

I have never seen any reason to do otherwise.

For instance, using special compilation flags for a certain source file, different from the others, is something that I consider a mistake. Whichever is the goal, it certainly can be achieved by other means (e.g. pragmas or attributes).

Moreover, the dependencies for any file must always be generated automatically, they must never be written explicitly, which removes the main reason why in bad Makefiles the names of the source files are written individually.

Post reply on HN