¿Cómo llamar manualmente a otro objetivo desde un objetivo make?


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 la creación de la biblioteca difiere.

¿Hay una alternativa a ejecutar make directamente?

make build

¿Una especie de post-requisito?

 21
Author: Simon A. Eugster, 2011-03-21

3 answers

Como lo has escrito, el destino build tendrá que hacer algo diferente dependiendo de si acabas de hacer una compilación ocelot o cuda. Esa es otra forma de decir que tienes que parametrizar 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 se escribe make build-cuda (por ejemplo). 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 tanto ${opts-$@} se expandió primero a ${opts-build-cuda}. Make ahora pasa a expandir ${opts-build-cuda}. Habrá definido opts-build-cuda (y por supuesto su hermana opts-build-ocelot) en otra parte del makefile.

P.d. Desde build-cuda et. al. no son archivos reales, es mejor que diga hacer esto (.PHONY: build-cuda).

 11
Author: bobbogo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-21 19:28:05

Nota: Esta respuesta se centra en el aspecto de una invocación recursiva robusta de un destino diferente en un makefile dado.

Para complementar la útil respuesta de Jack Kelly , aquí hay un fragmento de makefile de GNU que demuestra el uso de $(MAKE) para invocar un destino diferente en el mismo makefile (asegurando que se llame al mismo binario make y que se apunte al mismo makefile):

# 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

Usando $(lastword $(MAKEFILE_LIST)) y -f ... asegura que el comando $(MAKE) use el mismo makefile, incluso si ese makefile fue pasado con una ruta explícita (-f ...) cuando se invocó originalmente make.


Nota: Aunque GNU make tiene características para las invocaciones recursivas - por ejemplo, la variable $(MAKE)existe específicamente para habilitarlas - su enfoque está en invocar makefiles subordinados, no en llamar a un destino diferente en el mismo makefile.

Dicho esto, a pesar de que la solución anterior es algo engorroso y oscuro, utiliza características regulares y debería ser robusto.

Aquí está el enlace a la sección del manual que cubre invocaciones recursivas ("sub-marcas"):

 36
Author: mklement0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:35

La mayoría de las versiones de make establecen una variable $(MAKE) que se puede usar para invocaciones recursivas.

 18
Author: Jack Kelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-21 18:52:09