如果上下文太多,最后会有TL; DR!
上下文
我正在尝试将项目使用的glibc版本更新为2.23(我知道它很旧,这是另一个问题)。为此,我需要换出库并使用关联的解释器。
换出看起来像ABI更改的解释器时,我遇到了一些问题,所以我认为这可能是因为头文件已进行了某种更改,并开始着手将那些包含在项目中。
最初,我尝试使用-I
包含 header ,但出现错误(请参见下文)。后来我尝试设置--sysroot
,但这很快就感觉像是一种错误的处理方式,因为我本质上是在重新发明g++已经对系统头文件所做的工作。后来我发现了另一种看起来更有希望的机制(请参阅问题部分)。
可以是XY issue吗?绝对可以,但是无论哪种方式,我所看到的问题对我来说都很奇怪。
问题
我调查了是否存在其他机制来在gcc和g++中包含系统库(例如glibc)的 header 。我发现了标记-isystem
:
-isystem dir Search dir for header files, after all directories specified by -I but before the standard system directories. Mark it as a system directory, so that it gets the same special treatment as is applied to the standard system directories. If dir begins with "=", then the "=" will be replaced by the sysroot prefix; see --sysroot and -isysroot.
我认为这可能是需要的,并着手将该标志集成到项目的构建系统中。生成的g++命令如下所示(简化并分成多行):
> /path/to/gcc-6.3.0/bin/g++
-c
-Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2
-Wl,--rpath=/path/to/glibc-2.23/build/install/lib
-isystem /path/to/glibc-2.23/build/install/include
-I.
-I/project-foo/include
-I/project-bar/include
-o example.o
example.cpp
这将导致以下错误,随后是许多类似错误:In file included from /usr/include/math.h:71:0,
from /path/to/gcc-6.3.0/include/c++/6.3.0/cmath:45,
from example.cpp:42:
/path/to/glibc-2.23/build/install/include/bits/mathcalls.h:63:16: error: expected constructor, destructor, or type conversion before '(' token
__MATHCALL_VEC (cos,, (_Mdouble_ __x));
对此进行调查,似乎该特定的math.h
与此版本的glibc不兼容。它尝试使用它的事实使我感到惊讶,因为math.h
文件存在于我指定的glibc目录中。为什么不使用它?这是我验证文件存在的方法:> ls /path/to/glibc-2.23/build/install/include/math.h
/path/to/glibc-2.23/build/install/include/math.h
研究我在互联网上搜索了存在类似问题的人,并发现了以下相关信息:
最后的是最有希望的。它讨论了为什么
-isystem
在这里不起作用,说明特殊的#include_next
以不同的方式遍历包含路径。在这里,解决方案似乎是“不要在需要帮助的地方使用-isystem
”,但是由于我尝试使用-I
只能再次遇到相同的问题,因此我不确定如何将其应用于此处。原始问题
使用新的glibc进行编译时,出现以下错误(我们的构建过程最终运行了一些其编译的程序,以生成更多要编译的源,因此在编译时会出现此运行时错误):
Inconsistency detected by ld.so: get-dynamic-info.h: 143: elf_get_dynamic_info: Assertion `info[DT_RPATH] == NULL' failed!
我发现了一些与此相关的东西:我看到的唯一解决方案是完全重新编译gcc以使用新的glibc。如果可能的话,我想避免这种情况,这就是导致我进入包含路线的原因。
消除复杂的构建系统
为了尝试消除“真实”项目上的复杂构建系统,我使用以下
test.cpp
文件重现了该问题:#include <cmath>
int main() {
}
编译使用:> /path/to/gcc-6.3.0/bin/g++ test.cpp -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2 -Wl,--rpath=/path/to/glibc-2.23/build/install/lib
运行产生相同的原始问题:> ./a.out
Inconsistency detected by ld.so: get-dynamic-info.h: 143: elf_get_dynamic_info: Assertion `info[DT_RPATH] == NULL' failed!
尝试使用更新的 header 会产生相同的包含问题:> /path/to/gcc-6.3.0/bin/g++ test.cpp -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2 -Wl,--rpath=/path/to/glibc-2.23/build/install/lib -isystem /path/to/glibc-2.23/build/install/include
In file included from /usr/include/math.h:71:0,
from /path/to/gcc-6.3.0/include/c++/6.3.0/cmath:45,
from test.cpp:1:
/path/to/glibc-2.23/build/install/include/bits/mathcalls.h:63:16: error: expected constructor, destructor, or type conversion before '(' token
__MATHCALL_VEC (cos,, (_Mdouble_ __x));
TL; DR 如何使g++正确地包含来自我的glibc构建的 header ,而不会意外地包含来自/usr/include的不兼容文件?
最佳答案
在您的GCC版本中,<cmath>
使用#include_next
,这意味着您需要确保包含cmath
文件的目录位于包含您要针对的glibc版本的正确math.h
的目录之前(在包含搜索路径上)。
您可以使用g++ -v
查看搜索路径。在您的情况下,可能看起来像这样:
#include "..." search starts here:
#include <...> search starts here:
.
/project-foo/include
/project-bar/include
/path/to/glibc-2.23/build/install/include
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
如果使用--prefix=/usr
配置glibc并使用DESTDIR=/path/to/glibc-2.23/build/install
安装它,则其头文件将安装在目录/path/to/glibc-2.23/build/install/usr/include
中。这意味着您应该能够使用-isysroot
选项,该选项将重写默认的/usr/include
目录,从而使搜索路径的顺序正确:#include "..." search starts here:
#include <...> search starts here:
.
/project-foo/include
/project-bar/include
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/path/to/glibc-2.23/build/install/usr/include
关于linux - 如何使g++正确使用我自己的glibc构建的 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62795463/