[CCing Warren due to my usual GMail->TUHS interference problems]

...that's how my Hungarian phrasebook tells me to word it.

Since this issue burns me every time I do a groff release (formerly as
deputy maintainer, now as a full bird), I wish to risk offending BSD
partisans by griping about their make.

Apparently BSD make tracks file identity in its dependency graph by
using...strings.

That's it.  Just strings.

So "foo" != "./foo" != "./././foo" and so on.  To BSD make, these are
different things, even though by design they must be file specifications
("pathnames") _on the file system_, and on every Unix, they _are the
same_.

So you get spurious build failures when, say, macro contents naming a
target disagree with target names in rules in ways that don't make sense
when you know what's going on (outside of make implementation details).

Let me offer some simplified examples.

FOO = ./foo

$(FOO): bar
        frob < bar > $(FOO)

If the "./" prefix seems like a silly thing to do, consider that it may
itself be the result of macro expansion.

FOO = $(BAZ)/foo

all: $(FOO)

$(FOO): bar
        frob < bar > $(FOO)

$ make BAZ=/look/over/there

(Yes, a real Makefile for BSD make would probably not be written this
way.[1])

This design is a landmine with a tripwire in front of it because in the
shell command "recipes" of a makefile rule, you once again get the
semantics you expect as a Unix file system user, because the _shell_
resolves whatever $(FOO) expands to.  So it is not fooled by "./" or
"./././." or any other variation on that theme.

I find this design choice even more confusing because Unix has had hard
links since day one, or just about.  The _name_ of a file as a string or
even a directory entry is not its uniquely identifying characteristic
(ignoring content).

Why does the BSD make dependency graph not track the device and inode
pair instead?

And won't this string-based approach fail to detect file identity in the
case of symbolic links as well?  Didn't BSD _invent_ symbolic links?

Can someone make this make sense?

Regards,
Branden

[1] You'd need "BAZ ?= ." to keep "foo" from being sought in the root
    directory if the macro wasn't defined on make's command line.  Or
    via inclusion, depending on the implementation.

    But "?=" is new to POSIX 2024 so I suppose that for a long time, one
    couldn't rely on its availability.

Attachment: signature.asc
Description: PGP signature

Reply via email to