相对于 g++ 的 -I(大写 i)路径在哪里?

Where is the -I (captial i) path relative to in g++?

我在我项目的 App 文件夹中。我运行下面的命令编译character.cpp

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

位于 App/Character 目录中。 character.cpp 包含以下内容

#include "Inventory/inventory.hpp"

其中 inventory.cpp 的文件夹是 App/Inventory.

我认为因为我正在 运行 从 App 执行 g++ 命令,默认包含路径将从 App 开始,因此我不需要有命令的 -I../App 部分。对我来说,这似乎是在说 "move one level higher than App then move into App and include from there" 这似乎是多余的,但没有那条线它就不起作用。

谁能解释为什么?

编辑

再次查看它和更多文档,我相信如果没有指定 -I 路径,g++ 将在其默认目录中查找,然后所有其他包含(比如我导致问题的那个)都是相对于包含它们的文件。所以我必须添加 -I 部分来表示 "look in the App directory too" 并且因为它不喜欢只是 -I,我必须使用 ../App 因为那相当于根本不动.谁能确认这是否准确?

您可以使用 -I. 从当前目录搜索 header,而不是 -I../App

这包括预处理器指令

 #include "Inventory/inventory.hpp"

强制 gcc(g++ 或 cpp)搜索 header 不是从当前路径(App/),而是从源文件的目录(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

此处记录: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

此行为无法在语言标准 (ISO C) 中修复,并且是 implementation-defined(如 Richard Corden 评论和 piCookie 在 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.

但根据 Posix, aka The Open Group Base Specifications Issue 7,这是 C 编译器在 Unix 下的工作方式:

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.

当你的当前目录远离源目录时很有用(这是 autotools/autoconf 中推荐的方法:做 mkdir build_dir5;cd build_dir5; /path/to/original/source_dir/configure --options; then make - 这不会改变源目录,也不会产生很多文件;您可以使用单个源副本进行多次构建)。

当您使用 -I.(或 -I../App-I/full_path/to/App)从 App 目录启动 g++ 时,gcc (g++) 将找到 Inventory。我在 header 中添加了警告,以查看何时包含它;和 gcc/g++ 的 -H 选项打印所有包含的 headers 路径:

/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"