如何告诉 g++ 编译器在哪里搜索包含文件?

Posted

技术标签:

【中文标题】如何告诉 g++ 编译器在哪里搜索包含文件?【英文标题】:How to tell g++ compiler where to search for include files? 【发布时间】:2013-03-18 13:27:13 【问题描述】:

在“工作目录”中,我有很多 #include 彼此的 *.cpp 和 *.h 文件以及来自子目录的文件。

例如:

#include "first.h"
#include "second.h"
#include "dir1/third.h"
#include "dir2/fourth.h"

在我自己的目录(不同于“工作”目录)中,我想创建一个新的 *.cpp 和 *.h 文件,其中包括“工作”目录中的文件之一。例如:

#include "/root/workingdirectory/first.h"

但是,它不起作用。因为“first.h”可能包含“second.h”并且“second.h”不在我的目录中。有没有办法告诉编译器它需要搜索不在当前但在工作目录中的包含文件:/root/workingdirectory/

为了更复杂,dir1dir2 不在我的工作目录中。它们位于/root/workingdirectory2/。那么,我的第二个问题是,是否可以通过让编译器知道子目录位于其他地方来解决这个问题?

我还需要补充一点,我不使用任何环境进行开发和从命令行编译(使用g++)。

【问题讨论】:

有人投票以“不具建设性”的方式关闭?以何种方式“使用此选项,哦,并且有指向手册的链接”没有事实、参考资料或特定专业知识的支持,并且可能会引发辩论、争论、投票或扩展讨论? 问题的-I 部分肯定是RTFM,但首先正确使用#include 指令 语言问题(而一个OP 没有' t显然知道要问) 人们阅读手册,他们尝试-I,它似乎工作。他们似乎知道-I 做了什么。然后很久以后它做了一些意想不到的事情。这就是为什么它真的不是一个 RTFM 问题。 【参考方案1】:

正如您已经被告知的,read the manual - 特别是 this chapter - 甚至更特别是 right here 很有用。

具体来说,你想要

g++ -I/root/workingdirectory -I/root/workingdirectory2

还要注意有关#include 指令语法的文档,将here 描述为:

2.1 包含语法

用户和系统头文件都包含在预处理中 指令#include。它有两种变体:

#include <file>

此变体用于系统头文件。它在系统目录的标准列表中搜索名为 file 的文件。您可以使用 -I 将目录添加到此列表中 选项(参见调用)。

#include "file"

此变体用于您自己程序的头文件。它首先在目录中搜索名为 file 的文件 包含当前文件,然后在引用目录中,然后 用于&lt;file&gt; 的相同目录。您可以将目录添加到 带有 -iquote 选项的报价目录列表。的论点 #include,无论是用引号还是尖括号分隔, 表现得像一个字符串常量,因为无法识别 cmets, 和宏名称不展开。因此,#include &lt;x/*y&gt; 指定 包含一个名为 x/*y 的系统头文件。

但是,如果文件中出现反斜杠,则将它们视为 普通文本字符,而不是转义字符。一个字符都没有 处理适合于 C 中字符串常量的转义序列。 因此,#include "x\n\\y" 指定一个包含三个 反斜杠。 (某些系统将 \ 解释为路径名分隔符。所有 其中也以同样的方式解释/。使用起来最便携 只有/。)

如果线路上有任何东西(除了cmets),这是一个错误 在文件名之后。

例如

#include "first.h"

开始在与包含该指令的 .cpp 文件相同的目录中查找(或采用相对于该目录的相对路径)。

如果你想使用包含路径(由-I 指定)你应该使用

#include <dir1/third.h>

通常的做法是使用#include "local.h" 表单作为库/包/模块中的头文件(无论您选择如何组织它),并使用#include &lt;external.h&gt; 表单作为来自外部/第 3 方或系统库的头文件.

【讨论】:

【参考方案2】:

Read The Fine Manual

每个人都可以阅读。你甚至可以选择使用什么(我会选择第一个):

-Idir

将目录dir添加到要搜索头文件的目录列表的头部。这可以用来覆盖系统头文件,替换您自己的版本,因为这些目录是在系统头文件目录之前搜索的。但是,您不应使用此选项来添加包含供应商提供的系统头文件的目录(为此使用-isystem)。如果您使用多个-I 选项,则目录按从左到右的顺序扫描;标准系统目录紧随其后。

如果标准系统包含目录,或用-isystem 指定的目录,也用-I 指定,则-I 选项将被忽略。该目录仍被搜索,但作为系统目录在系统包含链中的正常位置。这是为了确保 GCC 修复有缺陷的系统头文件的过程和 include_next 指令的顺序不会被无意更改。如果您确实需要更改系统目录的搜索顺序,请使用-nostdinc 和/或-isystem 选项。

-iquotedir

仅针对#include "file"的情况,将目录dir添加到要搜索头文件的目录列表的头部;他们不会搜索#include &lt;file&gt;,否则就像-I

【讨论】:

@johannes_lalala 这个答案将 OP 和每个未来的读者/googler(包括您)指向信息的实际来源,包括此处的相关位,以供您观赏。每个人都应该阅读手册而不是询问有关这些事情的问题,是的,但是手册对搜索引擎的优化程度较低,因此(在 SO 上)与它们建立良好的链接本身就很有用。仅仅说“RTFM”的答案是没有成效的。这个是,并试图向人们指出他们在不久的将来可能会寻找的大量其他信息。 是的,答案很好。除了你在前两句话中讲授 RTFM'ing-before-asking-questions 的部分。我觉得有点粗鲁。对不起,伙计,只是不需要为了获取信息而阅读它(除此之外还不错)。另一件事是:想象一下这个人实际上已经阅读了手册,找到了答案,但一开始并没有发布问题。你会更喜欢这种情况吗?我可以吗?有人会投票吗?还是一般的***? @johannes_lalala 恕我直言,但此元帖子链接自StacxkOverflow help page:meta.***.com/questions/261592。谷歌搜索“编译器找不到头文件”字面上可以找到数十个甚至数百个结果。这个问题也缺少 qttempted 解决方案,以及有效重现的方法。我没有因为不适合 SO 按照他们自己的规则而关闭它,而是链接到手册并从那里复制粘贴了答案。请注意,这些手册都已被您喜欢的搜索引擎收录。【参考方案3】:

对于 gcc,它是 header includes 的 -I 选项。对于 .cpp 文件,您只需要将它们作为 gcc 命令的参数显示即可。

【讨论】:

【参考方案4】:

每个 C/C++ 编译器(g++、gcc、MinGW、clang 等)在其根路径中都有一个名为“include”的文件夹,它会自动查找头文件。如果您使用 MinGW,它将位于,例如:“C:\MinGW\include”。只需将标题保存到包含文件夹中,如下所示:C:\MinGW\include\header1.h 或 C:\MinGW\include\LibGUI\Window.h

【讨论】:

这将使文件可用于整个系统,而不仅仅是项目。 我就是这样做的 无论如何,让文件对整个系统可用可能会有用,因为您可能希望重用头文件。

以上是关于如何告诉 g++ 编译器在哪里搜索包含文件?的主要内容,如果未能解决你的问题,请参考以下文章

在哪里告诉 Qt Creator 搜索用于自动完成的头文件

如何在 Ubuntu 中使用 g++ 编译 fltk 程序?

我在哪里可以获得 comdef.h?

java用eclipse编译运行后的文件保存在哪里呢?

19.路径搜索的综合示例

调试选项 -g 如何更改二进制可执行文件?