构建库时的Clang和undefined符号

Mic*_*ael 8 c++ cmake clang

我正在研究一个C++框架,当我在使用Clang的OSX上编译它时会出现一些问题.

首先,我正在使用其他一些库,例如openssl,而clang抱怨我在构建库时没有解决某些符号.它们不应该是:这些库将与最终的二进制文件链接,它不应该发生在中介上.

然后,还有一些方法和变量应该在"客户端"二进制文件中实现...使用GCC,没有问题,但Clang也抱怨这些符号在编译期间无法解决.

怎么会 ?我该怎么办 ?

这是我的CMakeLists.txt,以防有用:

cmake_minimum_required(VERSION 2.8)

project(crails_project)

set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wno-deprecated-declarations -pedantic -DASYNC_SERVER -DSERVER_DEBUG -DUSE_MONGODB_SESSION_STORE")

find_package(cppnetlib REQUIRED)

include_directories(include /usr/local/include ${CPPNETLIB_INCLUDE_DIRS} .)

file(GLOB crails_core
     src/*.cpp)

file(GLOB crails_sql
     src/sql/*.cpp)

file(GLOB crails_mongodb
     src/mongodb/*.cpp)

add_library(crails-core    SHARED ${crails_core})
add_library(crails-sql     SHARED ${crails_sql})
add_library(crails-mongodb SHARED ${crails_mongodb})
Run Code Online (Sandbox Code Playgroud)

这是崩溃的命令:

/usr/bin/c++  -std=c++0x -Wall -Wno-deprecated-declarations -pedantic -DASYNC_SERVER -DSERVER_DEBUG -DUSE_MONGODB_SESSION_STORE -dynamiclib -Wl,-headerpad_max_install_names   -o libcrails-core.dylib -install_name /Users/michael/Personal/crails/build/libcrails-core.dylib CMakeFiles/crails-core.dir/src/assets.cpp.o CMakeFiles/crails-core.dir/src/cgi2params.cpp.o CMakeFiles/crails-core.dir/src/cipher.cpp.o [...]
Run Code Online (Sandbox Code Playgroud)

以下是我得到的两种错误:

架构x86_64的未定义符号:

  "_BIO_ctrl", referenced from:
      Cipher::encode_base64(unsigned char*, unsigned int) const in cipher.cpp.o
Run Code Online (Sandbox Code Playgroud)

第二个:

  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for boost::detail::thread_data_base", referenced from:
      boost::detail::thread_data_base::thread_data_base() in server.cpp.o
Run Code Online (Sandbox Code Playgroud)

Mic*_*ael 12

解决了!Clang需要-undefined dynamic_lookup在编译库时接收忽略缺失符号的选项.

将其添加到CMakeFile.txt以产生预期效果:

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
  set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -undefined dynamic_lookup")
endif()
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好答案,根本不是一个答案。如果您缺少_open,因为它应该是open,则-undefined dynamic_lookup不会解决任何问题。为什么Clang会将这些_添加到没有导出的函数中?我看到应有的东西出现各种错误:_close,_write,_sleep。我是否需要链接一些我不知道的特殊LLVM libc?所使用的函数在没有下划线的情况下使用,并且在/lib/libc-2.27.so中定义,没有!ef在哪里是llvm libc? (2认同)

Bar*_*osz 12

我不建议启用全局动态查找:

-undefined dynamic_lookup 这会将所有未定义的符号标记为必须在运行时查找.

解决特定符号的更安全的方法:

-Wl,-U,symbol_name,仅对给定符号执行此操作(注意:您必须在符号名称前加下划线)

您还可以使用弱动态链接:

extern int SayHello() __attribute__((weak));
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`-undefined dynamic_lookup` 是特定于 OSX 的。Linux 共享库的行为就像一直启用 `-undefined dynamic_lookup` 一样。我不确定 Windows。 (2认同)