首页 > 解决方案 > 如何在静态库中查找缺少的库依赖项(或根本原因)以及何时使用 externalproject 方法构建 cmake 目标

问题描述

我想为 jaeger 使用静态目标而不是链接到动态目标,静态目标编译得很好但是当我在我的代码库中使用它时,我看到未定义的引用错误:试过:

  1. Thrift 的动态/静态链接显式到 ceph(主代码库):
[100%] Linking CXX executable ../bin/ceph-osd
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransportException::TTransportException(apache::thrift::transport::TTransportException::TTransportExceptionType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport19TTransportExceptionC2ENS2_23TTransportExceptionTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6apache6thrift9transport19TTransportExceptionC5ENS2_23TTransportExceptionTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x2d): undefined reference to `vtable for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransportException::~TTransportException()':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport19TTransportExceptionD2Ev[_ZN6apache6thrift9transport19TTransportExceptionD5Ev]+0x13): undefined reference to `vtable for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransport::open()':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport10TTransport4openEv[_ZN6apache6thrift9transport10TTransport4openEv]+0x8b): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransport::close()':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport10TTransport5closeEv[_ZN6apache6thrift9transport10TTransport5closeEv]+0x8b): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransport::read_virt(unsigned char*, unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport10TTransport9read_virtEPhj[_ZN6apache6thrift9transport10TTransport9read_virtEPhj]+0x92): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransport::write_virt(unsigned char const*, unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport10TTransport10write_virtEPKhj[_ZN6apache6thrift9transport10TTransport10write_virtEPKhj]+0x92): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TTransport::consume_virt(unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport10TTransport12consume_virtEj[_ZN6apache6thrift9transport10TTransport12consume_virtEj]+0x8e): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::protocol::TProtocol::TProtocol(std::shared_ptr<apache::thrift::transport::TTransport>)':
UDPTransporter.cpp:(.text._ZN6apache6thrift8protocol9TProtocolC2ESt10shared_ptrINS0_9transport10TTransportEE[_ZN6apache6thrift8protocol9TProtocolC5ESt10shared_ptrINS0_9transport10TTransportEE]+0x17): undefined reference to `vtable for apache::thrift::protocol::TProtocol'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::protocol::TProtocolFactory::TProtocolFactory()':
UDPTransporter.cpp:(.text._ZN6apache6thrift8protocol16TProtocolFactoryC2Ev[_ZN6apache6thrift8protocol16TProtocolFactoryC5Ev]+0xf): undefined reference to `vtable for apache::thrift::protocol::TProtocolFactory'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TBufferBase::consume(unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport11TBufferBase7consumeEj[_ZN6apache6thrift9transport11TBufferBase7consumeEj]+0xe4): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::transport::TMemoryBuffer::TMemoryBuffer(unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport13TMemoryBufferC2Ej[_ZN6apache6thrift9transport13TMemoryBufferC5Ej]+0x23): undefined reference to `vtable for apache::thrift::transport::TMemoryBuffer'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `unsigned int apache::thrift::transport::readAll<apache::thrift::transport::TTransport>(apache::thrift::transport::TTransport&, unsigned char*, unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport7readAllINS1_10TTransportEEEjRT_Phj[_ZN6apache6thrift9transport7readAllINS1_10TTransportEEEjRT_Phj]+0xd6): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `unsigned int apache::thrift::transport::readAll<apache::thrift::transport::TBufferBase>(apache::thrift::transport::TBufferBase&, unsigned char*, unsigned int)':
UDPTransporter.cpp:(.text._ZN6apache6thrift9transport7readAllINS1_11TBufferBaseEEEjRT_Phj[_ZN6apache6thrift9transport7readAllINS1_11TBufferBaseEEEjRT_Phj]+0xd6): undefined reference to `typeinfo for apache::thrift::transport::TTransportException'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::protocol::TCompactProtocolFactoryT<apache::thrift::transport::TTransport>::~TCompactProtocolFactoryT()':
UDPTransporter.cpp:(.text._ZN6apache6thrift8protocol24TCompactProtocolFactoryTINS0_9transport10TTransportEED2Ev[_ZN6apache6thrift8protocol24TCompactProtocolFactoryTINS0_9transport10TTransportEED5Ev]+0x2a): undefined reference to `apache::thrift::protocol::TProtocolFactory::~TProtocolFactory()'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o):(.data.rel.ro._ZTVN6apache6thrift8protocol17TProtocolDefaultsE[_ZTVN6apache6thrift8protocol17TProtocolDefaultsE]+0x170): undefined reference to `apache::thrift::protocol::TProtocol::skip_virt(apache::thrift::protocol::TType)'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o):(.data.rel.ro._ZTIN6apache6thrift8protocol24TCompactProtocolFactoryTINS0_9transport10TTransportEEE[_ZTIN6apache6thrift8protocol24TCompactProtocolFactoryTINS0_9transport10TTransportEEE]+0x10): undefined reference to `typeinfo for apache::thrift::protocol::TProtocolFactory'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o):(.data.rel.ro._ZTIN6apache6thrift8protocol17TProtocolDefaultsE[_ZTIN6apache6thrift8protocol17TProtocolDefaultsE]+0x10): undefined reference to `typeinfo for apache::thrift::protocol::TProtocol'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(UDPTransporter.cpp.o): in function `apache::thrift::protocol::TProtocolDefaults::~TProtocolDefaults()':
UDPTransporter.cpp:(.text._ZN6apache6thrift8protocol17TProtocolDefaultsD2Ev[_ZN6apache6thrift8protocol17TProtocolDefaultsD5Ev]+0x2a): undefined reference to `apache::thrift::protocol::TProtocol::~TProtocol()'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(HTTPTransporter.cpp.o): in function `jaegertracing::utils::HTTPTransporter::HTTPTransporter(jaegertracing::net::URI const&, int)':
HTTPTransporter.cpp:(.text+0x19f): undefined reference to `apache::thrift::transport::THttpClient::THttpClient(std::shared_ptr<apache::thrift::transport::TTransport>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(HTTPTransporter.cpp.o): in function `apache::thrift::protocol::TBinaryProtocolFactoryT<apache::thrift::transport::TTransport, apache::thrift::protocol::TNetworkBigEndian>::~TBinaryProtocolFactoryT()':
HTTPTransporter.cpp:(.text._ZN6apache6thrift8protocol23TBinaryProtocolFactoryTINS0_9transport10TTransportENS1_17TNetworkBigEndianEED2Ev[_ZN6apache6thrift8protocol23TBinaryProtocolFactoryTINS0_9transport10TTransportENS1_17TNetworkBigEndianEED5Ev]+0x2a): undefined reference to `apache::thrift::protocol::TProtocolFactory::~TProtocolFactory()'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(HTTPTransporter.cpp.o):(.data.rel.ro._ZTIN6apache6thrift8protocol23TBinaryProtocolFactoryTINS0_9transport10TTransportENS1_17TNetworkBigEndianEEE[_ZTIN6apache6thrift8protocol23TBinaryProtocolFactoryTINS0_9transport10TTransportENS1_17TNetworkBigEndianEEE]+0x10): undefined reference to `typeinfo for apache::thrift::protocol::TProtocolFactory'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(ThriftSender.cpp.o): in function `apache::thrift::transport::TMemoryBuffer::TMemoryBuffer()':
ThriftSender.cpp:(.text._ZN6apache6thrift9transport13TMemoryBufferC2Ev[_ZN6apache6thrift9transport13TMemoryBufferC5Ev]+0x20): undefined reference to `vtable for apache::thrift::transport::TMemoryBuffer'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(Agent.cpp.o): in function `jaegertracing::agent::thrift::AgentProcessor::dispatchCall(apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, void*)':
Agent.cpp:(.text+0x1037): undefined reference to `apache::thrift::TApplicationException::write(apache::thrift::protocol::TProtocol*) const'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(Agent.cpp.o): in function `jaegertracing::agent::thrift::AgentConcurrentClient::send_emitZipkinBatch(std::vector<twitter::zipkin::thrift::Span, std::allocator<twitter::zipkin::thrift::Span> > const&)':
Agent.cpp:(.text+0x1b32): undefined reference to `apache::thrift::async::TConcurrentSendSentry::TConcurrentSendSentry(apache::thrift::async::TConcurrentClientSyncInfo*)'
/usr/bin/ld: Agent.cpp:(.text+0x1c63): undefined reference to `apache::thrift::async::TConcurrentSendSentry::commit()'
/usr/bin/ld: Agent.cpp:(.text+0x1c7b): undefined reference to `apache::thrift::async::TConcurrentSendSentry::~TConcurrentSendSentry()'
/usr/bin/ld: Agent.cpp:(.text+0x1d04): undefined reference to `apache::thrift::async::TConcurrentSendSentry::~TConcurrentSendSentry()'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(Agent.cpp.o): in function `jaegertracing::agent::thrift::AgentConcurrentClient::send_emitBatch(jaegertracing::thrift::Batch const&)':
Agent.cpp:(.text+0x1da4): undefined reference to `apache::thrift::async::TConcurrentSendSentry::TConcurrentSendSentry(apache::thrift::async::TConcurrentClientSyncInfo*)'
/usr/bin/ld: Agent.cpp:(.text+0x1ed5): undefined reference to `apache::thrift::async::TConcurrentSendSentry::commit()'
/usr/bin/ld: Agent.cpp:(.text+0x1eed): undefined reference to `apache::thrift::async::TConcurrentSendSentry::~TConcurrentSendSentry()'
/usr/bin/ld: Agent.cpp:(.text+0x1f76): undefined reference to `apache::thrift::async::TConcurrentSendSentry::~TConcurrentSendSentry()'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(Agent.cpp.o): in function `apache::thrift::TDispatchProcessor::process(std::shared_ptr<apache::thrift::protocol::TProtocol>, std::shared_ptr<apache::thrift::protocol::TProtocol>, void*)':
Agent.cpp:(.text._ZN6apache6thrift18TDispatchProcessor7processESt10shared_ptrINS0_8protocol9TProtocolEES5_Pv[_ZN6apache6thrift18TDispatchProcessor7processESt10shared_ptrINS0_8protocol9TProtocolEES5_Pv]+0x7e): undefined reference to `apache::thrift::GlobalOutput'
/usr/bin/ld: Agent.cpp:(.text._ZN6apache6thrift18TDispatchProcessor7processESt10shared_ptrINS0_8protocol9TProtocolEES5_Pv[_ZN6apache6thrift18TDispatchProcessor7processESt10shared_ptrINS0_8protocol9TProtocolEES5_Pv]+0x8b): undefined reference to `apache::thrift::TOutput::printf(char const*, ...)'
/usr/bin/ld: jaeger/lib/libjaegertracing.a(Agent.cpp.o): in function `apache::thrift::concurrency::Mutex::~Mutex()':
Agent.cpp:(.text._ZN6apache6thrift11concurrency5MutexD2Ev[_ZN6apache6thrift11concurrency5MutexD5Ev]+0x13): undefined reference to `vtable for apache::thrift::concurrency::Mutex'

  1. 尝试更改节俭静态库链接的顺序。
  2. 提示:由 Project 的 CMake 创建的静态目标可以与示例代码一起正常工作,但我不知道当它被构建为 ExternalProject(CMake) 时如何测试该目标,我可以以某种方式做到这一点吗?

on提示缺少定义,但我不知道为什么它没有包含在静态文件中,而当我链接到静态目标(例如代码(独立)而不是我想要链接的代码时,一切using **nm -uC libjaegertracing.a**正常. 我想知道如何知道并包含缺少的库/定义,以便在尝试将手动创建的目标与 libjaegertracing.a 一起使用时不会出现这些错误

U jaegertracing::thrift::Tag::Tag(jaegertracing::thrift::Tag const&)
                 U jaegertracing::thrift::Tag::~Tag()
                 U jaegertracing::thrift::Span::Span(jaegertracing::thrift::Span const&)
                 U jaegertracing::thrift::Span::~Span()
                 U jaegertracing::thrift::Batch::__set_spans(std::vector<jaegertracing::thrift::Span, std::allocator<jaegertracing::thrift::Span> > const&)
                 U jaegertracing::thrift::Batch::__set_process(jaegertracing::thrift::Process const&)
                 U jaegertracing::thrift::Batch::~Batch()
                 U jaegertracing::thrift::Process::__set_tags(std::vector<jaegertracing::thrift::Tag, std::allocator<jaegertracing::thrift::Tag> > const&)
                 U jaegertracing::thrift::Process::~Process()
                 U jaegertracing::Tag::thrift(jaegertracing::thrift::Tag&) const
                 U jaegertracing::Span::thrift(jaegertracing::thrift::Span&) const
                 U std::runtime_error::what() const
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::empty() const
                 U std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::str() const
                 U std::allocator<char>::allocator()
                 U std::allocator<char>::~allocator()
                 U std::ostream::operator<<(int)
                 U std::runtime_error::runtime_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
                 U std::runtime_error::~runtime_error()
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
                 U std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream()
                 U std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_ostringstream()
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
                 U std::bad_alloc::~bad_alloc()
                 U std::exception::~exception()
                 U operator new(unsigned long)

为了验证我是否编译了依赖库来构建静态库,我使用了:

$ ar t libjaegertracing.a

这给出了预期的编译文件:

Config.cpp.o
DynamicLoad.cpp.o
LogRecord.cpp.o
Logging.cpp.o
Reference.cpp.o
Span.cpp.o
SpanContext.cpp.o
Tag.cpp.o
TraceID.cpp.o
Tracer.cpp.o
TracerFactory.cpp.o
Sender.cpp.o
ThriftSender.cpp.o
BaggageSetter.cpp.o
RemoteRestrictionJSON.cpp.o
RemoteRestrictionManager.cpp.o
Restriction.cpp.o
RestrictionManager.cpp.o
RestrictionsConfig.cpp.o
Counter.cpp.o
Gauge.cpp.o
InMemoryStatsReporter.cpp.o
Metric.cpp.o
Metrics.cpp.o
NullCounter.cpp.o
NullGauge.cpp.o
NullStatsFactory.cpp.o
NullStatsReporter.cpp.o
NullTimer.cpp.o
StatsFactory.cpp.o
StatsFactoryImpl.cpp.o
StatsReporter.cpp.o
Timer.cpp.o
IPAddress.cpp.o
Socket.cpp.o
URI.cpp.o
Error.cpp.o
Header.cpp.o
Method.cpp.o
Request.cpp.o
Response.cpp.o
Endian.cpp.o
Hostname.cpp.o
Extractor.cpp.o
HeadersConfig.cpp.o
Injector.cpp.o
Propagator.cpp.o
CompositeReporter.cpp.o
Config.cpp.o
InMemoryReporter.cpp.o
LoggingReporter.cpp.o
NullReporter.cpp.o
RemoteReporter.cpp.o
Reporter.cpp.o
AdaptiveSampler.cpp.o
Config.cpp.o
ConstSampler.cpp.o
GuaranteedThroughputProbabilisticSampler.cpp.o
ProbabilisticSampler.cpp.o
RateLimitingSampler.cpp.o
RemoteSamplingJSON.cpp.o
RemotelyControlledSampler.cpp.o
Sampler.cpp.o
SamplingStatus.cpp.o
Agent.cpp.o
AggregationValidator.cpp.o
BaggageRestrictionManager.cpp.o
Collector.cpp.o
Dependency.cpp.o
SamplingManager.cpp.o
ZipkinCollector.cpp.o
agent_constants.cpp.o
agent_types.cpp.o
aggregation_validator_constants.cpp.o
aggregation_validator_types.cpp.o
baggage_constants.cpp.o
baggage_types.cpp.o
dependency_constants.cpp.o
dependency_types.cpp.o
jaeger_constants.cpp.o
jaeger_types.cpp.o
sampling_constants.cpp.o
sampling_types.cpp.o
zipkincore_constants.cpp.o
zipkincore_types.cpp.o
ErrorUtil.cpp.o
HexParsing.cpp.o
EnvVariable.cpp.o
RateLimiter.cpp.o
UDPTransporter.cpp.o
HTTPTransporter.cpp.o
YAML.cpp.o
ThriftMethods.cpp.o

构建良好的目标:[works] 用于添加依赖项:

function(add_lib_deps lib)
  target_include_directories(${lib} PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>)
  target_link_libraries(${lib} PUBLIC ${link_flags} ${LIBS})
  target_compile_options(${lib} PUBLIC ${cxx_flags})
endfunction()

添加源文件:

add_library(jaegertracing-static STATIC ${SRC})

与示例代码链接:

target_link_libraries(app PUBLIC ${JAEGERTRACING_LIB})

使用源代码[不起作用]

 add_library(jaeger-static STATIC IMPORTED)                                                                          
  add_dependencies(jaeger-static jaeger)                                                                              
  set(jaeger_INCLUDE_DIR ${jaeger_SOURCE_DIR}/src/)                                                                   
  set(jaeger_LIBRARY ${jaeger_BINARY_DIR}/lib/libjaegertracing.a)                                                     
  include_directories(jaeger_INCLUDE_DIR)                                                                             
  set_target_properties(jaeger-static PROPERTIES                                                                      
    INTERFACE_LINK_LIBRARIES "${jaeger_LIBRARY}"                                                                      
    IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"                                                                           
    IMPORTED_LOCATION "${jaeger_LIBRARY}"                                                                             
    INTERFACE_INCLUDE_DIRECTORIES "${jaeger_INCLUDE_DIR}") 

然后:

target_link_libraries() with primary target from my codebase

标签: c++c++11cmakestatic-linkingmissing-symbols

解决方案


推荐阅读