Home | History | Annotate | Download | only in ceres-solver
      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 (a] google.com (Keir Mierle)
     30 #          alexs.mac (a] gmail.com (Alex Stewart)
     31 
     32 CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
     33 CMAKE_POLICY(VERSION 2.8)
     34 
     35 IF (COMMAND cmake_policy)
     36   CMAKE_POLICY(SET CMP0003 NEW)
     37 ENDIF (COMMAND cmake_policy)
     38 
     39 PROJECT(CERES C CXX)
     40 
     41 # Set up the git hook to make Gerrit Change-Id: lines in commit messages.
     42 SET (LOCAL_GIT_DIRECTORY)
     43 IF (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)
     47 ELSE (EXISTS ${CMAKE_SOURCE_DIR}/.git)
     48   # TODO(keir) Add proper Windows support
     49 ENDIF (EXISTS ${CMAKE_SOURCE_DIR}/.git)
     50 
     51 IF (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)
     65 ENDIF (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.
     70 LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
     71 INCLUDE(UpdateCacheVariable)
     72 
     73 SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
     74 SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
     75 SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
     76 # Set postfixes for generated libraries based on buildtype.
     77 SET(CMAKE_RELEASE_POSTFIX "")
     78 SET(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.
     87 SET(CERES_VERSION_MAJOR 1)
     88 SET(CERES_VERSION_MINOR 9)
     89 SET(CERES_VERSION_PATCH 0)
     90 SET(CERES_VERSION
     91     ${CERES_VERSION_MAJOR}.${CERES_VERSION_MINOR}.${CERES_VERSION_PATCH})
     92 SET(CERES_ABI_VERSION 1.9.0)
     93 
     94 ENABLE_TESTING()
     95 
     96 OPTION(MINIGLOG "Use a stripped down version of glog." OFF)
     97 OPTION(GFLAGS "Enable Google Flags." ON)
     98 OPTION(SUITESPARSE "Enable SuiteSparse." ON)
     99 OPTION(CXSPARSE "Enable CXSparse." ON)
    100 OPTION(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.
    104 OPTION(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
    105 OPTION(CUSTOM_BLAS
    106        "Use handcoded BLAS routines (usually faster) instead of Eigen."
    107        ON)
    108 # Multithreading using OpenMP
    109 OPTION(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON)
    110 OPTION(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)
    119 OPTION(BUILD_TESTING "Enable tests" ON)
    120 OPTION(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
    121 OPTION(BUILD_EXAMPLES "Build examples" ON)
    122 OPTION(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
    123 IF (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)
    134 ENDIF (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.
    158 IF (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()
    180 ENDIF (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.
    190 MACRO(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})
    206 ENDMACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT)
    207 
    208 MACRO(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})
    235 ENDMACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT)
    236 
    237 UNSET(CERES_COMPILE_OPTIONS)
    238 
    239 # Eigen.
    240 HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS)
    241 FIND_PACKAGE(Eigen REQUIRED)
    242 IF (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("")
    262 ENDIF (EIGEN_FOUND)
    263 
    264 # LAPACK (& BLAS).
    265 IF (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))
    284 ELSE (LAPACK)
    285   MESSAGE("-- Building without LAPACK.")
    286   LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
    287 ENDIF (LAPACK)
    288 
    289 # SuiteSparse.
    290 IF (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)
    297 ENDIF (SUITESPARSE AND NOT LAPACK)
    298 IF (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)
    333 ELSE (SUITESPARSE)
    334   MESSAGE("-- Building without SuiteSparse.")
    335   LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
    336 ENDIF (SUITESPARSE)
    337 
    338 # CXSparse.
    339 IF (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)
    353 ELSE (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)
    362 ENDIF (CXSPARSE)
    363 
    364 # GFlags.
    365 IF (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)
    378 ELSE (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)
    386 ENDIF (GFLAGS)
    387 
    388 # MiniGLog.
    389 IF (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)
    400 ELSE (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)
    414 ENDIF (MINIGLOG)
    415 
    416 IF (NOT SCHUR_SPECIALIZATIONS)
    417   LIST(APPEND CERES_COMPILE_OPTIONS CERES_RESTRICT_SCHUR_SPECIALIZATION)
    418   MESSAGE("-- Disabling Schur specializations (faster compiles)")
    419 ENDIF (NOT SCHUR_SPECIALIZATIONS)
    420 
    421 IF (NOT CUSTOM_BLAS)
    422   LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CUSTOM_BLAS)
    423   MESSAGE("-- Disabling custom blas")
    424 ENDIF (NOT CUSTOM_BLAS)
    425 
    426 IF (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")
    452 ELSE (OPENMP)
    453   MESSAGE("-- Building without OpenMP (disabling multithreading).")
    454   LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
    455 ENDIF (OPENMP)
    456 
    457 INCLUDE(CheckIncludeFileCXX)
    458 CHECK_INCLUDE_FILE_CXX(unordered_map HAVE_STD_UNORDERED_MAP_HEADER)
    459 IF (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)
    493 ELSE (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)
    503 ENDIF (HAVE_STD_UNORDERED_MAP_HEADER)
    504 
    505 INCLUDE(FindSharedPtr)
    506 FIND_SHARED_PTR()
    507 IF (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)
    514 ELSE (SHARED_PTR_FOUND)
    515   MESSAGE(FATAL_ERROR "Unable to find shared_ptr.")
    516 ENDIF (SHARED_PTR_FOUND)
    517 
    518 INCLUDE_DIRECTORIES(
    519   include
    520   internal
    521   internal/ceres
    522   ${GLOG_INCLUDE_DIRS}
    523   ${EIGEN_INCLUDE_DIRS})
    524 
    525 IF (SUITESPARSE)
    526   INCLUDE_DIRECTORIES(${SUITESPARSE_INCLUDE_DIRS})
    527 ENDIF (SUITESPARSE)
    528 
    529 IF (CXSPARSE)
    530   INCLUDE_DIRECTORIES(${CXSPARSE_INCLUDE_DIRS})
    531 ENDIF (CXSPARSE)
    532 
    533 IF (GFLAGS)
    534   INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE_DIRS})
    535 ENDIF (GFLAGS)
    536 
    537 IF (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)
    545 ELSE (BUILD_SHARED_LIBS)
    546   MESSAGE("-- Building Ceres as a static library.")
    547 ENDIF (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.
    554 IF (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)
    559 ELSE (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")
    566 ENDIF (NOT CMAKE_BUILD_TYPE)
    567 
    568 # Set the default Ceres flags to an empty string.
    569 SET (CERES_CXX_FLAGS)
    570 
    571 IF (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 ()
    606 ENDIF (CMAKE_BUILD_TYPE STREQUAL "Release")
    607 
    608 SET (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.
    611 IF (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")
    663 ENDIF (MSVC)
    664 
    665 IF (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")
    669 ENDIF (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.
    675 IF (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)
    686 ENDIF ()
    687 
    688 # Xcode 4.5.x used Clang 4.1 (Apple version), this has a bug that prevents
    689 # compilation of Ceres.
    690 IF (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)
    704 ENDIF (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).
    712 LIST(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
    713 INCLUDE(CreateCeresConfig)
    714 CREATE_CERES_CONFIG("${CERES_COMPILE_OPTIONS}"
    715   ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal)
    716 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/config)
    717 
    718 ADD_SUBDIRECTORY(internal/ceres)
    719 
    720 IF (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)
    726 ENDIF (BUILD_DOCUMENTATION)
    727 
    728 IF (BUILD_EXAMPLES)
    729   MESSAGE("-- Build the examples.")
    730   ADD_SUBDIRECTORY(examples)
    731 ELSE (BUILD_EXAMPLES)
    732   MESSAGE("-- Do not build any example.")
    733 ENDIF (BUILD_EXAMPLES)
    734 
    735 # Setup installation of Ceres public headers.
    736 FILE(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
    737 INSTALL(FILES ${CERES_HDRS} DESTINATION include/ceres)
    738 
    739 FILE(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
    740 INSTALL(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.
    744 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal/config.h
    745         DESTINATION include/ceres/internal)
    746 
    747 
    748 IF (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)
    753 ENDIF (MINIGLOG)
    754 
    755 # Add an uninstall target to remove all installed files.
    756 CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
    757                "${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
    758                IMMEDIATE @ONLY)
    759 
    760 ADD_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.
    765 IF (WIN32)
    766   SET(RELATIVE_CMAKECONFIG_INSTALL_DIR CMake)
    767 ELSE ()
    768   SET(RELATIVE_CMAKECONFIG_INSTALL_DIR share/Ceres)
    769 ENDIF ()
    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().
    778 INSTALL(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.
    785 FILE(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.
    792 CONFIGURE_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.
    799 CONFIGURE_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.
    805 INSTALL(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