Подтвердить что ты не робот

Как вручную вызывать другую цель из целевого объекта?

Я хотел бы иметь 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

Вид послереквизита?

4b9b3361

Ответ 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), которую вы можете использовать для рекурсивных вызовов.