在Linux中注册标头搜索位置的常用机制是什么?

时间:2019-04-11 19:55:03

标签: linux g++ gnu-make header-files

假设我在linux下下载了一个库并构建它:configure,make,sudo make install。

该库带有我要包含在项目中的标头。编译器如何知道在哪里搜索标头?

  • 提请Dorman对This Question的回答给出了一个很好的示例,说明了如何在系统级别检查编译器在哪里寻找标头:

    gcc -print-prog-name=cc1plus -v

  • 包含文件夹可以在项目中添加带有-I参数的makefile。自然,它们可以在Makefile中看到。

还有其他我未考虑过的用于注册标头位置的机制吗?这些组合的方法是否给我提供了全面的了解,或者换句话说,如果我查看这些地方,假设我正在使用gnu-make,是否已经看到了所有内容?最后,是否有一种方便的方法可以让Make向我显示要检查标题的位置?

背景: 我正在处理的库是zeromq和Google的协议缓冲区。平台是CentOS。编译器抱怨找不到标题。我已经在替代系统(Fedora)上构建了该程序,该系统似乎不需要其他干预即可确保可访问这些标头。

1 个答案:

答案 0 :(得分:0)

在Linux(或其他类似Unix的操作系统)中没有通常的机制来注册标头搜索位置。

对于您的系统类型,

GCC是内置的,带有默认的预处理程序搜索目录列表 对于C和C ++中的每一个。您可以使用以下命令(包括其他命令)为C显示该列表:

$ gcc -x c  -E -Wp,-v -
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...
$ [CNTL-C]

以及对于C ++:

$ gcc -x c++  -E -Wp,-v -
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/8"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/8
 /usr/include/x86_64-linux-gnu/c++/8
 /usr/include/c++/8/backward
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...
$ [CNTL-C]

请注意,C和C ++的默认搜索目录不同:C ++-list 是C列表的超集。当您以常规方式编译C源文件时,将搜索C列表:

gcc [options...] foo.c ...

,当您以常规方式编译C ++源代码时,将搜索C ++列表:

g++ [options...] foo.cpp bar.cc gum.cxx ...

只有两种方法可以将标头搜索目录传递给 预处理器:-

您可以使用以下命令在命令行中明确指定搜索目录 选项:

-I dir
-iquote dir
-isystem dir
-idirafter dir

按照the manual: 3.15 Options for Directory Search

或者您可以在环境变量之一的设置中列出搜索目录 预处理器将其解释为搜索目录列表。对于C,这些是:

CPATH
C_INCLUDE_PATH

对于C ++,它们是:

CPATH
CPLUS_INCLUDE_PATH

按照the manual: 3.20 Environment Variables Affecting GCC

在Linux中可以给环境变量一个持久的默认值 系统范围内的定义,方法是在根特权文件/etc/environment/etc/profile/etc/profile.d//etc/bash.bashrc中定义一个。 因此,如果某个代理商要在以下其中一项中定义CPATH和或C_INCLUDE_PATH|CPLUS_INCLUDE_PATH 这些文件作为:标点符号的目录列表,可以有效地注册 这些目录作为C | C ++的GCC搜索目录。但是,不会安装GCC安装 任何此类设置:只能由root用户手动设置。您可以检查,然后 如果绘制空白,则只有在以下位置定义这些变量时,这些变量才有影响力 瞬态外壳。在构建系统中很少使用它们,正是因为 引入了对手术环境的不透明依赖。

我上面用来列出默认搜索目录的命令对 通过两种可能的方法之一添加非默认目录:

$ mkdir my_include

$ gcc -x c  -I my_include -E -Wp,-v -
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 my_include
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

或:

$ gcc -x c  -iquote my_include -E -Wp,-v -
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
 my_include
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

或:

$ export CPLUS_INCLUDE_PATH=my_include
$ gcc -x c++  -E -Wp,-v -
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/8"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 my_include
 /usr/include/c++/8
 /usr/include/x86_64-linux-gnu/c++/8
 /usr/include/c++/8/backward
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
  

是否有一种方便的方法可以让Make向我显示要检查标题的位置?

Make对编译过程及其所涉及的概念一无所知:它不知道 检查标题在其工作过程中经常发生。在执行makefile时,命令可能是 运行并调用GCC前端执行编译,然后 it 将尝试 以已经概述的方式定位头文件。

在其他条件相同的情况下,编译代码的最可能原因 应该在某些Fedora系统上成功,但在某些CentOS系统上失败,因为, 例如#include <google/protobuf/someheader.h>无法解决,是因为 具有root特权的用户已安装开发包protobuf-devel或 Fedora系统上的protobuf源压缩文件,而CentOS系统上没有人做过。

如果两个系统上均确实安装了protobuf,则 其他情况不平等。

google/protobuf/someheader.h可能是一个标头, 由Fedora系统上安装的protobuf的(较新的?)版本提供 但不是由CentOS系统上安装的(较旧的)版本提供的。

其他一些不平等现象可能解释了您的情况,但没有具体说明 Fedora和CentOS软件包安装步骤的详细信息和具体示例 投机成功和失败的构建只能描述所有这些。您现在对GCC解决#include指令的方法一无所知,对此几乎可以肯定没有解释。

类似的注意事项适用于您发现的编译失败 到zeromq标头。