After some digging and experimentation, I've discovered a couple of things.
The approach recommended by this reference, which refers to the paper Recursive Make Considered Harmful, is pretty complicated, and involves manually maintaining a directory stack throughout the makefile inclusion heirarchy.
I also discovered, independently of any reference, that the last element of the variable $(MAKEFILE_LIST) will, at least for some basic test cases, contain the name of the makefile that's currently being included. This means that it's possible to store its directory in a simply expanded, target-specific variable with code like
foo: dir := $(dir $(lastword $(MAKEFILE_LIST)))
That's it. Then you can just use $(dir)
within that rule like any other variable; it retains the value that it assumed during makefile inclusion. cd
to it, put it in command paths, whatever.
You have to be careful to put the assignment to dir
before any include directives in that makefile.
This won't work if there's a space in the directory name, but I gather that pretty much nothing in make
works if there are spaces in file or directory names.
It's also notable that this approach uses features only found in GNU make. Sounds like a killer app to me, though I remain a bit perplexed as to why they don't just provide the directory name in a builtin variable or function.
Anyway this seems to work, at least at first glance. I'm still pretty much just floating this one without any real backup, so comments on the practicality of this approach, and alternative suggestions, are very welcome.