Bug 2249227

Summary: spdlog headers are broken
Product: [Fedora] Fedora Reporter: Susi Lehtola <susi.lehtola>
Component: spdlogAssignee: Vitaly <vitaly>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 38CC: dimitri.papadopoulos, epel-packagers-sig, logans, thunderbirdtr, vitaly
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2024-04-17 08:18:24 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Susi Lehtola 2023-11-11 14:19:40 UTC
Description of problem:
spdlog header files are broken. The failure can be triggered by trying to compile the test program

hello.cpp:
#include <spdlog/spdlog.h>
int main(void) {
  std::cout << "Hello world!\n";
  return 0;
}

$ g++ hello.cpp 
In file included from /usr/include/spdlog/common.h:45,
                 from /usr/include/spdlog/spdlog.h:12,
                 from hello.cpp:1:
/usr/include/spdlog/fmt/fmt.h:27:14: fatal error: spdlog/fmt/bundled/core.h: No such file or directory
   27 | #    include <spdlog/fmt/bundled/core.h>
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.


Version-Release number of selected component (if applicable):
$ rpm -q spdlog
spdlog-1.11.0-5.fc38.x86_64

Comment 1 Dimitri Papadopoulos Orfanos 2024-03-09 14:05:54 UTC
File include/spdlog/common.h looks like this:

	//
	// Include a bundled header-only copy of fmtlib or an external one.
	// By default spdlog include its own copy.
	//
	#include <spdlog/tweakme.h>
	
	#if defined(SPDLOG_USE_STD_FORMAT)  // SPDLOG_USE_STD_FORMAT is defined - use std::format
	    #include <format>
	#elif !defined(SPDLOG_FMT_EXTERNAL)
	    [...]
	    #include <spdlog/fmt/bundled/core.h>
	    #include <spdlog/fmt/bundled/format.h>
	
	#else  // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib
	    #include <fmt/core.h>
	    #include <fmt/format.h>
	#endif

In case SPDLOG_USE_STD_FORMAT is not defined, I suspect SPDLOG_FMT_EXTERNAL should be defined in Linux distributions which ship dependencies such as the ftm library separately, instead of bundling them. Has include/spdlog/tweak.me been updated accordingly?///////////////////////////////////////////////////////////////////////////////

	// Uncomment to use your own copy of the fmt library instead of spdlog's copy.
	// In this case spdlog will try to include <fmt/format.h> so set your -I flag
	// accordingly.
	//
	// #define SPDLOG_FMT_EXTERNAL
	///////////////////////////////////////////////////////////////////////////////

Comment 2 Dimitri Papadopoulos Orfanos 2024-03-09 14:39:08 UTC
Looks like an spdlog bug or peculiarity. The spec file appears to be doing the right thing with "-DSPDLOG_FMT_EXTERNAL=ON":

	%build
	%cmake -G Ninja \
	    -DCMAKE_INSTALL_LIBDIR=%{_lib} \
	    -DCMAKE_BUILD_TYPE=Release \
	    -DSPDLOG_BUILD_SHARED=ON \
	    -DSPDLOG_BUILD_EXAMPLE=OFF \
	    -DSPDLOG_BUILD_BENCH=OFF \
	    -DSPDLOG_BUILD_TESTS=ON \
	    -DSPDLOG_INSTALL=ON \
	    -DSPDLOG_FMT_EXTERNAL=ON
	%cmake_build

The result is:
1. Ninja does not install include/spdlog/fmt/bundled. However, it does install include/spdlog/fmt. Isn't that an issue by itself?
2. File include/spdlog/tweakme.h is not modified by the build process. I think it needs to be specifically tweaked.

Comment 3 Dimitri Papadopoulos Orfanos 2024-03-09 14:52:42 UTC
Concerning item 1, the build system install include/spdlog/fmt by design:

	    if(NOT SPDLOG_USE_STD_FORMAT AND NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
	        install(DIRECTORY include/${PROJECT_NAME}/fmt/bundled/
	                DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/fmt/bundled/")
	    endif()

Concerning item 2, it would be nice to tweak include/spdlog/tweakme.h. Ubuntu does that:

	///////////////////////////////////////////////////////////////////////////////
	// Uncomment to use your own copy of the fmt library instead of spdlog's copy.
	// In this case spdlog will try to include <fmt/format.h> so set your -I flag
	// accordingly.
	//
	#define SPDLOG_FMT_EXTERNAL 1
	///////////////////////////////////////////////////////////////////////////////

But then the intent is to use pkgconfig I guess, which does suggest to define macro constants accordingly:

	CFlags: -I${includedir} -DSPDLOG_SHARED_LIB -DSPDLOG_COMPILED_LIB -DSPDLOG_FMT_EXTERNAL
	Libs: -L${libdir} -lspdlog -pthread

So in you case, try:

	g++ `pkg-config spdlog --cflags` hello.cpp `pkg-config spdlog --libs`

Still, it would be nice to tweak include/spdlog/tweakme.h like Ubuntu does.

Comment 4 Vitaly 2024-04-17 08:18:24 UTC
> But then the intent is to use pkgconfig I guess, which does suggest to define macro constants accordingly:

You should always use pkg-config or cmake to ensure the correct compiler flags are set.

> Still, it would be nice to tweak include/spdlog/tweakme.h like Ubuntu does.

This file should be auto-generated by CMake. Please report this issue to upstream.