Hi,
On 03/10/2021 21:50, David Boyce wrote:
For instance in the test case below the target depends on
its parent directory $(@D) which comes out as "foo". We've supplied a rule
for making it but due to the behavior of the $(dir ...) function that comes
out as "foo/" which doesn't match.
$ cat Makefile
.SECONDEXPANSION:
target := foo/bar
$(target): $$(@D)
touch $@
$(dir $(target)):
mkdir -p $@
In any use case that boils down to this, why would you not put the mkdir
in with the touch?
More generally, I don't really see how a directory is useful as a
target. Suppose you have:
foo.dir: bar.file
mkdir -p $@
In the first case, it builds the directory. But thereafter, the
directory's timestamp doesn't really mean anything (as you alluded to on
order-only prerequisites). Whether bar.file changes or not, the mkdir
is redundant.
If the recipe also builds the directory contents, it must build all of
it, as any other recipe that builds part of it will set foo.dir's stamp,
masking the need to build the rest. If you make the rest explicitly
depend on bar.file to avoid this, you don't need foo.dir as a target,
because the other recipes can just mkdir it as necessary. If the recipe
builds all of the contents, you can make the last file updated be the
target instead of the directory.
If you're building a large directory structure for zipping up, and some
empty directories are required, there should be a target (perhaps empty)
for the directory structure as a whole, and the mkdirs can go there. Or
you could create dummy files that are excluded from the zip. Or put the
mkdirs in with the zip.
Perhaps there's a better use case…?
Cheers,
Steven