Як викликати Makefile з іншого Makefile?


125

Я отримую кілька несподіваних результатів, викликаючи один makefile з іншого. У мене є два makefiles, один закликаний /path/to/project/makefileта один закликаний /path/to/project/gtest-1.4.0/make/Makefile. Я намагаюся, щоб перший називав останній. У / шлях / до / проект / 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/.

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

Це make / gmake 3.81 у баш.


3
Я думаю, замість make -f gtest-1.4.0/make/Makefile cleanтебе краще скажи $(MAKE) -C gtest-1.4.0/make clean. Чому ви не визначили хибних цілей?
dma_k

Відповіді:


112

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

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

Зауважте, що кожен рядок Makefileвиконується в окремій оболонці, тому немає необхідності змінювати каталог назад.


67
Замість того, щоб вручну cdпереходити до gtest-1.4.0dir, слід скористатися -Cопцією make.
Тадер

29
Або, принаймні, вам обов'язково слід використовувати &&між cd та make командою. В іншому випадку, якщо CD не вдасться, він все одно буде працювати make clean... в неправильному каталозі !! Крім того, завжди слід використовувати $(MAKE)ТОЛЬКО make, коли не повторюється безголове слово , при повторному повторенні. Тож на кшталт: cd gtest-1.4.0 && $(MAKE) clean
MadScientist


1
Це питання про gnu-make і -Cє у специфікації: gnu.org/software/make/manual/make.html#Recursion
Cas

123

Замість того , щоб -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

1
Цей спосіб здається найкращим. cdОтримайте інші відповіді, які використовують, що спричиняє потрапляння терміналу в нескінченний цикл.
gbmhunter

$ (Зробити) -C gtest-1.4.0 / очистити не працює для мене. Я думаю, це повинно бути $ (ЗРОБИТИ) -C gtest-1.4.0 чисто
Arigion


1

Здається, що $(TESTS)це порожньо, тому ваш файл файлів 1.4.0 ефективно

all: 

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

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


$ (TESTS) визначається з a wildcardі a patsubst, однак вони повертаються порожніми з основного makefile, оскільки каталог фактично не змінюється. Добре око.
Кріс Тонкінсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.