概述
当我想把spdlog加入到我的Linux QT项目工程中去,用于做Log服务,但是当我编译时出现了奇怪的问题:
ld链接报了两个错:
/usr/bin/ld: /home/zzh/WeyeDataHub/linux_build/RadarSimSystem/../../linux_output/release/x64/weye_log/libweye_log.so: undefined reference to `fmt::SystemError::init(int, fmt::BasicCStringRef<char>, fmt::ArgList)'
/usr/bin/ld: /home/zzh/WeyeDataHub/linux_build/RadarSimSystem/../../linux_output/release/x64/weye_log/libweye_log.so: undefined reference to `fmt::report_system_error(int, fmt::BasicStringRef<char>)'
我当时还在纳闷,为什么会出现没有定义这种情况,我去看了spdlog源码,发现report_system_error和init都是定义并且实现了的。
最后我注意到了这个函数的定义
FMT_API void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
这段代码位于fmt/bundled/format.h当中大概是4023行。
我去看了一下FMT_API的宏定义
#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
#ifdef FMT_EXPORT
#define FMT_API __declspec(dllexport)
#elif defined(FMT_SHARED)
#define FMT_API __declspec(dllimport)
#endif
#endif
#ifndef FMT_API
#define FMT_API
#endif
首先就是一大堆条件宏
这段很简单就是先判断FMT_HEADER_ONLY是否定义并且逻辑取反,就是不定义时为true,同时需要又__WIN32这个宏的存在
因为当时是Linux环境所以这段宏基本上不会进去
而后又判断FMT_SHARED这个宏是否存在我查阅了源代码也是不存在的,所以这里也进不去。
所以这里基本是没有问题的。
那么我又看到实现里不是使用FMT_API的宏,而是FMT_FUNC,我就去查了一下这个宏的定义
#ifdef FMT_HEADER_ONLY
#define FMT_FUNC inline
#include "format.cc"
#else
#define FMT_FUNC
#endif
我发现每次FMT_FUNC都会被定义出来,为inline内联函数,如果是内联函数那么编译器就会对这段代码进行展开,就不会有函数名称,所以就间接导致无法导出函数,产生了这个原因,所以我给这两个函数前面的FMT_FUNC去掉了发现编译没问题了。
为此我加了条件宏,如果为linux环境则不加FMT_FUNC,否则加上,至少我要保证我的平台是正常编译的。
最后
以上就是傲娇灰狼为你收集整理的spdlog: undefined reference to `fmt::SystemError::init(int, fmt::BasicCStringRef<char>, fmt::ArgList的全部内容,希望文章能够帮你解决spdlog: undefined reference to `fmt::SystemError::init(int, fmt::BasicCStringRef<char>, fmt::ArgList所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复