How to use fmt library in the header-only mode?
Asked Answered
I

1

10

Having a hard time using the header-only mode of fmt library. Here is what I tried in details: I downloaded fmt7.1.3 from https://fmt.dev/latest/index.html, only put the directory fmt-7.1.3/include/fmt in a directory ([trgdir]) and wrote a test.cpp as follow:

#include <iostream>
#include <fmt/format.h>
int main() {
    fmt::format("The answer is {}.", 42);
    return 0;
}

Then in the terminal I use

gcc -I[trgdir] test.cpp

where gcc I defined as

alias gcc='gcc-10 -xc++ -lstdc++ -shared-libgcc -std=c++17 -O2 '

I got the error goes as

Undefined symbols for architecture x86_64:
  "__ZN3fmt2v76detail7vformatB5cxx11ENS0_17basic_string_viewIcEENS0_11format_argsE", referenced from:
      _main in ccEeTo0w.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

I have checked this post but I still cannot solve my issue. How to use the fmt library without getting "Undefined symbols for architecture x86_64"

Intended answered 4/4, 2021 at 18:28 Comment(13)
I recommend using a build system like CMAKE together with a package manager like vcpkgAshwin
I believe you cannot. fmt builds a static library. You need to add linking.Hospitable
@Hospitable fmt does have a header-only version. Check the documentationAshwin
@Ashwin Thanks for the recommendation on the usage of build system and package manager. Definitely go that route in the future.Intended
I think you need to put the library in directory [trgdir]/fmt.Generality
Are you using literal square braces [ and ]? If so you´ll need to escape them on the command line.Generality
You can also replace gcc-10 -xc++ -lstdc++ -shared-libgcc with g++-10.Sher
@Galik. Re [trgdir]/fmt Do you mean the header file is the directory [trgdir]/fmt/fmt/format.h?Intended
@Sher Thank you for the suggestion. Just curiosity, is ``` g++-10``` an equivalent of gcc-10 -xc++ -lstdc++ -shared-libgcc or there is some tiny different? The reason I use gcc-10 is I want to use new features of C++. Back to the question, with the replacement, I still got Undefined symbols for architecture x86_64:Intended
No. I mean -I[trgdir]is prepended to your #includestatement giving a search path of [trgdir]/fmt/format.h to find the file.Generality
@Generality I see. I believe my fmt file is inside [targdir] Intended
There is no difference, but gcc is a C compiler. You should use g++ to compile and link a C++ program.Sher
@rustyx. Thank you!Intended
J
16

You need to define a macro before include, like this:

#define FMT_HEADER_ONLY
#include "fmt/format.h"
Julienne answered 4/4, 2021 at 22:59 Comment(3)
Thank you. You save my day. Finally I can use fmt May I ask how you figure it out? because some library does not need to include #define** such as Eigen.Intended
@Intended You can find it at the very end of the fmt/format.h file. But, frankly saying, I don't understand why it's lacking in the official documentation.Julienne
I just installed fmt via vcpkg and I ran into this same issue. This solved it for me but I'm irritated that this is required in the first place.Steffy

© 2022 - 2024 — McMap. All rights reserved.