148 votes

Vérifier si un programme existe à partir d'un Makefile

Comment puis-je vérifier si un programme est appelable depuis un Makefile ?

(C'est-à-dire que le programme doit exister dans le chemin ou être appelable d'une autre manière).

Il pourrait être utilisé pour vérifier quel compilateur est installé, par exemple.

Par exemple, quelque chose comme cette question mais sans supposer que le shell sous-jacent est compatible POSIX.

10voto

Flow Points 8018

Ma solution implique une petite aide script. 1 qui place un fichier indicateur si toutes les commandes requises existent. Cela présente l'avantage que la vérification des commandes requises n'est effectuée qu'une seule fois et non pas à chaque fois que l'on utilise la fonction make l'invocation.

check_cmds.sh

#!/bin/bash

NEEDED_COMMANDS="jlex byaccj ant javac"

for cmd in ${NEEDED_COMMANDS} ; do
    if ! command -v ${cmd} &> /dev/null ; then
        echo Please install ${cmd}!
        exit 1
    fi
done

touch .cmd_ok

Makefile

.cmd_ok:
    ./check_cmds.sh

build: .cmd_ok target1 target2

1 En savoir plus sur le command -v technique peut être trouvée aquí .

10voto

Rudi Points 2888

Je définis personnellement un require cible qui s'exécute avant toutes les autres. Cette cible exécute simplement les commandes de version de toutes les exigences, une par une, et affiche les messages d'erreur appropriés si la commande est invalide.

all: require validate test etc

require:
    @echo "Checking the programs required for the build are installed..."
    @shellcheck --version >/dev/null 2>&1 || (echo "ERROR: shellcheck is required."; exit 1)
    @derplerp --version >/dev/null 2>&1 || (echo "ERROR: derplerp is required."; exit 1) 

# And the rest of your makefile below.

La sortie du script ci-dessous est

Checking the programs required for the build are installed...
ERROR: derplerp is required.
makefile:X: recipe for target 'prerequisites' failed
make: *** [prerequisites] Error 1

6voto

Vit Bernatik Points 56

Pour moi, toutes les réponses ci-dessus sont basées sur linux et ne fonctionnent pas avec Windows. Je suis nouveau dans le domaine, donc mon approche peut ne pas être idéale. Mais l'exemple complet qui fonctionne pour moi à la fois sur linux et Windows est le suivant :

# detect what shell is used
ifeq ($(findstring cmd.exe,$(SHELL)),cmd.exe)
$(info "shell Windows cmd.exe")
DEVNUL := NUL
WHICH := where
else
$(info "shell Bash")
DEVNUL := /dev/null
WHICH := which
endif

# detect platform independently if gcc is installed
ifeq ($(shell ${WHICH} gcc 2>${DEVNUL}),)
$(error "gcc is not in your system PATH")
else
$(info "gcc found")
endif

facultativement lorsque j'ai besoin de détecter d'autres outils que je peux utiliser :

EXECUTABLES = ls dd 
K := $(foreach myTestCommand,$(EXECUTABLES),\
        $(if $(shell ${WHICH} $(myTestCommand) 2>${DEVNUL} ),\
            $(myTestCommand) found,\
            $(error "No $(myTestCommand) in PATH)))
$(info ${K})

4voto

kenorb Points 2464

Vous pouvez utiliser des commandes construites en bash telles que type foo o command -v foo comme ci-dessous :

SHELL := /bin/bash
all: check

check:
        @type foo

foo est votre programme/commande. Rediriger vers > /dev/null si vous voulez qu'il soit silencieux.

3voto

lkanab Points 159

Supposons que vous ayez des cibles et des constructeurs différents, chacun nécessitant une autre série d'outils. Établissez une liste de ces outils et considérez-les comme des cibles pour forcer la vérification de leur disponibilité.

Par exemple :

make_tools := gcc md5sum gzip

$(make_tools):  
    @which $@ > /dev/null

file.txt.gz: file.txt gzip
    gzip -c file.txt > file.txt.gz

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X