web-dev-qa-db-fra.com

Si les conditions dans un Makefile, dans une cible

J'essaye d'installer un Makefile qui recherchera et copiera certains fichiers (si-sinon) et je ne peux pas comprendre ce qui ne va pas avec? (mais je suis presque sûr que c'est à cause d'une combinaison d'espaces/onglets écrits au mauvais endroit). Puis-je obtenir de l'aide pour cela, 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, cela affichera "Oui", "Copier l'en-tête" deux fois, puis cessera de dire que sed ne peut pas lire /usr/include/asm-i386/unistd.h (qui, bien sûr, ne peut pas être lu car je suis sur un système x64). Je pourrais dire que make ne comprend tout simplement pas le if/else, mais exécute tout ce qui se trouve ligne par ligne.

38
alexandernst

Il y a plusieurs problèmes ici, je vais donc commencer par mon conseil de haut niveau habituel: Commencez petit et simple, ajoutez de la complexité petit à petit, testez à chaque étape et n’ajoutez jamais de 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 vertigineuse. Vous n'auriez jamais dû le laisser devenir aussi gros sans avoir à faire des tests. Partons de l'extérieur et travaillons à 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 construire unistd_32.h (peut-être) avant d'appeler le second make, vous pouvez en faire un préalable. Et puisque vous ne voulez cela 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 construire 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 à deux endroits. Le moyen le plus simple de nettoyer cela consiste à utiliser une directive vpath:

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

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

Vous pouvez simplement utiliser les commandes Shell. Si vous souhaitez supprimer l’écho de la sortie, utilisez le signe "@". Par exemple:

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

Notez que la fermeture ";" et "\" sont nécessaires.

62
Omer Dagan