On 04 Jan 2023 21:10, Nick Bowler wrote: > 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).
thanks ... i vaguely recall seeing a thread somewhere in the last year or two talking about portable $(@D)/$(@F) issues somewhere which is how i learned about these in the first place, but i can't seem to locate it, and the syntax is not conducive to Google searches. you don't happen to know what i'm remembering ? or have a link to some docs about how portable these vars are ? i thought it'd be useful to include them in our docs and/or manual somewhere. i can build & install dmake easily since someone is maintaining it in GH: https://github.com/jimjag/dmake i'll throw some bugs at them :) > 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. that'll be good to note in our docs too > 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 this is interesting. we actually have some uses of this already in the tree. no one seems to have complained though afaict. automake-1.13+ has: lib/am/subdirs.am:AM_RECURSIVE_TARGETS += $(am__recursive_targets:-recursive=) automake-1.9+ has: lib/am/texibuild.am: for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ dmake is one implementation that fails, and your suggestion doesn't work :/. $ dmake foo/bar.o dmake: Error: -- Incomplete macro expression [)' b='$(at_f:.o=)'; test x"$$a.o" = x"$(@F)" || a=$$b;\ echo $$a] how portable is $() ? that seems to work in GNU make & dmake. $ cat Makefile DEPDIR = ./$(@D)/depdir/$(@F:.o=$()) foo/bar.o: @echo $(DEPDIR) $ dmake ./foo//depdir/bar -mike
signature.asc
Description: PGP signature