Пример для иллюстрации моего вопроса:
Makefile верхнего уровня
rootdir = $(realpath .)
export includedir = $(rootdir)/include
default:
@$(MAKE) --directory=$(rootdir)/src/libs/libfoo
Makefile для src / libfoo
currentdir = $(realpath .)
includedir = $(function or magic to make a relative path
from $(currentdir) to $(includedir),
which in this example would be ../../../include)
Другой пример:
current dir = /home/username/projects/app/trunk/src/libs/libfoo/
destination = /home/username/projects/app/build/libfoo/
relative = ../../../../build/libfoo
Как это можно сделать, стараясь быть максимально портативным?
Делать то, что вы хотите, выглядит непросто. Возможно, можно использовать много комбинированных $ (если
в make-файле, но не переносимый (только gmake) и громоздкий.
ИМХО, вы пытаетесь решить проблему, которую создаете сами. Почему не Если вы отправляете правильное значение includedir
в качестве относительного пути из Makefile верхнего уровня? Это можно сделать очень просто следующим образом:
rootdir = $(realpath .)
default:
@$(MAKE) --directory=$(rootdir)/src/libs/libfoo includedir=../../../include
Затем вы можете использовать $ (includedir)
во вложенных make-файлах. Он уже определен как относительный.
Python переносим! Итак, я предлагаю вам этот простой пример в вашем файле submakefile
с current_dir
и destination_dir
paths os.path.relpath ()
делает работу за вас. так что вам не придется заново изобретать колесо.
submakefile.mk
current_dir=$(CURDIR)
makefile_target:
(echo "import os"; echo "print os.path.relpath('$(destination_dir)', '$(current_dir)')" )| python
Ответ Дидье - лучший, но следующие могут дать вам некоторые идеи:
includedir=/a/b/c/d
currentdir=/a/b/e/f/g
up=; while ! expr $includedir : $currentdir >/dev/null; do up=../$up; currentdir=`dirname $currentdir`; done; relative=$up`expr $includedir : $currentdir'/*\(.*\)'`
echo "up=$up currentdir=$currentdir, relative=$relative"
Разобрались!
(никто не говорил, что это должно быть красиво...)