C++ CMake:使静态库工作,但动态库不工作';T

C++ CMake:使静态库工作,但动态库不工作';T,c++,makefile,cmake,C++,Makefile,Cmake,我正在尝试使用CMake创建共享库,但是如果我以静态方式创建它,它会工作得很好,但动态无法: CMAKE_MINIMUM_REQUIRED(VERSION 3.6) PROJECT(TestDemo) SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_COMPILER clang++) # Headers INCLUDE_DIRECTORIES(src) INCLUDE_DIRECTORIES(src/xxx) INCLUDE_DIRECTORIES(3rdp

我正在尝试使用CMake创建共享库,但是如果我以静态方式创建它,它会工作得很好,但动态无法:

CMAKE_MINIMUM_REQUIRED(VERSION 3.6)
PROJECT(TestDemo)

SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_COMPILER clang++)

# Headers
INCLUDE_DIRECTORIES(src)
INCLUDE_DIRECTORIES(src/xxx)
INCLUDE_DIRECTORIES(3rdparty/zstd)
INCLUDE_DIRECTORIES(/usr/local/include)

# CORE LIB
FILE(GLOB CORE_SRC src/xxx/*.cpp
        src/xxx/io/*.cpp
        src/xxx/util/*.cpp
        src/xxx/thread/*.cpp)
LIST(REMOVE_ITEM CORE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/xxx/io/BzipStream.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/src/xxx/io/GzipStream.cpp)

# This works
ADD_LIBRARY(xxx-core STATIC ${CORE_SRC})
# This doesn't
#ADD_LIBRARY(xxx-core SHARED ${CORE_SRC})
错误消息是:

[100%] Linking CXX shared library libxxxdb-core.dylib
Undefined symbols for architecture x86_64:
  "_mpool_get_global", referenced from:
      xxx::mpoolxx<xxx::alloc_to_mpool_bridge<xxx::mpoolxx<long>, 1>::MemBlock>::get_vtab() in trb_cxx.cpp.o
  "_sfixed_mpool_destroy", referenced from:
      xxx::fixed_mpool_wrapper<24>::~fixed_mpool_wrapper() in trb_cxx.cpp.o
  "_sfixed_mpool_init", referenced from:
      xxx::fixed_mpool_wrapper<24>::fixed_mpool_wrapper() in trb_cxx.cpp.o
  "_trb_destroy", referenced from:
      xxx::trbstrmap_imp<int, unsigned char, &(xxx_trb_compare_less_tag), xxx::mpoolxx<long>, 0, 16>::~trbstrmap_imp() in trb_cxx.cpp.o
      xxx::trbtab<int const, std::__1::pair<int const, int>, 0, &(xxx_trb_compare_less_tag), xxx::fixed_mpoolxx<long>, 0, 16>::~trbtab() in trb_cxx.cpp.o
  "_trb_erase", referenced from:
      xxx::trbtab<int const, std::__1::pair<int const, int>, 0, &(xxx_trb_compare_less_tag), xxx::fixed_mpoolxx<long>, 0, 16>::erase(int const&) in trb_cxx.cpp.o
      xxx::trbtab<int const, std::__1::pair<int const, int>, 0, &(xxx_trb_compare_less_tag), xxx::fixed_mpoolxx<long>, 0, 16>::erase(xxx::trb_iterator<std::__1::pair<int const, int>, 16, 0>) in trb_cxx.cpp.o
  "_trb_iter_first", referenced from:
      xxx::trbtab<int const, std::__1::pair<int const, int>, 0, &(xxx_trb_compare_less_tag), xxx::fixed_mpoolxx<long>, 0, 16>::begin() const in trb_cxx.cpp.o
  "_trb_iter_next", referenced from:
      xxx::trb_iterator<std::__1::pair<int const, int>, 16, 0>::operator++() in trb_cxx.cpp.o
  "_trb_probe", referenced from:
      xxx::trbtab<int const, std::__1::pair<int const, int>, 0, &(xxx_trb_compare_less_tag), xxx::fixed_mpoolxx<long>, 0, 16>::insert(std::__1::pair<int const, int> const&) in trb_cxx.cpp.o
      xxx::trbmap<int, int, &(xxx_trb_compare_less_tag), xxx::fixed_mpoolxx<long>, 0, 16>::operator[](int const&) in trb_cxx.cpp.o
  "_trb_probe_node", referenced from:
      xxx::trbstrmap_imp<int, unsigned char, &(xxx_trb_compare_less_tag), xxx::mpoolxx<long>, 0, 16>::probe_raw(char const*, unsigned long, char const*) in trb_cxx.cpp.o
  "_trb_vtab_init", referenced from:
      xxx::trbxx_vtab_init_by_cxx_type(trb_vtab*, field_type_t, int (*)(trb_vtab const*, trb_tree const*, void const*, void const*), int (*)(trb_vtab const*, trb_tree const*, void const*, void const*)) in trb_cxx.cpp.o
      xxx::trbxx_vtab_init(trb_vtab*, field_type_t, int (*)(trb_vtab const*, trb_tree const*, void const*, void const*)) in trb_cxx.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[100%]链接CXX共享库libxxxdb-core.dylib
架构x86_64的未定义符号:
“\u mpool\u get\u global”,引用自:
xxx::mpoolxx::在trb_cxx.cpp.o中获取_vtab()
“\u sfixed\u mpool\u destroy”,引用自:
xxx::fixed\u mpool\u wrapper::~trb\u cxx.cpp.o中的fixed\u mpool\u wrapper()
“\u sfixed\u mpool\u init”,引用自:
xxx::fixed\u mpool\u wrapper::trb\u cxx.cpp.o中的fixed\u mpool\u wrapper()
“\u trb\u destroy”,引用自:
xxx::trbstrmap_imp::~trbstrmap_imp()位于trb_cxx.cpp.o中
trb_cxx.cpp.o中的xxx::trbtab::~trbtab()
“\u trb\u erase”,引用自:
trb_cxx.cpp.o中的xxx::trbtab::擦除(int const&)
trb_cxx.cpp.o中的xxx::trbtab::erase(xxx::trb_迭代器)
“_trb_iter_first”,引用自:
trb_cxx.cpp.o中的xxx::trbtab::begin()常量
“\u trb\u iter\u next”,引用自:
trb_cxx.cpp.o中的xxx::trb_迭代器::operator++()
“_trb_probe”,引用自:
xxx::trbtab::在trb_cxx.cpp.o中插入(std:u 1::pair const&)
trb_cxx.cpp.o中的xxx::trbmap::operator[](int const&)
“_trb_probe_node”,引用自:
trb_cxx.cpp.o中的xxx::trbstrmap_imp::probe_raw(char const*,unsigned long,char const*)
“_trb_vtab_init”,引用自:
xxx::trbxx_vtab_init_按trb_cxx_类型(trb_vtab*,field_type_t,int(*)(trb_vtab常量*,trb_树常量*,void常量*,void常量*),int(*)(trb_vtab常量*,trb_树常量*,void常量*),在trb_cxx.cpp.o中
xxx::trbxx_vtab_init(trb_vtab*,字段类型,int(*)(trb_vtab const*,trb_tree const*,void const*,void const*)在trb_cxx.cpp.o中
ld:找不到架构x86_64的符号
叮当声:错误:链接器命令失败,退出代码为1(使用-v查看调用)

创建静态库时不会发生链接,因为静态库 不是由链接器生成的:它只是创建的对象文件的存档 和档案管理员在一起。那就不可能了 创建静态库时,可能会出现任何未定义的引用或其他链接错误, 就像创建对象文件的
.tar
.zip
存档一样,不可能存在这样的问题。 看,

链接器和MacOS/Darwin会生成一个共享库,就像一个程序一样 链接器(与GNU/Linux链接器不同)默认情况下不允许使用未定义的符号 共享库中的引用

您有两个选择:

您可以指定
xxx core
依赖于其链接的所有库, 与

或者,您可以使用链接选项覆盖链接器的默认行为 ,表示 加载程序将在运行时解析共享库中未定义的引用。 在CMakeLists.txt中,使用 定义
xxx核心
目标后:

ADD_LIBRARY(xxx-core SHARED ${CORE_SRC})
SET_TARGET_PROPERTIES(xxx-core LINK_FLAGS Wl,-undefined=dynamic_lookup)

静态库实际上是对象文件的集合,它不是真正链接的,创建它时不会出现链接器错误。根据平台的不同,在链接时,共享库可能需要解析所有外部符号。这就是Windows中的情况;创建Windows dll时,需要链接提供错误消息中所示所有这些符号的库。不确定它在Mac上是如何工作的,但可能是一样的。