Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile: How to correctly include header file and its directory?

Tags:

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?

like image 865
tonga Avatar asked Mar 20 '14 21:03

tonga


People also ask

How do I add a header file in makefile?

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 is the correct syntax to include header file?

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”.

Where should I include header files?

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.

Can you include header files in header files?

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.


2 Answers

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) 
like image 129
David Hammen Avatar answered Oct 21 '22 12:10

David Hammen


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 missing

and in

  • $INC_DIR (i.e. ../StdCUtil/ = /root/Core/../StdCUtil/ = /root/StdCUtil/). So ../StdCUtil/ + StdCUtil/split.h = ../StdCUtil/StdCUtil/split.h and the file is missing

You 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:

  • C++ #include semantics

EDIT/UPDATE

It should also be

CXX = g++ CXXFLAGS = -c -Wall -I$(INC_DIR)  ...  %.o: %.cpp $(DEPS)     $(CXX) -o $@ $< $(CXXFLAGS) 
like image 21
manlio Avatar answered Oct 21 '22 14:10

manlio