如何在gcc/g++中指定尖括号头文件的位置?

3

有没有办法告诉gcc/g++/clang在寻找尖括号("<", ">")引用的头文件时去哪里查找?

我不使用尖括号约定非系统文件,但问题在于当我尝试使用我下载的一些软件包中的头文件时,所有包含的文件都会出现错误。

例如,假设我想从一个名为Foo的模块中包含头文件:

/foo-v1.0/include/DependencyA.hpp:

#ifndef DEP_A_HPP
#define DEP_A_HPP

class DependencyA
{
  ...
};

#endif

/foo-v1.0/include/Api.hpp:

#ifndef FOO_HPP
#define FOO_HPP
#include <Foo/DependencyA.hpp>

void doSomething(DependencyA* da);

#endif

然后,在我的代码中:

/mycode.cpp:

#include "/foo-v1.0/include/Api.hpp"

DependencyA* da = new DependencyA();
doSomething(da);


我遇到了编译错误:fatal error: 'Foo/DependencyA.hpp' file not found 我尝试使用以下命令进行构建:
  • clang -c mycode.cpp -isystem./foo-v1.0/include -o mycode.o
  • clang -c mycode.cpp -isystem./foo-v1.0/include/ -o mycode.o
  • clang -c mycode.cpp -I./foo-v1.0/include -o mycode.o
  • clang -c mycode.cpp -I./foo-v1.0/include/ -o mycode.o
但都没有成功。
如何告诉编译器将<Foo/**/*>解析为特定的根目录,以便每个包含的文件都能找到?

2
你有一个问题。实际的文件路径中没有以Foo/DependencyA.hpp结尾的路径。设置搜索路径无法解决这个问题,编译器试图将Foo/DependencyA.hpp添加到你在包含搜索路径中列出的每个目录中。 - Ben Voigt
1
你可能想要创建一个Foo的符号链接(可能在/usr/local/include中,也可能在通过-isystem添加的某个项目本地目录中),指向/foo-v1.0/include - Ben Voigt
如果您输入man gcc,您将阅读到有关gcc命令的文档,其中包括您正在寻找的设置/选项。确实如上所述的原因,适当的gcc设置/选项不会对您有所帮助;然而,您应该知道man gcc提供了所有可用gcc选项的完整文档。知道在哪里找到并如何阅读技术文档是每个C++开发者所必备的技能。 - Sam Varshavchik
1个回答

1
答案已经在评论中了。
要检查包含目录,可以使用此处描述的方法:GCC默认包含目录是什么?,最好用-替换为/dev/null
clang -xc -E  -v /dev/null

在我的机器上,对于clang,它会给出:
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/clang/11.0.0/include
 /usr/include
End of search list.

要了解如何操作这个列表,只需阅读gcc(或clang)手册(man clang或在互联网上查找,例如https://man7.org/linux/man-pages/man1/gcc.1.html)。对于gcc来说,它的内容如下:

Options for Directory Search
       These options specify directories to search for header files, for
       libraries and for parts of the compiler:

       -I dir
       -iquote dir
       -isystem dir
       -idirafter dir
           Add the directory dir to the list of directories to be searched
           for header files during preprocessing.  If dir begins with = or
           $SYSROOT, then the = or $SYSROOT is replaced by the sysroot
           prefix; see --sysroot and -isysroot.

           Directories specified with -iquote apply only to the quote form
           of the directive, "#include "file"".  Directories specified with
           -I, -isystem, or -idirafter apply to lookup for both the
           "#include "file"" and "#include <file>" directives.

这段描述后面是对头文件搜索顺序的详细说明,以及一些关于使用哪个选项来达到哪个目的的建议。您可以在手册中找到它。搜索“目录搜索选项”。
我真正不喜欢你代码中的这行代码:
#include "/foo-v1.0/include/Api.hpp"

它似乎包含了头文件的绝对路径,我从未见过这样的写法。我会将其改为

#include "Api.hpp"   

通过通常的编译器-I命令行选项,将/foo-v1.0/include添加到搜索列表中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接