Boost::Log 在 macOS 上找不到体系结构的符号

Boost::Log Symbol not found for architecture on macOS

我真的不想问这个基本问题,但我正在尝试构建一个使用 websocketpp 的系统,希望在某个时候将其部署到 Ubuntu 服务器,我想要为应用程序使用 Boost Logging。我想既然 websocketpp 已经需要 boost,我不妨使用它的日志记录。

我目前正在 mac 上测试设置,因为我只有这些。我的项目仍然只是一个 main.cpp 文件,它遵循 this tutorial。它看起来像这样:

main.cpp

#include <iostream>

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/expressions.hpp>

namespace logging = boost::log;

void init_logging(const char * logger_filename)
{
    logging::add_file_log(logger_filename);

    logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);
}


int main(int, char*[]) {
    init_logging("titan_logger.log");
    BOOST_LOG_TRIVIAL(trace) << "This is a trace severity message";
    BOOST_LOG_TRIVIAL(debug) << "This is a debug severity message";
    BOOST_LOG_TRIVIAL(info) << "This is an informational severity message";
    BOOST_LOG_TRIVIAL(warning) << "This is a warning severity message";
    BOOST_LOG_TRIVIAL(error) << "This is an error severity message";
    BOOST_LOG_TRIVIAL(fatal) << "and this is a fatal severity message";
    std::cin.get();
    return 0;
} 

在我想使用文件记录器之前,我一直在成功地学习教程。然后我开始收到这样结束的错误:

...
traits<wchar_t>, std::__1::allocator<wchar_t> > >, boost::log::v2s_mt_posix::fallback_to_none>::operator()<boost::log::v2s_mt_posix::binder1st<boost::log::v2s_mt_posix::output_fun, boost::log::v2s_mt_posix::expressions::aux::stream_ref<boost::log::v2s_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >&> >(boost::log::v2s_mt_posix::attribute_name const&, boost::log::v2s_mt_posix::attribute_value_set const&, boost::log::v2s_mt_posix::binder1st<boost::log::v2s_mt_posix::output_fun, boost::log::v2s_mt_posix::expressions::aux::stream_ref<boost::log::v2s_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >&>) const in main.o
      boost::log::v2s_mt_posix::value_extractor<boost::log::v2s_mt_posix::trivial::severity_level, boost::log::v2s_mt_posix::fallback_to_none, boost::log::v2s_mt_posix::trivial::tag::severity>::operator()(boost::log::v2s_mt_posix::attribute_name const&, boost::log::v2s_mt_posix::attribute_value_set const&) const in main.o
  "boost::log::v2s_mt_posix::aux::once_block_sentry::enter_once_block() const", referenced from:
      boost::log::v2s_mt_posix::aux::once_block_sentry::executed() const in main.o
  "boost::log::v2s_mt_posix::core::get_logging_enabled() const", referenced from:
      boost::log::v2s_mt_posix::record boost::log::v2s_mt_posix::sources::basic_composite_logger<char, boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level>, boost::log::v2s_mt_posix::sources::multi_thread_model<boost::log::v2s_mt_posix::aux::light_rw_mutex>, boost::log::v2s_mt_posix::sources::features<boost::log::v2s_mt_posix::sources::severity<boost::log::v2s_mt_posix::trivial::severity_level> > >::open_record<boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > >(boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > const&) in main.o
ld: symbol(s) not found for architecture x86_64

我猜我正在使用 boost 库,几天前我 link 使用 brew install boost 运行 编辑了它。现在我需要为 Boost::Log 构建的增强库,它失败了。

我是如何建立提升的

我使用 this tutorial 构建了 boost,但使用了 g++-10std=c++14

我下载了 boost_1_75_0 并将其放在我的项目目录中,然后我 运行 (来自项目目录)的完整命令是:

cd boost_1_75_0

./bootstrap.sh

./b2 -link=static toolset=gcc cxxflags=-std=c++14 --build-dir=../build --with-log --with-regex --with-random --with-system --with-thread --with-filesystem --with-date_time

我听从了this comment的第二个建议,将所有静态库放在它们自己的名为lib_boost的文件夹中。该应用程序名为 Titan,这就是下面命令中的含义。

make 命令:

g++ -Wall -I/Users/QuantumHoneybees/Desktop/Titan/Titan/boost_1_75_0 -std=c++14 -lpthread main.cpp -o titan -L./lib_boost  -lboost_log_setup-mt   -lboost_log-mt -lboost_filesystem-mt  -lboost_thread-mt -lboost_system-mt

我的直觉

似乎有同样的问题,但使用 cmake。问题是……我确实有 thread 库 linked。我只是认为 link 编辑得不正确。我认为部分问题是我正在使用静态 linking...我正在尝试优化 运行 时间,我并不真正关心二进制大小。所以我有意使用静态 linking.

我认为我没有 link 正确地使用库...我不是 C++ 的完全新手,但我很讨厌 link 错误...我真的不'知道这里可能是什么问题。任何帮助,将不胜感激。谢谢。


更新:(虽然不是一个干净的解决方案)

所以事实证明存在一些问题:

  1. 删除并取消linked 自制软件安装版本,这导致了一些误报

  2. 我不得不link到静态编译的.a文件 直接获取 boost_log 文件。

  3. 我还必须使用 clang 重建 Boost 并切换 make 以使用它

这是最后的(非常难看的)命令:

clang++ -Wall -I/Users/QH/Desktop/Titan/Titan/boost_1_75_0 -std=c++14 -lpthread main.cpp -o titan -L/Users/QH/Desktop/Titan/Titan/boost_1_75_0/stage/lib -lboost_system -lboost_thread -lboost_thread -lboost_filesystem /Users/QH/Desktop/Titan/Titan/boost_1_75_0/stage/lib/libboost_log.a

它有效,但显示了很多关于导致错误的相同 boost::log::v2s_mt_posix:: 方法的警告,但老实说,我现在不关心修复它们。

出于某种原因,如果我用 -lboost_log 替换最后一个库,我会再次遇到相同的未定义引用错误。我希望能帮助别人回答!


对于未来的旅行者,这里是全套工作步骤(感谢@AndreySemashev:

  1. 将boost zip和cd下载到目录中,类似于boost_1_75_0(您的版本可能不同)

  2. 运行 ./bootstrap.sh

  3. 运行 以下:./b2 link=static cxxstd=14 --build-dir=../build --with-log --with-regex --with-random --with-system --with-thread --with-filesystem --with-date_time*

  4. 编译,运行clang++ -Wall -I./boost_1_75_0 -std=c++14 -lpthread main.cpp -o titan -L./boost_1_75_0/stage/lib -lboost_system -lboost_thread -lboost_thread -lboost_filesystem -lboost_log_setup -lboost_log

当您指定 -lboost_log 时,linker 默认会尝试查找共享库。只有没有找到,它才会寻找静态库。

在 Boost.Log 中,静态库和共享库中的符号被破坏 differently 以使其不兼容。默认情况下,库采用静态 linking。为了启用动态 linking,您必须在编译使用 Boost.Log 的代码时定义 BOOST_LOG_DYN_LINKBOOST_ALL_DYN_LINK(前者意味着只有 Boost.Log 是 link 动态编辑,后者 - 所有 Boost 库都是 link 动态编辑的)。


其他一些注意事项:

  • 您必须确保用于构建 Boost 的 C++ 标准库与您的应用程序匹配。例如,您不能使用 libc++ 构建 Boost 而使用 libstdc++ 构建代码 - 这两个标准库定义了不同的符号并具有不同的 ABI,因此您的代码不会 link 使用 Boost。
  • 您必须确保 Boost 是使用与您的代码相同或更高版本的 C++ 构建的。否则,您可能无法 link 因为缺少符号(例如,涉及 C++11 特性的方法在 C++03 Boost 库中不可用)。
  • 您必须确保影响 ABI 的编译器选项和宏在构建 Boost 和您的代码时以相同的方式定义。否则,您可能会遇到 ABI 不兼容问题,这些问题很难诊断和调试。
  • b2命令行中,-link=static不带破折号,可以用cxxstd=14代替cxxflags=-std=c++14
  • 如果您使用 boost/log/utility/setup 目录中的 Boost.Log 功能,除了 boost_log 之外,您可能还需要 link 和 boost_log_setup 库。 boost_log_setup 依赖于 boost_log 并提供额外的库设置助手。