Merge pull request #25883 from CrystalP/fix-slowscan
[xbmc.git] / cmake / modules / FindSpdlog.cmake
blob4432acc434775be3fe55753d6447772b3207d890
1 # FindSpdlog
2 # -------
3 # Finds the Spdlog library
5 # This will define the following target:
7 #   ${APP_NAME_LC}::Spdlog   - The Spdlog library
9 macro(buildSpdlog)
10   if(APPLE)
11     set(EXTRA_ARGS "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}")
12   endif()
14   if(WIN32 OR WINDOWS_STORE)
15     set(patches "${CMAKE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/001-windows-pdb-symbol-gen.patch")
16     generate_patchcommand("${patches}")
18     set(EXTRA_ARGS -DSPDLOG_WCHAR_SUPPORT=ON
19                    -DSPDLOG_WCHAR_FILENAMES=ON)
21     set(EXTRA_DEFINITIONS SPDLOG_WCHAR_FILENAMES
22                           SPDLOG_WCHAR_TO_UTF8_SUPPORT)
23   endif()
25   set(SPDLOG_VERSION ${${MODULE}_VER})
26   # spdlog debug uses postfix d for all platforms
27   set(SPDLOG_DEBUG_POSTFIX d)
29   set(CMAKE_ARGS -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}
30                  -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
31                  -DSPDLOG_BUILD_EXAMPLE=OFF
32                  -DSPDLOG_BUILD_TESTS=OFF
33                  -DSPDLOG_BUILD_BENCH=OFF
34                  -DSPDLOG_FMT_EXTERNAL=ON
35                  ${EXTRA_ARGS})
37   # Set definitions that will be set in the built cmake config file
38   # We dont import the config file if we build internal (chicken/egg scenario)
39   set(_spdlog_definitions SPDLOG_COMPILED_LIB
40                           SPDLOG_FMT_EXTERNAL
41                           ${EXTRA_DEFINITIONS})
43   BUILD_DEP_TARGET()
45   add_dependencies(${MODULE_LC} ${APP_NAME_LC}::Fmt)
46 endmacro()
48 if(NOT TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME})
49   include(cmake/scripts/common/ModuleHelpers.cmake)
51   # Check for dependencies - Must be done before SETUP_BUILD_VARS
52   # Todo: We might need a way to do this after SETUP_BUILD_VARS...
53   if(ENABLE_INTERNAL_SPDLOG)
54     get_libversion_data("fmt" "target")
55     find_package(Fmt ${LIB_FMT_VER} MODULE REQUIRED)
56   endif()
58   if(TARGET ${APP_NAME_LC}::Fmt)
59     # Check if we want to force a build due to a dependency rebuild
60     get_property(LIB_FORCE_REBUILD TARGET ${APP_NAME_LC}::Fmt PROPERTY LIB_BUILD)
61   endif()
63   set(MODULE_LC spdlog)
64   SETUP_BUILD_VARS()
66   # Check for existing SPDLOG. If version >= SPDLOG-VERSION file version, dont build
67   find_package(SPDLOG CONFIG QUIET
68                              HINTS ${DEPENDS_PATH}/lib/cmake
69                              ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
71   if((SPDLOG_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_SPDLOG) OR
72      ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_SPDLOG) OR
73      LIB_FORCE_REBUILD)
75     buildSpdlog()
76   else()
77     if(TARGET spdlog::spdlog)
78       # This is for the case where a distro provides a non standard (Debug/Release) config type
79       # eg Debian's config file is spdlogConfigTargets-none.cmake
80       # convert this back to either DEBUG/RELEASE or just RELEASE
81       # we only do this because we use find_package_handle_standard_args for config time output
82       # and it isnt capable of handling TARGETS, so we have to extract the info
83       get_target_property(_SPDLOG_CONFIGURATIONS spdlog::spdlog IMPORTED_CONFIGURATIONS)
84       foreach(_spdlog_config IN LISTS _SPDLOG_CONFIGURATIONS)
85         # Some non standard config (eg None on Debian)
86         # Just set to RELEASE var so select_library_configurations can continue to work its magic
87         string(TOUPPER ${_spdlog_config} _spdlog_config_UPPER)
88         if((NOT ${_spdlog_config_UPPER} STREQUAL "RELEASE") AND
89            (NOT ${_spdlog_config_UPPER} STREQUAL "DEBUG"))
90           get_target_property(SPDLOG_LIBRARY_RELEASE spdlog::spdlog IMPORTED_LOCATION_${_spdlog_config_UPPER})
91         else()
92           get_target_property(SPDLOG_LIBRARY_${_spdlog_config_UPPER} spdlog::spdlog IMPORTED_LOCATION_${_spdlog_config_UPPER})
93         endif()
94       endforeach()
96       get_target_property(SPDLOG_INCLUDE_DIR spdlog::spdlog INTERFACE_INCLUDE_DIRECTORIES)
97     else()
98       find_package(PkgConfig)
99       # Fallback to pkg-config and individual lib/include file search
100       if(PKG_CONFIG_FOUND)
101         pkg_check_modules(PC_SPDLOG spdlog QUIET)
103         # Only add -D definitions. Skip -I include as we do a find_path for the header anyway
104         foreach(_spdlog_cflag IN LISTS PC_SPDLOG_CFLAGS)
105           if(${_spdlog_cflag} MATCHES "^-D(.*)")
106             list(APPEND _spdlog_definitions ${CMAKE_MATCH_1})
107           endif()
108         endforeach()
110         set(SPDLOG_VERSION ${PC_SPDLOG_VERSION})
111       endif()
113       find_path(SPDLOG_INCLUDE_DIR NAMES spdlog/spdlog.h
114                                    HINTS ${DEPENDS_PATH}/include ${PC_SPDLOG_INCLUDEDIR}
115                                    ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
117       find_library(SPDLOG_LIBRARY_RELEASE NAMES spdlog
118                                           HINTS ${DEPENDS_PATH}/lib ${PC_SPDLOG_LIBDIR}
119                                           ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
120       find_library(SPDLOG_LIBRARY_DEBUG NAMES spdlogd
121                                         HINTS ${DEPENDS_PATH}/lib ${PC_SPDLOG_LIBDIR}
122                                         ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
123     endif()
124   endif()
126   include(SelectLibraryConfigurations)
127   select_library_configurations(SPDLOG)
128   unset(SPDLOG_LIBRARIES)
130   include(FindPackageHandleStandardArgs)
131   find_package_handle_standard_args(Spdlog
132                                     REQUIRED_VARS SPDLOG_LIBRARY SPDLOG_INCLUDE_DIR
133                                     VERSION_VAR SPDLOG_VERSION)
135   if(Spdlog_FOUND)
136     # cmake target and not building internal
137     if(TARGET spdlog::spdlog AND NOT TARGET spdlog)
138       add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} ALIAS spdlog::spdlog)
140     else()
141       add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} UNKNOWN IMPORTED)
142       if(SPDLOG_LIBRARY_RELEASE)
143         set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
144                                                                          IMPORTED_CONFIGURATIONS RELEASE
145                                                                          IMPORTED_LOCATION_RELEASE "${SPDLOG_LIBRARY_RELEASE}")
146       endif()
147       if(SPDLOG_LIBRARY_DEBUG)
148         set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
149                                                                          IMPORTED_LOCATION_DEBUG "${SPDLOG_LIBRARY_DEBUG}")
150         set_property(TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} APPEND PROPERTY
151                                                                               IMPORTED_CONFIGURATIONS DEBUG)
152       endif()
153       set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
154                                                                        INTERFACE_INCLUDE_DIRECTORIES "${SPDLOG_INCLUDE_DIR}")
156       if(_spdlog_definitions)
157         # We need to append in case the cmake config already has definitions
158         set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
159                                                                          INTERFACE_COMPILE_DEFINITIONS "${_spdlog_definitions}")
160       endif()
161     endif()
163     if(TARGET spdlog)
164       add_dependencies(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} spdlog)
165     endif()
167     # Add internal build target when a Multi Config Generator is used
168     # We cant add a dependency based off a generator expression for targeted build types,
169     # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
170     # therefore if the find heuristics only find the library, we add the internal build
171     # target to the project to allow user to manually trigger for any build type they need
172     # in case only a specific build type is actually available (eg Release found, Debug Required)
173     # This is mainly targeted for windows who required different runtime libs for different
174     # types, and they arent compatible
175     if(_multiconfig_generator)
176       if(NOT TARGET spdlog)
177         buildSpdlog()
178         set_target_properties(spdlog PROPERTIES EXCLUDE_FROM_ALL TRUE)
179       endif()
180       add_dependencies(build_internal_depends spdlog)
181     endif()
182   else()
183     if(Spdlog_FIND_REQUIRED)
184       message(FATAL_ERROR "Spdlog libraries were not found. You may want to try -DENABLE_INTERNAL_SPDLOG=ON")
185     endif()
186   endif()
187 endif()