On 2023-01-03, Mike Frysinger <vap...@gentoo.org> wrote: > The echo|sed is used to split the dirname & filename so it can insert > $(DEPDIR) in the middle, and then chop the trailing object suffix. In > the generic case, %OBJ% is $@, so we can leverage the POSIX vars $(@D) > and $(@F) to do the pathname splitting and insert $(DEPDIR) in between. > For chopping the object suffix, we can use the $(xxx:...=...) syntax. > This avoids invoking sed completely.
I think this is a generally good idea. > These dirname/filename vars have been in POSIX since at least 2004. Except for one minor detail, $(@F) and $(@D) are highly portable. I expect they were in the very first POSIX.2 specs as they predate the earliest standards; I believe they first appeared in UNIX System V (ca. 1983) and were later added to BSD in 4.3BSD-Reno (ca. 1990). The only potential problem I am aware of with these features is one implementation (dmake) which does not follow the POSIX rule of excluding the trailing slash from the directory part, and (a bit more troublesome) will expand $(@D) to the empty string if the directory part is empty, instead of . as required by POSIX. Usually this is not a major issue, as writing something like ./$(@D)/$(@F) is usually sufficient to avoid any problems with empty $(@D). It's worth noting that $(?F), $(?D), $(%F) and $(%D) were never added to BSD and as a result are missing from many BSD derivatives. However, these variables are of limited utility and are unlikely to be missed. The $(x:a=b) suffix substitutions are of identical vintage, and as far as I know every make supporting file/directory variables also, in principle, supports suffix substitution too. However, there are many bugs in real-world implementations of this feature. Of particular relevance to this patch: older versions of NetBSD make, while they do support suffix substitution, fail to correctly parse $(@F:.o=): % cat >Makefile <<'EOF' foo/bar.o: echo $(@F:.o=) EOF % make echo bar.o.o=) Syntax error: ")" unexpected *** Error code 2 NetBSD make was widely adopted by other systems, so this particular issue may actually be found elsewhere. This bug was present as recently as NetBSD 7.2 (ca. 2018). Furthermore, old versions of FreeBSD (before they ditched their own make in favour of NetBSD's version) also fail to correctly handle $(@F:.o=), but in a different way. The good news is that these problems can be worked around pretty easily simply by using another variable: % cat >Makefile <<'EOF' at_f = $(@F) foo/bar.o: echo $(at_f:.o=) EOF % make echo bar bar But this workaround trips over a different suffix substitution bug on ULTRIX, which would otherwise work just fine with plain $(@F:.o=). Maybe ULTRIX is not worth worrying about these days, but nevertheless, it is not too hard to detect and work around both problems in pure shell, which should still work to avoid the additional forks/sed, maybe something like: % cat >Makefile <<'EOF' at_f = $(@F) foo/bar.o: a='$(@F:.o=)' b='$(at_f:.o=)'; test x"$$a.o" = x"$(@F)" || a=$$b;\ echo $$a EOF Cheers, Nick