c++ - Target Boost::<library> 已有导入位置 + 链接错误

标签 c++ boost cmake linker

我正在使用 Homebrew 在 MacOS Mojave 上安装 LLVM、Boost 和 CMake。将我的 LLVM 升级到版本 9.0.0 并将 Boost 升级到 1.71.0 后,CMake(v3.15.3)开始提示各种库已经具有导入位置,例如:

CMake Warning at /usr/local/lib/cmake/boost_system-1.71.0/libboost_system-variant-shared.cmake:59 (message):
  Target Boost::system already has an imported location
  '/usr/local/lib/libboost_system-mt.dylib', which will be overwritten with
  '/usr/local/lib/libboost_system.dylib'
Call Stack (most recent call first):
  /usr/local/lib/cmake/boost_system-1.71.0/boost_system-config.cmake:43 (include)
  /usr/local/lib/cmake/Boost-1.71.0/BoostConfig.cmake:117 (find_package)
  /usr/local/lib/cmake/Boost-1.71.0/BoostConfig.cmake:182 (boost_find_component)
  /usr/local/Cellar/cmake/3.15.3/share/cmake/Modules/FindBoost.cmake:443 (find_package)
  src/CMakeLists.txt:673 (find_package)

我的 CMakeLists.txt 的相关部分如下所示:

set(REQUIRED_BOOST_LIBRARIES
    system
    filesystem
    program_options
    date_time
    log_setup
    log
    iostreams
    timer
    thread
)

find_package (Boost 1.65 REQUIRED COMPONENTS ${REQUIRED_BOOST_LIBRARIES} REQUIRED)
message(STATUS "Boost include dir: " ${Boost_INCLUDE_DIR})
    message(STATUS "Boost libraries: " ${Boost_LIBRARIES})
target_include_directories (myproject PUBLIC
        ${Boost_INCLUDE_DIR})
target_link_libraries (myproject ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
check_ipo_supported(RESULT ipo_supported OUTPUT output)
if(ipo_supported)
    set_property(TARGET myproject PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

在成功编译我的项目后,我也遇到了一堆链接错误,例如:

undef: __ZN5boost3log11v2_mt_posix5sinks17text_file_backend7consumeERKNS1_11record_viewERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE
undef: __ZN5boost3log11v2_mt_posix5sinks17text_file_backendD1Ev
undef: __ZN5boost3log11v2_mt_posix3aux17code_convert_implEPKwmRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEmRKNS5_6localeE
undef: __ZNK5boost3log11v2_mt_posix19attribute_value_set4findENS1_14attribute_nameE
...
Undefined symbols for architecture x86_64:
  "boost::log::v2_mt_posix::sinks::text_file_backend::consume(boost::log::v2_mt_posix::record_view const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      boost::log::v2_mt_posix::sinks::synchronous_sink<boost::log::v2_mt_posix::sinks::text_file_backend>::consume(boost::log::v2_mt_posix::record_view const&) in lto.o
      boost::log::v2_mt_posix::sinks::synchronous_sink<boost::log::v2_mt_posix::sinks::text_file_backend>::try_consume(boost::log::v2_mt_posix::record_view const&) in lto.o
  "boost::log::v2_mt_posix::sinks::text_file_backend::~text_file_backend()", referenced from:
      boost::detail::sp_counted_impl_pd<boost::log::v2_mt_posix::sinks::text_file_backend*, boost::detail::sp_ms_deleter<boost::log::v2_mt_posix::sinks::text_file_backend> >::~sp_counted_impl_pd() in lto.o
      boost::detail::sp_counted_impl_pd<boost::log::v2_mt_posix::sinks::text_file_backend*, boost::detail::sp_ms_deleter<boost::log::v2_mt_posix::sinks::text_file_backend> >::~sp_counted_impl_pd() in lto.o
      boost::detail::sp_counted_impl_pd<boost::log::v2_mt_posix::sinks::text_file_backend*, boost::detail::sp_ms_deleter<boost::log::v2_mt_posix::sinks::text_file_backend> >::dispose() in lto.o
  "boost::log::v2_mt_posix::aux::code_convert_impl(wchar_t const*, unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long, std::__1::locale const&)", referenced from:
      void boost::log::v2_mt_posix::type_dispatcher::callback_base::trampoline<boost::log::v2_mt_posix::binder1st<boost::log::v2_mt_posix::output_fun, boost::log::v2_mt_posix::expressions::aux::stream_ref<boost::log::v2_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >&>, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >(void*, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&) in lto.o
...

我查看了 CMake 生成的链接器命令,它似乎选择了非-mt.dylib Boost 库:

clang++ ... /usr/local/lib/libboost_system.dylib /usr/local/lib/libboost_filesystem.dylib /usr/local/lib/libboost_program_options.dylib /usr/local/lib/libboost_date_time.dylib /usr/local/lib/libboost_log_setup.dylib /usr/local/lib/libboost_log.dylib /usr/local/lib/libboost_iostreams.dylib /usr/local/lib/libboost_timer.dylib /usr/local/lib/libboost_thread-mt.dylib /usr/local/lib/libhts.dylib  /usr/local/lib/libboost_filesystem.dylib /usr/local/lib/libboost_date_time.dylib /usr/local/lib/libboost_atomic-mt.dylib /usr/local/lib/libboost_regex.dylib /usr/local/lib/libboost_chrono.dylib

我想这就是 CMake 警告所暗示的。为什么会出现这种情况,可以做什么?

最佳答案

我询问了 Slack 上的 CMake 警告。正如 Peter Dimov 所解释的那样:

this is because homebrew installs both multithreaded and single-threaded boost

in addition, due to an issue in boost 1.71's cmake support, Boost_USE_MULTITHREADED is not respected

I've fixed this for the next release

you can define Boost_NO_BOOST_CMAKE=ON to get around it

参见 https://github.com/boostorg/boost_install/issues/13 , 它应该在下一个版本中修复。

2020 年 1 月 22 日:通过 brew upgrade boostboost 更新到 1.72 并添加 set(Boost_USE_MULTITHREADED TRUE) 我的 CMakeLists.txt 已经为我解决了这个问题。

关于c++ - Target Boost::<library> 已有导入位置 + 链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58081084/

相关文章:

c++ - 使用 boost::mpl 获取 vector 的大小

linux - 用于 boost 的旧 gcc 版本

python - WSL Ubuntu - 制作 libfreenect - CYTHON_EXECUTABLE-NOTFOUND

c++ - 如何将 QListWidget/QStandardItemModel 项目映射到我的逻辑?

c++ - 为什么这个 std::bind 没有转换为 std::function?

c++ - 具有特殊情况实现的迭代器

c++ - Opencv windows 7 cmake mingw-32 报错

iphone - UIView 和 XIB 连接。正在显示吗?

c++ - 命名管道客户端错误 5 (C++)

android-studio - 构建错误 : depfile has multiple output paths ninja: build stopped: subcommand failed