CMake: Add option to link against system-wide Gflags library
[blender.git] / build_files / cmake / Modules / FindGflags.cmake
1 # Ceres Solver - A fast non-linear least squares minimizer
2 # Copyright 2015 Google Inc. All rights reserved.
3 # http://ceres-solver.org/
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
7 #
8 # * Redistributions of source code must retain the above copyright notice,
9 #   this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above copyright notice,
11 #   this list of conditions and the following disclaimer in the documentation
12 #   and/or other materials provided with the distribution.
13 # * Neither the name of Google Inc. nor the names of its contributors may be
14 #   used to endorse or promote products derived from this software without
15 #   specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28 #
29 # Author: alexs.mac@gmail.com (Alex Stewart)
30 #
31
32 # FindGflags.cmake - Find Google gflags logging library.
33 #
34 # This module will attempt to find gflags, either via an exported CMake
35 # configuration (generated by gflags >= 2.1 which are built with CMake), or
36 # by performing a standard search for all gflags components.  The order of
37 # precedence for these two methods of finding gflags is controlled by:
38 # GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION.
39 #
40 # This module defines the following variables:
41 #
42 # GFLAGS_FOUND: TRUE iff gflags is found.
43 # GFLAGS_INCLUDE_DIRS: Include directories for gflags.
44 # GFLAGS_LIBRARIES: Libraries required to link gflags.
45 # GFLAGS_NAMESPACE: The namespace in which gflags is defined.  In versions of
46 #                   gflags < 2.1, this was google, for versions >= 2.1 it is
47 #                   by default gflags, although can be configured when building
48 #                   gflags to be something else (i.e. google for legacy
49 #                   compatibility).
50 #
51 # The following variables control the behaviour of this module when an exported
52 # gflags CMake configuration is not found.
53 #
54 # GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION: TRUE/FALSE, iff TRUE then
55 #                           then prefer using an exported CMake configuration
56 #                           generated by gflags >= 2.1 over searching for the
57 #                           gflags components manually.  Otherwise (FALSE)
58 #                           ignore any exported gflags CMake configurations and
59 #                           always perform a manual search for the components.
60 #                           Default: TRUE iff user does not define this variable
61 #                           before we are called, and does NOT specify either
62 #                           GFLAGS_INCLUDE_DIR_HINTS or GFLAGS_LIBRARY_DIR_HINTS
63 #                           otherwise FALSE.
64 # GFLAGS_INCLUDE_DIR_HINTS: List of additional directories in which to
65 #                           search for gflags includes, e.g: /timbuktu/include.
66 # GFLAGS_LIBRARY_DIR_HINTS: List of additional directories in which to
67 #                           search for gflags libraries, e.g: /timbuktu/lib.
68 # GFLAGS_ROOT_DIR,          The base directory to search for Gflags.
69 #                           This can also be an environment variable.
70 #
71 # The following variables are also defined by this module, but in line with
72 # CMake recommended FindPackage() module style should NOT be referenced directly
73 # by callers (use the plural variables detailed above instead).  These variables
74 # do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which
75 # are NOT re-called (i.e. search for library is not repeated) if these variables
76 # are set with valid values _in the CMake cache_. This means that if these
77 # variables are set directly in the cache, either by the user in the CMake GUI,
78 # or by the user passing -DVAR=VALUE directives to CMake when called (which
79 # explicitly defines a cache variable), then they will be used verbatim,
80 # bypassing the HINTS variables and other hard-coded search locations.
81 #
82 # GFLAGS_INCLUDE_DIR: Include directory for gflags, not including the
83 #                     include directory of any dependencies.
84 # GFLAGS_LIBRARY: gflags library, not including the libraries of any
85 #                 dependencies.
86
87 # If GFLAGS_ROOT_DIR was defined in the environment, use it.
88 if(NOT GFLAGS_ROOT_DIR AND NOT $ENV{GFLAGS_ROOT_DIR} STREQUAL "")
89   set(GFLAGS_ROOT_DIR $ENV{GFLAGS_ROOT_DIR})
90 endif()
91
92 if(DEFINED GFLAGS_ROOT_DIR)
93   set(GFLAGS_ROOT_DIR_INCLUDE "${GFLAGS_ROOT_DIR}/include")
94   set(GFLAGS_ROOT_DIR_LIB "${GFLAGS_ROOT_DIR}/lib")
95 endif()
96
97 # Reset CALLERS_CMAKE_FIND_LIBRARY_PREFIXES to its value when FindGflags was
98 # invoked, necessary for MSVC.
99 macro(GFLAGS_RESET_FIND_LIBRARY_PREFIX)
100   if(MSVC)
101     set(CMAKE_FIND_LIBRARY_PREFIXES "${CALLERS_CMAKE_FIND_LIBRARY_PREFIXES}")
102   endif()
103 endmacro()
104
105 # Called if we failed to find gflags or any of it's required dependencies,
106 # unsets all public (designed to be used externally) variables and reports
107 # error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
108 macro(GFLAGS_REPORT_NOT_FOUND REASON_MSG)
109   unset(GFLAGS_FOUND)
110   unset(GFLAGS_INCLUDE_DIRS)
111   unset(GFLAGS_LIBRARIES)
112   # Do not use unset, as we want to keep GFLAGS_NAMESPACE in the cache,
113   # but simply clear its value.
114   set(GFLAGS_NAMESPACE "" CACHE STRING
115     "gflags namespace (google or gflags)" FORCE)
116
117   # Make results of search visible in the CMake GUI if gflags has not
118   # been found so that user does not have to toggle to advanced view.
119   mark_as_advanced(CLEAR GFLAGS_INCLUDE_DIR
120                          GFLAGS_LIBRARY
121                          GFLAGS_NAMESPACE)
122
123   gflags_reset_find_library_prefix()
124
125   # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
126   # use the camelcase library name, not uppercase.
127   if(Gflags_FIND_QUIETLY)
128     message(STATUS "Failed to find gflags - " ${REASON_MSG} ${ARGN})
129   elseif(Gflags_FIND_REQUIRED)
130     message(FATAL_ERROR "Failed to find gflags - " ${REASON_MSG} ${ARGN})
131   else()
132     # Neither QUIETLY nor REQUIRED, use no priority which emits a message
133     # but continues configuration and allows generation.
134     message("-- Failed to find gflags - " ${REASON_MSG} ${ARGN})
135   endif()
136   return()
137 endmacro()
138
139 # Verify that all variable names passed as arguments are defined (can be empty
140 # but must be defined) or raise a fatal error.
141 macro(GFLAGS_CHECK_VARS_DEFINED)
142   foreach(CHECK_VAR ${ARGN})
143     if(NOT DEFINED ${CHECK_VAR})
144       message(FATAL_ERROR "Ceres Bug: ${CHECK_VAR} is not defined.")
145     endif()
146   endforeach()
147 endmacro()
148
149 # Use check_cxx_source_compiles() to compile trivial test programs to determine
150 # the gflags namespace.  This works on all OSs except Windows.  If using Visual
151 # Studio, it fails because msbuild forces check_cxx_source_compiles() to use
152 # CMAKE_BUILD_TYPE=Debug for the test project, which usually breaks detection
153 # because MSVC requires that the test project use the same build type as gflags,
154 # which would normally be built in Release.
155 #
156 # Defines: GFLAGS_NAMESPACE in the caller's scope with the detected namespace,
157 #          which is blank (empty string, will test FALSE is CMake conditionals)
158 #          if detection failed.
159 function(GFLAGS_CHECK_GFLAGS_NAMESPACE_USING_TRY_COMPILE)
160   # Verify that all required variables are defined.
161   gflags_check_vars_defined(
162     GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY)
163   # Ensure that GFLAGS_NAMESPACE is always unset on completion unless
164   # we explicitly set if after having the correct namespace.
165   set(GFLAGS_NAMESPACE "" PARENT_SCOPE)
166
167   include(CheckCXXSourceCompiles)
168   # Setup include path & link library for gflags for CHECK_CXX_SOURCE_COMPILES.
169   set(CMAKE_REQUIRED_INCLUDES ${GFLAGS_INCLUDE_DIR})
170   set(CMAKE_REQUIRED_LIBRARIES ${GFLAGS_LIBRARY} ${GFLAGS_LINK_LIBRARIES})
171   # First try the (older) google namespace.  Note that the output variable
172   # MUST be unique to the build type as otherwise the test is not repeated as
173   # it is assumed to have already been performed.
174   check_cxx_source_compiles(
175     "#include <gflags/gflags.h>
176      int main(int argc, char * argv[]) {
177        google::ParseCommandLineFlags(&argc, &argv, true);
178        return 0;
179      }"
180      GFLAGS_IN_GOOGLE_NAMESPACE)
181   if(GFLAGS_IN_GOOGLE_NAMESPACE)
182     set(GFLAGS_NAMESPACE google PARENT_SCOPE)
183     return()
184   endif()
185
186   # Try (newer) gflags namespace instead.  Note that the output variable
187   # MUST be unique to the build type as otherwise the test is not repeated as
188   # it is assumed to have already been performed.
189   set(CMAKE_REQUIRED_INCLUDES ${GFLAGS_INCLUDE_DIR})
190   set(CMAKE_REQUIRED_LIBRARIES ${GFLAGS_LIBRARY} ${GFLAGS_LINK_LIBRARIES})
191   check_cxx_source_compiles(
192     "#include <gflags/gflags.h>
193      int main(int argc, char * argv[]) {
194         gflags::ParseCommandLineFlags(&argc, &argv, true);
195         return 0;
196      }"
197      GFLAGS_IN_GFLAGS_NAMESPACE)
198   if(GFLAGS_IN_GFLAGS_NAMESPACE)
199     set(GFLAGS_NAMESPACE gflags PARENT_SCOPE)
200     return()
201   endif()
202 endfunction()
203
204 # Use regex on the gflags headers to attempt to determine the gflags namespace.
205 # Checks both gflags.h (contained namespace on versions < 2.1.2) and
206 # gflags_declare.h, which contains the namespace on versions >= 2.1.2.
207 # In general, this method should only be used when
208 # GFLAGS_CHECK_GFLAGS_NAMESPACE_USING_TRY_COMPILE() cannot be used, or has
209 # failed.
210 #
211 # Defines: GFLAGS_NAMESPACE in the caller's scope with the detected namespace,
212 #          which is blank (empty string, will test FALSE is CMake conditionals)
213 #          if detection failed.
214 function(GFLAGS_CHECK_GFLAGS_NAMESPACE_USING_REGEX)
215   # Verify that all required variables are defined.
216   gflags_check_vars_defined(GFLAGS_INCLUDE_DIR)
217   # Ensure that GFLAGS_NAMESPACE is always undefined on completion unless
218   # we explicitly set if after having the correct namespace.
219   set(GFLAGS_NAMESPACE "" PARENT_SCOPE)
220
221   # Scan gflags.h to identify what namespace gflags was built with.  On
222   # versions of gflags < 2.1.2, gflags.h was configured with the namespace
223   # directly, on >= 2.1.2, gflags.h uses the GFLAGS_NAMESPACE #define which
224   # is defined in gflags_declare.h, we try each location in turn.
225   set(GFLAGS_HEADER_FILE ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
226   if(NOT EXISTS ${GFLAGS_HEADER_FILE})
227     gflags_report_not_found(
228       "Could not find file: ${GFLAGS_HEADER_FILE} "
229       "containing namespace information in gflags install located at: "
230       "${GFLAGS_INCLUDE_DIR}.")
231   endif()
232   file(READ ${GFLAGS_HEADER_FILE} GFLAGS_HEADER_FILE_CONTENTS)
233
234   string(REGEX MATCH "namespace [A-Za-z]+"
235     GFLAGS_NAMESPACE "${GFLAGS_HEADER_FILE_CONTENTS}")
236   string(REGEX REPLACE "namespace ([A-Za-z]+)" "\\1"
237     GFLAGS_NAMESPACE "${GFLAGS_NAMESPACE}")
238
239   if(NOT GFLAGS_NAMESPACE)
240     gflags_report_not_found(
241       "Failed to extract gflags namespace from header file: "
242       "${GFLAGS_HEADER_FILE}.")
243   endif()
244
245   if(GFLAGS_NAMESPACE STREQUAL "google" OR
246      GFLAGS_NAMESPACE STREQUAL "gflags")
247     # Found valid gflags namespace from gflags.h.
248     set(GFLAGS_NAMESPACE "${GFLAGS_NAMESPACE}" PARENT_SCOPE)
249     return()
250   endif()
251
252   # Failed to find gflags namespace from gflags.h, gflags is likely a new
253   # version, check gflags_declare.h, which in newer versions (>= 2.1.2) contains
254   # the GFLAGS_NAMESPACE #define, which is then referenced in gflags.h.
255   set(GFLAGS_DECLARE_FILE ${GFLAGS_INCLUDE_DIR}/gflags/gflags_declare.h)
256   if(NOT EXISTS ${GFLAGS_DECLARE_FILE})
257     gflags_report_not_found(
258       "Could not find file: ${GFLAGS_DECLARE_FILE} "
259       "containing namespace information in gflags install located at: "
260       "${GFLAGS_INCLUDE_DIR}.")
261   endif()
262   file(READ ${GFLAGS_DECLARE_FILE} GFLAGS_DECLARE_FILE_CONTENTS)
263
264   string(REGEX MATCH "#define GFLAGS_NAMESPACE [A-Za-z]+"
265     GFLAGS_NAMESPACE "${GFLAGS_DECLARE_FILE_CONTENTS}")
266   string(REGEX REPLACE "#define GFLAGS_NAMESPACE ([A-Za-z]+)" "\\1"
267     GFLAGS_NAMESPACE "${GFLAGS_NAMESPACE}")
268
269   if(NOT GFLAGS_NAMESPACE)
270     gflags_report_not_found(
271       "Failed to extract gflags namespace from declare file: "
272       "${GFLAGS_DECLARE_FILE}.")
273   endif()
274
275   if(GFLAGS_NAMESPACE STREQUAL "google" OR
276      GFLAGS_NAMESPACE STREQUAL "gflags")
277     # Found valid gflags namespace from gflags.h.
278     set(GFLAGS_NAMESPACE "${GFLAGS_NAMESPACE}" PARENT_SCOPE)
279     return()
280   endif()
281 endfunction()
282
283 # -----------------------------------------------------------------
284 # By default, if the user has expressed no preference for using an exported
285 # gflags CMake configuration over performing a search for the installed
286 # components, and has not specified any hints for the search locations, then
287 # prefer a gflags exported configuration if available.
288 if(NOT DEFINED GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION
289    AND NOT GFLAGS_INCLUDE_DIR_HINTS
290    AND NOT GFLAGS_LIBRARY_DIR_HINTS)
291   message(STATUS "No preference for use of exported gflags CMake configuration "
292     "set, and no hints for include/library directories provided. "
293     "Defaulting to preferring an installed/exported gflags CMake configuration "
294     "if available.")
295   set(GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION TRUE)
296 endif()
297
298 if(GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION)
299   # Try to find an exported CMake configuration for gflags, as generated by
300   # gflags versions >= 2.1.
301   #
302   # We search twice, s/t we can invert the ordering of precedence used by
303   # find_package() for exported package build directories, and installed
304   # packages (found via CMAKE_SYSTEM_PREFIX_PATH), listed as items 6) and 7)
305   # respectively in [1].
306   #
307   # By default, exported build directories are (in theory) detected first, and
308   # this is usually the case on Windows.  However, on OS X & Linux, the install
309   # path (/usr/local) is typically present in the PATH environment variable
310   # which is checked in item 4) in [1] (i.e. before both of the above, unless
311   # NO_SYSTEM_ENVIRONMENT_PATH is passed).  As such on those OSs installed
312   # packages are usually detected in preference to exported package build
313   # directories.
314   #
315   # To ensure a more consistent response across all OSs, and as users usually
316   # want to prefer an installed version of a package over a locally built one
317   # where both exist (esp. as the exported build directory might be removed
318   # after installation), we first search with NO_CMAKE_PACKAGE_REGISTRY which
319   # means any build directories exported by the user are ignored, and thus
320   # installed directories are preferred.  If this fails to find the package
321   # we then research again, but without NO_CMAKE_PACKAGE_REGISTRY, so any
322   # exported build directories will now be detected.
323   #
324   # To prevent confusion on Windows, we also pass NO_CMAKE_BUILDS_PATH (which
325   # is item 5) in [1]), to not preferentially use projects that were built
326   # recently with the CMake GUI to ensure that we always prefer an installed
327   # version if available.
328   #
329   # [1] http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:find_package
330   find_package(gflags QUIET
331                       NO_MODULE
332                       NO_CMAKE_PACKAGE_REGISTRY
333                       NO_CMAKE_BUILDS_PATH)
334   if(gflags_FOUND)
335     message(STATUS "Found installed version of gflags: ${gflags_DIR}")
336   else()
337     # Failed to find an installed version of gflags, repeat search allowing
338     # exported build directories.
339     message(STATUS "Failed to find installed gflags CMake configuration, "
340       "searching for gflags build directories exported with CMake.")
341     # Again pass NO_CMAKE_BUILDS_PATH, as we know that gflags is exported and
342     # do not want to treat projects built with the CMake GUI preferentially.
343     find_package(gflags QUIET
344                         NO_MODULE
345                         NO_CMAKE_BUILDS_PATH)
346     if(gflags_FOUND)
347       message(STATUS "Found exported gflags build directory: ${gflags_DIR}")
348     endif()
349   endif()
350
351   set(FOUND_INSTALLED_GFLAGS_CMAKE_CONFIGURATION ${gflags_FOUND})
352
353   # gflags v2.1 - 2.1.2 shipped with a bug in their gflags-config.cmake [1]
354   # whereby gflags_LIBRARIES = "gflags", but there was no imported target
355   # called "gflags", they were called: gflags[_nothreads]-[static/shared].
356   # As this causes linker errors when gflags is not installed in a location
357   # on the current library paths, detect if this problem is present and
358   # fix it.
359   #
360   # [1] https://github.com/gflags/gflags/issues/110
361   if(gflags_FOUND)
362     # NOTE: This is not written as additional conditions in the outer
363     #       if(gflags_FOUND) as the NOT TARGET "${gflags_LIBRARIES}"
364     #       condition causes problems if gflags is not found.
365     if(${gflags_VERSION} VERSION_LESS 2.1.3 AND
366         NOT TARGET "${gflags_LIBRARIES}")
367       message(STATUS "Detected broken gflags install in: ${gflags_DIR}, "
368         "version: ${gflags_VERSION} <= 2.1.2 which defines gflags_LIBRARIES = "
369         "${gflags_LIBRARIES} which is not an imported CMake target, see: "
370         "https://github.com/gflags/gflags/issues/110.  Attempting to fix by "
371         "detecting correct gflags target.")
372       # Ordering here expresses preference for detection, specifically we do not
373       # want to use the _nothreads variants if the full library is available.
374       list(APPEND CHECK_GFLAGS_IMPORTED_TARGET_NAMES
375         gflags-shared gflags-static
376         gflags_nothreads-shared gflags_nothreads-static)
377       foreach(CHECK_GFLAGS_TARGET ${CHECK_GFLAGS_IMPORTED_TARGET_NAMES})
378         if(TARGET ${CHECK_GFLAGS_TARGET})
379           message(STATUS "Found valid gflags target: ${CHECK_GFLAGS_TARGET}, "
380             "updating gflags_LIBRARIES.")
381           set(gflags_LIBRARIES ${CHECK_GFLAGS_TARGET})
382           break()
383         endif()
384       endforeach()
385       if(NOT TARGET ${gflags_LIBRARIES})
386         message(STATUS "Failed to fix detected broken gflags install in: "
387           "${gflags_DIR}, version: ${gflags_VERSION} <= 2.1.2, none of the "
388           "imported targets for gflags: ${CHECK_GFLAGS_IMPORTED_TARGET_NAMES} "
389           "are defined.  Will continue with a manual search for gflags "
390           "components.  We recommend you build/install a version of gflags > "
391           "2.1.2 (or master).")
392         set(FOUND_INSTALLED_GFLAGS_CMAKE_CONFIGURATION FALSE)
393       endif()
394     endif()
395   endif()
396
397   if(FOUND_INSTALLED_GFLAGS_CMAKE_CONFIGURATION)
398     message(STATUS "Detected gflags version: ${gflags_VERSION}")
399     set(GFLAGS_FOUND ${gflags_FOUND})
400     set(GFLAGS_INCLUDE_DIR ${gflags_INCLUDE_DIR})
401     set(GFLAGS_LIBRARY ${gflags_LIBRARIES})
402
403     # gflags does not export the namespace in their CMake configuration, so
404     # use our function to determine what it should be, as it can be either
405     # gflags or google dependent upon version & configuration.
406     #
407     # NOTE: We use the regex method to determine the namespace here, as
408     #       check_cxx_source_compiles() will not use imported targets, which
409     #       is what gflags will be in this case.
410     gflags_check_gflags_namespace_using_regex()
411
412     if(NOT GFLAGS_NAMESPACE)
413       gflags_report_not_found(
414         "Failed to determine gflags namespace using regex for gflags "
415         "version: ${gflags_VERSION} exported here: ${gflags_DIR} using CMake.")
416     endif()
417   else()
418     message(STATUS "Failed to find an installed/exported CMake configuration "
419       "for gflags, will perform search for installed gflags components.")
420   endif()
421 endif()
422
423 if(NOT GFLAGS_FOUND)
424   # Either failed to find an exported gflags CMake configuration, or user
425   # told us not to use one.  Perform a manual search for all gflags components.
426
427   # Handle possible presence of lib prefix for libraries on MSVC, see
428   # also GFLAGS_RESET_FIND_LIBRARY_PREFIX().
429   if(MSVC)
430     # Preserve the caller's original values for CMAKE_FIND_LIBRARY_PREFIXES
431     # s/t we can set it back before returning.
432     set(CALLERS_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
433     # The empty string in this list is important, it represents the case when
434     # the libraries have no prefix (shared libraries / DLLs).
435     set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "" "${CMAKE_FIND_LIBRARY_PREFIXES}")
436   endif()
437
438   # Search user-installed locations first, so that we prefer user installs
439   # to system installs where both exist.
440   list(APPEND GFLAGS_CHECK_INCLUDE_DIRS
441     ${GFLAGS_ROOT_DIR_INCLUDE}
442     /usr/local/include
443     /usr/local/homebrew/include # Mac OS X
444     /opt/local/var/macports/software # Mac OS X.
445     /opt/local/include
446     /usr/include
447     /sw/include # Fink
448     /opt/csw/include # Blastwave
449     /opt/lib/gflags/include)
450
451   list(APPEND GFLAGS_CHECK_PATH_SUFFIXES
452     gflags/include # Windows (for C:/Program Files prefix).
453     gflags/Include) # Windows (for C:/Program Files prefix).
454
455   list(APPEND GFLAGS_CHECK_LIBRARY_DIRS
456     ${GFLAGS_ROOT_DIR_LIB}
457     /usr/local/lib
458     /usr/local/homebrew/lib # Mac OS X.
459     /opt/local/lib
460     /usr/lib
461     /sw/lib # Fink
462     /opt/csw/lib # Blastwave
463     /opt/lib/gflags/lib)
464   list(APPEND GFLAGS_CHECK_LIBRARY_SUFFIXES
465     gflags/lib # Windows (for C:/Program Files prefix).
466     gflags/Lib) # Windows (for C:/Program Files prefix).
467
468   # Search supplied hint directories first if supplied.
469   find_path(GFLAGS_INCLUDE_DIR
470     NAMES gflags/gflags.h
471     PATHS ${GFLAGS_INCLUDE_DIR_HINTS}
472     ${GFLAGS_CHECK_INCLUDE_DIRS}
473     PATH_SUFFIXES ${GFLAGS_CHECK_PATH_SUFFIXES})
474   if(NOT GFLAGS_INCLUDE_DIR OR
475       NOT EXISTS ${GFLAGS_INCLUDE_DIR})
476     gflags_report_not_found(
477       "Could not find gflags include directory, set GFLAGS_INCLUDE_DIR "
478       "to directory containing gflags/gflags.h")
479   endif(NOT GFLAGS_INCLUDE_DIR OR
480     NOT EXISTS ${GFLAGS_INCLUDE_DIR})
481
482   find_library(GFLAGS_LIBRARY NAMES gflags
483     PATHS ${GFLAGS_LIBRARY_DIR_HINTS}
484     ${GFLAGS_CHECK_LIBRARY_DIRS}
485     PATH_SUFFIXES ${GFLAGS_CHECK_LIBRARY_SUFFIXES})
486   if(NOT GFLAGS_LIBRARY OR
487       NOT EXISTS ${GFLAGS_LIBRARY})
488     gflags_report_not_found(
489       "Could not find gflags library, set GFLAGS_LIBRARY "
490       "to full path to libgflags.")
491   endif(NOT GFLAGS_LIBRARY OR
492     NOT EXISTS ${GFLAGS_LIBRARY})
493
494   # gflags typically requires a threading library (which is OS dependent), note
495   # that this defines the CMAKE_THREAD_LIBS_INIT variable.  If we are able to
496   # detect threads, we assume that gflags requires it.
497   find_package(Threads QUIET)
498   set(GFLAGS_LINK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
499   # On Windows (including MinGW), the Shlwapi library is used by gflags if
500   # available.
501   if(WIN32)
502     include(CheckIncludeFileCXX)
503     check_include_file_cxx("shlwapi.h" HAVE_SHLWAPI)
504     if(HAVE_SHLWAPI)
505       list(APPEND GFLAGS_LINK_LIBRARIES shlwapi.lib)
506     endif()
507   endif()
508
509   # Mark internally as found, then verify. GFLAGS_REPORT_NOT_FOUND() unsets
510   # if called.
511   set(GFLAGS_FOUND TRUE)
512
513   # Identify what namespace gflags was built with.
514   if(GFLAGS_INCLUDE_DIR AND NOT GFLAGS_NAMESPACE)
515     # To handle Windows peculiarities / CMake bugs on MSVC we try two approaches
516     # to detect the gflags namespace:
517     #
518     # 1) Try to use check_cxx_source_compiles() to compile a trivial program
519     #    with the two choices for the gflags namespace.
520     #
521     # 2) [In the event 1) fails] Use regex on the gflags headers to try to
522     #    determine the gflags namespace.  Whilst this is less robust than 1),
523     #    it does avoid any interaction with msbuild.
524     gflags_check_gflags_namespace_using_try_compile()
525
526     if(NOT GFLAGS_NAMESPACE)
527       # Failed to determine gflags namespace using check_cxx_source_compiles()
528       # method, try and obtain it using regex on the gflags headers instead.
529       message(STATUS "Failed to find gflags namespace using using "
530         "check_cxx_source_compiles(), trying namespace regex instead, "
531         "this is expected on Windows.")
532       gflags_check_gflags_namespace_using_regex()
533
534       if(NOT GFLAGS_NAMESPACE)
535         gflags_report_not_found(
536           "Failed to determine gflags namespace either by "
537           "check_cxx_source_compiles(), or namespace regex.")
538       endif()
539     endif()
540   endif()
541
542   # Make the GFLAGS_NAMESPACE a cache variable s/t the user can view it, and could
543   # overwrite it in the CMake GUI.
544   set(GFLAGS_NAMESPACE "${GFLAGS_NAMESPACE}" CACHE STRING
545     "gflags namespace (google or gflags)" FORCE)
546
547   # gflags does not seem to provide any record of the version in its
548   # source tree, thus cannot extract version.
549
550   # Catch case when caller has set GFLAGS_NAMESPACE in the cache / GUI
551   # with an invalid value.
552   if(GFLAGS_NAMESPACE AND
553       NOT GFLAGS_NAMESPACE STREQUAL "google" AND
554       NOT GFLAGS_NAMESPACE STREQUAL "gflags")
555     gflags_report_not_found(
556       "Caller defined GFLAGS_NAMESPACE:"
557       " ${GFLAGS_NAMESPACE} is not valid, not google or gflags.")
558   endif()
559   # Catch case when caller has set GFLAGS_INCLUDE_DIR in the cache / GUI and
560   # thus FIND_[PATH/LIBRARY] are not called, but specified locations are
561   # invalid, otherwise we would report the library as found.
562   if(GFLAGS_INCLUDE_DIR AND
563       NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
564     gflags_report_not_found(
565       "Caller defined GFLAGS_INCLUDE_DIR:"
566       " ${GFLAGS_INCLUDE_DIR} does not contain gflags/gflags.h header.")
567   endif(GFLAGS_INCLUDE_DIR AND
568     NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
569   # TODO: This regex for gflags library is pretty primitive, we use lowercase
570   #       for comparison to handle Windows using CamelCase library names, could
571   #       this check be better?
572   string(TOLOWER "${GFLAGS_LIBRARY}" LOWERCASE_GFLAGS_LIBRARY)
573   if(GFLAGS_LIBRARY AND
574       NOT "${LOWERCASE_GFLAGS_LIBRARY}" MATCHES ".*gflags[^/]*")
575     gflags_report_not_found(
576       "Caller defined GFLAGS_LIBRARY: "
577       "${GFLAGS_LIBRARY} does not match gflags.")
578   endif(GFLAGS_LIBRARY AND
579     NOT "${LOWERCASE_GFLAGS_LIBRARY}" MATCHES ".*gflags[^/]*")
580
581   gflags_reset_find_library_prefix()
582
583 endif()
584
585 # Set standard CMake FindPackage variables if found.
586 if(GFLAGS_FOUND)
587   set(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR})
588   set(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY} ${GFLAGS_LINK_LIBRARIES})
589 endif()
590
591 # Handle REQUIRED / QUIET optional arguments.
592 include(FindPackageHandleStandardArgs)
593 find_package_handle_standard_args(GFLAGS DEFAULT_MSG
594   GFLAGS_INCLUDE_DIRS GFLAGS_LIBRARIES GFLAGS_NAMESPACE)
595
596 # Only mark internal variables as advanced if we found gflags, otherwise
597 # leave them visible in the standard GUI for the user to set manually.
598 if(GFLAGS_FOUND)
599   mark_as_advanced(FORCE GFLAGS_INCLUDE_DIR
600     GFLAGS_LIBRARY
601     GFLAGS_NAMESPACE
602     gflags_DIR) # Autogenerated by find_package(gflags)
603 endif()