FindBrotli.cmake 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # A simple FindBrotli package for Cmake's find_package function.
  2. # Note: This find package doesn't have version support, as the version file doesn't seem to be installed on most systems.
  3. #
  4. # If you want to find the static packages instead of shared (the default), define BROTLI_USE_STATIC_LIBS as TRUE.
  5. # The targets will have the same names, but it will use the static libs.
  6. #
  7. # Valid find_package COMPONENTS names: "decoder", "encoder", and "common"
  8. #
  9. # Defines the libraries (if found): Brotli::decoder, Brotli::encoder, Brotli::common
  10. # and the includes path variable: Brotli_INCLUDE_DIR
  11. function(brotli_err_msg _err_msg)
  12. # If the package is required, throw a fatal error
  13. # Otherwise, if not running quietly, we throw a warning
  14. if(Brotli_FIND_REQUIRED)
  15. message(FATAL_ERROR "${_err_msg}")
  16. elseif(NOT Brotli_FIND_QUIETLY)
  17. message(WARNING "${_err_msg}")
  18. endif()
  19. endfunction()
  20. # If they asked for a specific version, warn/fail since we don't support it.
  21. if(Brotli_FIND_VERSION)
  22. brotli_err_msg("FindBrotli.cmake doesn't have version support!")
  23. endif()
  24. # Since both decoder & encoder require the common lib (I think), force its requirement..
  25. # if the user is requiring either of those other libs.
  26. if(Brotli_FIND_REQUIRED_decoder OR Brotli_FIND_REQUIRED_encoder)
  27. set(Brotli_FIND_REQUIRED_common TRUE)
  28. endif()
  29. # Make PkgConfig optional, since some users (mainly Windows) don't have it.
  30. # But it's a lot more clean than manually using find_library.
  31. find_package(PkgConfig QUIET)
  32. if(PKG_CONFIG_FOUND)
  33. if(BROTLI_USE_STATIC_LIBS)
  34. pkg_check_modules(Brotli_common_STATIC QUIET IMPORTED_TARGET libbrotlicommon)
  35. pkg_check_modules(Brotli_decoder_STATIC QUIET IMPORTED_TARGET libbrotlidec)
  36. pkg_check_modules(Brotli_encoder_STATIC QUIET IMPORTED_TARGET libbrotlienc)
  37. else()
  38. pkg_check_modules(Brotli_common QUIET IMPORTED_TARGET libbrotlicommon)
  39. pkg_check_modules(Brotli_decoder QUIET IMPORTED_TARGET libbrotlidec)
  40. pkg_check_modules(Brotli_encoder QUIET IMPORTED_TARGET libbrotlienc)
  41. endif()
  42. endif()
  43. # Only used if the PkgConfig libraries aren't used.
  44. find_path(Brotli_INCLUDE_DIR
  45. NAMES "brotli/decode.h" "brotli/encode.h"
  46. PATH_SUFFIXES "include" "includes"
  47. DOC "The path to Brotli's include directory."
  48. )
  49. # Also check if Brotli_decoder was defined, as it can be passed by the end-user
  50. if(NOT TARGET PkgConfig::Brotli_decoder AND NOT Brotli_decoder)
  51. if(BROTLI_USE_STATIC_LIBS)
  52. list(APPEND _brotli_decoder_lib_names
  53. "brotlidec-static"
  54. "libbrotlidec-static"
  55. )
  56. else()
  57. list(APPEND _brotli_decoder_lib_names
  58. "brotlidec"
  59. "libbrotlidec"
  60. )
  61. endif()
  62. find_library(Brotli_decoder
  63. NAMES ${_brotli_decoder_lib_names}
  64. PATH_SUFFIXES
  65. "lib"
  66. "lib64"
  67. "libs"
  68. "libs64"
  69. "lib/x86_64-linux-gnu"
  70. )
  71. endif()
  72. # Also check if Brotli_encoder was defined, as it can be passed by the end-user
  73. if(NOT TARGET PkgConfig::Brotli_encoder AND NOT Brotli_encoder)
  74. if(BROTLI_USE_STATIC_LIBS)
  75. list(APPEND _brotli_encoder_lib_names
  76. "brotlienc-static"
  77. "libbrotlienc-static"
  78. )
  79. else()
  80. list(APPEND _brotli_encoder_lib_names
  81. "brotlienc"
  82. "libbrotlienc"
  83. )
  84. endif()
  85. find_library(Brotli_encoder
  86. NAMES ${_brotli_encoder_lib_names}
  87. PATH_SUFFIXES
  88. "lib"
  89. "lib64"
  90. "libs"
  91. "libs64"
  92. "lib/x86_64-linux-gnu"
  93. )
  94. endif()
  95. # Also check if Brotli_common was defined, as it can be passed by the end-user
  96. if(NOT TARGET PkgConfig::Brotli_common AND NOT Brotli_common)
  97. if(BROTLI_USE_STATIC_LIBS)
  98. list(APPEND _brotli_common_lib_names
  99. "brotlicommon-static"
  100. "libbrotlicommon-static"
  101. )
  102. else()
  103. list(APPEND _brotli_common_lib_names
  104. "brotlicommon"
  105. "libbrotlicommon"
  106. )
  107. endif()
  108. find_library(Brotli_common
  109. NAMES ${_brotli_common_lib_names}
  110. PATH_SUFFIXES
  111. "lib"
  112. "lib64"
  113. "libs"
  114. "libs64"
  115. "lib/x86_64-linux-gnu"
  116. )
  117. endif()
  118. set(_brotli_req_vars "")
  119. # Generic loop to either create all the aliases for the end-user, or throw errors/warnings.
  120. # Note that the case here needs to match the case we used elsewhere in this file.
  121. foreach(_target_name "common" "decoder" "encoder")
  122. # The PkgConfig IMPORTED_TARGET has PkgConfig:: prefixed to it.
  123. if(TARGET PkgConfig::Brotli_${_target_name})
  124. add_library(Brotli::${_target_name} ALIAS PkgConfig::Brotli_${_target_name})
  125. if(Brotli_FIND_REQUIRED_${_target_name})
  126. # The PkgConfig version of the library has a slightly different path to its lib.
  127. if(BROTLI_USE_STATIC_LIBS)
  128. list(APPEND _brotli_req_vars "Brotli_${_target_name}_STATIC_LINK_LIBRARIES")
  129. else()
  130. list(APPEND _brotli_req_vars "Brotli_${_target_name}_LINK_LIBRARIES")
  131. endif()
  132. endif()
  133. # This will only trigger for libraries we found using find_library
  134. elseif(Brotli_${_target_name})
  135. add_library("Brotli::${_target_name}" UNKNOWN IMPORTED)
  136. # Safety-check the includes dir
  137. if(NOT Brotli_INCLUDE_DIR)
  138. brotli_err_msg("Failed to find Brotli's includes directory. Try manually defining \"Brotli_INCLUDE_DIR\" to Brotli's header path on your system.")
  139. endif()
  140. # Attach the literal library and include dir to the IMPORTED target for the end-user
  141. set_target_properties("Brotli::${_target_name}" PROPERTIES
  142. INTERFACE_INCLUDE_DIRECTORIES "${Brotli_INCLUDE_DIR}"
  143. IMPORTED_LOCATION "${Brotli_${_target_name}}"
  144. )
  145. # Attach the library from find_library to our required vars (if it's required)
  146. if(Brotli_FIND_REQUIRED_${_target_name})
  147. list(APPEND _brotli_req_vars "Brotli_${_target_name}")
  148. endif()
  149. # This will only happen if it's a required library but we didn't find it.
  150. elseif(Brotli_FIND_REQUIRED_${_target_name})
  151. # Only bother with an error/failure if they actually required the lib.
  152. brotli_err_msg("Failed to find Brotli's ${_target_name} library. Try manually defining \"Brotli_${_target_name}\" to its path on your system.")
  153. endif()
  154. endforeach()
  155. include(FindPackageHandleStandardArgs)
  156. find_package_handle_standard_args(Brotli
  157. FOUND_VAR Brotli_FOUND
  158. REQUIRED_VARS ${_brotli_req_vars}
  159. )
  160. if(Brotli_FOUND)
  161. include(FindPackageMessage)
  162. foreach(_lib_name ${_brotli_req_vars})
  163. # TODO: remove this if/when The Cmake PkgConfig file fixes the non-quiet message about libbrotlicommon being found.
  164. if(${_lib_name} MATCHES "common")
  165. # This avoids a duplicate "Found Brotli: /usr/lib/libbrotlicommon.so" type message.
  166. continue()
  167. endif()
  168. # Double-expand the var to get the actual path instead of the variable's name.
  169. find_package_message(Brotli "Found Brotli: ${${_lib_name}}"
  170. "[${${_lib_name}}][${Brotli_INCLUDE_DIR}]"
  171. )
  172. endforeach()
  173. endif()