109 votes

Si les conditions dans un Makefile, à l'intérieur d'une cible

J'essaie de configurer un Makefile qui va chercher et copier certains fichiers (condition if-else) et je n'arrive pas à trouver ce qui ne va pas exactement ? (mais je suis presque sûr que c'est à cause d'une combinaison d'espaces/tabulations écrits au mauvais endroit). Puis-je obtenir de l'aide à ce sujet, s'il vous plaît ?

Voici ce que j'ai actuellement :

obj-m = linuxmon.o

KDIR = /lib/modules/$(shell uname -r)/build
UNAME := $(shell uname -m)

all:

    $(info Checking if custom header is needed)
    ifeq ($(UNAME), x86_64)
        $(info Yes)
        F1_EXISTS=$(shell [ -e /usr/include/asm/unistd_32.h ] && echo 1 || echo 0 )
        ifeq ($(F1_EXISTS), 1)
            $(info Copying custom header)
            $(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm/unistd_32.h > unistd_32.h)
        else    
            F2_EXISTS=$(shell [[ -e /usr/include/asm-i386/unistd.h ]] && echo 1 || echo 0 )
            ifeq ($(F2_EXISTS), 1)
                $(info Copying custom header)
                $(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm-i386/unistd.h > unistd_32.h)
            else
                $(error asm/unistd_32.h and asm-386/unistd.h does not exist)
            endif
        endif
        $(info No)
    endif

    @make -C $(KDIR) M=$(PWD) modules

clean:
    make -C $(KDIR) M=$(PWD) clean
    rm unistd_32.h

Quoi qu'il en soit, ça imprimera "Oui", "Copying header" deux fois et ensuite ça s'arrêtera en disant que sed ne peut pas lire /usr/include/asm-i386/unistd.h (qu'il ne peut évidemment pas lire car je suis sur un système x64). Je pourrais dire que make ne comprend pas les if/else et préfère tout exécuter ligne par ligne.

210voto

Omer Dagan Points 889

Vous pouvez simplement utiliser les commandes du shell. Si vous voulez supprimer l'écho de la sortie, utilisez le signe "@". Par exemple :

clean:
    @if [ "test" = "test" ]; then\
        echo "Hello world";\
    fi

Notez que la fermeture ; y \ à chaque ligne sont nécessaires

(C'est parce que make interpréter chaque ligne comme une commande distincte sauf si il se termine par \ )

98voto

Beta Points 37745

Il y a plusieurs problèmes ici, donc je vais commencer par mes conseils habituels de haut niveau : Commencez petit et simple, ajoutez de la complexité petit à petit, testez à chaque étape et n'ajoutez jamais au code qui ne fonctionne pas. (Je devrais vraiment avoir ce raccourci clavier.)

Vous mélangez la syntaxe Make et la syntaxe shell d'une manière qui est tout simplement vertigineuse. Vous ne devriez jamais le laisser devenir aussi gros sans le tester. Commençons par l'extérieur et travaillons vers l'intérieur.

UNAME := $(shell uname -m)

all:
    $(info Checking if custom header is needed)
    ifeq ($(UNAME), x86_64)
    ... do some things to build unistd_32.h
    endif

    @make -C $(KDIR) M=$(PWD) modules

Donc, vous voulez que unistd_32.h soit construit (peut-être) avant d'invoquer la deuxième commande make vous pouvez en faire une condition préalable. Et puisque vous ne le voulez que dans un certain cas, vous pouvez le mettre dans une condition :

ifeq ($(UNAME), x86_64)
all: unistd_32.h
endif

all:
    @make -C $(KDIR) M=$(PWD) modules

unistd_32.h:
    ... do some things to build unistd_32.h

Maintenant, pour la construction unistd_32.h :

F1_EXISTS=$(shell [ -e /usr/include/asm/unistd_32.h ] && echo 1 || echo 0 )
ifeq ($(F1_EXISTS), 1)
    $(info Copying custom header)
    $(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm/unistd_32.h > unistd_32.h)
else    
    F2_EXISTS=$(shell [[ -e /usr/include/asm-i386/unistd.h ]] && echo 1 || echo 0 )
    ifeq ($(F2_EXISTS), 1)
        $(info Copying custom header)
        $(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm-i386/unistd.h > unistd_32.h)
    else
        $(error asm/unistd_32.h and asm-386/unistd.h does not exist)
    endif
endif

Vous essayez de construire unistd.h de unistd_32.h le seul truc est que unistd_32.h pourrait être dans l'un des deux endroits suivants. La façon la plus simple de régler ce problème est d'utiliser un fichier vpath directive :

vpath unistd.h /usr/include/asm /usr/include/asm-i386

unistd_32.h: unistd.h
    sed -e 's/__NR_/__NR32_/g' $< > $@

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