|
5 | 5 | # The targets will have the same names, but it will use the static libs.
|
6 | 6 | #
|
7 | 7 | # Valid find_package COMPONENTS names: "decoder", "encoder", and "common"
|
| 8 | +# Note that if you're requiring "decoder" or "encoder", then "common" will be automatically added as required. |
8 | 9 | #
|
9 | 10 | # Defines the libraries (if found): Brotli::decoder, Brotli::encoder, Brotli::common
|
10 | 11 | # and the includes path variable: Brotli_INCLUDE_DIR
|
| 12 | +# |
| 13 | +# If it's failing to find the libraries, try setting BROTLI_ROOT_DIR to the folder containing your library & include dir. |
11 | 14 |
|
12 |
| -function(brotli_err_msg _err_msg) |
| 15 | +# If they asked for a specific version, warn/fail since we don't support it. |
| 16 | +# TODO: if they start distributing the version somewhere, implement finding it. |
| 17 | +# But currently there's a version header that doesn't seem to get installed. |
| 18 | +if(Brotli_FIND_VERSION) |
| 19 | + set(_brotli_version_error_msg "FindBrotli.cmake doesn't have version support!") |
13 | 20 | # If the package is required, throw a fatal error
|
14 | 21 | # Otherwise, if not running quietly, we throw a warning
|
15 | 22 | if(Brotli_FIND_REQUIRED)
|
16 |
| - message(FATAL_ERROR "${_err_msg}") |
| 23 | + message(FATAL_ERROR "${_brotli_version_error_msg}") |
17 | 24 | elseif(NOT Brotli_FIND_QUIETLY)
|
18 |
| - message(WARNING "${_err_msg}") |
| 25 | + message(WARNING "${_brotli_version_error_msg}") |
19 | 26 | endif()
|
20 |
| -endfunction() |
21 |
| - |
22 |
| -# If they asked for a specific version, warn/fail since we don't support it. |
23 |
| -if(Brotli_FIND_VERSION) |
24 |
| - brotli_err_msg("FindBrotli.cmake doesn't have version support!") |
25 | 27 | endif()
|
26 | 28 |
|
27 |
| -# Since both decoder & encoder require the common lib (I think), force its requirement.. |
| 29 | +# Since both decoder & encoder require the common lib, force its requirement.. |
28 | 30 | # if the user is requiring either of those other libs.
|
29 | 31 | if(Brotli_FIND_REQUIRED_decoder OR Brotli_FIND_REQUIRED_encoder)
|
30 | 32 | set(Brotli_FIND_REQUIRED_common TRUE)
|
31 | 33 | endif()
|
32 | 34 |
|
| 35 | +# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES |
| 36 | +# Credit to FindOpenSSL.cmake for this |
| 37 | +if(BROTLI_USE_STATIC_LIBS) |
| 38 | + set(_brotli_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) |
| 39 | + if(WIN32) |
| 40 | + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) |
| 41 | + else() |
| 42 | + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) |
| 43 | + endif() |
| 44 | +endif() |
| 45 | + |
33 | 46 | # Make PkgConfig optional, since some users (mainly Windows) don't have it.
|
34 | 47 | # But it's a lot more clean than manually using find_library.
|
35 | 48 | find_package(PkgConfig QUIET)
|
36 |
| -if(PKG_CONFIG_FOUND) |
37 |
| - if(BROTLI_USE_STATIC_LIBS) |
38 |
| - # Have to use _STATIC to tell PkgConfig to find the static libs. |
39 |
| - pkg_check_modules(Brotli_common_STATIC QUIET IMPORTED_TARGET libbrotlicommon) |
40 |
| - pkg_check_modules(Brotli_decoder_STATIC QUIET IMPORTED_TARGET libbrotlidec) |
41 |
| - pkg_check_modules(Brotli_encoder_STATIC QUIET IMPORTED_TARGET libbrotlienc) |
42 |
| - else() |
43 |
| - pkg_check_modules(Brotli_common QUIET IMPORTED_TARGET libbrotlicommon) |
44 |
| - pkg_check_modules(Brotli_decoder QUIET IMPORTED_TARGET libbrotlidec) |
45 |
| - pkg_check_modules(Brotli_encoder QUIET IMPORTED_TARGET libbrotlienc) |
46 |
| - endif() |
47 |
| -endif() |
48 | 49 |
|
49 | 50 | # Only used if the PkgConfig libraries aren't used.
|
50 | 51 | find_path(Brotli_INCLUDE_DIR
|
51 |
| - NAMES "brotli/decode.h" "brotli/encode.h" |
52 |
| - PATH_SUFFIXES "include" "includes" |
| 52 | + NAMES |
| 53 | + "brotli/decode.h" |
| 54 | + "brotli/encode.h" |
| 55 | + HINTS |
| 56 | + ${BROTLI_ROOT_DIR} |
| 57 | + PATH_SUFFIXES |
| 58 | + "include" |
| 59 | + "includes" |
53 | 60 | DOC "The path to Brotli's include directory."
|
54 | 61 | )
|
| 62 | +# Hides this var from the GUI |
| 63 | +mark_as_advanced(Brotli_INCLUDE_DIR) |
55 | 64 |
|
56 |
| -# Also check if Brotli_decoder was defined, as it can be passed by the end-user |
57 |
| -if(NOT TARGET PkgConfig::Brotli_decoder AND NOT Brotli_decoder AND NOT TARGET PkgConfig::Brotli_decoder_STATIC) |
58 |
| - if(BROTLI_USE_STATIC_LIBS) |
59 |
| - list(APPEND _brotli_decoder_lib_names |
60 |
| - "brotlidec-static" |
61 |
| - "libbrotlidec-static" |
62 |
| - ) |
63 |
| - else() |
64 |
| - list(APPEND _brotli_decoder_lib_names |
65 |
| - "brotlidec" |
66 |
| - "libbrotlidec" |
67 |
| - ) |
68 |
| - endif() |
69 |
| - find_library(Brotli_decoder |
70 |
| - NAMES ${_brotli_decoder_lib_names} |
71 |
| - PATH_SUFFIXES |
72 |
| - "lib" |
73 |
| - "lib64" |
74 |
| - "libs" |
75 |
| - "libs64" |
76 |
| - "lib/x86_64-linux-gnu" |
77 |
| - ) |
| 65 | +# Just used for PkgConfig stuff in the loop below |
| 66 | +set(_brotli_stat_str "") |
| 67 | +if(BROTLI_USE_STATIC_LIBS) |
| 68 | + set(_brotli_stat_str "_STATIC") |
78 | 69 | endif()
|
79 | 70 |
|
80 |
| -# Also check if Brotli_encoder was defined, as it can be passed by the end-user |
81 |
| -if(NOT TARGET PkgConfig::Brotli_encoder AND NOT Brotli_encoder AND NOT TARGET PkgConfig::Brotli_encoder_STATIC) |
82 |
| - if(BROTLI_USE_STATIC_LIBS) |
83 |
| - list(APPEND _brotli_encoder_lib_names |
84 |
| - "brotlienc-static" |
85 |
| - "libbrotlienc-static" |
86 |
| - ) |
87 |
| - else() |
88 |
| - list(APPEND _brotli_encoder_lib_names |
89 |
| - "brotlienc" |
90 |
| - "libbrotlienc" |
91 |
| - ) |
| 71 | +# Lets us know we are using the PkgConfig libraries |
| 72 | +# Will be set false if any non-pkgconf vars are used |
| 73 | +set(_brotli_using_pkgconf TRUE) |
| 74 | + |
| 75 | +# Each string here is "ComponentName;LiteralName" (the semi-colon is a delimiter) |
| 76 | +foreach(_listvar "common;common" "decoder;dec" "encoder;enc") |
| 77 | + # Split the component name and literal library name from the listvar |
| 78 | + list(GET _listvar 0 _component_name) |
| 79 | + list(GET _listvar 1 _libname) |
| 80 | + |
| 81 | + if(PKG_CONFIG_FOUND) |
| 82 | + # These need to be GLOBAL for MinGW when making ALIAS libraries against them. |
| 83 | + if(BROTLI_USE_STATIC_LIBS) |
| 84 | + # Have to use _STATIC to tell PkgConfig to find the static libs. |
| 85 | + pkg_check_modules(Brotli_${_component_name}_STATIC QUIET GLOBAL IMPORTED_TARGET libbrotli${_libname}) |
| 86 | + else() |
| 87 | + pkg_check_modules(Brotli_${_component_name} QUIET GLOBAL IMPORTED_TARGET libbrotli${_libname}) |
| 88 | + endif() |
| 89 | + endif() |
| 90 | + |
| 91 | + # Check if the target was already found by Pkgconf |
| 92 | + if(TARGET PkgConfig::Brotli_${_component_name} OR TARGET PkgConfig::Brotli_${_component_name}_STATIC) |
| 93 | + # Can't use generators for ALIAS targets, so you get this jank |
| 94 | + add_library(Brotli::${_component_name} ALIAS PkgConfig::Brotli_${_component_name}${_brotli_stat_str}) |
| 95 | + |
| 96 | + # Tells HANDLE_COMPONENTS we found the component |
| 97 | + set(Brotli_${_component_name}_FOUND TRUE) |
| 98 | + if(Brotli_FIND_REQUIRED_${_component_name}) |
| 99 | + # If the lib is required, we can add its literal path as a required var for FindPackageHandleStandardArgs |
| 100 | + # Since it won't accept the PkgConfig targets |
| 101 | + if(BROTLI_USE_STATIC_LIBS) |
| 102 | + list(APPEND _brotli_req_vars "Brotli_${_component_name}_STATIC_LIBRARIES") |
| 103 | + else() |
| 104 | + list(APPEND _brotli_req_vars "Brotli_${_component_name}_LINK_LIBRARIES") |
| 105 | + endif() |
| 106 | + endif() |
| 107 | + |
| 108 | + # Skip searching for the libs with find_library since it was already found by Pkgconf |
| 109 | + continue() |
| 110 | + endif() |
| 111 | + |
| 112 | + # Lets us know we aren't using the PkgConfig libraries |
| 113 | + set(_brotli_using_pkgconf FALSE) |
| 114 | + if(Brotli_FIND_REQUIRED_${_component_name}) |
| 115 | + # If it's required, we can set the name used in find_library as a required var for FindPackageHandleStandardArgs |
| 116 | + list(APPEND _brotli_req_vars "Brotli_${_component_name}") |
92 | 117 | endif()
|
93 |
| - find_library(Brotli_encoder |
94 |
| - NAMES ${_brotli_encoder_lib_names} |
95 |
| - PATH_SUFFIXES |
96 |
| - "lib" |
97 |
| - "lib64" |
98 |
| - "libs" |
99 |
| - "libs64" |
100 |
| - "lib/x86_64-linux-gnu" |
101 |
| - ) |
102 |
| -endif() |
103 | 118 |
|
104 |
| -# Also check if Brotli_common was defined, as it can be passed by the end-user |
105 |
| -if(NOT TARGET PkgConfig::Brotli_common AND NOT Brotli_common AND NOT TARGET PkgConfig::Brotli_common_STATIC) |
106 | 119 | if(BROTLI_USE_STATIC_LIBS)
|
107 |
| - list(APPEND _brotli_common_lib_names |
108 |
| - "brotlicommon-static" |
109 |
| - "libbrotlicommon-static" |
| 120 | + list(APPEND _brotli_lib_names |
| 121 | + "brotli${_libname}-static" |
| 122 | + "libbrotli${_libname}-static" |
110 | 123 | )
|
111 | 124 | else()
|
112 |
| - list(APPEND _brotli_common_lib_names |
113 |
| - "brotlicommon" |
114 |
| - "libbrotlicommon" |
| 125 | + list(APPEND _brotli_lib_names |
| 126 | + "brotli${_libname}" |
| 127 | + "libbrotli${_libname}" |
115 | 128 | )
|
116 | 129 | endif()
|
117 |
| - find_library(Brotli_common |
118 |
| - NAMES ${_brotli_common_lib_names} |
| 130 | + |
| 131 | + find_library(Brotli_${_component_name} |
| 132 | + NAMES ${_brotli_lib_names} |
| 133 | + HINTS ${BROTLI_ROOT_DIR} |
119 | 134 | PATH_SUFFIXES
|
120 | 135 | "lib"
|
121 | 136 | "lib64"
|
122 | 137 | "libs"
|
123 | 138 | "libs64"
|
124 | 139 | "lib/x86_64-linux-gnu"
|
125 | 140 | )
|
126 |
| -endif() |
| 141 | + # Hide the library variable from the Cmake GUI |
| 142 | + mark_as_advanced(Brotli_${_component_name}) |
127 | 143 |
|
128 |
| -set(_brotli_req_vars "") |
129 |
| -# Generic loop to either create all the aliases for the end-user, or throw errors/warnings. |
130 |
| -# Note that the case here needs to match the case we used elsewhere in this file. |
131 |
| -foreach(_target_name "common" "decoder" "encoder") |
132 |
| - # The PkgConfig IMPORTED_TARGET has PkgConfig:: prefixed to it. |
133 |
| - if(TARGET PkgConfig::Brotli_${_target_name} OR TARGET PkgConfig::Brotli_${_target_name}_STATIC) |
134 |
| - set(_stat_str "") |
135 |
| - if(BROTLI_USE_STATIC_LIBS) |
136 |
| - set(_stat_str "_STATIC") |
137 |
| - endif() |
138 |
| - # Can't use generators for ALIAS targets, so you get this jank |
139 |
| - add_library(Brotli::${_target_name} ALIAS PkgConfig::Brotli_${_target_name}${_stat_str}) |
| 144 | + # Unset since otherwise it'll stick around for the next loop and break things |
| 145 | + unset(_brotli_lib_names) |
140 | 146 |
|
141 |
| - # The PkgConfig version of the library has a slightly different path to its lib. |
142 |
| - if(Brotli_FIND_REQUIRED_${_target_name}) |
143 |
| - if(BROTLI_USE_STATIC_LIBS) |
144 |
| - list(APPEND _brotli_req_vars "Brotli_${_target_name}_STATIC_LIBRARIES") |
145 |
| - else() |
146 |
| - list(APPEND _brotli_req_vars "Brotli_${_target_name}_LINK_LIBRARIES") |
147 |
| - endif() |
148 |
| - endif() |
149 |
| - # This will only trigger for libraries we found using find_library |
150 |
| - elseif(Brotli_${_target_name}) |
151 |
| - add_library("Brotli::${_target_name}" UNKNOWN IMPORTED) |
152 |
| - # Safety-check the includes dir |
153 |
| - if(NOT Brotli_INCLUDE_DIR) |
154 |
| - brotli_err_msg("Failed to find Brotli's includes directory. Try manually defining \"Brotli_INCLUDE_DIR\" to Brotli's header path on your system.") |
155 |
| - endif() |
| 147 | + # Check if find_library found the library |
| 148 | + if(Brotli_${_component_name}) |
| 149 | + # Tells HANDLE_COMPONENTS we found the component |
| 150 | + set(Brotli_${_component_name}_FOUND TRUE) |
| 151 | + |
| 152 | + add_library("Brotli::${_component_name}" UNKNOWN IMPORTED) |
156 | 153 | # Attach the literal library and include dir to the IMPORTED target for the end-user
|
157 |
| - set_target_properties("Brotli::${_target_name}" PROPERTIES |
| 154 | + set_target_properties("Brotli::${_component_name}" PROPERTIES |
158 | 155 | INTERFACE_INCLUDE_DIRECTORIES "${Brotli_INCLUDE_DIR}"
|
159 |
| - IMPORTED_LOCATION "${Brotli_${_target_name}}" |
| 156 | + IMPORTED_LOCATION "${Brotli_${_component_name}}" |
160 | 157 | )
|
161 |
| - # Attach the library from find_library to our required vars (if it's required) |
162 |
| - if(Brotli_FIND_REQUIRED_${_target_name}) |
163 |
| - list(APPEND _brotli_req_vars "Brotli_${_target_name}") |
164 |
| - endif() |
165 |
| - # This will only happen if it's a required library but we didn't find it. |
166 |
| - elseif(Brotli_FIND_REQUIRED_${_target_name}) |
167 |
| - # Only bother with an error/failure if they actually required the lib. |
168 |
| - brotli_err_msg("Failed to find Brotli's ${_target_name} library. Try manually defining \"Brotli_${_target_name}\" to its path on your system.") |
169 |
| - # If the compnent was required but not found, you set XXX_FOUND to false to signify failure to find component(s) |
170 |
| - # This is used in find_package_handle_standard_args's HANDLE_COMPONENTS (I think) |
171 |
| - set(Brotli_FOUND FALSE) |
| 158 | + else() |
| 159 | + # Tells HANDLE_COMPONENTS we found the component |
| 160 | + set(Brotli_${_component_name}_FOUND FALSE) |
172 | 161 | endif()
|
173 | 162 | endforeach()
|
174 | 163 |
|
175 | 164 | include(FindPackageHandleStandardArgs)
|
| 165 | +# Sets Brotli_FOUND, and fails the find_package(Brotli) call if it was REQUIRED but missing libs. |
176 | 166 | find_package_handle_standard_args(Brotli
|
177 |
| - FOUND_VAR Brotli_FOUND |
178 |
| - REQUIRED_VARS ${_brotli_req_vars} |
| 167 | + FOUND_VAR |
| 168 | + Brotli_FOUND |
| 169 | + REQUIRED_VARS |
| 170 | + Brotli_INCLUDE_DIR |
| 171 | + ${_brotli_required_targets} |
179 | 172 | HANDLE_COMPONENTS
|
180 | 173 | )
|
181 | 174 |
|
182 |
| -if(Brotli_FOUND) |
183 |
| - include(FindPackageMessage) |
184 |
| - foreach(_lib_name ${_brotli_req_vars}) |
185 |
| - # TODO: remove this if/when The Cmake PkgConfig file fixes the non-quiet message about libbrotlicommon being found. |
186 |
| - if(${_lib_name} MATCHES "common") |
187 |
| - # This avoids a duplicate "Found Brotli: /usr/lib/libbrotlicommon.so" type message. |
188 |
| - continue() |
189 |
| - endif() |
190 |
| - # Double-expand the var to get the actual path instead of the variable's name. |
191 |
| - find_package_message(Brotli "Found Brotli: ${${_lib_name}}" |
192 |
| - "[${${_lib_name}}][${Brotli_INCLUDE_DIR}]" |
193 |
| - ) |
194 |
| - endforeach() |
| 175 | +# Restore the original find library ordering |
| 176 | +if(BROTLI_USE_STATIC_LIBS) |
| 177 | + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_brotli_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) |
195 | 178 | endif()
|
0 commit comments