Как вручную вызывать другую цель из целевого объекта?
Я хотел бы иметь make файл вот так:
cudaLib :
# Create shared library with nvcc
ocelotLib :
# Create shared library for gpuocelot
build-cuda : cudaLib
make build
build-ocelot : ocelotLib
make build
build :
# build and link with the shared library
т.е. задачи *Lib
создают библиотеку, которая запускает cuda непосредственно на устройстве, или на gpuocelot соответственно.
Для обеих задач сборки мне нужно выполнить одни и те же шаги сборки, только создание библиотеки отличается.
Есть ли альтернатива запуску make напрямую?
make build
Вид послереквизита?
Ответы
Ответ 1
Как вы его написали, цель build
должна будет сделать что-то другое в зависимости от того, вы только что сделали ocelot или cuda build. Это еще один способ сказать, что вам нужно каким-то образом параметризовать build
. Я предлагаю отдельные цели сборки (как и у вас уже есть), с соответствующими переменными. Что-то вроде:
build-cuda: cudaLib
build-ocelot: ocelotLib
build-cuda build-ocelot:
shell commands
which invoke ${[email protected]}
В командной строке введите make build-cuda
(скажем). Сделайте первые сборки cudaLib
, затем он выполнит рецепт для build-cuda
. Он расширяет макросы перед вызовом оболочки. [email protected]
в этом случае build-cuda
, поэтому ${[email protected]}
сначала расширяется до ${opts-build-cuda}
. Теперь сделаем расширение ${opts-build-cuda}
. Вы определите opts-build-cuda
(и, конечно, его сестра opts-build-ocelot
) в другом месте в файле makefile.
P.S. Так как build-cuda
et. и др. не являются реальными файлами, вам лучше сказать это (.PHONY: build-cuda
).
Ответ 2
Примечание. Этот ответ фокусируется на аспекте надежного рекурсивного вызова другой цели в данном файле makefile.
Чтобы дополнить полезный ответ Джека Келли, вот фрагмент файла GNU makefile, который демонстрирует использование $(MAKE)
для надежного вызова другой цели в том же make файле (что вызывается тот же самый make
двоичный код и тот же самый файл makefile):
# Determine this makefile path.
# Be sure to place this BEFORE `include` directives, if any.
THIS_FILE := $(lastword $(MAKEFILE_LIST))
target:
@echo [email protected] # print target name
@$(MAKE) -f $(THIS_FILE) other-target # invoke other target
other-target:
@echo [email protected] # print target name
Вывод:
$ make target
target
other-target
Использование $(lastword $(MAKEFILE_LIST))
и -f ...
гарантирует, что команда $(MAKE)
использует тот же make файл, даже если этот make файл был передан с явным путем (-f ...
), когда изначально был вызван make.
Примечание. В то время как в GNU make
есть функции для рекурсивных вызовов - например, переменная $(MAKE)
специально существует для их включения - их фокус заключается в вызове подчиненных make файлов, а не при вызове другой цели в том же make файле.
Тем не менее, хотя обходной путь выше несколько громоздкий и неясный, он использует регулярные функции и должен быть надежным.
Вот ссылка на раздел руководства, посвященный рекурсивным вызовам ( "подмаски" ):
Ответ 3
Большинство версий make устанавливают переменную $(MAKE)
, которую вы можете использовать для рекурсивных вызовов.