Hacker News new | ask | show | jobs
by ainar-g 2228 days ago
Note that this article (like many, many others) assumes GNU Make. POSIX Make has neither .ONESHELL nor local macros. Neither do most built-in Make implementations in other OSes, like OpenBSD's bmake.
2 comments

POSIX shell is also notoriously obtuse and difficult to use. As a big advocate of POSIX as a target, I don't blame anyone for using GNU make - or perhaps BSD make is a better lowest common denominator.

Personally, I try to use POSIX Makefiles, but I often find that they're most useful as a target for Makefile generators (in my case, these are usually a shell script called configure).

One person's obtuseness is other person's simplicity :-) . In all of my personal and some of my work projects I used nothing but portable features in Shell, Make, Sed, etc. Checking with multiple implementations where possible. As long as you use the right tool for the right job, there shouldn't be any problems.

The most common mistake of that sort that I've seen is people trying to do complex conditionals inside their makefiles when they clearly would be better off in a Shell script. (I'm looking at you, fans of ifeq.)

You can implement conditionals semi-portably. See https://github.com/wahern/autoguess/blob/master/Makefile.gue..., which works with GNU Make, NetBSD/FreeBSD make, OpenBSD make, and Solaris make. Alas, it doesn't work with AIX's native make.

Once POSIX standardizes "!=" then POSIX-portable conditionals will be possible using the same technique as above, replacing, e.g. OS = $(shell $(OS.exec))$(OS.exec:sh) with just OS != $(OS.exec). Though, you'd need to wait for Solaris, AIX, and macOS gmake[1] to add support for !=.

Alternatively, if you add an extra level of indirection using .DEFAULT to capture and forward make invocations, you can simply pass OS, etc, as invocation arguments. Indirection solves everything, though, so that's cheating.

[1] Apple's ancient GNU Make 3.81 predates != support. :(

bmake is the implementation of make in NetBSD and FreeBSD. OpenBSD dropped bmake a long time ago and wrote their own implementation. OpenBSD make doesn't support ONESHELL, either, though.