3

在我们的项目中,我们决定在我们的项目中使用最新的 fmt 版本(6.2.0)并主要使用 printf 功能,因为我们在广泛使用 printf 的地方进行了日志记录。

我使用 fmt 包中包含的 CMakeLists.txt 在我们的 Linux 机器上构建了 libfmt.a。在我的过程中,我包含了 libfmt 包含目录和 target_link_libraries。在我只使用的代码中#include<fmt/printf.h>。现在,当我编译代码时,代码被编译,但在链接时,我得到错误:还有很多,但以下是第一个,我相信如果这个问题得到解决,其余的将自动解决

abc.cpp:(.text._ZN3fmt2V68internal8groupingIcEESsNS1_10locale_refE[_ZN3fmt2v68internal8groupingIcEESsNS1_10locale_refE]+0X20): 对`std::string fmt::v6::internal::grouping_impl(fmtref::v6::internal::locale)的未定义引用

我做了一些分析,发现这个函数的定义存在于format-inl.h中。我尝试将它包含在我的代码中,但仍然存在相同的链接问题。

现在,当我在代码中定义宏FMT_HEADER_ONLY时,链接起作用了。

我的问题是:当我与库 libfmt.a 链接时,它无法找到该函数。为什么?我不想使用仅标题版本。

请让我知道如何解决这个问题。

4

1 回答 1

2

链接顺序很重要(请参阅https://stackoverflow.com/a/409470/471164)。确保在使用它的源文件或目标文件之后传递库。例如:

git clone https://github.com/fmtlib/fmt.git
cd fmt
make fmt
cat <<EOF > test.cc
#include <fmt/printf.h>

int main() {
  fmt::printf("Hello, %s!", "world");
}
EOF
g++ test.cc -L. -lfmt -Iinclude
./a.out

这个例子从 github 获取 {fmt},编译它,创建和一个小的测试源,编译并运行它给出以下输出:

Hello, world!

如果你通过-lfmt之前test.cc你会得到链接错误。

我建议使用 CMake,它将为您处理链接顺序:https ://fmt.dev/latest/usage.html#usage-with-cmake

于 2020-05-05T13:35:29.637 回答