Repository: conan-io/conan-center-index

Issue:
[package] spdlog/1.6.1: embedded fmt conflicts with conan fmt 
<!-- 
  Please don't forget to update the issue title.
  Include all applicable information to help us reproduce your problem.
-->

### Package and Environment Details (include every applicable attribute)
  * Package Name/Version: **spdlog/1.6.1**
  * Operating System+version: **Windows 10**
  * Compiler+version: **MSVC 2019**
  * Conan version: **conan 1.26.0**
  * Python version: **Python 3.7.2**


### Conan profile (output of `conan profile show default` or `conan profile show <profile>` if custom profile is in use)
```
[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=Visual Studio
compiler.version=16
build_type=Release
[options]
[build_requires]
[env]
```


### Steps to reproduce (Include if Applicable)
* create a conan file with a requirement on fmt/7.0.1 and spdlog/1.6.1
* when building spdlog gets an error because it embeds fmt/6.2.1
* workaround is to use fmt/6.2.1

This one is admittedly a bit weird...it's really a library problem but it can potentially be fixed in the recipe. I guess the most you can hope for is that spdlog pulls in fmt/6.2.1 via a conan requirement, and then you get a nice error message from conan saying there's a conflict rather than trying to extract the real problem from the compilation errors.



Discussion:

Resolving patch:
diff --git a/recipes/spdlog/all/conanfile.py b/recipes/spdlog/all/conanfile.py
--- a/recipes/spdlog/all/conanfile.py
+++ b/recipes/spdlog/all/conanfile.py
@@ -11,7 +11,7 @@ class SpdlogConan(ConanFile):
     homepage = "https://github.com/gabime/spdlog"
     topics = ("conan", "spdlog", "logging", "header-only")
     license = "MIT"
-    exports_sources = ["CMakeLists.txt", "patches/*"]
+    exports_sources = ["CMakeLists.txt"]
     generators = "cmake", "cmake_find_package"
     settings = "os", "arch", "compiler", "build_type"
     options = {"shared": [True, False],
@@ -48,7 +48,9 @@ def configure(self):
             raise ConanInvalidConfiguration("wchar is not yet supported under windows")
 
     def requirements(self):
-        if Version(self.version) >= "1.5.0":
+        if Version(self.version) >= "1.7.0":
+            self.requires("fmt/7.0.1")
+        elif Version(self.version) >= "1.5.0":
             self.requires("fmt/6.2.0")
         else:
             self.requires("fmt/6.0.0")
@@ -68,6 +70,7 @@ def _configure_cmake(self):
         self._cmake.definitions["SPDLOG_BUILD_TESTS_HO"] = False
         self._cmake.definitions["SPDLOG_BUILD_BENCH"] = False
         self._cmake.definitions["SPDLOG_FMT_EXTERNAL"] = True
+        self._cmake.definitions["SPDLOG_FMT_EXTERNAL_HO"] = self.options["fmt"].header_only
         self._cmake.definitions["SPDLOG_BUILD_SHARED"] = not self.options.header_only and self.options.shared
         self._cmake.definitions["SPDLOG_WCHAR_SUPPORT"] = self.options.wchar_support
         self._cmake.definitions["SPDLOG_WCHAR_FILENAMES"] = self.options.wchar_filenames
@@ -82,19 +85,24 @@ def _disable_werror(self):
         tools.replace_in_file(os.path.join(self._source_subfolder, "cmake", "utils.cmake"), "/WX", "")
 
     def build(self):
+        if tools.Version(self.version) < "1.7" and tools.Version(self.deps_cpp_info["fmt"].version) >= 7:
+            raise ConanInvalidConfiguration("The project spdlog/{} requires fmt <7.x".format(self.version))
+
         self._disable_werror()
-        if self.options.header_only:
-            tools.patch(**self.conan_data["patches"][self.version])
-        cmake = self._configure_cmake()
-        cmake.build()
+        if not self.options.header_only:
+            cmake = self._configure_cmake()
+            cmake.build()
 
     def package(self):
         self.copy("LICENSE", dst="licenses", src=self._source_subfolder)
-        cmake = self._configure_cmake()
-        cmake.install()
-        tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
-        tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
-        tools.rmdir(os.path.join(self.package_folder, "lib", "spdlog", "cmake"))
+        if self.options.header_only:
+            self.copy(pattern="*.h", dst="include", src=os.path.join(self._source_subfolder, "include"))
+        else:
+            cmake = self._configure_cmake()
+            cmake.install()
+            tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
+            tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
+            tools.rmdir(os.path.join(self.package_folder, "lib", "spdlog", "cmake"))
 
     def package_id(self):
         if self.options.header_only:
@@ -102,15 +110,22 @@ def package_id(self):
 
     def package_info(self):
         if self.options.header_only:
-            self.cpp_info.defines = ["SPDLOG_FMT_EXTERNAL"]
+            component_name = "spdlog_header_only"
+        else:
+            component_name = "libspdlog"
+            self.cpp_info.components["libspdlog"].libs = tools.collect_libs(self)
+            self.cpp_info.components["libspdlog"].defines.append("SPDLOG_COMPILED_LIB")
+            
+        self.cpp_info.components[component_name].defines.append("SPDLOG_FMT_EXTERNAL")
+        if self.options["fmt"].header_only:
+            self.cpp_info.components[component_name].requires = ["fmt::fmt"]
         else:
-            self.cpp_info.libs = tools.collect_libs(self)
-            self.cpp_info.defines = ["SPDLOG_COMPILED_LIB", "SPDLOG_FMT_EXTERNAL"]
+            self.cpp_info.components[component_name].requires = ["fmt::fmt-header-only"]
         if self.options.wchar_support:
-            self.cpp_info.defines.append("SPDLOG_WCHAR_TO_UTF8_SUPPORT")
+            self.cpp_info.components[component_name].defines.append("SPDLOG_WCHAR_TO_UTF8_SUPPORT")
         if self.options.wchar_filenames:
-            self.cpp_info.defines.append("SPDLOG_WCHAR_FILENAMES")
+            self.cpp_info.components[component_name].defines.append("SPDLOG_WCHAR_FILENAMES")
         if self.options.no_exceptions:
-            self.cpp_info.defines.append("SPDLOG_NO_EXCEPTIONS")
+            self.cpp_info.components[component_name].defines.append("SPDLOG_NO_EXCEPTIONS")
         if self.settings.os == "Linux":
-            self.cpp_info.system_libs = ["pthread"]
+            self.cpp_info.components[component_name].system_libs = ["pthread"]


Test patch:
diff --git a/recipes/spdlog/all/test_package/CMakeLists.txt b/recipes/spdlog/all/test_package/CMakeLists.txt
--- a/recipes/spdlog/all/test_package/CMakeLists.txt
+++ b/recipes/spdlog/all/test_package/CMakeLists.txt
@@ -1,8 +1,6 @@
 cmake_minimum_required(VERSION 2.8.11)
 project(test_package)
 
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-
 include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
 conan_basic_setup()