Reputation: 191
I'm trying to use the fmt (https://github.com/fmtlib/fmt) formatting header library in my c++ project.
I've added the path to the core header file at the top of my main file like so:
#include "../third_party/fmt/core.h"
but when I try to call any function like:
string message = fmt::format("The answer is {}", 42);
I get the following error:
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
I'm not sure how to use this as this is how I have used other header libraries in the past such as cxxopts. Any help would be appreciated!
Upvotes: 10
Views: 15593
Reputation: 3253
I'm working on Mac, and I did not realize that you can install the library using brew
. It appears at the end of the page. I have been dealing with symbol errors all evening, and I'm not sure that all my problems were related to the build process. The compiling process was also not working properly.
The paths where the library is installed are: /usr/local/include
and /usr/local/lib
.
I'm using g++-11
to build my project and this instruction works for me:
g++-11 -std=c++20 -I/usr/local/include -L/usr/local/lib -lfmt main.cpp -o main
The only problem is that it works partially. It works fine with print
:
fmt::print("Don't {}!\n", "panic");
But it breaks using format
:
fmt::format("Don't {}!\n", "panic");
I'm missing something, but I'm not sure what.
By the way, if you are using VSCode, you can create a c_cpp_properties.json
into your .vscode
folder and add the include path for the headers.
{
"includePath": [
[...],
"/usr/local/include/"
],
}
Not sure if this is related to your case, but I hope it helps.
Upvotes: 3
Reputation: 3799
From a comment in @vitaut's answer, if you change your #include
line from this:
#include "../third_party/fmt/core.h"
to this:
#include "../third_party/fmt/format.h"
it will cause the code to be compiled in "header-only mode", and you won't need to change your build process to compile and link in the {fmt} library.
Upvotes: 1
Reputation: 55605
You should link with the fmt
library or use the optional header-only mode.
For example, if you have the file test.cc
:
#include <fmt/core.h>
int main() {
fmt::print("The answer is {}.", 42);
}
You can compile and link it with gcc:
g++ -std=c++11 test.cc -lfmt
Upvotes: 6