我真的不想问这个基本问题,但我正在尝试构建一个使用websocketpp
的系统,该系统有望在某个时候部署到Ubuntu服务器上,我想为应用程序使用Boost Logging。我想既然websocketpp
已经需要boost
,我还不如使用它的日志记录。
我目前正在mac上测试设置,因为这就是我的全部。我的项目仍然只是一个main.cpp
文件,它遵循本教程。它看起来像这样:
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
库,该库是我使用几天前运行的brew install boost
链接的。现在我需要为boost::Log构建boost库,但它失败了。
我是如何建立助推的我使用本教程构建了boost,但使用了g++-10
和std=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
我遵循了这条评论的第二条建议,并将所有静态库放在它们自己的名为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
我的驼背
这个SO线程似乎有同样的问题,但使用了cmake
。问题是。。。我确实链接了thread
库。我只是觉得联系不好。我认为问题的一部分是我使用了静态链接。。。我正在尝试优化运行时,我其实并不关心二进制大小。所以我有意使用静态链接。
我想我没有正确地链接库。。。我不是一个完全的C++新手,但我很擅长链接错误。。。我真的不知道这里可能出了什么问题。如有任何帮助,我们将不胜感激。谢谢
更新:(但不是一个干净的解决方案)
所以事实证明有几个问题:
删除和取消链接的自制软件安装版本,这导致了的一些假阴性
我必须链接到静态编译的
.a
文件直接用于CCD_ 20文件。我还必须使用
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:
将boost zip和cd下载到目录中,类似于
boost_1_75_0
(您的版本可能不同)运行
./bootstrap.sh
运行以下操作:
./b2 link=static cxxstd=14 --build-dir=../build --with-log --with-regex --with-random --with-system --with-thread --with-filesystem --with-date_time
*要进行编译,请运行
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
时,链接器默认情况下会尝试查找共享库。只有在找不到它的情况下,它才会查找静态库。
在Boost.Log中,静态库和共享库中的符号被不同地篡改,使它们不兼容。默认情况下,库采用静态链接。为了启用动态链接,在编译使用Boost.Log的代码时,必须定义BOOST_LOG_DYN_LINK
或BOOST_ALL_DYN_LINK
(前者意味着只有Boost.Log动态链接,后者意味着所有Boost库都动态链接)。
其他一些注意事项:
- 您必须确保用于构建Boost的C++标准库与您的应用程序相匹配。例如,您不能用libc++构建Boost,也不能用libstdc++构建代码——这两个标准库定义了不同的符号,并具有不同的ABI,因此您的代码不会与Boost链接
- 您必须确保Boost是使用与您的代码相同或更高版本的C++构建的。否则,您可能无法链接,因为缺少符号(例如,涉及C++11功能的方法在C++03 Boost库中不可用)
- 在构建Boost和代码时,必须确保影响ABI的编译器选项和宏的定义方式相同。否则,您可能会遇到ABI不兼容问题,这很难诊断和调试
- 在
b2
命令行中,应指定不带短划线的-link=static
,并且可以使用cxxstd=14
而不是cxxflags=-std=c++14
- 如果您正在使用Boost。从
boost/log/utility/setup
目录中记录功能,除了boost_log
之外,您可能还需要链接到boost_log_setup
库。boost_log_setup
依赖于boost_log
并提供额外的库设置帮助程序