web-dev-qa-db-fra.com

Makefile: Comment inclure correctement le fichier d'en-tête et son répertoire?

J'ai le makefile suivant:

CC=g++
INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h

all: Lock.o DBC.o Trace.o

%.o: %.cpp $(DEPS)
    $(CC) -o $@ $< $(CFLAGS)

clean:
    rm -rf *o all

Ce makefile et les trois fichiers source Lock.cpp, DBC.cpp, Trace.cpp se trouvent dans le répertoire courant appelé Core. L'un des fichiers source Trace.cpp contient une ligne qui inclut un fichier d'en-tête en dehors du répertoire courant:

//in Trace.cpp
#include "StdCUtil/split.h"

Le fichier d'en-tête split.h est situé à un niveau au-dessus du répertoire courant, puis dans le sous-répertoire appelé StdCUtil. Voilà pourquoi j'ai ajouté INC_DIR = ../StdCUtil dans le makefile. La structure globale du répertoire ressemble à ceci:

root
  |___Core
  |     |
  |     |____Makefile
  |     |____DBC.cpp
  |     |____Lock.cpp
  |     |____Trace.cpp
  |
  |___StdCUtil
        |___split.h

Mais quand je le fais, ça me donne l'erreur:

Trace.cpp:8:28: fatal error: StdCUtil/split.h: No such file or directory
 #include "StdCUtil/split.h"
                            ^
compilation terminated.
<builtin>: recipe for target 'Trace.o' failed

Pourquoi cela ne trouve pas le fichier d'en-tête split.h même si je spécifie le INC_DIR dans le makefile? Comment corriger ça?

19
tonga

Ces lignes dans votre makefile,

INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h

et cette ligne dans votre fichier .cpp,

#include "StdCUtil/split.h"

sont en conflit.

Avec votre makefile dans votre répertoire source et avec ce -I option que vous devriez utiliser #include "split.h" in your source file, and your dependency should be ../StdCUtil/split.h`.

Une autre option:

INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)/..  # Ugly!
DEPS = $(INC_DIR)/split.h

Avec cela, votre #include la directive resterait comme #include "StdCUtil/split.h".

Encore une autre option consiste à placer votre makefile dans le répertoire parent:

root
  |____Makefile
  |
  |___Core
  |     |____DBC.cpp
  |     |____Lock.cpp
  |     |____Trace.cpp
  |
  |___StdCUtil
        |___split.h

Avec cette disposition, il est courant de placer les fichiers objets (et éventuellement l'exécutable) dans un sous-répertoire parallèle à vos répertoires Core et StdCUtil. Object, par exemple. Avec cela, votre makefile devient:

INC_DIR = StdCUtil
SRC_DIR = Core
OBJ_DIR = Object
CFLAGS  = -c -Wall -I.
SRCS = $(SRC_DIR)/Lock.cpp $(SRC_DIR)/DBC.cpp $(SRC_DIR)/Trace.cpp
OBJS = $(OBJ_DIR)/Lock.o $(OBJ_DIR)/DBC.o $(OBJ_DIR)/Trace.o
# Note: The above will soon get unwieldy.
# The wildcard and patsubt commands will come to your rescue.

DEPS = $(INC_DIR)/split.h
# Note: The above will soon get unwieldy.
# You will soon want to use an automatic dependency generator.


all: $(OBJS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
  $(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR)/Trace.o: $(DEPS)
26
David Hammen

Le préprocesseur recherche StdCUtil/split.h dans

et en

  • $INC_DIR (c'est à dire. ../StdCUtil/ = /root/Core/../StdCUtil/ = /root/StdCUtil/). Alors ../StdCUtil/ + StdCUtil/split.h = ../StdCUtil/StdCUtil/split.h et le fichier est manquant

Vous pouvez corriger l'erreur en modifiant le $INC_DIR variable (meilleure solution):

$INC_DIR = ../

ou la directive include:

#include "split.h"

mais de cette façon, vous avez perdu la "syntaxe du chemin" qui rend très clair à quel espace de noms ou module appartient le fichier d'en-tête.

Référence:

MODIFIER/METTRE À JOUR

Il faut également

CXX = g++
CXXFLAGS = -c -Wall -I$(INC_DIR)

...

%.o: %.cpp $(DEPS)
    $(CXX) -o $@ $< $(CXXFLAGS)
4
manlio

Ce n'est pas une question de make, c'est une question de sémantique du #include directive.

Le problème est qu'il n'y a pas de fichier sur le chemin "../StdCUtil/StdCUtil/split.h". Il s'agit du chemin qui résulte lorsque le compilateur combine le chemin d'inclusion "../StdCUtil" avec le chemin relatif de #include directive "StdCUtil/split.h".

Pour résoudre ce problème, utilisez simplement -I.. au lieu de -I../StdCUtil.

0
cmaster

Essayez INC_DIR=../ ../StdCUtil.

Ensuite, définissez CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))

EDIT: modifiez également votre #include Pour qu'il soit #include <StdCUtil/split.h> Afin que le compilateur sache utiliser -I plutôt que le chemin local du .cpp en utilisant le #include.

0
Bill Perkins