An example to illustrate my question:
Top level makefile
rootdir = $(realpath .)
export includedir = $(rootdir)/include
default:
@$(MAKE) --directory=$(rootdir)/src/libs/libfoo
Makefile for src/libfoo
currentdir = $(realpath .)
includedir = $(function or magic to make a relative path
from $(currentdir) to $(includedir),
which in this example would be ../../../include)
Another example:
current dir = /home/username/projects/app/trunk/src/libs/libfoo/
destination = /home/username/projects/app/build/libfoo/
relative = ../../../../build/libfoo
How can this be done, while trying to be as portable as possible?
Doing what you want does not look easy. It may be possible using a lot of combined $(if
in the makefile but not portable (gmake only) and cumbersome.
IMHO, you are trying to solve a problem that you create yourself. Why don't you send the correct value of includedir
as a relative path from the Top-level Makefile? It can be done very easily as follows:
rootdir = $(realpath .)
default:
@$(MAKE) --directory=$(rootdir)/src/libs/libfoo includedir=../../../include
Then you can use $(includedir)
in the sub-makefiles. It is already defined as relative.
This meta-answer is the best one -- avoid the problem! Note also that
--directory
isn't portable:cd $(rootdir)/src/libs/libfoo; $(MAKE) ...
would be more reliable.I don't think I'd go as far as wrong, but not all
make
commands support it (and it's not in posix, for example), so if this makefile is for distribution, then it might create problems. In any case, I tend to think thatcd foo; $(MAKE)...
expresses the intention more clearly.