psingh
psingh

Reputation: 47

Linking errors with fmt: undefined reference to `std::string fmt::v6::internal::grouping_impl<char>(fmt::v6::internal::locale_ref)'

In our project, we decided to use the latest fmt version(6.2.0) in our project and use mainly the printf functionality as we had our logging where we are using printf extensively.

I built the libfmt.a on our Linux box using the CMakeLists.txt included in the fmt package. In my process, I included the libfmt include directory and in the target_link_libraries. In the code I only used #include<fmt/printf.h>. Now when I compile the code, the code gets compiled but at the time of linking, I get the errors: There are many more but the following is the first one and I believe if this gets resolved, rest will be resolved automatically

abc.cpp:(.text._ZN3fmt2V68internal8groupingIcEESsNS1_10locale_refE[_ZN3fmt2v68internal8groupingIcEESsNS1_10locale_refE]+0X20): undefined eference to `std::string fmt::v6::internal::grouping_impl(fmt::v6::internal::locale_ref)'

I did some analysis and found that this function's definition is present in format-inl.h. I tried including it in my code but still the same linking issue.

Now, when I defined the macro FMT_HEADER_ONLY in the code the linking worked.

My question is: When I am linking with the library libfmt.a, its not able to find that function. Why? I do not want to use the header-only version.

Please let me know how to get this fixed.

Upvotes: 4

Views: 5245

Answers (1)

vitaut
vitaut

Reputation: 55605

The linkage order is important (see https://stackoverflow.com/a/409470/471164). Make sure to pass the library after the source or object files that use it. For example:

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

This example fetches {fmt} from github, compiles it, creates and a small test source, compiles and runs it giving the following output:

Hello, world!

If you pass -lfmt before test.cc you'll get linkage errors.

I recommend using CMake which will take care of the linkage order for you: https://fmt.dev/latest/usage.html#usage-with-cmake

Upvotes: 5

Related Questions