我是靠谱客的博主 傲娇灰狼,最近开发中收集的这篇文章主要介绍spdlog: undefined reference to `fmt::SystemError::init(int, fmt::BasicCStringRef<char>, fmt::ArgList,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

当我想把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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部