如何使用 fmt 库而不获取“架构 x86_64 的未定义符号”

Posted

技术标签:

【中文标题】如何使用 fmt 库而不获取“架构 x86_64 的未定义符号”【英文标题】:How to use the fmt library without getting "Undefined symbols for architecture x86_64" 【发布时间】:2019-06-15 08:20:41 【问题描述】:

我正在尝试在我的 c++ 项目中使用 fmt (https://github.com/fmtlib/fmt) 格式化头库。

我在主文件顶部添加了核心头文件的路径,如下所示:

#include "../third_party/fmt/core.h"

但是当我尝试调用任何函数时:

string message = fmt::format("The answer is ", 42);

我收到以下错误:

Undefined symbols for architecture x86_64:
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > fmt::v5::internal::vformat<char>(fmt::v5::basic_string_view<char>, fmt::v5::basic_format_args<fmt::v5::buffer_context<char>::type>)", referenced from:
      std::__1::basic_string<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type, std::__1::char_traits<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type>, std::__1::allocator<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type> > fmt::v5::format<char [17], int>(char const (&) [17], int const&) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [main] Error 1
make[1]: *** [CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

我不确定如何使用它,因为这是我过去使用其他头库的方式,例如 cxxopts。任何帮助将不胜感激!

【问题讨论】:

不问显而易见的问题,但你定义了FMT_HEADER_ONLY吗? 问显而易见的问题总是一个好主意 请生成minimal reproducible example。不仅仅是一行代码。一个(非常)简短但完整的程序以及您的编译器标志是必须的。 @PeterT 不,我没有。有这玩意的菜鸟。我实际上并没有看到需要在文档中定义。我看到github自述文件中有一行关于它。这对于头库来说很常见吗?感谢您的帮助! @CoderCal 是的,仅标头库通常使用预处理器定义进行配置或基本上甚至编译。对于所有翻译单元,或者有时他们要求定义只在一个翻译单元内完成(实现所在的位置)。 【参考方案1】:

您应该链接fmt 库或使用optional header-only mode。

例如,如果您有文件test.cc

#include <fmt/core.h>

int main() 
  fmt::print("The answer is .", 42);

你可以用gcc编译链接:

g++ -std=c++11 test.cc -lfmt

【讨论】:

您能介意一些关于如何使用可选的仅标头模式的 sn-ps 吗?我想使用fmt::format("The answer is ", 42); 在您提供的链接之后,我仍然对如何使用仅标头模式没有太多想法。您的意思是我们可以为“可选仅标头模式”执行gcc -I[the directory to header files] src/format.cc my-test.cpp 吗?其中my-test.cpp 包括fmt/core.h, fmt/format.h, fmt/format-inl.h 用法几乎相同,唯一的区别是你应该包括fmt/format.h而不是fmt/core.h【参考方案2】:

我正在使用 Mac,但我没有意识到您可以使用 brew 安装库。它出现在page 的末尾。我整个晚上都在处理符号错误,我不确定我的所有问题都与构建过程有关。编译过程也无法正常工作。

安装库的路径是:/usr/local/include/usr/local/lib

我正在使用g++-11 来构建我的项目,此说明对我有用:

g++-11 -std=c++20 -I/usr/local/include -L/usr/local/lib -lfmt main.cpp -o main

唯一的问题是它只能部分工作。它适用于print

fmt::print("Don't !\n", "panic");

但使用format 会中断:

fmt::format("Don't !\n", "panic");

我遗漏了一些东西,但我不确定是什么。

顺便说一句,如果您使用的是 VSCode,您可以在您的 .vscode 文件夹中创建一个 c_cpp_properties.json 并添加标题的包含路径。


  "includePath": [
    [...],
    "/usr/local/include/"
  ],

不确定这是否与您的情况有关,但希望对您有所帮助。

【讨论】:

【参考方案3】:

根据@vitaut's answer 中的评论,如果您将#include 行从此更改:

#include "../third_party/fmt/core.h"

到这里:

#include "../third_party/fmt/format.h"

它将导致代码以“仅头文件模式”编译,您无需更改构建过程即可在 fmt 库中进行编译和链接。

【讨论】:

以上是关于如何使用 fmt 库而不获取“架构 x86_64 的未定义符号”的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 错误 - 架构 x86_64 的未定义符号?

QT-creator 中架构 x86_64 的未定义符号

解决警告:没有规则来处理架构 x86_64 的文件

如何解决 NSScanner 上的“架构 x86_64 的未定义符号”? react-native 中的 Swift pod

Cordova - 架构 x86_64 的未定义符号

架构 x86_64 的未定义符号,颤振 ios