web-dev-qa-db-fra.com

Comment appeler manuellement une autre cible à partir d'une cible make?

J'aimerais avoir un makefile comme celui-ci:

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

C'est à dire. les *Lib tâches créent une bibliothèque qui exécute cuda directement sur le périphérique ou sur gpuocelot respectivement.

Pour les deux tâches de génération, je dois exécuter les mêmes étapes de génération, seule la création de la bibliothèque diffère.

Existe-t-il une alternative à l'exécution de make directement?

make build

Une sorte de post-requis?

34
Simon A. Eugster

Comme vous l'avez écrit, la cible build devra faire quelque chose de différent selon que vous venez de faire un build ocelot ou cuda. C'est une autre façon de dire que vous devez paramétrer build d'une manière ou d'une autre. Je suggère des cibles de build distinctes (un peu comme vous l'avez déjà fait), avec des variables associées. Quelque chose comme:

build-cuda: cudaLib
build-ocelot: ocelotLib

build-cuda build-ocelot:
    Shell commands
    which invoke ${opts-$@}

Sur la ligne de commande, vous tapez make build-cuda (dire). Faites d'abord les builds cudaLib, puis il exécute la recette de build-cuda. Il développe les macros avant d'appeler le Shell. $@ dans ce cas est build-cuda, Donc ${opts-$@} est d'abord étendu à ${opts-build-cuda}. Make continue maintenant à développer ${opts-build-cuda}. Vous aurez défini opts-build-cuda (et bien sûr sa sœur opts-build-ocelot) ailleurs dans le makefile.

P.S. Puisque build-cuda et. Al. ne sont pas de vrais fichiers, il vaut mieux dire à faire ceci (.PHONY: build-cuda).

11
bobbogo

Remarque: Cette réponse se concentre sur l'aspect d'une invocation récursive robuste d'une cible différente dans un makefile donné.

Pour compléter la réponse utile de Jack Kelly , voici un GNU extrait de makefile qui montre l'utilisation de $(MAKE) to de manière robuste invoquez une cible différente dans le même makefile (en vous assurant que le même make binaire est appelé et que le même makefile est ciblé):

# 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

Production:

$ make target

target
other-target

L'utilisation de $(lastword $(MAKEFILE_LIST)) et -f ... Garantit que la commande $(MAKE) utilise le même makefile, même si ce makefile a été transmis avec un chemin explicite (-f ...) Lorsque make a été à l'origine invoqué.


Remarque: Bien que GNU make possède des fonctionnalités pour les invocations récursives - par exemple, la variable $(MAKE) existe spécifiquement pour les activer - leur objectif est d'invoquer makefiles subordonnés , pas en appelant une cible différente dans le même makefile.

Cela dit, même si la solution de contournement ci-dessus est quelque peu lourde et obscure, elle utilise des fonctionnalités régulières et devrait être robuste .

Voici le lien vers la section du manuel traitant des invocations récursives ("sous-marques"):

65
mklement0

La plupart des versions de make définissent une variable $(MAKE) que vous pouvez utiliser pour les invocations récursives.

28
Jack Kelly