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 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):or the include directive:
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
These lines in your makefile,
and this line in your .cpp file,
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:
With this your
#include
directive would remain as#include "StdCUtil/split.h"
.Yet another option is to place your makefile in the parent directory:
With this layout it is common to put the object files (and possibly the executable) in a subdirectory that is parallel to your
Core
andStdCUtil
directories.Object
, for example. With this, your makefile becomes:This is not a question about make, it is a question about the semantic of the
#include
directive.The problem is, that there is no file at the path "../StdCUtil/StdCUtil/split.h". This is the path that results when the compiler combines the include path "../StdCUtil" with the relative path from the
#include
directive "StdCUtil/split.h".To fix this, just use
-I..
instead of-I../StdCUtil
.Try
INC_DIR=../ ../StdCUtil
.Then, set
CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))
EDIT: Also, modify your
#include
to be#include <StdCUtil/split.h>
so that the compiler knows to use -I rather than local path of the .cpp using the#include
.