gnu make - sobre - ¿Cómo llamar manualmente a otro objetivo desde un objetivo de marca?
objetivos de una empresa de medios (3)
La mayoría de las versiones de make establecen una variable $(MAKE)
que puede usar para invocaciones recursivas.
Me gustaría tener un makefile como este:
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
Es decir, las tareas *Lib
crean una biblioteca que ejecuta cuda directamente en el dispositivo, o en gpuocelot respectivamente.
Para ambas tareas de compilación necesito ejecutar los mismos pasos de compilación, solo crear la biblioteca difiere.
¿Hay una alternativa para ejecutar make directamente?
make build
¿Una especie de post-requisito?
Tal como lo ha escrito, el objetivo de build
tendrá que hacer algo diferente dependiendo de si acaba de hacer una compilación de ocelote o cuda. Esa es otra manera de decir que tienes que parametrizar la build
de alguna manera. Sugiero objetivos de compilación separados (como los que ya tienes), con variables asociadas. Algo como:
build-cuda: cudaLib
build-ocelot: ocelotLib
build-cuda build-ocelot:
shell commands
which invoke ${opts-$@}
En la línea de comandos, escriba make build-cuda
(say). Hacer primero construye cudaLib
, luego lleva a cabo la receta para build-cuda
. Expande las macros antes de llamar al shell. $@
en este caso es build-cuda
, por lo que ${opts-$@}
primero se expande a ${opts-build-cuda}
. Make ahora va a expandir ${opts-build-cuda}
. Habrá definido opts-build-cuda
(y, por supuesto, su hermana opts-build-ocelot
) en otro lugar del archivo make.
PD Desde build-cuda
et. Alabama. No son archivos reales, es mejor que digas que haga esto ( .PHONY: build-cuda
).
Nota: Esta respuesta se enfoca en el aspecto de una invocación recursiva robusta de un objetivo diferente en un archivo make determinado.
Para complementar la útil respuesta de Jack Kelly , aquí hay un fragmento de archivo makefile de GNU que demuestra el uso de $(MAKE)
para invocar de manera sólida un objetivo diferente en el mismo archivo make (asegurándose de que se llame al mismo archivo binario, y de que el archivo make sea el mismo):
# Determine this makefile''s path.
# Be sure to place this BEFORE `include` directives, if any.
THIS_FILE := $(lastword $(MAKEFILE_LIST))
target:
@echo $@ # print target name
@$(MAKE) -f $(THIS_FILE) other-target # invoke other target
other-target:
@echo $@ # print target name
Salida:
$ make target
target
other-target
El uso de $(lastword $(MAKEFILE_LIST))
y -f ...
garantiza que el comando $(MAKE)
use el mismo archivo MAKE, incluso si ese archivo MAKE se pasó con una ruta explícita ( -f ...
) cuando se invocó originalmente. .
Nota: mientras que GNU make
tiene características para invocaciones recursivas, por ejemplo, la variable $(MAKE)
existe específicamente para habilitarlas, su foco está en invocar makefiles subordinados , no en llamar a un objetivo diferente en el mismo makefile.
Dicho esto, a pesar de que la solución anterior es algo incómoda y oscura, usa características regulares y debe ser robusta .
Aquí está el enlace a la sección del manual que cubre invocaciones recursivas ("sub-marcas"):