|
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