9

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"

Ethanabc
  • 311
  • 2
  • 7
  • 1
    I recommend using a build system like CMAKE together with a package manager like vcpkg – bolov Apr 04 '21 at 18:32
  • I believe you cannot. `fmt` builds a static library. You need to add linking. – ALX23z Apr 04 '21 at 18:33
  • @ALX23z fmt does have a header-only version. Check the [documentation](https://fmt.dev/latest/usage.html#header-only-usage-with-cmake) – bolov Apr 04 '21 at 18:34
  • @bolov Thanks for the recommendation on the usage of build system and package manager. Definitely go that route in the future. – Ethanabc Apr 04 '21 at 18:39
  • I think you need to put the library in directory `[trgdir]/fmt`. – Galik Apr 04 '21 at 18:51
  • Are you using literal square braces `[` and `]`? If so you´ll need to escape them on the command line. – Galik Apr 04 '21 at 18:52
  • 1
    You can also replace `gcc-10 -xc++ -lstdc++ -shared-libgcc` with `g++-10`. – rustyx Apr 04 '21 at 18:57
  • @Galik. Re ```[trgdir]/fmt``` Do you mean the header file is the directory ```[trgdir]/fmt/fmt/format.h```? – Ethanabc Apr 04 '21 at 19:00
  • @rustyx 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:``` – Ethanabc Apr 04 '21 at 19:07
  • No. I mean `-I[trgdir]`is prepended to your `#include`statement giving a search path of `[trgdir]/fmt/format.h` to find the file. – Galik Apr 04 '21 at 19:08
  • @Galik I see. I believe my ```fmt``` file is inside ```[targdir] ``` – Ethanabc Apr 04 '21 at 19:25
  • 1
    There is no difference, but `gcc` is a C compiler. You should use `g++` to compile and link a C++ program. – rustyx Apr 04 '21 at 19:26
  • @rustyx. Thank you! – Ethanabc Apr 04 '21 at 19:27

1 Answers1

14

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

#define FMT_HEADER_ONLY
#include "fmt/format.h"
Jovibor
  • 759
  • 2
  • 6
  • 16
  • 1
    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. – Ethanabc Apr 04 '21 at 23:35
  • 3
    @Ethanabc 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. – Jovibor Apr 05 '21 at 00:29
  • 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. – WBuck Jul 08 '21 at 19:20