3

I am in the App folder of my project. I run the following command to compile character.cpp

g++ -Wall -std=c++11 -I../App -c Character/character.cpp -o Obj/character.o

which is in App/Character directory. character.cpp has the following include

#include "Inventory/inventory.hpp"

where the folder of inventory.cpp is App/Inventory.

I thought because I am running the g++ command from App, the default include path would start from App and therefore I wouldn't need to have the -I../App part of the command. To me this seems to be saying "move one level higher than App then move into App and include from there" which seems redundant but without that line it doesn't work.

Can anyone explain why?

EDIT

Looking at it again and some more documentation, I believe that if no -I path is specified, g++ will look in its default directories and then all other includes (like the one I have causing problems) are relative to the file that includes them. So I have to add the -I part to say "look in the App directory too" and since it doesn't like just -I, I have to use ../App because that is equivalent to not moving at all. Can anyone confirm if this is at all accurate?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Kvothe
  • 1,819
  • 2
  • 23
  • 37

1 Answers1

3

You can use -I. for searching headers from the current directory, instead of -I../App.

This include preprocessor directive

 #include "Inventory/inventory.hpp"

forces gcc (g++ or cpp) to search the header not from the current path (App/), but from directory of your source file (App/Character):

/root/App# strace -f g++ -c -H ./Character/character.cpp 2>&1 |grep Inven
[pid 31316] read(3, "#include \"Inventory/inventory.hp"..., 35) = 35
[pid 31316] stat64("./Character/Inventory/inventory.hpp.gch", 0xbfffe6a4) = -1 ENOENT (No such file or directory)
[pid 31316] open("./Character/Inventory/inventory.hpp", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory)
..then try system directories

This is documented here: https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html

GCC looks for headers requested with #include "file" first in the directory containing the current file

This behavior can be not fixed in the Language standard (ISO C), and is implementation-defined (as commented by Richard Corden and answered by piCookie in What is the difference between #include <filename> and #include "filename"?):

specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner.

But this is the way the C compiler should work under Unix, according to Posix, aka The Open Group Base Specifications Issue 7:

Thus, headers whose names are enclosed in double-quotes ( "" ) shall be searched for first in the directory of the file with the #include line, then in directories named in -I options, and last in the usual places. For headers whose names are enclosed in angle brackets ( "<>" ), the header shall be searched for only in directories named in -I options and then in the usual places. Directories named in -I options shall be searched in the order specified.

It is useful when your current directory is far from the source directory (this is the recommended way in autotools/autoconf: do mkdir build_dir5;cd build_dir5; /path/to/original/source_dir/configure --options; then make - this will not change source dir and will not generate lot of file in it; you can do several build with single copy of source).

When you start g++ from the App directory with -I. (or with -I../App or -I/full_path/to/App), gcc (g++) will find the Inventory. I added warning to the header to see when it will be included; and -H option of gcc/g++ prints all included headers with pathes:

/root/App# cat Inventory/inventory.hpp
#warning "Inventory/inventory.h included"
/root/App# cat Character/character.cpp
#include "Inventory/inventory.hpp"
/root/App# g++ -I. ./Character/character.cpp  -H -c
. ./Inventory/inventory.hpp
In file included from ./Character/character.cpp:1:
./Inventory/inventory.hpp:1:2: warning: #warning "Inventory/inventory.h included"
Community
  • 1
  • 1
osgx
  • 90,338
  • 53
  • 357
  • 513