0

Good day!
I installed the fmt library in Ubuntu. Added it in my project

#include "fmt/core.h"
#include "fmt/format.h"
#include "fmt/format-inl.h"

to use fmt::format_int и fmt::format. I added library headers in several cpp files of my project. During linkage I got the mistake "multiple definition":

obj/container.o: In function fmt::v7::format_error::~format_error()': container.cpp:(.text+0x40e): multiple definition of fmt::v7::format_error::~format_error()' obj/line.o:line.cpp:(.text+0x40e): first defined here

I've read something about this mistake. It is recommended to divide declaration and implementation in h and cpp files, to set some status to objects that causes mistake and so on. But all this recommendations imply editing of library (not my!) code!
What is wrong?

I do the following
compilation of files - one by one
g++ -std=c++11 -Wall -o obj/line.o -c /home/...//line.cpp
g++ -std=c++11 -Wall -o obj/container.o -c /home/...//container.cpp
g++ -std=c++11 -Wall -o obj/geometryObject.o -c /...//geometryObject.cpp
g++ -std=c++11 -Wall -o obj/model.o -c /home/...//model.cpp
g++ -std=c++11 -Wall -o obj/point.o -c /home/...//point.cpp
g++ -std=c++11 -Wall -o obj/main.o -c /home/...//main.cpp
Linking - error here
g++ -std=c++11 -Wall -o myapp obj/line.o obj/container.o obj/geometryObject.o obj/model.o obj/point.o obj/main.o

  • 1
    How are you, or how is your build system, linking the code? – gspr Jun 08 '21 at 13:03
  • 2
    Dont include "fmt/core.h" and "fmt/format-inl.h", just include fmt/format.h, it will include the other two. – Cortex0101 Jun 08 '21 at 13:10
  • g++ -std=c++11 -Wall -o myapp obj/line.o obj/container.o obj/geometryObject.o obj/model.o obj/point.o obj/main.o – Alexander Vachenko Jun 08 '21 at 13:39
  • I deleted format-inl.h and core.h. But plenty of mistakes "multiple definition" and among them "undefined reference to". It seems the same thing. Didn't make any sense. In official recommendation it is said to include all h files (https://fmt.dev/latest/usage.html). But i think you are 100% right. At least about core.h. – Alexander Vachenko Jun 08 '21 at 13:46
  • What version of the fmt library are you using? The one in your Ubuntu installation, or one that you self-installed? – jjramsey Jun 08 '21 at 14:22
  • Master version from github. – Alexander Vachenko Jun 08 '21 at 14:26
  • How are you installing it? In particular, what are you doing with `src/format.cc`, which is *not* a header file? – jjramsey Jun 08 '21 at 15:11
  • Installation is here (https://fmt.dev/latest/usage.html). cmake + make + sudo make install. I don't have anything to do with *.cc files according to installation procedure. – Alexander Vachenko Jun 08 '21 at 15:25
  • I think you need to edit your question to include more information, then. Include the *exact* steps you used, not only to build the fmt library itself, but also how you tried to compile and link your own code. Without that, we're just stabbing in the dark. You may end up doing some ["rubber duck debugging"](https://rubberduckdebugging.com/) in the process. – jjramsey Jun 08 '21 at 17:29
  • @jjramsey have you tried to use fmt library in several files yourself? – Alexander Vachenko Jun 08 '21 at 18:26
  • No. From Googling around, though, it looks like the problem is that you're `#include`ing `fmt/format-inl.h`. Try removing that, and then compile with the flag `-DFMT_HEADER_ONLY`. – jjramsey Jun 08 '21 at 19:17

1 Answers1

4

You shouldn't be including fmt/format-inl.h because it's an internal header. Please see the documentation for the list of public headers and what they provide.

vitaut
  • 49,672
  • 25
  • 199
  • 336
  • Hey men, I'm sorry for my stupid question and my not attentive reaction on right answers! I followed your advice and "multiple definition" disappeared. Thank you. But I got another mistake - "undefined reference to". I found solution [here](https://github.com/fmtlib/fmt/issues/2157). I'm not professional programmer; could you give me a hint: why #define FMT_HEADER_ONLY should be placed above #include "fmt/format.h"? For what FMT_HEADER_ONLY is needed for? And so on. I just what to understand a general rule of these things - how do they work. – Alexander Vachenko Jun 09 '21 at 15:37
  • @AlexanderVachenko "undefined reference to *what*?" That's the important part. Also, very likely, you shouldn *not* use `FMT_HEADER_ONLY`, lest reading the official documentation says you should. – Marcus Müller Jun 09 '21 at 16:14
  • @AlexanderVachenko If you look at the bottom of the `fmt/format.h` header, you'll see that if `FMT_HEADER_ONLY` is defined, then `FMT_FUNC` is defined as inline, and `fmt/format-inl.h` is then included. It looks like defining `FMT_FUNC` as inline leads to the functions in `fmt/format-inl.h` being inlined--which avoids the "multiple definition" problem. – jjramsey Jun 09 '21 at 17:04
  • Make sure to link the the fmt library (libfmt.a on Linux). – vitaut Jun 09 '21 at 17:36