I have the following makefile:
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
This makefile and all three source files Lock.cpp
, DBC.cpp
, Trace.cpp
are located in the current directory called Core
. One of the source file Trace.cpp
contains a line that includes a header file outside the current directory:
//in Trace.cpp #include "StdCUtil/split.h"
The header file split.h
is located at one level above the current directory and then in the subdirectory called StdCUtil
. So that's why I added INC_DIR = ../StdCUtil
in the makefile. The overall directory structure looks like the following:
root |___Core | | | |____Makefile | |____DBC.cpp | |____Lock.cpp | |____Trace.cpp | |___StdCUtil |___split.h
But when I make it, it gives me the error:
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
Why this doesn't find the header file split.h
even if I specify the INC_DIR
in the makefile? How to correct this?
The only way to include the header file is to treat the filename in the same way you treat a string. Makefiles are a UNIX thing, not a programming language thing Makefiles contain UNIX commands and will run them in a specified sequence.
Which of the following is the correct syntax of including a user defined header files in C++? Explanation: C++ uses double quotes to include a user-defined header file. The correct syntax of including user-defined is #include “userdefinedname”.
Header files should #include the minimum header files necessary, and source files should also, though it's not as important for source files. The source file will have the headers it #include s, and the headers they #include , and so on up to the maximum nesting depth.
Yes, this will work. Note, however, that if you include a lot of headers in this file and don't need all of them in each of your source files, it will likely increase your compilation time.
These lines in your makefile,
INC_DIR = ../StdCUtil CFLAGS=-c -Wall -I$(INC_DIR) DEPS = split.h
and this line in your .cpp file,
#include "StdCUtil/split.h"
are in conflict.
With your makefile in your source directory and with that -I
option you should be using #include "split.h"
in your source file, and your dependency should be ../StdCUtil/split.h
.
Another option:
INC_DIR = ../StdCUtil CFLAGS=-c -Wall -I$(INC_DIR)/.. # Ugly! DEPS = $(INC_DIR)/split.h
With this your #include
directive would remain as #include "StdCUtil/split.h"
.
Yet another option is to place your makefile in the parent directory:
root |____Makefile | |___Core | |____DBC.cpp | |____Lock.cpp | |____Trace.cpp | |___StdCUtil |___split.h
With this layout it is common to put the object files (and possibly the executable) in a subdirectory that is parallel to your Core
and StdCUtil
directories. Object
, for example. With this, your makefile becomes:
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)
The preprocessor is looking for StdCUtil/split.h
in
./
(i.e. /root/Core/
, the directory that contains the #include statement). So ./
+ StdCUtil/split.h
= ./StdCUtil/split.h
and the file is missingand in
$INC_DIR
(i.e. ../StdCUtil/
= /root/Core/../StdCUtil/
= /root/StdCUtil/
). So ../StdCUtil/
+ StdCUtil/split.h
= ../StdCUtil/StdCUtil/split.h
and the file is missingYou can fix the error changing the $INC_DIR
variable (best solution):
$INC_DIR = ../
or the include directive:
#include "split.h"
but in this way you lost the "path syntax" that makes it very clear what namespace or module the header file belongs to.
Reference:
EDIT/UPDATE
It should also be
CXX = g++ CXXFLAGS = -c -Wall -I$(INC_DIR) ... %.o: %.cpp $(DEPS) $(CXX) -o $@ $< $(CXXFLAGS)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With