Как вызвать Makefile из другого Makefile? - PullRequest
108 голосов
/ 05 февраля 2010

Я получаю неожиданные результаты, вызывая один make-файл из другого. У меня есть два make-файла, один называется /path/to/project/makefile, а другой - /path/to/project/gtest-1.4.0/make/Makefile. Я пытаюсь заставить первого позвонить второму. В / path / to / project / makefile у меня есть

dev: $(OBJ_FILES)
  $(CPPC) $(LIBS) $(FLAGS_DEV) $(OBJ_FILES) -o $(BIN_DIR)/$(PROJECT)
  $(MAKE) -f ./gtest-1.4.0/make/Makefile

clean:
  rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o
  rm -f ../svn-commit.tmp~
  rm -f $(BIN_DIR)/$(PROJECT)
  make -f gtest-1.4.0/make/Makefile clean

А в /path/to/project/gtest-1.4.0/make/Makefile у меня

all: $(TESTS)

clean:
  rm -f $(TESTS) gtest.a gtest_main.a *.o

Выдает следующее:

cd /path/to/project
make

Выходы:

make -f ./gtest-1.4.0/make/Makefile
make[1]: Entering directory `/path/to/project'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/path/to/project'

Однако, когда я выполняю эти команды:

cd /path/to/project
make clean

Понятно:

make -f gtest-1.4.0/make/Makefile clean
make[1]: Entering directory `/path/to/project'
rm -f  gtest.a gtest_main.a *.o
make[1]: Leaving directory `/path/to/project'

Я не понимаю: в обоих случаях /path/to/project/makefile говорит мне, что входит в текущий рабочий каталог. В первом случае он не думает, что у него есть работа (когда он это делает), а во втором случае он может найти соответствующую директиву (когда вывод говорит мне, что он смотрит в неправильный каталог), но он пытается выполнить команду rm в /path/to/project вместо /path/to/makefile/gtest-1.4.0/make/.

Я упускаю что-то фундаментальное для вызова make-файлов друг от друга? Я совершил вопиющую концептуальную ошибку или попал в общую ловушку? Как эффективно изменить каталоги и вызвать второй make-файл из первого? Насколько я понимаю, достаточно просто позвонить make -f <name>.

Это make / gmake 3.81 в bash.

Ответы [ 4 ]

112 голосов
/ 02 мая 2012

Вместо -f из make вы можете использовать опцию -C <path>. Это сначала меняет путь на «<path>», а затем вызывает make там.

Пример:

clean:
  rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o
  rm -f ../svn-commit.tmp~
  rm -f $(BIN_DIR)/$(PROJECT)
  $(MAKE) -C gtest-1.4.0/make clean
97 голосов
/ 05 февраля 2010

Я не совсем понимаю, о чем вы спрашиваете, но использование параметра командной строки -f просто указывает файл - он не указывает make на изменение каталогов. Если вы хотите выполнить работу в другом каталоге, вам нужно cd в каталог:

clean:
    cd gtest-1.4.0 && $(MAKE) clean

Обратите внимание, что каждая строка в Makefile работает в отдельной оболочке, поэтому нет необходимости менять каталог обратно.

30 голосов
/ 02 августа 2013

http://www.gnu.org/software/make/manual/make.html#Recursion

 subsystem:
         cd subdir && $(MAKE)

или, что эквивалентно, это:

 subsystem:
         $(MAKE) -C subdir
1 голос
/ 05 февраля 2010

Кажется очевидным, что $(TESTS) пусто, поэтому ваш сборочный файл 1.4.0 эффективен

all: 

clean:
  rm -f  gtest.a gtest_main.a *.o

Действительно, все не имеет ничего общего. и clean делает именно то, что говорит rm -f gtest.a ...

...