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