I am unable to link against a dynamic library that defines a set of classes that I need to use. My compiled code tries to link against the typeinfo structure of the class, but it is not exported by the library. However, the virtual table of the class is.
Using nm, I find the symbol I'm trying to resolve:
U __ZTIN3net14QuicSpdyStreamE
The only special symbol in the dynamic lib for this class is:
S __ZTVN3net14QuicSpdyStreamE
I have 2 questions:
Background
I am trying to link against libnet.dylib which I build via a component build of Chromium. The class of interest is QuicSpdyStream. All of its virtual functions are defined in quic_spdy_stream.cc. QuicSpdyStream itself is derived from QuicStream which has a single pure virtual function OnDataAvailable()
.
My test program looks like this:
#include <iostream>
#include "base/macros.h"
#include "net/quic/core/quic_spdy_stream.h"
#include "net/quic/core/quic_types.h"
using namespace std;
class MyStream : public net::QuicSpdyStream {
public:
MyStream(net::QuicStreamId id, net::QuicSpdySession* session)
: net::QuicSpdyStream(id, session){};
void OnDataAvailable() override {};
private:
DISALLOW_COPY_AND_ASSIGN(MyStream);
};
int main(int argc, char** argv) {
auto stream = new MyStream(net::QuicStreamId(1), NULL);
cout << "Created stream with id:" << stream->id() << endl;
return 0;
}
When I try to build:
$ clang++ -I../externals/quic/src -I../externals/quic
-L../externals/libs -lnet -std=c++1y test.cpp
Undefined symbols for architecture x86_64: "typeinfo for net::QuicSpdyStream", referenced from:
typeinfo for net::MyStream in test-b130b2.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
Chromium itself ships with a toy quic_server that makes use of this class in much the same way here and here. When I build a component build, the associated quic_server has no dependence on the typeinfo structure symbol -- this makes me think I don't really need it.
I'm wondering if this is an ABI issue as the Chromium lib is built on my Mac with clang version 7.0.0 and my system version is LLVM version 9.0.0 (clang-900.0.39.2).
To resolve this problem you have to compile your code just like Chromium with RTTI disabled using: -fno-rtti
Undefined symbols for architecture x86_64: "typeinfo for net::QuicSpdyStream", referenced from: typeinfo for net::MyStream
Means that the run-time type information (RTTI) the compiler generated for your class MyStream
references a missing type information for its base class net::QuicSpdyStream
. That's because the Chromium is build with by default RTTI disabled[1].
... Chromium builds without RTTI by default, but some sanitizers are known to require it, like CFI diagnostics and UBsan variants.
It's also possible to enable it in the Chromium configuration if you want to (configure
with rtti
or no_rtti
).
protobuf needs RTTI but has an define that allows to use it without it GOOGLE_PROTOBUF_NO_RTTI
[2][3][4].