1# Ceres Solver - A fast non-linear least squares minimizer
2# Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3# http://code.google.com/p/ceres-solver/
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# Authors: keir@google.com (Keir Mierle)
30#          alexs.mac@gmail.com (Alex Stewart)
31
32CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
33CMAKE_POLICY(VERSION 2.8)
34
35IF (COMMAND cmake_policy)
36  CMAKE_POLICY(SET CMP0003 NEW)
37ENDIF (COMMAND cmake_policy)
38
39PROJECT(CERES C CXX)
40
41# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
42SET (LOCAL_GIT_DIRECTORY)
43IF (EXISTS ${CMAKE_SOURCE_DIR}/.git)
44  # .git directory can be found on Unix based system, or on Windows with
45  # Git Bash (shipped with msysgit)
46  SET (LOCAL_GIT_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
47ELSE (EXISTS ${CMAKE_SOURCE_DIR}/.git)
48  # TODO(keir) Add proper Windows support
49ENDIF (EXISTS ${CMAKE_SOURCE_DIR}/.git)
50
51IF (EXISTS ${LOCAL_GIT_DIRECTORY})
52  IF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
53    # Download the hook only if it is not already present
54    FILE(DOWNLOAD https://ceres-solver-review.googlesource.com/tools/hooks/commit-msg
55         ${CMAKE_BINARY_DIR}/commit-msg)
56
57    # Make the downloaded file executable, since it is not by default.
58    FILE(COPY ${CMAKE_BINARY_DIR}/commit-msg
59         DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
60         FILE_PERMISSIONS
61           OWNER_READ OWNER_WRITE OWNER_EXECUTE
62           GROUP_READ GROUP_WRITE GROUP_EXECUTE
63           WORLD_READ WORLD_EXECUTE)
64  ENDIF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
65ENDIF (EXISTS ${LOCAL_GIT_DIRECTORY})
66
67# Make CMake aware of the cmake folder for local FindXXX scripts,
68# append rather than set in case the user has passed their own
69# additional paths via -D.
70LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
71INCLUDE(UpdateCacheVariable)
72
73SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
74SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
75SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
76# Set postfixes for generated libraries based on buildtype.
77SET(CMAKE_RELEASE_POSTFIX "")
78SET(CMAKE_DEBUG_POSTFIX "-debug")
79
80# Important: Always bump the second number (e.g. 1.3.x to 1.4.0) for any
81# release that changes the ABI. The ABI changes for almost any modification to
82# include/ceres (e.g. the public API). If you are unsure about whether
83# something is an ABI change, please ask on the list.
84#
85# For versions without ABI changes, bump the smallest number in CERES_VERSION,
86# but leave the CERES_ABI_VERSION unchanged.
87SET(CERES_VERSION_MAJOR 1)
88SET(CERES_VERSION_MINOR 9)
89SET(CERES_VERSION_PATCH 0)
90SET(CERES_VERSION
91    ${CERES_VERSION_MAJOR}.${CERES_VERSION_MINOR}.${CERES_VERSION_PATCH})
92SET(CERES_ABI_VERSION 1.9.0)
93
94ENABLE_TESTING()
95
96OPTION(MINIGLOG "Use a stripped down version of glog." OFF)
97OPTION(GFLAGS "Enable Google Flags." ON)
98OPTION(SUITESPARSE "Enable SuiteSparse." ON)
99OPTION(CXSPARSE "Enable CXSparse." ON)
100OPTION(LAPACK "Enable use of LAPACK." ON)
101# Template specializations for the Schur complement based solvers. If
102# compile time, binary size or compiler performance is an issue, you
103# may consider disabling this.
104OPTION(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
105OPTION(CUSTOM_BLAS
106       "Use handcoded BLAS routines (usually faster) instead of Eigen."
107       ON)
108# Multithreading using OpenMP
109OPTION(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON)
110OPTION(EIGENSPARSE
111  "Enable the use of Eigen as a sparse linear algebra library for
112   solving the nonlinear least squares problems. Enabling this
113   option will result in an LGPL licensed version of Ceres Solver
114   as the Simplicial Cholesky factorization in Eigen is licensed under the LGPL.
115   This does not affect the covariance estimation algorithm, as it
116   depends on the sparse QR factorization algorithm, which is licensed
117   under the MPL."
118  OFF)
119OPTION(BUILD_TESTING "Enable tests" ON)
120OPTION(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
121OPTION(BUILD_EXAMPLES "Build examples" ON)
122OPTION(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
123IF (MSVC)
124  OPTION(MSVC_USE_STATIC_CRT
125    "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
126
127  IF (BUILD_TESTING AND BUILD_SHARED_LIBS)
128    MESSAGE(
129      "-- Disabling tests. The flags BUILD_TESTING and BUILD_SHARED_LIBS"
130      " are incompatible with MSVC."
131      )
132    UPDATE_CACHE_VARIABLE(BUILD_TESTING OFF)
133  ENDIF (BUILD_TESTING AND BUILD_SHARED_LIBS)
134ENDIF (MSVC)
135
136# Use ios-cmake to build a static library for iOS
137#
138# We need to add isysroot to force cmake to find the toolchains from the iOS SDK
139# instead of using the standard ones. And add flag mios-simulator-version so clang
140# knows we are building for ios simulator but not mac.
141#
142# You can build for OS (armv7, armv7s, arm64), SIMULATOR (i386) or SIMULATOR64 (x86_64)
143# separately and use lipo to merge them into one static library.
144#
145# There are some features/algorithms are not available in iOS version and the
146# minimum supported iOS version is 6.0 now.
147#
148# Use cmake ../ceres-solver -DCMAKE_TOOLCHAIN_FILE=../ceres-solver/cmake/iOS.cmake \
149# -DIOS_PLATFORM=PLATFORM -DEIGEN_INCLUDE_DIR=/path/to/eigen/header
150# to config the cmake. The PLATFORM can be one of OS, SIMULATOR and SIMULATOR64.
151# Check the documentation in iOS.cmake to find more options.
152#
153# After building, you will get a single library: libceres.a, which
154# you need to add to your Xcode project.
155#
156# If you use the lapack and blas, then you also need to add Accelerate.framework
157# to your Xcode project's linking dependency.
158IF (IOS)
159  MESSAGE(STATUS "Building Ceres for iOS platform: ${IOS_PLATFORM}")
160
161  UPDATE_CACHE_VARIABLE(MINIGLOG ON)
162  MESSAGE(STATUS "Building for iOS, forcing use of miniglog instead of glog.")
163
164  UPDATE_CACHE_VARIABLE(SUITESPARSE OFF)
165  UPDATE_CACHE_VARIABLE(CXSPARSE OFF)
166  UPDATE_CACHE_VARIABLE(GFLAGS OFF)
167  UPDATE_CACHE_VARIABLE(OPENMP OFF)
168
169  MESSAGE(STATUS "Building for iOS: SuiteSparse, CXSparse, gflags and OpenMP are not available.")
170
171  UPDATE_CACHE_VARIABLE(BUILD_EXAMPLES OFF)
172  MESSAGE(STATUS "Building for iOS, will not build examples.")
173
174  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-abi-version=2 -fobjc-arc -isysroot ${CMAKE_OSX_SYSROOT}")
175  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-abi-version=2 -fobjc-arc -isysroot ${CMAKE_OSX_SYSROOT}")
176
177  IF (${IOS_PLATFORM} STREQUAL "SIMULATOR" OR ${IOS_PLATFORM} STREQUAL "SIMULATOR64")
178    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mios-simulator-version-min=6.0")
179  ENDIF()
180ENDIF (IOS)
181
182# Prior to October 2013, Ceres used some non-CMake standardised variables to
183# hold user-specified (as opposed to FindPackage found) include directory and
184# library paths for Ceres dependencies.  These were were of the form:
185# <DEPENDENCY>_LIB / <DEPENDENCY>_INCLUDE.  Since then, Ceres now has
186# FindPackage() scripts for all of its dependencies which obey the standard
187# CMake variables: <DEPENDENCY>_LIBRARIES & <DEPENDENCY>_INCLUDE_DIRS.  In order
188# to ensure backwards compatibility, we use convert any legacy variables to
189# _directory_ hints for the FindPackage() scripts.
190MACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT
191    LEGACY_VAR DIRECTORY_HINT_VAR)
192  IF (DEFINED ${LEGACY_VAR})
193    # Get the dependency name (all caps) from the hint directory variable
194    # for the warning message.
195    STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
196    MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
197      "to specify the include directory for ${DEPENDENCY_NAME}.  This is "
198      "deprecated and support for it will be removed in a future release. "
199      "Please use either the search directory hints variable: "
200      "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_INCLUDE_DIR to specify "
201      "exactly the directory used (no search performed), see: "
202      "http://homes.cs.washington.edu/~sagarwal/ceres-solver/dev/building.html "
203      "for more information.")
204    LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
205  ENDIF (DEFINED ${LEGACY_VAR})
206ENDMACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT)
207
208MACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT
209    LEGACY_VAR DIRECTORY_HINT_VAR)
210  IF (DEFINED ${LEGACY_VAR})
211    # Get the dependency name (all caps) from the hint directory variable
212    # for the warning message.
213    STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
214    MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
215      "to specify the library for ${DEPENDENCY_NAME}.  This is "
216      "deprecated and support for it will be removed in a future release. "
217      "Please use either the search directory hints variable: "
218      "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_LIBRARY to specify "
219      "exactly the library used (no search performed), see: "
220      "http://homes.cs.washington.edu/~sagarwal/ceres-solver/dev/building.html "
221      "for more information.")
222    IF (EXISTS ${${LEGACY_VAR}} AND
223        NOT IS_DIRECTORY ${${LEGACY_VAR}})
224      # User specified an explicit (library) file using the legacy variable
225      # interface, hints to FindPackage() scripts are directories so add the
226      # parent directory of the specified file.
227      GET_FILENAME_COMPONENT(DIR_HINT ${${LEGACY_VAR}} PATH)
228      LIST(APPEND ${DIRECTORY_HINT_VAR} ${DIR_HINT})
229    ELSEIF (EXISTS ${${LEGACY_VAR}} AND
230            IS_DIRECTORY ${${LEGACY_VAR}})
231      # User specified a directory hint using the legacy variable, use it.
232      LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
233    ENDIF()
234  ENDIF (DEFINED ${LEGACY_VAR})
235ENDMACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT)
236
237UNSET(CERES_COMPILE_OPTIONS)
238
239# Eigen.
240HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS)
241FIND_PACKAGE(Eigen REQUIRED)
242IF (EIGEN_FOUND)
243  MESSAGE("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}")
244  # Ensure that only MPL2 licensed code is part of the default build.
245  MESSAGE("")
246  MESSAGE("   ===============================================================")
247  IF (EIGENSPARSE)
248    LIST(APPEND CERES_COMPILE_OPTIONS CERES_USE_EIGEN_SPARSE)
249    MESSAGE("   Enabling the use of Eigen as a sparse linear algebra library ")
250    MESSAGE("   for solving the nonlinear least squares problems. Enabling ")
251    MESSAGE("   this option will result in an LGPL licensed version of ")
252    MESSAGE("   Ceres Solver as the Simplicial Cholesky factorization in Eigen")
253    MESSAGE("   is licensed under the LGPL. ")
254  ELSE (EIGENSPARSE)
255    MESSAGE("   Disabling the use of Eigen as a sparse linear algebra library.")
256    MESSAGE("   This does not affect the covariance estimation algorithm ")
257    MESSAGE("   which can still use the EIGEN_SPARSE_QR algorithm.")
258    ADD_DEFINITIONS(-DEIGEN_MPL2_ONLY)
259  ENDIF (EIGENSPARSE)
260    MESSAGE("   ===============================================================")
261    MESSAGE("")
262ENDIF (EIGEN_FOUND)
263
264# LAPACK (& BLAS).
265IF (LAPACK)
266  FIND_PACKAGE(LAPACK QUIET)
267  IF (LAPACK_FOUND)
268    MESSAGE("-- Found LAPACK library: ${LAPACK_LIBRARIES}")
269  ELSE (LAPACK_FOUND)
270    MESSAGE("-- Did not find LAPACK library, disabling LAPACK support.")
271  ENDIF (LAPACK_FOUND)
272
273  FIND_PACKAGE(BLAS QUIET)
274  IF (BLAS_FOUND)
275    MESSAGE("-- Found BLAS library: ${BLAS_LIBRARIES}")
276  ELSE (BLAS_FOUND)
277    MESSAGE("-- Did not find BLAS library, disabling LAPACK support.")
278  ENDIF (BLAS_FOUND)
279
280  IF (NOT (LAPACK_FOUND AND BLAS_FOUND))
281    UPDATE_CACHE_VARIABLE(LAPACK OFF)
282    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
283  ENDIF (NOT (LAPACK_FOUND AND BLAS_FOUND))
284ELSE (LAPACK)
285  MESSAGE("-- Building without LAPACK.")
286  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
287ENDIF (LAPACK)
288
289# SuiteSparse.
290IF (SUITESPARSE AND NOT LAPACK)
291  # If user has disabled LAPACK, but left SUITESPARSE ON, turn it OFF,
292  # LAPACK controls whether Ceres will be linked, directly or indirectly
293  # via SuiteSparse to LAPACK.
294  MESSAGE("-- Disabling SuiteSparse as use of LAPACK has been disabled, "
295    "turn ON LAPACK to enable (optional) building with SuiteSparse.")
296  UPDATE_CACHE_VARIABLE(SUITESPARSE OFF)
297ENDIF (SUITESPARSE AND NOT LAPACK)
298IF (SUITESPARSE)
299  # By default, if SuiteSparse and all dependencies are found, Ceres is
300  # built with SuiteSparse support.
301
302  # Check for SuiteSparse and dependencies.
303  FIND_PACKAGE(SuiteSparse)
304  IF (SUITESPARSE_FOUND)
305    # On Ubuntu the system install of SuiteSparse (v3.4.0) up to at least
306    # Ubuntu 13.10 cannot be used to link shared libraries.
307    IF (BUILD_SHARED_LIBS AND
308        SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
309      MESSAGE(FATAL_ERROR "You are attempting to build Ceres as a shared "
310        "library on Ubuntu using a system package install of SuiteSparse "
311        "3.4.0. This package is broken and does not support the "
312        "construction of shared libraries (you can still build Ceres as "
313        "a static library).  If you wish to build a shared version of Ceres "
314        "you should uninstall the system install of SuiteSparse "
315        "(libsuitesparse-dev) and perform a source install of SuiteSparse "
316        "(we recommend that you use the latest version), "
317        "see: http://homes.cs.washington.edu/~sagarwal"
318        "/ceres-solver/dev/building.html for more information.")
319    ENDIF (BUILD_SHARED_LIBS AND
320      SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
321
322    # By default, if all of SuiteSparse's dependencies are found, Ceres is
323    # built with SuiteSparse support.
324    MESSAGE("-- Found SuiteSparse ${SUITESPARSE_VERSION}, "
325            "building with SuiteSparse.")
326  ELSE (SUITESPARSE_FOUND)
327    # Disable use of SuiteSparse if it cannot be found and continue.
328    MESSAGE("-- Did not find all SuiteSparse dependencies, disabling "
329      "SuiteSparse support.")
330    UPDATE_CACHE_VARIABLE(SUITESPARSE OFF)
331    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
332  ENDIF (SUITESPARSE_FOUND)
333ELSE (SUITESPARSE)
334  MESSAGE("-- Building without SuiteSparse.")
335  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
336ENDIF (SUITESPARSE)
337
338# CXSparse.
339IF (CXSPARSE)
340  # Don't search with REQUIRED as we can continue without CXSparse.
341  FIND_PACKAGE(CXSparse)
342  IF (CXSPARSE_FOUND)
343    # By default, if CXSparse and all dependencies are found, Ceres is
344    # built with CXSparse support.
345    MESSAGE("-- Found CXSparse version: ${CXSPARSE_VERSION}, "
346      "building with CXSparse.")
347  ELSE (CXSPARSE_FOUND)
348    # Disable use of CXSparse if it cannot be found and continue.
349    MESSAGE("-- Did not find CXSparse, Building without CXSparse.")
350    UPDATE_CACHE_VARIABLE(CXSPARSE OFF)
351    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
352  ENDIF (CXSPARSE_FOUND)
353ELSE (CXSPARSE)
354  MESSAGE("-- Building without CXSparse.")
355  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
356  # Mark as advanced (remove from default GUI view) the CXSparse search
357  # variables in case user enabled CXSPARSE, FindCXSparse did not find it, so
358  # made search variables visible in GUI for user to set, but then user disables
359  # CXSPARSE instead of setting them.
360  MARK_AS_ADVANCED(FORCE CXSPARSE_INCLUDE_DIR
361                         CXSPARSE_LIBRARY)
362ENDIF (CXSPARSE)
363
364# GFlags.
365IF (GFLAGS)
366  HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GFLAGS_INCLUDE GFLAGS_INCLUDE_DIR_HINTS)
367  HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GFLAGS_LIB GFLAGS_LIBRARY_DIR_HINTS)
368
369  # Don't search with REQUIRED as we can continue without gflags.
370  FIND_PACKAGE(Gflags)
371  IF (GFLAGS_FOUND)
372    MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}")
373  ELSE (GFLAGS_FOUND)
374    MESSAGE("-- Did not find Google Flags (gflags), Building without gflags "
375      "- no tests or tools will be built!")
376    UPDATE_CACHE_VARIABLE(GFLAGS OFF)
377  ENDIF (GFLAGS_FOUND)
378ELSE (GFLAGS)
379  MESSAGE("-- Google Flags disabled; no tests or tools will be built!")
380  # Mark as advanced (remove from default GUI view) the gflags search
381  # variables in case user enabled GFLAGS, FindGflags did not find it, so
382  # made search variables visible in GUI for user to set, but then user disables
383  # GFLAGS instead of setting them.
384  MARK_AS_ADVANCED(FORCE GFLAGS_INCLUDE_DIR
385                         GFLAGS_LIBRARY)
386ENDIF (GFLAGS)
387
388# MiniGLog.
389IF (MINIGLOG)
390  MESSAGE("-- Compiling minimal glog substitute into Ceres.")
391  SET(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
392  MESSAGE("-- Using minimal glog substitute (include): ${GLOG_INCLUDE_DIRS}")
393
394  # Mark as advanced (remove from default GUI view) the glog search
395  # variables in case user disables MINIGLOG, FindGlog did not find it, so
396  # made search variables visible in GUI for user to set, but then user enables
397  # MINIGLOG instead of setting them.
398  MARK_AS_ADVANCED(FORCE GLOG_INCLUDE_DIR
399                         GLOG_LIBRARY)
400ELSE (MINIGLOG)
401  HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GLOG_INCLUDE GLOG_INCLUDE_DIR_HINTS)
402  HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GLOG_LIB GLOG_LIBRARY_DIR_HINTS)
403
404  # Don't search with REQUIRED so that configuration continues if not found and
405  # we can output an error messages explaining MINIGLOG option.
406  FIND_PACKAGE(Glog)
407  IF (GLOG_FOUND)
408    MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE_DIRS}")
409  ELSE (GLOG_FOUND)
410    MESSAGE(FATAL_ERROR "Can't find Google Log. Please set GLOG_INCLUDE_DIR & "
411      "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
412      "implementation.")
413  ENDIF (GLOG_FOUND)
414ENDIF (MINIGLOG)
415
416IF (NOT SCHUR_SPECIALIZATIONS)
417  LIST(APPEND CERES_COMPILE_OPTIONS CERES_RESTRICT_SCHUR_SPECIALIZATION)
418  MESSAGE("-- Disabling Schur specializations (faster compiles)")
419ENDIF (NOT SCHUR_SPECIALIZATIONS)
420
421IF (NOT CUSTOM_BLAS)
422  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CUSTOM_BLAS)
423  MESSAGE("-- Disabling custom blas")
424ENDIF (NOT CUSTOM_BLAS)
425
426IF (OPENMP)
427  # Clang does not (yet) support OpenMP.
428  IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
429    UPDATE_CACHE_VARIABLE(OPENMP OFF)
430    MESSAGE("-- Compiler is Clang, disabling OpenMP.")
431    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
432  ELSE (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
433    # Find quietly s/t as we can continue without OpenMP if it is not found.
434    FIND_PACKAGE(OpenMP QUIET)
435    IF (OPENMP_FOUND)
436      MESSAGE("-- Building with OpenMP.")
437      LIST(APPEND CERES_COMPILE_OPTIONS CERES_USE_OPENMP)
438      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
439      IF (UNIX)
440        # At least on Linux, we need pthreads to be enabled for mutex to
441        # compile.  This may not work on Windows or Android.
442        FIND_PACKAGE(Threads REQUIRED)
443        LIST(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_PTHREAD)
444        LIST(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_RWLOCK)
445      ENDIF (UNIX)
446    ELSE (OPENMP_FOUND)
447      MESSAGE("-- Failed to find OpenMP, disabling.")
448      UPDATE_CACHE_VARIABLE(OPENMP OFF)
449      LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
450    ENDIF (OPENMP_FOUND)
451  ENDIF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
452ELSE (OPENMP)
453  MESSAGE("-- Building without OpenMP (disabling multithreading).")
454  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
455ENDIF (OPENMP)
456
457INCLUDE(CheckIncludeFileCXX)
458CHECK_INCLUDE_FILE_CXX(unordered_map HAVE_STD_UNORDERED_MAP_HEADER)
459IF (HAVE_STD_UNORDERED_MAP_HEADER)
460  # Finding the unordered_map header doesn't mean that unordered_map
461  # is in std namespace.
462  #
463  # In particular, MSVC 2008 has unordered_map declared in std::tr1.
464  # In order to support this, we do an extra check to see which
465  # namespace should be used.
466  INCLUDE(CheckCXXSourceCompiles)
467  CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
468                             int main() {
469                               std::unordered_map<int, int> map;
470                               return 0;
471                             }"
472                            HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
473  IF (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
474    LIST(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP)
475    MESSAGE("-- Found unordered_map/set in std namespace.")
476  ELSE (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
477    CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
478                               int main() {
479                                 std::tr1::unordered_map<int, int> map;
480                                 return 0;
481                               }"
482                              HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
483    IF (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
484      LIST(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
485      MESSAGE("-- Found unordered_map/set in std::tr1 namespace.")
486    ELSE (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
487      MESSAGE("-- Found <unordered_map> but cannot find either std::unordered_map "
488              "or std::tr1::unordered_map.")
489      MESSAGE("-- Replacing unordered_map/set with map/set (warning: slower!)")
490      LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP)
491    ENDIF (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
492  ENDIF (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
493ELSE (HAVE_STD_UNORDERED_MAP_HEADER)
494  CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP_HEADER)
495  IF (HAVE_TR1_UNORDERED_MAP_HEADER)
496    LIST(APPEND CERES_COMPILE_OPTIONS CERES_TR1_UNORDERED_MAP)
497    MESSAGE("-- Found tr1/unordered_map/set in std::tr1 namespace.")
498  ELSE (HAVE_TR1_UNORDERED_MAP_HEADE)
499    MESSAGE("-- Unable to find <unordered_map> or <tr1/unordered_map>. ")
500    MESSAGE("-- Replacing unordered_map/set with map/set (warning: slower!)")
501    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP)
502  ENDIF (HAVE_TR1_UNORDERED_MAP_HEADER)
503ENDIF (HAVE_STD_UNORDERED_MAP_HEADER)
504
505INCLUDE(FindSharedPtr)
506FIND_SHARED_PTR()
507IF (SHARED_PTR_FOUND)
508  IF (SHARED_PTR_TR1_MEMORY_HEADER)
509    LIST(APPEND CERES_COMPILE_OPTIONS CERES_TR1_MEMORY_HEADER)
510  ENDIF (SHARED_PTR_TR1_MEMORY_HEADER)
511  IF (SHARED_PTR_TR1_NAMESPACE)
512    LIST(APPEND CERES_COMPILE_OPTIONS CERES_TR1_SHARED_PTR)
513  ENDIF (SHARED_PTR_TR1_NAMESPACE)
514ELSE (SHARED_PTR_FOUND)
515  MESSAGE(FATAL_ERROR "Unable to find shared_ptr.")
516ENDIF (SHARED_PTR_FOUND)
517
518INCLUDE_DIRECTORIES(
519  include
520  internal
521  internal/ceres
522  ${GLOG_INCLUDE_DIRS}
523  ${EIGEN_INCLUDE_DIRS})
524
525IF (SUITESPARSE)
526  INCLUDE_DIRECTORIES(${SUITESPARSE_INCLUDE_DIRS})
527ENDIF (SUITESPARSE)
528
529IF (CXSPARSE)
530  INCLUDE_DIRECTORIES(${CXSPARSE_INCLUDE_DIRS})
531ENDIF (CXSPARSE)
532
533IF (GFLAGS)
534  INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE_DIRS})
535ENDIF (GFLAGS)
536
537IF (BUILD_SHARED_LIBS)
538  MESSAGE("-- Building Ceres as a shared library.")
539  # The CERES_BUILDING_SHARED_LIBRARY compile definition is NOT stored in
540  # CERES_COMPILE_OPTIONS as it must only be defined when Ceres is compiled
541  # not when it is used as it controls the CERES_EXPORT macro which provides
542  # dllimport/export support in MSVC.
543  ADD_DEFINITIONS(-DCERES_BUILDING_SHARED_LIBRARY)
544  LIST(APPEND CERES_COMPILE_OPTIONS CERES_USING_SHARED_LIBRARY)
545ELSE (BUILD_SHARED_LIBS)
546  MESSAGE("-- Building Ceres as a static library.")
547ENDIF (BUILD_SHARED_LIBS)
548
549# Change the default build type from Debug to Release, while still
550# supporting overriding the build type.
551#
552# The CACHE STRING logic here and elsewhere is needed to force CMake
553# to pay attention to the value of these variables.
554IF (NOT CMAKE_BUILD_TYPE)
555  MESSAGE("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.")
556  SET(CMAKE_BUILD_TYPE Release CACHE STRING
557    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
558    FORCE)
559ELSE (NOT CMAKE_BUILD_TYPE)
560  IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
561    MESSAGE("\n=================================================================================")
562    MESSAGE("\n-- Build type: Debug. Performance will be terrible!")
563    MESSAGE("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.")
564    MESSAGE("\n=================================================================================")
565  ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug")
566ENDIF (NOT CMAKE_BUILD_TYPE)
567
568# Set the default Ceres flags to an empty string.
569SET (CERES_CXX_FLAGS)
570
571IF (CMAKE_BUILD_TYPE STREQUAL "Release")
572  IF (CMAKE_COMPILER_IS_GNUCXX)
573    # Linux
574    IF (CMAKE_SYSTEM_NAME MATCHES "Linux")
575      IF (NOT GCC_VERSION VERSION_LESS 4.2)
576        SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -march=native -mtune=native")
577      ENDIF (NOT GCC_VERSION VERSION_LESS 4.2)
578    ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux")
579    # Mac OS X
580    IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
581      SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -msse3")
582      # Use of -fast only applicable for Apple's GCC
583      # Assume this is being used if GCC version < 4.3 on OSX
584      EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER}
585        ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
586        OUTPUT_VARIABLE GCC_VERSION
587        OUTPUT_STRIP_TRAILING_WHITESPACE)
588      IF (GCC_VERSION VERSION_LESS 4.3)
589        SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -fast")
590      ENDIF (GCC_VERSION VERSION_LESS 4.3)
591    ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
592  ENDIF (CMAKE_COMPILER_IS_GNUCXX)
593  IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
594    # Use of -flto requires use of gold linker & LLVM-gold plugin, which might
595    # well not be present / in use and without which files will compile, but
596    # not link ('file not recognized') so explicitly check for support
597    INCLUDE(CheckCXXCompilerFlag)
598    CHECK_CXX_COMPILER_FLAG("-flto" HAVE_LTO_SUPPORT)
599    IF (HAVE_LTO_SUPPORT)
600      MESSAGE(STATUS "Enabling link-time optimization (-flto)")
601      SET(CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -flto")
602    ELSE ()
603      MESSAGE(STATUS "Compiler/linker does not support link-time optimization (-flto), disabling.")
604    ENDIF (HAVE_LTO_SUPPORT)
605  ENDIF ()
606ENDIF (CMAKE_BUILD_TYPE STREQUAL "Release")
607
608SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CERES_CXX_FLAGS}")
609
610# After the tweaks for the compile settings, disable some warnings on MSVC.
611IF (MSVC)
612  # Disable signed/unsigned int conversion warnings.
613  ADD_DEFINITIONS("/wd4018")
614  # Disable warning about using struct/class for the same symobl.
615  ADD_DEFINITIONS("/wd4099")
616  # Disable warning about the insecurity of using "std::copy".
617  ADD_DEFINITIONS("/wd4996")
618  # Disable performance warning about int-to-bool conversion.
619  ADD_DEFINITIONS("/wd4800")
620  # Disable performance warning about fopen insecurity.
621  ADD_DEFINITIONS("/wd4996")
622  # Disable warning about int64 to int32 conversion. Disabling
623  # this warning may not be correct; needs investigation.
624  # TODO(keir): Investigate these warnings in more detail.
625  ADD_DEFINITIONS("/wd4244")
626  # It's not possible to use STL types in DLL interfaces in a portable and
627  # reliable way. However, that's what happens with Google Log and Google Flags
628  # on Windows. MSVC gets upset about this and throws warnings that we can't do
629  # much about. The real solution is to link static versions of Google Log and
630  # Google Test, but that seems tricky on Windows. So, disable the warning.
631  ADD_DEFINITIONS("/wd4251")
632
633  # Google Flags doesn't have their DLL import/export stuff set up correctly,
634  # which results in linker warnings. This is irrelevant for Ceres, so ignore
635  # the warnings.
636  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049")
637
638  # Update the C/CXX flags for MSVC to use either the static or shared
639  # C-Run Time (CRT) library based on the user option: MSVC_USE_STATIC_CRT.
640  LIST(APPEND C_CXX_FLAGS
641    CMAKE_CXX_FLAGS
642    CMAKE_CXX_FLAGS_DEBUG
643    CMAKE_CXX_FLAGS_RELEASE
644    CMAKE_CXX_FLAGS_MINSIZEREL
645    CMAKE_CXX_FLAGS_RELWITHDEBINFO)
646
647  FOREACH(FLAG_VAR ${C_CXX_FLAGS})
648    IF (MSVC_USE_STATIC_CRT)
649      # Use static CRT.
650      IF (${FLAG_VAR} MATCHES "/MD")
651        STRING(REGEX REPLACE "/MD" "/MT" ${FLAG_VAR} "${${FLAG_VAR}}")
652      ENDIF (${FLAG_VAR} MATCHES "/MD")
653    ELSE (MSVC_USE_STATIC_CRT)
654      # Use shared, not static, CRT.
655      IF (${FLAG_VAR} MATCHES "/MT")
656        STRING(REGEX REPLACE "/MT" "/MD" ${FLAG_VAR} "${${FLAG_VAR}}")
657      ENDIF (${FLAG_VAR} MATCHES "/MT")
658    ENDIF (MSVC_USE_STATIC_CRT)
659  ENDFOREACH()
660
661  # Tuple sizes of 10 are used by Gtest.
662  ADD_DEFINITIONS("-D_VARIADIC_MAX=10")
663ENDIF (MSVC)
664
665IF (UNIX)
666  # GCC is not strict enough by default, so enable most of the warnings.
667  SET(CMAKE_CXX_FLAGS
668    "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
669ENDIF (UNIX)
670
671# Use a larger inlining threshold for Clang, since it hobbles Eigen,
672# resulting in an unreasonably slow version of the blas routines. The
673# -Qunused-arguments is needed because CMake passes the inline
674# threshold to the linker and clang complains about it and dies.
675IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
676  SET(CMAKE_CXX_FLAGS
677      "${CMAKE_CXX_FLAGS} -Qunused-arguments -mllvm -inline-threshold=600")
678  # Older versions of Clang (<= 2.9) do not support the 'return-type-c-linkage'
679  # option, so check for its presence before adding it to the default flags set.
680  INCLUDE(CheckCXXCompilerFlag)
681  CHECK_CXX_COMPILER_FLAG("-Wno-return-type-c-linkage"
682                          HAVE_RETURN_TYPE_C_LINKAGE)
683  IF (HAVE_RETURN_TYPE_C_LINKAGE)
684    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage")
685  ENDIF(HAVE_RETURN_TYPE_C_LINKAGE)
686ENDIF ()
687
688# Xcode 4.5.x used Clang 4.1 (Apple version), this has a bug that prevents
689# compilation of Ceres.
690IF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
691  EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER}
692    ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
693    OUTPUT_VARIABLE CLANG_VERSION
694    OUTPUT_STRIP_TRAILING_WHITESPACE)
695  # Use version > 4.0 & < 4.2 to catch all 4.1(.x) versions.
696  IF (CLANG_VERSION VERSION_GREATER 4.0 AND
697      CLANG_VERSION VERSION_LESS 4.2)
698    MESSAGE(FATAL_ERROR "You are attempting to build Ceres on OS X using Xcode "
699      "4.5.x (Clang version: ${CLANG_VERSION}). This version of Clang has a "
700      "bug that prevents compilation of Ceres, please update to "
701      "Xcode >= 4.6.3.")
702  ENDIF (CLANG_VERSION VERSION_GREATER 4.0 AND
703    CLANG_VERSION VERSION_LESS 4.2)
704ENDIF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
705
706# Configure the Ceres config.h compile options header using the current
707# compile options and put the configured header into the Ceres build
708# directory.  Note that the ceres/internal subdir in <build>/config where
709# the configured config.h is placed is important, because Ceres will be
710# built against this configured header, it needs to have the same relative
711# include path as it would if it were in the source tree (or installed).
712LIST(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
713INCLUDE(CreateCeresConfig)
714CREATE_CERES_CONFIG("${CERES_COMPILE_OPTIONS}"
715  ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal)
716INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/config)
717
718ADD_SUBDIRECTORY(internal/ceres)
719
720IF (BUILD_DOCUMENTATION)
721  MESSAGE("-- Documentation building is enabled")
722
723  # Generate the User's Guide (html).
724  # The corresponding target is UserGuide, but is included in ALL.
725  ADD_SUBDIRECTORY(docs)
726ENDIF (BUILD_DOCUMENTATION)
727
728IF (BUILD_EXAMPLES)
729  MESSAGE("-- Build the examples.")
730  ADD_SUBDIRECTORY(examples)
731ELSE (BUILD_EXAMPLES)
732  MESSAGE("-- Do not build any example.")
733ENDIF (BUILD_EXAMPLES)
734
735# Setup installation of Ceres public headers.
736FILE(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
737INSTALL(FILES ${CERES_HDRS} DESTINATION include/ceres)
738
739FILE(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
740INSTALL(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
741
742# Also setup installation of Ceres config.h configured with the current
743# build options into the installed headers directory.
744INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal/config.h
745        DESTINATION include/ceres/internal)
746
747
748IF (MINIGLOG)
749  # Install miniglog header if being used as logging #includes appear in
750  # installed public Ceres headers.
751  INSTALL(FILES ${CMAKE_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
752          DESTINATION include/ceres/internal/miniglog/glog)
753ENDIF (MINIGLOG)
754
755# Add an uninstall target to remove all installed files.
756CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
757               "${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
758               IMMEDIATE @ONLY)
759
760ADD_CUSTOM_TARGET(uninstall
761                  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)
762
763# Set relative install paths, which are appended to CMAKE_INSTALL_PREFIX to
764# generate the absolute install paths.
765IF (WIN32)
766  SET(RELATIVE_CMAKECONFIG_INSTALL_DIR CMake)
767ELSE ()
768  SET(RELATIVE_CMAKECONFIG_INSTALL_DIR share/Ceres)
769ENDIF ()
770
771# This "exports" all targets which have been put into the export set
772# "CeresExport". This means that CMake generates a file with the given
773# filename, which can later on be loaded by projects using this package.
774# This file contains ADD_LIBRARY(bar IMPORTED) statements for each target
775# in the export set, so when loaded later on CMake will create "imported"
776# library targets from these, which can be used in many ways in the same way
777# as a normal library target created via a normal ADD_LIBRARY().
778INSTALL(EXPORT CeresExport
779        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR} FILE CeresTargets.cmake)
780
781# Figure out the relative path from the installed Config.cmake file to the
782# install prefix (which may be at runtime different from the chosen
783# CMAKE_INSTALL_PREFIX if under Windows the package was installed anywhere)
784# This relative path will be configured into the CeresConfig.cmake.
785FILE(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
786     ${CMAKE_INSTALL_PREFIX}/${RELATIVE_CMAKECONFIG_INSTALL_DIR}
787     ${CMAKE_INSTALL_PREFIX})
788
789# Create a CeresConfig.cmake file. <name>Config.cmake files are searched by
790# FIND_PACKAGE() automatically. We configure that file so that we can put any
791# information we want in it, e.g. version numbers, include directories, etc.
792CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
793               "${CMAKE_CURRENT_BINARY_DIR}/CeresConfig.cmake" @ONLY)
794
795# Additionally, when CMake has found a CeresConfig.cmake, it can check for a
796# CeresConfigVersion.cmake in the same directory when figuring out the version
797# of the package when a version has been specified in the FIND_PACKAGE() call,
798# e.g. FIND_PACKAGE(Ceres [1.4.2] REQUIRED). The version argument is optional.
799CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
800               "${CMAKE_CURRENT_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
801
802# Install these files into the same directory as the generated exports-file,
803# we include the FindPackage scripts for libraries whose headers are included
804# in the public API of Ceres and should thus be present in CERES_INCLUDE_DIRS.
805INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CeresConfig.cmake"
806              "${CMAKE_CURRENT_BINARY_DIR}/CeresConfigVersion.cmake"
807              "${CMAKE_SOURCE_DIR}/cmake/FindEigen.cmake"
808              "${CMAKE_SOURCE_DIR}/cmake/FindGlog.cmake"
809        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
810