如何检查库是否使用 -fno-rtti 编译

How can I check if a library was compiled with -fno-rtti?

本文关键字:是否 -fno-rtti 编译 何检查 检查      更新时间:2023-10-16

>假设一个简单的文件bla.cpp

struct MyClass {
  virtual int foo(int x);
  virtual ~MyClass();
};

int MyClass::foo(int x) { return x + 23; }
MyClass::~MyClass() {}

构建到共享库中

g++ -c -fPIC bla.cpp
g++ -shared -o bla.so bla.o

通常会包含一些type_info符号,因为 RTTI 在 gcc 上默认启用。但是,如果我使用

g++ -c -fPIC -fno-rtti bla.cpp

type_info将丢失。

有没有一种简单、可靠的方法(在gccclang)来检查库是用-fno-rtti还是-frtti构建的?我问是因为今天我盯着臭名昭著的undefined reference to type_info,我花了一点时间才明白这是由我链接的图书馆引起的,反对用-fno-rtti构建。

如果一个类有虚拟函数,它应该有类型信息。nm -C libname.so并注意"vtable for","typeinfo for"和"typeinfo name for"。例:

00000000 b .bss
00000000 d .data
00000000 r .eh_frame
00000000 r .rdata$_ZTI3Foo
00000000 r .rdata$_ZTS3Foo
00000000 r .rdata$_ZTV3Foo
00000000 r .rdata$zzz
00000000 t .text
00000000 T Foo::foo()
00000000 R typeinfo for Foo
00000000 R typeinfo name for Foo
00000000 R vtable for Foo
         U vtable for __cxxabiv1::__class_type_info

如果你有vtable但没有typeinfo,这是用-fno-rtti编译的。例:

00000000 b .bss
00000000 d .data
00000000 r .eh_frame
00000000 r .rdata$_ZTV3Foo
00000000 r .rdata$zzz
00000000 t .text
00000000 T Foo::foo()
00000000 R vtable for Foo

如果你没有任何虚拟功能,你就无法分辨(也不应该关心)。

如果你需要这个进行配置,请像 GNU autoconf 那样做:编写一个最小的程序来执行检查并构建它。构建(或运行)是否失败会告诉您需要了解的内容。