我已经使用boost日志制作了一个自定义的接收器。我一直在Windows11.4的另一个项目中使用它,现在我在另一个项目中使用了它的精简变体,它将(必须)运行在FreeBSD 11.4上。为了支持在Windows/Linux/FreeBSD上构建,我切换到了cmake版本。我可以在Windows (CentOS8)和FreeBSD 12.2上编译和链接静态和动态。然而,在FreeBSD 11.2上,我在使用静态链接时遇到了链接问题。
我使用的是Boost1.74,并且我已经使用bootstrap和b2对clang编译器进行了源代码编译。我使用cmake 1.74root作为-DBOOST_ROOT=boost参数来指定boost根。
我做了一个最小的cmake项目,它使用我的水槽来排除任何其他问题。当尝试静态链接时,我得到以下错误:
usr/local/bin/cmake -E cmake_link_script CMakeFiles/logtest.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/logtest.dir/logtest.cpp.o CMakeFiles/logtest.dir/applogger.cpp.o -o logtest /home/user/dev/boost/lib/libboost_log.a /home/user/dev/boost/lib/libboost_log_setup.a /home/user/dev/boost/lib/libboost_filesystem.a /home/user/dev/boost/lib/libboost_thread.a /home/user/dev/boost/lib/libboost_date_time.a -lpthread /home/user/dev/boost/lib/libboost_regex.a /home/user/dev/boost/lib/libboost_chrono.a /home/user/dev/boost/lib/libboost_atomic.a
/home/user/dev/boost/lib/libboost_log_setup.a(default_formatter_factory.o): In function `void boost::log::v2s_mt_posix::type_dispatcher::callback_base::trampoline<boost::log::v2s_mt_posix::aux::anonymous::default_formatter<char>::visitor, boost::log::v2s_mt_posix::aux::id<boost::log::v2s_mt_posix::aux::process> >(void*, boost::log::v2s_mt_posix::aux::id<boost::log::v2s_mt_posix::aux::process> const&)':
default_formatter_factory.cpp:(.text._ZN5boost3log12v2s_mt_posix15type_dispatcher13callback_base10trampolineINS1_3aux9anonymous17default_formatterIcE7visitorENS5_2idINS5_7processEEEEEvPvRKT0_[_ZN5boost3log12v2s_mt_posix15type_dispatcher13callback_base10trampolineINS1_3aux9anonymous17default_formatterIcE7visitorENS5_2idINS5_7processEEEEEvPvRKT0_]+0xd): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >& boost::log::v2s_mt_posix::aux::operator<< <char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, boost::log::v2s_mt_posix::aux::id<boost::log::v2s_mt_posix::aux::process> const&)'
/home/user/dev/boost/lib/libboost_log_setup.a(default_formatter_factory.o): In function `void boost::log::v2s_mt_posix::type_dispatcher::callback_base::trampoline<boost::log::v2s_mt_posix::aux::anonymous::default_formatter<wchar_t>::visitor, boost::log::v2s_mt_posix::aux::id<boost::log::v2s_mt_posix::aux::process> >(void*, boost::log::v2s_mt_posix::aux::id<boost::log::v2s_mt_posix::aux::process> const&)':
default_formatter_factory.cpp:(.text._ZN5boost3log12v2s_mt_posix15type_dispatcher13callback_base10trampolineINS1_3aux9anonymous17default_formatterIwE7visitorENS5_2idINS5_7processEEEEEvPvRKT0_[_ZN5boost3log12v2s_mt_posix15type_dispatcher13callback_base10trampolineINS1_3aux9anonymous17default_formatterIwE7visitorENS5_2idINS5_7processEEEEEvPvRKT0_]+0x11): undefined reference to `std::__1::basic_ostream<wchar_t, std::__1::char_traits<wchar_t> >& boost::log::v2s_mt_posix::aux::operator<< <wchar_t, std::__1::char_traits<wchar_t> >(std::__1::basic_ostream<wchar_t, std::__1::char_traits<wchar_t> >&, boost::log::v2s_mt_posix::aux::id<boost::log::v2s_mt_posix::aux::process> const&)'
c++: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeLists.txt内容:
project(logtest)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED
COMPONENTS
log
log_setup
)
add_executable(logtest)
target_sources(logtest PRIVATE logtest.cpp applogger.h applogger.cpp)
target_link_libraries(logtest PRIVATE Boost::log)
# Dynamic linking works
#target_compile_definitions(logtest PRIVATE BOOST_LOG_DYN_LINK=1)
applogger.h:
#pragma once
#include <boost/log/attributes/mutable_constant.hpp>
#include <boost/log/core.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/manipulators/add_value.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <string>
#include <vector>
#include <iostream>
namespace appLogger
{
const uint32_t no_log = 0;
const uint32_t console_log = 1;
const uint32_t use_ram_log = 2;
} // namespace AppLogger
namespace sinks = boost::log::sinks;
BOOST_LOG_GLOBAL_LOGGER(
sysLogger,
boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>)
class AppLogger
{
public:
/// Init with default info level logging
static void init(
uint32_t logSink = appLogger::no_log,
boost::log::trivial::severity_level level = boost::log::trivial::error);
/// Disable logging
static void disable();
// Flush log
static void flushLogs();
// Convert file path to only the filename
static std::string path_to_filename(std::string path)
{
return path.substr(path.find_last_of("/\\") + 1);
}
// Set Log level
static void setLogLevel(int32_t level);
};
#define LOG_LOG_LOCATION(LOGGER, LEVEL, ARG) \
BOOST_LOG_SEV(LOGGER, boost::log::trivial::LEVEL) \
<< boost::log::add_value("Line", std::to_string(__LINE__)) \
<< boost::log::add_value("File", AppLogger::path_to_filename(__FILE__)) << ARG
// System Log macros.
// TRACE < DEBUG < INFO < WARN < ERROR < FATAL
#define LOG_TRACE(ARG) LOG_LOG_LOCATION(sysLogger::get(), trace, ARG);
#define LOG_DEBUG(ARG) LOG_LOG_LOCATION(sysLogger::get(), debug, ARG);
#define LOG_INFO(ARG) LOG_LOG_LOCATION(sysLogger::get(), info, ARG);
#define LOG_WARN(ARG) LOG_LOG_LOCATION(sysLogger::get(), warning, ARG);
#define LOG_ERROR(ARG) LOG_LOG_LOCATION(sysLogger::get(), error, ARG);
#define LOG_FATAL(ARG) LOG_LOG_LOCATION(sysLogger::get(), fatal, ARG);
applogger.cpp:
// appLogger.cpp
#include "applogger.h"
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/common.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/settings.hpp>
#include <iostream>
#include <string>
BOOST_LOG_GLOBAL_LOGGER_DEFAULT(
sysLogger,
boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level>)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_timestamp, "TimeStamp", boost::log::attributes::timer::value_type)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", boost::log::trivial::severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_file, "File", std::string)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_line, "Line", std::string)
void AppLogger::init(
uint32_t logSink,
boost::log::trivial::severity_level level)
{
boost::log::register_simple_formatter_factory<boost::log::trivial::severity_level, char>(
"Severity");
if(logSink == appLogger::console_log)
{
boost::log::add_console_log(
std::clog,
boost::log::keywords::format =
"[%TimeStamp%] [%ThreadID%] [%Severity%] %File%(%Line%): %Message%");
}
// boost::log::add_common_attributes();
boost::log::core::get()->add_global_attribute("TimeStamp", boost::log::attributes::timer());
boost::log::core::get()->add_global_attribute(
"ThreadID", boost::log::attributes::current_thread_id());
boost::log::core::get()->set_filter(boost::log::trivial::severity >= level);
// Indicate start of logging
LOG_INFO("Log Start");
}
void AppLogger::disable()
{
boost::log::core::get()->set_logging_enabled(false);
}
void AppLogger::flushLogs()
{
boost::log::core::get()->flush();
}
void AppLogger::setLogLevel(int32_t level)
{
boost::log::core::get()->set_filter(boost::log::trivial::severity >= level);
}
logtest.cpp (应用程序):
#include "applogger.h"
#include <boost/log/trivial.hpp>
int main()
{
boost::log::trivial::severity_level logLevel = boost::log::trivial::debug;
AppLogger::init(appLogger::console_log, logLevel);
BOOST_LOG_TRIVIAL(trace) << "Hello Logger";
LOG_DEBUG("Starting Client!")
return 0;
}
有什么想法可以解决这个问题或者进一步解决问题吗?
/Thanks
发布于 2020-12-08 22:03:10
正如安德烈所建议的:这是CMake FindBoost中的一个问题,它对依赖项感到困惑。
修复: Add in CMakeLists.txt: set(_Boost_LOG_SETUP_DEPENDENCIES日志)
我仍然不知道为什么在FreeBSD 12.2中没有这个修复的情况下它可以工作。它使用与11.4 (3.18.3)相同的CMake版本。
https://stackoverflow.com/questions/65187297
复制相似问题