Merge pull request #25883 from CrystalP/fix-slowscan
[xbmc.git] / cmake / modules / FindFmt.cmake
blob475238ec829a968b0795e75c61f7eb14d02b1020
1 # FindFmt
2 # -------
3 # Finds the Fmt library
5 # This will define the following target:
7 #   ${APP_NAME_LC}::Fmt   - The Fmt library
9 if(NOT TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME})
11   include(cmake/scripts/common/ModuleHelpers.cmake)
13   # Macro for building INTERNAL_FMT
14   macro(buildFmt)
15     if(APPLE)
16       set(EXTRA_ARGS "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}")
17     endif()
19     set(FMT_VERSION ${${MODULE}_VER})
20     # fmt debug uses postfix d for all platforms
21     set(FMT_DEBUG_POSTFIX d)
23     if(WIN32 OR WINDOWS_STORE)
24       set(patches "${CMAKE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/001-windows-pdb-symbol-gen.patch")
25       generate_patchcommand("${patches}")
26     endif()
28     set(CMAKE_ARGS -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}
29                    -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
30                    -DFMT_DOC=OFF
31                    -DFMT_TEST=OFF
32                    -DFMT_INSTALL=ON
33                    "${EXTRA_ARGS}")
35     BUILD_DEP_TARGET()
36   endmacro()
38   set(MODULE_LC fmt)
40   SETUP_BUILD_VARS()
42   # Check for existing FMT. If version >= FMT-VERSION file version, dont build
43   find_package(FMT CONFIG QUIET
44                    HINTS ${DEPENDS_PATH}/lib/cmake
45                    ${${CORE_PLATFORM_NAME_LC}_SEARCH_CONFIG})
47   if((FMT_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_FMT) OR
48      ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_FMT))
49     # build internal module
50     buildFmt()
51   else()
52     if(NOT TARGET fmt::fmt)
53       # Do not use pkgconfig on windows
54       if(PKG_CONFIG_FOUND AND NOT WIN32)
55         pkg_check_modules(PC_FMT libfmt QUIET)
56         set(FMT_VERSION ${PC_FMT_VERSION})
57       endif()
59       find_path(FMT_INCLUDE_DIR NAMES fmt/format.h
60                                 HINTS ${DEPENDS_PATH}/include ${PC_FMT_INCLUDEDIR}
61                                 ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
63       find_library(FMT_LIBRARY_RELEASE NAMES fmt
64                                        HINTS ${DEPENDS_PATH}/lib ${PC_FMT_LIBDIR}
65                                        ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
66       find_library(FMT_LIBRARY_DEBUG NAMES fmtd
67                                      HINTS ${DEPENDS_PATH}/lib ${PC_FMT_LIBDIR}
68                                      ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
69     else()
70       # This is for the case where a distro provides a non standard (Debug/Release) config type
71       # eg Debian's config file is fmtConfigTargets-none.cmake
72       # convert this back to either DEBUG/RELEASE or just RELEASE
73       # we only do this because we use find_package_handle_standard_args for config time output
74       # and it isnt capable of handling TARGETS, so we have to extract the info
75       get_target_property(_FMT_CONFIGURATIONS fmt::fmt IMPORTED_CONFIGURATIONS)
76       foreach(_fmt_config IN LISTS _FMT_CONFIGURATIONS)
77         # Some non standard config (eg None on Debian)
78         # Just set to RELEASE var so select_library_configurations can continue to work its magic
79         string(TOUPPER ${_fmt_config} _fmt_config_UPPER)
80         if((NOT ${_fmt_config_UPPER} STREQUAL "RELEASE") AND
81            (NOT ${_fmt_config_UPPER} STREQUAL "DEBUG"))
82           get_target_property(FMT_LIBRARY_RELEASE fmt::fmt IMPORTED_LOCATION_${_fmt_config_UPPER})
83         else()
84           get_target_property(FMT_LIBRARY_${_fmt_config_UPPER} fmt::fmt IMPORTED_LOCATION_${_fmt_config_UPPER})
85         endif()
86       endforeach()
88       get_target_property(FMT_INCLUDE_DIR fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
89     endif()
90   endif()
92   include(SelectLibraryConfigurations)
93   select_library_configurations(FMT)
94   unset(FMT_LIBRARIES)
96   include(FindPackageHandleStandardArgs)
97   find_package_handle_standard_args(Fmt
98                                     REQUIRED_VARS FMT_LIBRARY FMT_INCLUDE_DIR
99                                     VERSION_VAR FMT_VERSION)
100   if(Fmt_FOUND)
101     # cmake target and not building internal
102     if(TARGET fmt::fmt AND NOT TARGET fmt)
103       add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} ALIAS fmt::fmt)
104     else()
105       add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} UNKNOWN IMPORTED)
106       if(FMT_LIBRARY_RELEASE)
107         set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
108                                                                          IMPORTED_CONFIGURATIONS RELEASE
109                                                                          IMPORTED_LOCATION_RELEASE "${FMT_LIBRARY_RELEASE}")
110       endif()
111       if(FMT_LIBRARY_DEBUG)
112         set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
113                                                                          IMPORTED_LOCATION_DEBUG "${FMT_LIBRARY_DEBUG}")
114         set_property(TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} APPEND PROPERTY
115                                                                               IMPORTED_CONFIGURATIONS DEBUG)
116       endif()
117       set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
118                                                                        INTERFACE_INCLUDE_DIRECTORIES "${FMT_INCLUDE_DIR}")
119     endif()
121     if(TARGET fmt)
122       add_dependencies(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} fmt)
123       # We are building as a requirement, so set LIB_BUILD property to allow calling
124       # modules to know we will be building, and they will want to rebuild as well.
125       set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES LIB_BUILD ON)
126     endif()
128     # Add internal build target when a Multi Config Generator is used
129     # We cant add a dependency based off a generator expression for targeted build types,
130     # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
131     # therefore if the find heuristics only find the library, we add the internal build
132     # target to the project to allow user to manually trigger for any build type they need
133     # in case only a specific build type is actually available (eg Release found, Debug Required)
134     # This is mainly targeted for windows who required different runtime libs for different
135     # types, and they arent compatible
136     if(_multiconfig_generator)
137       if(NOT TARGET fmt)
138         buildFmt()
139         set_target_properties(fmt PROPERTIES EXCLUDE_FROM_ALL TRUE)
140       endif()
141       add_dependencies(build_internal_depends fmt)
142     endif()
143   else()
144     if(Fmt_FIND_REQUIRED)
145       message(FATAL_ERROR "Fmt libraries were not found. You may want to use -DENABLE_INTERNAL_FMT=ON")
146     endif()
147   endif()
148 endif()