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 # Author: keir (a] google.com (Keir Mierle)
     30 
     31 CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
     32 
     33 IF (COMMAND cmake_policy)
     34   CMAKE_POLICY(SET CMP0003 NEW)
     35 ENDIF (COMMAND cmake_policy)
     36 
     37 PROJECT(CERES C CXX)
     38 
     39 # Set up the git hook to make Gerrit Change-Id: lines in commit messages.
     40 SET (LOCAL_GIT_DIRECTORY)
     41 IF (EXISTS ${CMAKE_SOURCE_DIR}/.git)
     42   # .git directory can be found on Unix based system, or on Windows with
     43   # Git Bash (shipped with msysgit)
     44   SET (LOCAL_GIT_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
     45 ELSE (EXISTS ${CMAKE_SOURCE_DIR}/.git)
     46   # TODO(keir) Add proper windows support
     47 ENDIF (EXISTS ${CMAKE_SOURCE_DIR}/.git)
     48 
     49 IF (EXISTS ${LOCAL_GIT_DIRECTORY})
     50   IF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
     51     # Download the hook only if it is not already present
     52     FILE(DOWNLOAD https://ceres-solver-review.googlesource.com/tools/hooks/commit-msg
     53          ${CMAKE_BINARY_DIR}/commit-msg)
     54 
     55     # Make the downloaded file executable, since it is not by default.
     56     FILE(COPY ${CMAKE_BINARY_DIR}/commit-msg
     57          DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
     58          FILE_PERMISSIONS
     59            OWNER_READ OWNER_WRITE OWNER_EXECUTE
     60            GROUP_READ GROUP_WRITE GROUP_EXECUTE
     61            WORLD_READ WORLD_EXECUTE)
     62   ENDIF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
     63 ENDIF (EXISTS ${LOCAL_GIT_DIRECTORY})
     64 
     65 SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
     66 SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
     67 SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
     68 
     69 # Important: Always bump the second number (e.g. 1.3.x to 1.4.0) for any
     70 # release that changes the ABI. The ABI changes for almost any modification to
     71 # include/ceres (e.g. the public API). If you are unsure about whether
     72 # something is an ABI change, please ask on the list.
     73 #
     74 # For versions without ABI changes, bump the smallest number in CERES_VERSION,
     75 # but leave the CERES_ABI_VERSION unchanged.
     76 SET(CERES_VERSION 1.4.0)
     77 SET(CERES_ABI_VERSION 1.4.0)
     78 
     79 ENABLE_TESTING()
     80 
     81 OPTION(BUILD_TESTING
     82        "Enable tests"
     83        ON)
     84 
     85 OPTION(BUILD_ANDROID
     86        "Build for Android. Use build_android.sh instead of setting this."
     87        OFF)
     88 
     89 # To get a more static build, try the following line on Mac and Linux:
     90 # SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
     91 
     92 # Default locations to search for on various platforms.
     93 LIST(APPEND SEARCH_LIBS /usr/lib)
     94 LIST(APPEND SEARCH_LIBS /usr/local/lib)
     95 LIST(APPEND SEARCH_LIBS /usr/local/homebrew/lib) # Mac OS X
     96 LIST(APPEND SEARCH_LIBS /opt/local/lib)
     97 
     98 LIST(APPEND SEARCH_HEADERS /usr/include)
     99 LIST(APPEND SEARCH_HEADERS /usr/local/include)
    100 LIST(APPEND SEARCH_HEADERS /usr/local/homebrew/include) # Mac OS X
    101 LIST(APPEND SEARCH_HEADERS /opt/local/include)
    102 
    103 # Locations to search for Eigen
    104 SET(EIGEN_SEARCH_HEADERS ${SEARCH_HEADERS})
    105 LIST(APPEND EIGEN_SEARCH_HEADERS /usr/include/eigen3) # Ubuntu 10.04's default location.
    106 LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/include/eigen3)
    107 LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/homebrew/include/eigen3)  # Mac OS X
    108 LIST(APPEND EIGEN_SEARCH_HEADERS /opt/local/var/macports/software/eigen3/opt/local/include/eigen3) # Mac OS X
    109 
    110 # Locations to search for SuiteSparse
    111 SET(SUITESPARSE_SEARCH_LIBS ${SEARCH_LIBS})
    112 LIST(APPEND SUITESPARSE_SEARCH_LIBS /usr/lib/suitesparse) # Ubuntu
    113 LIST(APPEND SUITESPARSE_SEARCH_LIBS /usr/local/lib/suitesparse)
    114 LIST(APPEND SUITESPARSE_SEARCH_LIBS /opt/local/lib/ufsparse) # Mac OS X
    115 
    116 SET(SUITESPARSE_SEARCH_HEADERS ${SEARCH_HEADERS})
    117 LIST(APPEND SUITESPARSE_SEARCH_HEADERS /usr/include/suitesparse) # Ubuntu
    118 LIST(APPEND SUITESPARSE_SEARCH_HEADERS /usr/local/include/suitesparse)
    119 LIST(APPEND SUITESPARSE_SEARCH_HEADERS /opt/local/include/ufsparse) # Mac OS X
    120 
    121 SET(CXSPARSE_SEARCH_LIBS ${SEARCH_LIBS})
    122 SET(CXSPARSE_SEARCH_HEADERS ${SEARCH_HEADERS})
    123 LIST(APPEND CXSPARSE_SEARCH_HEADERS /usr/include/suitesparse) # Ubuntu
    124 
    125 # Check for SuiteSparse dependencies
    126 MESSAGE("-- Check for AMD")
    127 SET(AMD_FOUND TRUE)
    128 
    129 FIND_LIBRARY(AMD_LIB NAMES amd PATHS ${SUITESPARSE_SEARCH_LIBS})
    130 IF (EXISTS ${AMD_LIB})
    131   MESSAGE("-- Found AMD library: ${AMD_LIB}")
    132 ELSE (EXISTS ${AMD_LIB})
    133   MESSAGE("-- Did not find AMD library")
    134   SET(AMD_FOUND FALSE)
    135 ENDIF (EXISTS ${AMD_LIB})
    136 
    137 FIND_PATH(AMD_INCLUDE NAMES amd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
    138 IF (EXISTS ${AMD_INCLUDE})
    139   MESSAGE("-- Found AMD header in: ${AMD_INCLUDE}")
    140 ELSE (EXISTS ${AMD_INCLUDE})
    141   MESSAGE("-- Did not find AMD header")
    142   SET(AMD_FOUND FALSE)
    143 ENDIF (EXISTS ${AMD_INCLUDE})
    144 
    145 MESSAGE("-- Check for CAMD")
    146 SET(CAMD_FOUND TRUE)
    147 
    148 FIND_LIBRARY(CAMD_LIB NAMES camd PATHS ${SUITESPARSE_SEARCH_LIBS})
    149 IF (EXISTS ${CAMD_LIB})
    150   MESSAGE("-- Found CAMD library: ${CAMD_LIB}")
    151 ELSE (EXISTS ${CAMD_LIB})
    152   MESSAGE("-- Did not find CAMD library")
    153   SET(CAMD_FOUND FALSE)
    154 ENDIF (EXISTS ${CAMD_LIB})
    155 
    156 FIND_PATH(CAMD_INCLUDE NAMES camd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
    157 IF (EXISTS ${CAMD_INCLUDE})
    158   MESSAGE("-- Found CAMD header in: ${CAMD_INCLUDE}")
    159 ELSE (EXISTS ${CAMD_INCLUDE})
    160   MESSAGE("-- Did not find CAMD header")
    161   SET(CAMD_FOUND FALSE)
    162 ENDIF (EXISTS ${CAMD_INCLUDE})
    163 
    164 MESSAGE("-- Check for COLAMD")
    165 SET(COLAMD_FOUND TRUE)
    166 
    167 FIND_LIBRARY(COLAMD_LIB NAMES colamd PATHS ${SUITESPARSE_SEARCH_LIBS})
    168 IF (EXISTS ${COLAMD_LIB})
    169   MESSAGE("-- Found COLAMD library: ${COLAMD_LIB}")
    170 ELSE (EXISTS ${COLAMD_LIB})
    171   MESSAGE("-- Did not find COLAMD library")
    172   SET(COLAMD_FOUND FALSE)
    173 ENDIF (EXISTS ${COLAMD_LIB})
    174 
    175 FIND_PATH(COLAMD_INCLUDE NAMES colamd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
    176 IF (EXISTS ${COLAMD_INCLUDE})
    177   MESSAGE("-- Found COLAMD header in: ${COLAMD_INCLUDE}")
    178 ELSE (EXISTS ${COLAMD_INCLUDE})
    179   MESSAGE("-- Did not find COLAMD header")
    180   SET(COLAMD_FOUND FALSE)
    181 ENDIF (EXISTS ${COLAMD_INCLUDE})
    182 
    183 MESSAGE("-- Check for CCOLAMD")
    184 SET(CCOLAMD_FOUND TRUE)
    185 
    186 FIND_LIBRARY(CCOLAMD_LIB NAMES ccolamd PATHS ${SUITESPARSE_SEARCH_LIBS})
    187 IF (EXISTS ${CCOLAMD_LIB})
    188   MESSAGE("-- Found CCOLAMD library: ${CCOLAMD_LIB}")
    189 ELSE (EXISTS ${CCOLAMD_LIB})
    190   MESSAGE("-- Did not find CCOLAMD library")
    191   SET(CCOLAMD_FOUND FALSE)
    192 ENDIF (EXISTS ${CCOLAMD_LIB})
    193 
    194 FIND_PATH(CCOLAMD_INCLUDE NAMES ccolamd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
    195 IF (EXISTS ${CCOLAMD_INCLUDE})
    196   MESSAGE("-- Found CCOLAMD header in: ${CCOLAMD_INCLUDE}")
    197 ELSE (EXISTS ${CCOLAMD_INCLUDE})
    198   MESSAGE("-- Did not find CCOLAMD header")
    199   SET(CCOLAMD_FOUND FALSE)
    200 ENDIF (EXISTS ${CCOLAMD_INCLUDE})
    201 
    202 MESSAGE("-- Check for CHOLMOD")
    203 SET(CHOLMOD_FOUND TRUE)
    204 
    205 FIND_LIBRARY(CHOLMOD_LIB NAMES cholmod PATHS ${SUITESPARSE_SEARCH_LIBS})
    206 IF (EXISTS ${CHOLMOD_LIB})
    207   MESSAGE("-- Found CHOLMOD library: ${CHOLMOD_LIB}")
    208 ELSE (EXISTS ${CHOLMOD_LIB})
    209   MESSAGE("-- Did not find CHOLMOD library")
    210   SET(CHOLMOD_FOUND FALSE)
    211 ENDIF (EXISTS ${CHOLMOD_LIB})
    212 
    213 FIND_PATH(CHOLMOD_INCLUDE NAMES cholmod.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
    214 IF (EXISTS ${CHOLMOD_INCLUDE})
    215   MESSAGE("-- Found CHOLMOD header in: ${CHOLMOD_INCLUDE}")
    216 ELSE (EXISTS ${CHOLMOD_INCLUDE})
    217   MESSAGE("-- Did not find CHOLMOD header")
    218   SET(CHOLMOD_FOUND FALSE)
    219 ENDIF (EXISTS ${CHOLMOD_INCLUDE})
    220 
    221 # If SuiteSparse version is >= 4 then SuiteSparse_config is required.
    222 # For SuiteSparse 3, UFconfig.h is required.
    223 MESSAGE("-- Check for SuiteSparse_config (SuiteSparse v4)")
    224 SET(SUITESPARSE_CONFIG_FOUND TRUE)
    225 
    226 FIND_LIBRARY(SUITESPARSE_CONFIG_LIB
    227              NAMES suitesparseconfig
    228              PATHS ${SUITESPARSE_SEARCH_LIBS})
    229 IF (EXISTS ${SUITESPARSE_CONFIG_LIB})
    230   MESSAGE("-- Found SuiteSparse_config library: ${SUITESPARSE_CONFIG_LIB}")
    231 ELSE (EXISTS ${SUITESPARSE_CONFIG_LIB})
    232   MESSAGE("-- Did not find SuiteSparse_config library")
    233 ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIB})
    234 
    235 FIND_PATH(SUITESPARSE_CONFIG_INCLUDE
    236           NAMES SuiteSparse_config.h
    237           PATHS ${SUITESPARSE_SEARCH_HEADERS})
    238 IF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE})
    239   MESSAGE("-- Found SuiteSparse_config header in: ${SUITESPARSE_CONFIG_INCLUDE}")
    240 ELSE (EXISTS ${SUITESPARSE_CONFIG_INCLUDE})
    241   MESSAGE("-- Did not find SuiteSparse_config header")
    242 ENDIF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE})
    243 
    244 IF (NOT EXISTS ${SUITESPARSE_CONFIG_LIB} OR NOT EXISTS ${SUITESPARSE_CONFIG_INCLUDE})
    245   SET(SUITESPARSE_CONFIG_FOUND FALSE)
    246 ENDIF (NOT EXISTS ${SUITESPARSE_CONFIG_LIB} OR NOT EXISTS ${SUITESPARSE_CONFIG_INCLUDE})
    247 
    248 MESSAGE("-- Check for UFconfig (SuiteSparse v3)")
    249 SET(UFCONFIG_FOUND TRUE)
    250 
    251 FIND_PATH(UFCONFIG_INCLUDE
    252           NAMES UFconfig.h
    253           PATHS ${SUITESPARSE_SEARCH_HEADERS})
    254 IF (EXISTS ${UFCONFIG_INCLUDE})
    255   MESSAGE("-- Found UFconfig header in: ${UFCONFIG_INCLUDE}")
    256 ELSE (EXISTS ${UFCONFIG_INCLUDE})
    257   MESSAGE("-- Did not find UFconfig header")
    258   SET(UFCONFIG_FOUND FALSE)
    259 ENDIF (EXISTS ${UFCONFIG_INCLUDE})
    260 
    261 MESSAGE("-- Check for METIS (optional)")
    262 FIND_LIBRARY(METIS_LIB NAMES metis PATHS ${SUITESPARSE_SEARCH_LIBS})
    263 
    264 IF (EXISTS ${METIS_LIB})
    265   MESSAGE("-- Found METIS library: ${METIS_LIB}")
    266 ELSE (EXISTS ${METIS_LIB})
    267   MESSAGE("-- Did not find METIS library")
    268 ENDIF (EXISTS ${METIS_LIB})
    269 
    270 SET(BLAS_AND_LAPACK_FOUND TRUE)
    271 IF (${APPLE})
    272   # Mac OS X has LAPACK/BLAS bundled in a framework called
    273   # "vecLib". Search for that instead of for the normal "lapack"
    274   # library.
    275   FIND_LIBRARY(LAPACK_LIB NAMES vecLib)
    276 ELSE (${APPLE})
    277   FIND_LIBRARY(BLAS_LIB NAMES blas)
    278   IF (EXISTS ${BLAS_LIB})
    279     MESSAGE("-- Found BLAS library: ${BLAS_LIB}")
    280   ELSE (EXISTS ${BLAS_LIB})
    281     MESSAGE("-- Did not find BLAS library")
    282     SET(BLAS_AND_LAPACK_FOUND FALSE)
    283   ENDIF (EXISTS ${BLAS_LIB})
    284   FIND_LIBRARY(LAPACK_LIB NAMES lapack)
    285 ENDIF (${APPLE})
    286 
    287 IF (EXISTS ${LAPACK_LIB})
    288   MESSAGE("-- Found LAPACK library: ${LAPACK_LIB}")
    289 ELSE (EXISTS ${LAPACK_LIB})
    290   SET(BLAS_AND_LAPACK_FOUND FALSE)
    291   MESSAGE("-- Did not find LAPACK library")
    292 ENDIF (EXISTS ${LAPACK_LIB})
    293 
    294 SET(SUITESPARSE_FOUND
    295     ${AMD_FOUND} AND
    296     ${CAMD_FOUND} AND
    297     ${COLAMD_FOUND} AND
    298     ${CCOLAMD_FOUND} AND
    299     ${CHOLMOD_FOUND} AND
    300     (${SUITESPARSE_CONFIG_FOUND} OR ${UFCONFIG_FOUND}) AND
    301     ${BLAS_AND_LAPACK_FOUND})
    302 
    303 # By default, if all of SuiteSparse's dependencies are found, Ceres is
    304 # built with SuiteSparse support. -DSUITESPARSE=ON/OFF can be used to
    305 # enable/disable SuiteSparse explicitly.
    306 IF (DEFINED SUITESPARSE)
    307   IF (${SUITESPARSE})
    308     IF (NOT ${SUITESPARSE_FOUND})
    309       MESSAGE(FATAL_ERROR "One or more of SuiteSparse's dependencies was not found")
    310     ENDIF (NOT ${SUITESPARSE_FOUND})
    311   ELSE (${SUITESPARSE})
    312     ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
    313   ENDIF (${SUITESPARSE})
    314 ELSE (DEFINED SUITESPARSE)
    315   IF (${SUITESPARSE_FOUND})
    316     MESSAGE("-- Found all SuiteSparse dependencies. Building with SuiteSparse")
    317     SET(SUITESPARSE ON)
    318   ELSE (${SUITESPARSE_FOUND})
    319     MESSAGE("-- Did not find all SuiteSparse dependencies. Building without SuiteSparse")
    320     SET(SUITESPARSE OFF)
    321     ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
    322   ENDIF (${SUITESPARSE_FOUND})
    323 ENDIF (DEFINED SUITESPARSE)
    324 
    325 # By default, if all of CXSparse's dependencies are found, Ceres is
    326 # built with CXSparse support. -DCXSPARSE=ON/OFF can be used to
    327 # enable/disable CXSparse explicitly.
    328 MESSAGE("-- Check for CXSparse")
    329 SET(CXSPARSE_FOUND ON)
    330 
    331 FIND_LIBRARY(CXSPARSE_LIB NAMES cxsparse PATHS ${CXSPARSE_SEARCH_LIBS})
    332 IF (EXISTS ${CXSPARSE_LIB})
    333   MESSAGE("-- Found CXSparse library in: ${CXSPARSE_LIB}")
    334 ELSE (EXISTS ${CXSPARSE_LIB})
    335   MESSAGE("-- Did not find CXSparse header")
    336   SET(CXSPARSE_FOUND FALSE)
    337 ENDIF (EXISTS ${CXSPARSE_LIB})
    338 
    339 FIND_PATH(CXSPARSE_INCLUDE NAMES cs.h PATHS ${CXSPARSE_SEARCH_HEADERS})
    340 IF (EXISTS ${CXSPARSE_INCLUDE})
    341   MESSAGE("-- Found CXSparse header in: ${CXSPARSE_INCLUDE}")
    342 ELSE (EXISTS ${CXSPARSE_INCLUDE})
    343   MESSAGE("-- Did not find CXSparse header")
    344   SET(CXSPARSE_FOUND FALSE)
    345 ENDIF (EXISTS ${CXSPARSE_INCLUDE})
    346 
    347 IF (DEFINED CXSPARSE)
    348   IF (${CXSPARSE})
    349     IF (NOT ${CXSPARSE_FOUND})
    350       MESSAGE(FATAL_ERROR "-- CXSparse not found.")
    351     ENDIF (NOT ${CXSPARSE_FOUND})
    352   ELSE (${CXSPARSE})
    353     ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
    354   ENDIF (${CXSPARSE})
    355 ELSE (DEFINED CXSPARSE)
    356   IF (${CXSPARSE_FOUND})
    357     MESSAGE("-- Building with CXSparse support.")
    358     SET(CXSPARSE ON)
    359   ELSE (${CXSPARSE_FOUND})
    360     MESSAGE("-- Building without CXSparse.")
    361     SET(CXSPARSE OFF)
    362     ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
    363   ENDIF (${CXSPARSE_FOUND})
    364 ENDIF (DEFINED CXSPARSE)
    365 
    366 # Google Flags
    367 OPTION(GFLAGS
    368        "Enable Google Flags."
    369        ON)
    370 
    371 IF (${GFLAGS})
    372   MESSAGE("-- Check for Google Flags")
    373   FIND_LIBRARY(GFLAGS_LIB NAMES gflags PATHS ${SEARCH_LIBS})
    374   IF (NOT EXISTS ${GFLAGS_LIB})
    375     MESSAGE(FATAL_ERROR
    376             "Can't find Google Flags. Please specify: "
    377             "-DGFLAGS_LIB=...")
    378   ENDIF (NOT EXISTS ${GFLAGS_LIB})
    379   MESSAGE("-- Found Google Flags library: ${GFLAGS_LIB}")
    380   FIND_PATH(GFLAGS_INCLUDE NAMES gflags/gflags.h PATHS ${SEARCH_HEADERS})
    381   IF (NOT EXISTS ${GFLAGS_INCLUDE})
    382     MESSAGE(FATAL_ERROR
    383             "Can't find Google Flags. Please specify: "
    384             "-DGFLAGS_INCLUDE=...")
    385   ENDIF (NOT EXISTS ${GFLAGS_INCLUDE})
    386   MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE}")
    387 ELSE (${GFLAGS})
    388   MESSAGE("-- Google Flags disabled; no tests or tools will be built!")
    389   ADD_DEFINITIONS(-DCERES_NO_GFLAGS)
    390 ENDIF (${GFLAGS})
    391 
    392 # Google Logging
    393 IF (NOT ${BUILD_ANDROID})
    394   MESSAGE("-- Check for Google Log")
    395   FIND_LIBRARY(GLOG_LIB NAMES glog PATHS ${SEARCH_LIBS})
    396   IF (NOT EXISTS ${GLOG_LIB})
    397     MESSAGE(FATAL_ERROR
    398             "Can't find Google Log. Please specify: "
    399             "-DGLOG_LIB=...")
    400   ENDIF (NOT EXISTS ${GLOG_LIB})
    401   MESSAGE("-- Found Google Log library: ${GLOG_LIB}")
    402 
    403   FIND_PATH(GLOG_INCLUDE NAMES glog/logging.h PATHS ${SEARCH_HEADERS})
    404   IF (NOT EXISTS ${GLOG_INCLUDE})
    405     MESSAGE(FATAL_ERROR
    406             "Can't find Google Log. Please specify: "
    407             "-DGLOG_INCLUDE=...")
    408   ENDIF (NOT EXISTS ${GLOG_INCLUDE})
    409   MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE}")
    410 ELSE (NOT ${BUILD_ANDROID})
    411   SET(GLOG_LIB miniglog)
    412   MESSAGE("-- Using minimal Glog substitute for Android (library): ${GLOG_LIB}")
    413   SET(GLOG_INCLUDE internal/ceres/miniglog)
    414   MESSAGE("-- Using minimal Glog substitute for Android (include): ${GLOG_INCLUDE}")
    415 ENDIF (NOT ${BUILD_ANDROID})
    416 
    417 # Eigen
    418 MESSAGE("-- Check for Eigen 3.0")
    419 FIND_PATH(EIGEN_INCLUDE NAMES Eigen/Core PATHS ${EIGEN_SEARCH_HEADERS})
    420 IF (NOT EXISTS ${EIGEN_INCLUDE})
    421   MESSAGE(FATAL_ERROR "Can't find Eigen. Try passing -DEIGEN_INCLUDE=...")
    422 ENDIF (NOT EXISTS ${EIGEN_INCLUDE})
    423 MESSAGE("-- Found Eigen 3.0: ${EIGEN_INCLUDE}")
    424 
    425 # Template specializations for the Schur complement based solvers. If
    426 # compile time, binary size or compiler performance is an issue, you
    427 # may consider disabling this.
    428 OPTION(SCHUR_SPECIALIZATIONS
    429        "Enable fixed-size schur specializations."
    430        ON)
    431 
    432 IF (NOT ${SCHUR_SPECIALIZATIONS})
    433   ADD_DEFINITIONS(-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
    434   MESSAGE("-- Disabling Schur specializations (faster compiles)")
    435 ENDIF (NOT ${SCHUR_SPECIALIZATIONS})
    436 
    437 # Multithreading using OpenMP
    438 OPTION(OPENMP
    439        "Enable threaded solving in Ceres (requires OpenMP)"
    440        ON)
    441 
    442 IF (${OPENMP})
    443   FIND_PACKAGE(OpenMP)
    444   IF(${OPENMP_FOUND})
    445     MESSAGE("-- Found OpenMP.")
    446     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    447     ADD_DEFINITIONS(-DCERES_USE_OPENMP)
    448   ELSE(${OPENMP_FOUND})
    449     MESSAGE("-- Can't find OpenMP. Continuing without it.")
    450   ENDIF(${OPENMP_FOUND})
    451 ENDIF (${OPENMP})
    452 
    453 # Protocol buffers
    454 OPTION(PROTOBUF
    455        "Enable protocol buffers support."
    456        ON)
    457 
    458 IF (${PROTOBUF})
    459   FIND_PACKAGE(Protobuf)
    460   IF (${PROTOBUF_FOUND})
    461     INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIRS})
    462     INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/internal)
    463   ELSE (${PROTOBUF_FOUND})
    464     ADD_DEFINITIONS(-DCERES_NO_PROTOCOL_BUFFERS)
    465   ENDIF (${PROTOBUF_FOUND})
    466 ELSE (${PROTOBUF})
    467   ADD_DEFINITIONS(-DCERES_NO_PROTOCOL_BUFFERS)
    468 ENDIF (${PROTOBUF})
    469 
    470 
    471 # Use threads but not on Android, where there is no support for OpenMP yet.
    472 IF ("${UNIX}" AND NOT ${BUILD_ANDROID})
    473   # At least on Linux, we need pthreads to be enabled for mutex to compile.
    474   # This may not work on windows or android.
    475   FIND_PACKAGE(Threads REQUIRED)
    476   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
    477   ADD_DEFINITIONS(-DCERES_HAVE_PTHREAD)
    478   ADD_DEFINITIONS(-DCERES_HAVE_RWLOCK)
    479 ENDIF ("${UNIX}" AND NOT ${BUILD_ANDROID})
    480 
    481 # Disable threads in mutex.h. Someday, after there is OpenMP support in
    482 # Android, this can get removed. Also turn on a workaround for an NDK bug.
    483 IF (${BUILD_ANDROID})
    484   ADD_DEFINITIONS(-DCERES_NO_THREADS)
    485   ADD_DEFINITIONS(-DCERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG)
    486 ENDIF (${BUILD_ANDROID})
    487 
    488 OPTION(DISABLE_TR1
    489        "Don't use TR1. This replaces some hash tables with sets. Slower."
    490        OFF)
    491 
    492 IF (${DISABLE_TR1})
    493   MESSAGE("-- Replacing unordered_map/set with map/set (warning: slower!)")
    494   ADD_DEFINITIONS(-DCERES_NO_TR1)
    495 ELSE (${DISABLE_TR1})
    496   MESSAGE("-- Using normal TR1 unordered_map/set")
    497   # Use the std namespace for the hash<> and related templates. This may vary by
    498   # system.
    499   IF (MSVC)
    500     # This is known to work with Visual Studio 2010 Express.
    501     ADD_DEFINITIONS("\"-DCERES_HASH_NAMESPACE_START=namespace std {\"")
    502     ADD_DEFINITIONS("\"-DCERES_HASH_NAMESPACE_END=}\"")
    503   ELSE (MSVC)
    504     # This is known to work with recent versions of Linux and Mac OS X.
    505     ADD_DEFINITIONS("\"-DCERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {\"")
    506     ADD_DEFINITIONS("\"-DCERES_HASH_NAMESPACE_END=}}\"")
    507   ENDIF (MSVC)
    508 ENDIF (${DISABLE_TR1})
    509 
    510 INCLUDE_DIRECTORIES(
    511   include
    512   internal
    513   internal/ceres
    514   ${GLOG_INCLUDE}
    515   ${EIGEN_INCLUDE}
    516   )
    517 
    518 FILE(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
    519 INSTALL(FILES ${CERES_HDRS} DESTINATION include/ceres)
    520 
    521 FILE(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
    522 INSTALL(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
    523 
    524 IF (${SUITESPARSE})
    525   INCLUDE_DIRECTORIES(${AMD_INCLUDE})
    526   INCLUDE_DIRECTORIES(${CAMD_INCLUDE})
    527   INCLUDE_DIRECTORIES(${COLAMD_INCLUDE})
    528   INCLUDE_DIRECTORIES(${CCOLAMD_INCLUDE})
    529   INCLUDE_DIRECTORIES(${CHOLMOD_INCLUDE})
    530   IF (${SUITESPARSE_CONFIG_FOUND})
    531     INCLUDE_DIRECTORIES(${SUITESPARSE_CONFIG_INCLUDE})
    532   ENDIF (${SUITESPARSE_CONFIG_FOUND})
    533   IF (${UFCONFIG_FOUND})
    534     INCLUDE_DIRECTORIES(${UFCONFIG_INCLUDE})
    535   ENDIF (${UFCONFIG_FOUND})
    536 ENDIF(${SUITESPARSE})
    537 
    538 IF (${CXSPARSE})
    539   INCLUDE_DIRECTORIES(${CXSPARSE_INCLUDE})
    540 ENDIF(${CXSPARSE})
    541 
    542 IF (${GFLAGS})
    543   INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE})
    544 ENDIF (${GFLAGS})
    545 
    546 # Change the default build type from Debug to Release, while still
    547 # supporting overriding the build type.
    548 #
    549 # The CACHE STRING logic here and elsewhere is needed to force CMake
    550 # to pay attention to the value of these variables.
    551 IF (NOT CMAKE_BUILD_TYPE)
    552   MESSAGE("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.")
    553   SET(CMAKE_BUILD_TYPE Release CACHE STRING
    554     "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
    555     FORCE)
    556 ELSE (NOT CMAKE_BUILD_TYPE)
    557   IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
    558     MESSAGE("\n=================================================================================")
    559     MESSAGE("\n-- Build type: Debug. Performance will be terrible!")
    560     MESSAGE("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.")
    561     MESSAGE("\n=================================================================================")
    562   ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug")
    563 ENDIF (NOT CMAKE_BUILD_TYPE)
    564 
    565 # Set the default Ceres flags to an empty string.
    566 SET (CERES_CXX_FLAGS)
    567 
    568 IF (CMAKE_BUILD_TYPE STREQUAL "Release")
    569   IF (CMAKE_COMPILER_IS_GNUCXX)
    570     IF (${BUILD_ANDROID})
    571       # TODO(keir): Figure out what flags should go here to make an optimized
    572       # native ARM binary for Android.
    573     ELSE (${BUILD_ANDROID})
    574       # Linux
    575       IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    576         SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -march=native -mtune=native")
    577       ENDIF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    578       # Mac OS X
    579       IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    580         SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -fast -msse3")
    581       ENDIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    582     ENDIF (${BUILD_ANDROID})
    583   ENDIF (CMAKE_COMPILER_IS_GNUCXX)
    584   SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CERES_CXX_FLAGS}"
    585        CACHE STRING "Release mode flags to the C++ Compiler" FORCE)
    586 ENDIF (CMAKE_BUILD_TYPE STREQUAL "Release")
    587 
    588 # After the tweaks for the compile settings, disable some warnings on MSVC.
    589 IF (MSVC)
    590   # Disable signed/unsigned int conversion warnings.
    591   ADD_DEFINITIONS("/wd4018")
    592   # Disable warning about using struct/class for the same symobl.
    593   ADD_DEFINITIONS("/wd4099")
    594   # Disable warning about the insecurity of using "std::copy".
    595   ADD_DEFINITIONS("/wd4996")
    596   # Disable performance warning about int-to-bool conversion.
    597   ADD_DEFINITIONS("/wd4800")
    598   # Disable performance warning about fopen insecurity.
    599   ADD_DEFINITIONS("/wd4996")
    600   # Disable warning about int64 to int32 conversion. Disabling
    601   # this warning may not be correct; needs investigation.
    602   # TODO(keir): Investigate these warnings in more detail.
    603   ADD_DEFINITIONS("/wd4244")
    604   # It's not possible to use STL types in DLL interfaces in a portable and
    605   # reliable way. However, that's what happens with Google Log and Google Flags
    606   # on Windows. MSVC gets upset about this and throws warnings that we can't do
    607   # much about. The real solution is to link static versions of Google Log and
    608   # Google Test, but that seems tricky on Windows. So, disable the warning.
    609   ADD_DEFINITIONS("/wd4251")
    610 
    611   # Google Flags doesn't have their DLL import/export stuff set up correctly,
    612   # which results in linker warnings. This is irrelevant for Ceres, so ignore
    613   # the warnings.
    614   SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049")
    615 ENDIF (MSVC)
    616 
    617 # GCC is not strict enough by default, so enable most of the warnings.
    618 IF ("${UNIX}")
    619   SET(CMAKE_CXX_FLAGS
    620       "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused -Wno-unused-parameter")
    621 ENDIF ("${UNIX}")
    622 
    623 ADD_SUBDIRECTORY(internal/ceres)
    624 
    625 OPTION(BUILD_DOCUMENTATION
    626        "Build User's Guide (pdf)"
    627        OFF)
    628 
    629 IF (${BUILD_DOCUMENTATION})
    630   MESSAGE("-- Documentation building is enabled")
    631 
    632   # Generate the User's Guide (pdf).
    633   # The corresponding target is UserGuide, but is included in ALL.
    634   ADD_SUBDIRECTORY(docs)
    635 ENDIF (${BUILD_DOCUMENTATION})
    636 
    637 OPTION(BUILD_EXAMPLES "Build examples" ON)
    638 
    639 IF (${BUILD_EXAMPLES})
    640   MESSAGE("-- Build the examples.")
    641   ADD_SUBDIRECTORY(examples)
    642 ELSE (${BUILD_EXAMPLES})
    643   MESSAGE("-- Do not build any example.")
    644 ENDIF (${BUILD_EXAMPLES})
    645 
    646 # Add an uninstall target to remove all installed files.
    647 CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
    648                "${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
    649                IMMEDIATE @ONLY)
    650 
    651 ADD_CUSTOM_TARGET(uninstall
    652                   COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)
    653