appel d'un mauvais compilateur avec make

erreur lors de l'écriture de makefile

Le problème exposé dans ce sujet a été résolu.

Bonjour. Je débute dans l’écriture de makefile. Mon problème est qu’avec ce code

CC=clang++
FLAGS=-Wall -Wextra -Weffc++ -pedantic
LDFLAGS=-lvulkan -lglfw
DFLAGS=-O0 -g
RFLAGS=-O2 -DNDEBUG
EXE=vktests
SRC=main.cpp
OBJ=$(SRC:.cpp=.o)

all:build

build:$(OBJ)
    $(CC) $(OBJ) $(LDFLAGS) -o $(EXE)

$(OBJ):release

release:$(SRC)
    $(CC) $(SRC) $(FLAGS) $(RFLAGS) -c && echo release

debug:$(SRC)
    $(CC) $(SRC) $(FLAGS) $(DFLAGS) -c && echo debug

clean:
    rm $(OBJ) $(EXE)

Le résultat est

clang++ main.cpp -Wall -Wextra -Weffc++ -pedantic -O2 -DNDEBUG -c && echo release
Can't read /proc/cpuinfo: No such file or directory
Can't read /proc/cpuinfo: No such file or directory
main.cpp:34:16: warning: unused variable 'test' [-Wunused-variable]
    auto const test { matrix * vector };
               ^
1 warning generated.
release
g++    -c -o main.o main.cpp
clang++ main.o -lvulkan -lglfw -o vktests
Can't read /proc/cpuinfo: No such file or directory

Comme vous pouvez le voir, g++ est appelé alors que j’ai demandé à mon makefile d’appeler clang++! Quel est le problème de ce code?

Bon, pour les Can't read /proc/cpuinfo: No such file or directory, ça doit venir du fait que mon environnement de développement est dans un chroot.

Merci de vos réponses! :)

Ce n’est pas ce que fait la ligne $(OBJ):release ? Je peux me tromper (d’ailleurs c’est certain car ça marche pas) mais je la lis comme "Pour la génération des .o, ne fait rien. Par contre tu as besoin que la routine release soit exécutée. Qu’est ce qui ne va pas dans ce raisonnement?

$(OBJ):release

Dit seulement que l’ensemble des éléments de la variable OBJ dépend de release.

Un makefile plus correct serait

CC=clang
CXX=clang++
CXXFLAGS=-Wall -Wextra -Weffc++ -pedantic
LDFLAGS=-lvulkan -lglfw
DFLAGS=-O0 -g
RFLAGS=-O2 -DNDEBUG
EXE=vktests
SRC=main.cpp
OBJ=$(SRC:.cpp=.o)

all:$(EXE)

$(EXE):$(OBJ)
    $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

debug release: $(EXE)
debug: CXXFLAGS += $(DFLAGS)
release: CXXFLAGS += $(RFLAGS)

clean:
    rm -rf $(OBJ) $(EXE)

et attention, cela ne gère pas les dépendances vis à vis des headers (qu’il faut générer avec clang++)

edit: correction de quelques erreurs

+0 -0

Alors cette ligne indique simplement que les fichiers .o de ta variable OBJ dépendent de la règle release. C’est bien pour cela qu’on voit ta ligne avec le echo release être appelée.

Mais ça ne remplace pas la règle implicite %.o: %.cpp. Ainsi quand tu exécutes make, ta règle build est appelée qui dépend des règles présentes dans $(OBJ).
Ces règles dépendent de release, donc elle est appelée et compile les fichiers sources.

Mais surtout, chaque .o dépend toujours du .cpp associé, donc la règle implicite est ensuite appelée pour chaque fichier, c’est la ligne que tu vois apparaître avec g++.

En fait il y a deux choses:

  • make vient avec des règles déjà faites, donc tu avais déjà une règle pour compiler un .cpp en .o
  • les dépendances dans les makefiles sont additives

Du coup, quand tu fais $(OBJ): release, tu n’écrases pas la règle par défaut pour compiler un objet, tu rajoutes juste «release» en dépendance de tous tes objets.

Ensuite, avec $(EXE):$(OBJ), tu demandes à make d’utiliser tous les objets. Or ils n’existent pas, donc make va les produire, et pour les produire il va ici seulement utiliser la règle par défaut, d’où g++ qui apparait.

La règle par défaut est:

%.o: %.cpp
#  recipe to execute (built-in):
        $(COMPILE.cpp) $(OUTPUT_OPTION) $<

et COMPILE.cpp vaut

COMPILE.cpp = $(COMPILE.cc)
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+0 -0

Si ça peu te rassurer BorisD, j’utilise souvent make et je ne savais même pas qu’il possédait des règles pas défaut.

+2 -0

Salut,

Comment puis-je le faire dépendre de $(EXE) tout en modifiant CXXFLAGS comme l’a fait @unidan dans son exemple?

Voir la ligne 16 de l’exemple d’unidan. Comme il l’expliquait, les dépendances sont additives, tu peux donc les mettre sur des lignes séparées.

Maintenant, à moins que ce soit une contrainte scolaire ou professionnelle, tu as intérêt à utiliser des systèmes de compilation un peu plus abstraits que les Makefiles, comme CMake ; ou alors, si tu y tiens vraiment, tu devrais apprendre à utiliser les Makefiles correctement en te tapant la doc, sinon tu vas perdre un temps fou.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte