Blame CMakeLists.txt

Packit ea1746
# Ceres Solver - A fast non-linear least squares minimizer
Packit ea1746
# Copyright 2015 Google Inc. All rights reserved.
Packit ea1746
# http://ceres-solver.org/
Packit ea1746
#
Packit ea1746
# Redistribution and use in source and binary forms, with or without
Packit ea1746
# modification, are permitted provided that the following conditions are met:
Packit ea1746
#
Packit ea1746
# * Redistributions of source code must retain the above copyright notice,
Packit ea1746
#   this list of conditions and the following disclaimer.
Packit ea1746
# * Redistributions in binary form must reproduce the above copyright notice,
Packit ea1746
#   this list of conditions and the following disclaimer in the documentation
Packit ea1746
#   and/or other materials provided with the distribution.
Packit ea1746
# * Neither the name of Google Inc. nor the names of its contributors may be
Packit ea1746
#   used to endorse or promote products derived from this software without
Packit ea1746
#   specific prior written permission.
Packit ea1746
#
Packit ea1746
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit ea1746
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit ea1746
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit ea1746
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit ea1746
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit ea1746
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit ea1746
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit ea1746
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit ea1746
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit ea1746
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit ea1746
# POSSIBILITY OF SUCH DAMAGE.
Packit ea1746
#
Packit ea1746
# Authors: keir@google.com (Keir Mierle)
Packit ea1746
#          alexs.mac@gmail.com (Alex Stewart)
Packit ea1746
Packit ea1746
cmake_minimum_required(VERSION 2.8.0)
Packit ea1746
cmake_policy(VERSION 2.8)
Packit ea1746
Packit ea1746
cmake_policy(SET CMP0003 NEW)
Packit ea1746
if (POLICY CMP0042)
Packit ea1746
  cmake_policy(SET CMP0042 NEW)
Packit ea1746
endif()
Packit ea1746
Packit ea1746
project(Ceres C CXX)
Packit ea1746
Packit ea1746
# NOTE: The 'generic' CMake variables CMAKE_[SOURCE/BINARY]_DIR should not be
Packit ea1746
#       used.  Always use the project-specific variants (generated by CMake):
Packit ea1746
#       <PROJECT_NAME_MATCHING_CASE>_[SOURCE/BINARY]_DIR, e.g.
Packit ea1746
#       Ceres_SOURCE_DIR (note, *not* CERES_SOURCE_DIR) instead, as these will
Packit ea1746
#       always point to the correct directories for the Ceres project, even if
Packit ea1746
#       it is nested inside another source tree, whereas the 'generic'
Packit ea1746
#       CMake variables refer to the *first* project() declaration, i.e. the
Packit ea1746
#       top-level project, not Ceres, if Ceres is nested.
Packit ea1746
Packit ea1746
# Make CMake aware of the cmake folder for local FindXXX scripts,
Packit ea1746
# append rather than set in case the user has passed their own
Packit ea1746
# additional paths via -D.
Packit ea1746
list(APPEND CMAKE_MODULE_PATH "${Ceres_SOURCE_DIR}/cmake")
Packit ea1746
include(UpdateCacheVariable)
Packit ea1746
Packit ea1746
# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
Packit ea1746
include(AddGerritCommitHook)
Packit ea1746
add_gerrit_commit_hook(${Ceres_SOURCE_DIR} ${Ceres_BINARY_DIR})
Packit ea1746
Packit ea1746
# On OS X, add the Homebrew prefix to the set of prefixes searched by
Packit ea1746
# CMake in find_path & find_library.  This should ensure that we can
Packit ea1746
# still build Ceres even if Homebrew is installed in a non-standard
Packit ea1746
# location (not /usr/local).
Packit ea1746
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
Packit ea1746
  find_program(HOMEBREW_EXECUTABLE brew)
Packit ea1746
  mark_as_advanced(FORCE HOMEBREW_EXECUTABLE)
Packit ea1746
  if (HOMEBREW_EXECUTABLE)
Packit ea1746
    # Detected a Homebrew install, query for its install prefix.
Packit ea1746
    execute_process(COMMAND ${HOMEBREW_EXECUTABLE} --prefix
Packit ea1746
      OUTPUT_VARIABLE HOMEBREW_INSTALL_PREFIX
Packit ea1746
      OUTPUT_STRIP_TRAILING_WHITESPACE)
Packit ea1746
    message(STATUS "Detected Homebrew with install prefix: "
Packit ea1746
      "${HOMEBREW_INSTALL_PREFIX}, adding to CMake search paths.")
Packit ea1746
    list(APPEND CMAKE_PREFIX_PATH "${HOMEBREW_INSTALL_PREFIX}")
Packit ea1746
  endif()
Packit ea1746
endif()
Packit ea1746
Packit ea1746
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/bin)
Packit ea1746
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
Packit ea1746
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
Packit ea1746
# Set postfixes for generated libraries based on buildtype.
Packit ea1746
set(CMAKE_RELEASE_POSTFIX "")
Packit ea1746
set(CMAKE_DEBUG_POSTFIX "-debug")
Packit ea1746
Packit ea1746
# Read the Ceres version from the source, such that we only ever have a single
Packit ea1746
# definition of the Ceres version.
Packit ea1746
include(ReadCeresVersionFromSource)
Packit ea1746
read_ceres_version_from_source(${Ceres_SOURCE_DIR})
Packit ea1746
Packit ea1746
enable_testing()
Packit ea1746
Packit ea1746
option(MINIGLOG "Use a stripped down version of glog." OFF)
Packit ea1746
option(GFLAGS "Enable Google Flags." ON)
Packit ea1746
option(SUITESPARSE "Enable SuiteSparse." ON)
Packit ea1746
option(CXSPARSE "Enable CXSparse." ON)
Packit ea1746
option(LAPACK "Enable use of LAPACK." ON)
Packit ea1746
# Template specializations for the Schur complement based solvers. If
Packit ea1746
# compile time, binary size or compiler performance is an issue, you
Packit ea1746
# may consider disabling this.
Packit ea1746
option(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
Packit ea1746
option(CUSTOM_BLAS
Packit ea1746
       "Use handcoded BLAS routines (usually faster) instead of Eigen."
Packit ea1746
       ON)
Packit ea1746
# Multithreading using OpenMP
Packit ea1746
option(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON)
Packit ea1746
# Enable the use of Eigen as a sparse linear algebra library for
Packit ea1746
# solving the nonlinear least squares problems. Enabling this
Packit ea1746
# option will result in an LGPL licensed version of Ceres Solver
Packit ea1746
# as the Simplicial Cholesky factorization in Eigen is licensed under the LGPL.
Packit ea1746
# This does not affect the covariance estimation algorithm, as it
Packit ea1746
# depends on the sparse QR factorization algorithm, which is licensed
Packit ea1746
# under the MPL.
Packit ea1746
OPTION(EIGENSPARSE
Packit ea1746
  "Enable Eigen as a sparse linear algebra library, WARNING: results in an LGPL licensed Ceres." OFF)
Packit ea1746
if (NOT MSVC)
Packit ea1746
  # Ceres does not use C++11 internally, however it does use shared_ptr
Packit ea1746
  # (required) and unordered_map (if available), both of which were present in
Packit ea1746
  # previous iterations of what became C++11.  GCC & Clang can have both TR1 &
Packit ea1746
  # C++11 versions of both shared_ptr & unordered_map and by default on Linux,
Packit ea1746
  # we will detect the TR1 versions if they exist, as they do NOT require
Packit ea1746
  # -std=c++11 to be passed when compiling Ceres, and any client code that uses
Packit ea1746
  # Ceres.  This will result in conflicts if the client code uses C++11.
Packit ea1746
  # Enabling this option forces the use of the C++11 versions (& -std=c++11) if
Packit ea1746
  # available.
Packit ea1746
  #
Packit ea1746
  # This option is not available on Windows when using MSVC, as there, any new
Packit ea1746
  # (C++11 etc) features available are on by default and there is no analogue to
Packit ea1746
  # -std=c++11.  It will however be available for MinGW & CygWin, which can
Packit ea1746
  # support -std=c++11.
Packit ea1746
  option(CXX11 "Enable use of C++11 headers if available (requires client code use C++11)." OFF)
Packit ea1746
endif(NOT MSVC)
Packit ea1746
option(EXPORT_BUILD_DIR
Packit ea1746
  "Export build directory using CMake (enables external use without install)." OFF)
Packit ea1746
option(BUILD_TESTING "Enable tests" ON)
Packit ea1746
option(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
Packit ea1746
option(BUILD_EXAMPLES "Build examples" ON)
Packit ea1746
option(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
Packit ea1746
if (MSVC)
Packit ea1746
  option(MSVC_USE_STATIC_CRT
Packit ea1746
    "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
Packit ea1746
Packit ea1746
  if (BUILD_TESTING AND BUILD_SHARED_LIBS)
Packit ea1746
    message(
Packit ea1746
      "-- Disabling tests. The flags BUILD_TESTING and BUILD_SHARED_LIBS"
Packit ea1746
      " are incompatible with MSVC.")
Packit ea1746
    update_cache_variable(BUILD_TESTING OFF)
Packit ea1746
  endif (BUILD_TESTING AND BUILD_SHARED_LIBS)
Packit ea1746
endif (MSVC)
Packit ea1746
# Allow user to specify a suffix for the library install directory, the only
Packit ea1746
# really sensible option (other than "") being "64", such that:
Packit ea1746
# ${CMAKE_INSTALL_PREFIX}/lib -> ${CMAKE_INSTALL_PREFIX}/lib64.
Packit ea1746
#
Packit ea1746
# Heuristic for determining LIB_SUFFIX. FHS recommends that 64-bit systems
Packit ea1746
# install native libraries to lib64 rather than lib. Most distros seem to
Packit ea1746
# follow this convention with a couple notable exceptions (Debian-based and
Packit ea1746
# Arch-based distros) which we try to detect here.
Packit ea1746
if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
Packit ea1746
    NOT DEFINED LIB_SUFFIX AND
Packit ea1746
    NOT CMAKE_CROSSCOMPILING AND
Packit ea1746
    CMAKE_SIZEOF_VOID_P EQUAL "8" AND
Packit ea1746
    NOT EXISTS "/etc/debian_version" AND
Packit ea1746
    NOT EXISTS "/etc/arch-release")
Packit ea1746
  message("-- Detected non-Debian/Arch-based 64-bit Linux distribution. "
Packit ea1746
    "Defaulting to library install directory: lib${LIB_SUFFIX}. You can "
Packit ea1746
    "override this by specifying LIB_SUFFIX.")
Packit ea1746
  set(LIB_SUFFIX "64")
Packit ea1746
endif ()
Packit ea1746
# Only create the cache variable (for the CMake GUI) after attempting to detect
Packit ea1746
# the suffix *if not specified by the user* (NOT DEFINED LIB_SUFFIX in if())
Packit ea1746
# s/t the user could override our autodetected suffix with "" if desired.
Packit ea1746
set(LIB_SUFFIX "${LIB_SUFFIX}" CACHE STRING
Packit ea1746
  "Suffix of library install directory (to support lib/lib64)." FORCE)
Packit ea1746
Packit ea1746
# IOS is defined iff using the iOS.cmake CMake toolchain to build a static
Packit ea1746
# library for iOS.
Packit ea1746
if (IOS)
Packit ea1746
  message(STATUS "Building Ceres for iOS platform: ${IOS_PLATFORM}")
Packit ea1746
Packit ea1746
  # Ceres requires at least iOS 7.0+.
Packit ea1746
  if (IOS_DEPLOYMENT_TARGET VERSION_LESS 7.0)
Packit ea1746
    message(FATAL_ERROR "Unsupported iOS version: ${IOS_DEPLOYMENT_TARGET}, Ceres "
Packit ea1746
      "requires at least iOS version 7.0")
Packit ea1746
  endif()
Packit ea1746
Packit ea1746
  update_cache_variable(MINIGLOG ON)
Packit ea1746
  message(STATUS "Building for iOS: Forcing use of miniglog instead of glog.")
Packit ea1746
Packit ea1746
  update_cache_variable(SUITESPARSE OFF)
Packit ea1746
  update_cache_variable(CXSPARSE OFF)
Packit ea1746
  update_cache_variable(GFLAGS OFF)
Packit ea1746
  update_cache_variable(OPENMP OFF)
Packit ea1746
  # Apple claims that the BLAS call dsyrk_ is a private API, and will not allow
Packit ea1746
  # you to submit to the Apple Store if the symbol is present.
Packit ea1746
  update_cache_variable(LAPACK OFF)
Packit ea1746
  message(STATUS "Building for iOS: SuiteSparse, CXSparse, LAPACK, gflags, "
Packit ea1746
    "and OpenMP are not available.")
Packit ea1746
Packit ea1746
  update_cache_variable(BUILD_EXAMPLES OFF)
Packit ea1746
  message(STATUS "Building for iOS: Will not build examples.")
Packit ea1746
endif (IOS)
Packit ea1746
Packit ea1746
unset(CERES_COMPILE_OPTIONS)
Packit ea1746
Packit ea1746
# Eigen.
Packit ea1746
find_package(Eigen REQUIRED)
Packit ea1746
if (EIGEN_FOUND)
Packit ea1746
  if (EIGEN_VERSION VERSION_LESS 3.1.0)
Packit ea1746
    message(FATAL_ERROR "-- Ceres requires Eigen version >= 3.1.0 in order "
Packit ea1746
      "that Eigen/SparseCore be available, detected version of Eigen is: "
Packit ea1746
      "${EIGEN_VERSION}")
Packit ea1746
  endif (EIGEN_VERSION VERSION_LESS 3.1.0)
Packit ea1746
Packit ea1746
  message("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}")
Packit ea1746
  # Ensure that only MPL2 licensed code is part of the default build.
Packit ea1746
  message("")
Packit ea1746
  message("   ===============================================================")
Packit ea1746
  if (EIGENSPARSE)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_USE_EIGEN_SPARSE)
Packit ea1746
    message("   Enabling the use of Eigen as a sparse linear algebra library ")
Packit ea1746
    message("   for solving the nonlinear least squares problems. Enabling ")
Packit ea1746
    message("   this option results in an LGPL licensed version of ")
Packit ea1746
    message("   Ceres Solver as the Simplicial Cholesky factorization in Eigen")
Packit ea1746
    message("   is licensed under the LGPL. ")
Packit ea1746
Packit ea1746
    if (EIGEN_VERSION VERSION_LESS 3.2.2)
Packit ea1746
      message("   WARNING:")
Packit ea1746
      message("")
Packit ea1746
      message("   Your version of Eigen is older than version 3.2.2.")
Packit ea1746
      message("   The performance of SPARSE_NORMAL_CHOLESKY and SPARSE_SCHUR")
Packit ea1746
      message("   linear solvers will suffer. ")
Packit ea1746
    endif (EIGEN_VERSION VERSION_LESS 3.2.2)
Packit ea1746
Packit ea1746
  else (EIGENSPARSE)
Packit ea1746
    message("   Disabling the use of Eigen as a sparse linear algebra library.")
Packit ea1746
    message("   This does not affect the covariance estimation algorithm ")
Packit ea1746
    message("   which can still use the EIGEN_SPARSE_QR algorithm.")
Packit ea1746
    add_definitions(-DEIGEN_MPL2_ONLY)
Packit ea1746
  endif (EIGENSPARSE)
Packit ea1746
    message("   ===============================================================")
Packit ea1746
    message("")
Packit ea1746
endif (EIGEN_FOUND)
Packit ea1746
Packit ea1746
# LAPACK (& BLAS).
Packit ea1746
if (LAPACK)
Packit ea1746
  find_package(LAPACK QUIET)
Packit ea1746
  if (LAPACK_FOUND)
Packit ea1746
    message("-- Found LAPACK library: ${LAPACK_LIBRARIES}")
Packit ea1746
  else (LAPACK_FOUND)
Packit ea1746
    message("-- Did not find LAPACK library, disabling LAPACK support.")
Packit ea1746
  endif (LAPACK_FOUND)
Packit ea1746
Packit ea1746
  find_package(BLAS QUIET)
Packit ea1746
  if (BLAS_FOUND)
Packit ea1746
    message("-- Found BLAS library: ${BLAS_LIBRARIES}")
Packit ea1746
  else (BLAS_FOUND)
Packit ea1746
    message("-- Did not find BLAS library, disabling LAPACK support.")
Packit ea1746
  endif (BLAS_FOUND)
Packit ea1746
Packit ea1746
  if (NOT (LAPACK_FOUND AND BLAS_FOUND))
Packit ea1746
    update_cache_variable(LAPACK OFF)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
Packit ea1746
  endif (NOT (LAPACK_FOUND AND BLAS_FOUND))
Packit ea1746
else (LAPACK)
Packit ea1746
  message("-- Building without LAPACK.")
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
Packit ea1746
endif (LAPACK)
Packit ea1746
Packit ea1746
# SuiteSparse.
Packit ea1746
if (SUITESPARSE AND NOT LAPACK)
Packit ea1746
  # If user has disabled LAPACK, but left SUITESPARSE ON, turn it OFF,
Packit ea1746
  # LAPACK controls whether Ceres will be linked, directly or indirectly
Packit ea1746
  # via SuiteSparse to LAPACK.
Packit ea1746
  message("-- Disabling SuiteSparse as use of LAPACK has been disabled, "
Packit ea1746
    "turn ON LAPACK to enable (optional) building with SuiteSparse.")
Packit ea1746
  update_cache_variable(SUITESPARSE OFF)
Packit ea1746
endif (SUITESPARSE AND NOT LAPACK)
Packit ea1746
if (SUITESPARSE)
Packit ea1746
  # By default, if SuiteSparse and all dependencies are found, Ceres is
Packit ea1746
  # built with SuiteSparse support.
Packit ea1746
Packit ea1746
  # Check for SuiteSparse and dependencies.
Packit ea1746
  find_package(SuiteSparse)
Packit ea1746
  if (SUITESPARSE_FOUND)
Packit ea1746
    # On Ubuntu the system install of SuiteSparse (v3.4.0) up to at least
Packit ea1746
    # Ubuntu 13.10 cannot be used to link shared libraries.
Packit ea1746
    if (BUILD_SHARED_LIBS AND
Packit ea1746
        SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
Packit ea1746
      message(FATAL_ERROR "You are attempting to build Ceres as a shared "
Packit ea1746
        "library on Ubuntu using a system package install of SuiteSparse "
Packit ea1746
        "3.4.0. This package is broken and does not support the "
Packit ea1746
        "construction of shared libraries (you can still build Ceres as "
Packit ea1746
        "a static library).  If you wish to build a shared version of Ceres "
Packit ea1746
        "you should uninstall the system install of SuiteSparse "
Packit ea1746
        "(libsuitesparse-dev) and perform a source install of SuiteSparse "
Packit ea1746
        "(we recommend that you use the latest version), "
Packit ea1746
        "see http://ceres-solver.org/building.html for more information.")
Packit ea1746
    endif (BUILD_SHARED_LIBS AND
Packit ea1746
      SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
Packit ea1746
Packit ea1746
    # By default, if all of SuiteSparse's dependencies are found, Ceres is
Packit ea1746
    # built with SuiteSparse support.
Packit ea1746
    message("-- Found SuiteSparse ${SUITESPARSE_VERSION}, "
Packit ea1746
            "building with SuiteSparse.")
Packit ea1746
  else (SUITESPARSE_FOUND)
Packit ea1746
    # Disable use of SuiteSparse if it cannot be found and continue.
Packit ea1746
    message("-- Did not find all SuiteSparse dependencies, disabling "
Packit ea1746
      "SuiteSparse support.")
Packit ea1746
    update_cache_variable(SUITESPARSE OFF)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
Packit ea1746
  endif (SUITESPARSE_FOUND)
Packit ea1746
else (SUITESPARSE)
Packit ea1746
  message("-- Building without SuiteSparse.")
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
Packit ea1746
endif (SUITESPARSE)
Packit ea1746
Packit ea1746
# CXSparse.
Packit ea1746
if (CXSPARSE)
Packit ea1746
  # Don't search with REQUIRED as we can continue without CXSparse.
Packit ea1746
  find_package(CXSparse)
Packit ea1746
  if (CXSPARSE_FOUND)
Packit ea1746
    # By default, if CXSparse and all dependencies are found, Ceres is
Packit ea1746
    # built with CXSparse support.
Packit ea1746
    message("-- Found CXSparse version: ${CXSPARSE_VERSION}, "
Packit ea1746
      "building with CXSparse.")
Packit ea1746
  else (CXSPARSE_FOUND)
Packit ea1746
    # Disable use of CXSparse if it cannot be found and continue.
Packit ea1746
    message("-- Did not find CXSparse, Building without CXSparse.")
Packit ea1746
    update_cache_variable(CXSPARSE OFF)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
Packit ea1746
  endif (CXSPARSE_FOUND)
Packit ea1746
else (CXSPARSE)
Packit ea1746
  message("-- Building without CXSparse.")
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
Packit ea1746
  # Mark as advanced (remove from default GUI view) the CXSparse search
Packit ea1746
  # variables in case user enabled CXSPARSE, FindCXSparse did not find it, so
Packit ea1746
  # made search variables visible in GUI for user to set, but then user disables
Packit ea1746
  # CXSPARSE instead of setting them.
Packit ea1746
  mark_as_advanced(FORCE CXSPARSE_INCLUDE_DIR
Packit ea1746
                         CXSPARSE_LIBRARY)
Packit ea1746
endif (CXSPARSE)
Packit ea1746
Packit ea1746
# Ensure that the user understands they have disabled all sparse libraries.
Packit ea1746
if (NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
Packit ea1746
  message("   ===============================================================")
Packit ea1746
  message("   Compiling without any sparse library: SuiteSparse, CXSparse ")
Packit ea1746
  message("   & Eigen (Sparse) are all disabled or unavailable.  No sparse ")
Packit ea1746
  message("   linear solvers (SPARSE_NORMAL_CHOLESKY & SPARSE_SCHUR)")
Packit ea1746
  message("   will be available when Ceres is used.")
Packit ea1746
  message("   ===============================================================")
Packit ea1746
endif(NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
Packit ea1746
Packit ea1746
# GFlags.
Packit ea1746
if (GFLAGS)
Packit ea1746
  # Don't search with REQUIRED as we can continue without gflags.
Packit ea1746
  find_package(Gflags)
Packit ea1746
  if (GFLAGS_FOUND)
Packit ea1746
    message("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}, "
Packit ea1746
      "in namespace: ${GFLAGS_NAMESPACE}")
Packit ea1746
    add_definitions(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
Packit ea1746
  else (GFLAGS_FOUND)
Packit ea1746
    message("-- Did not find Google Flags (gflags), Building without gflags "
Packit ea1746
      "- no tests or tools will be built!")
Packit ea1746
    update_cache_variable(GFLAGS OFF)
Packit ea1746
  endif (GFLAGS_FOUND)
Packit ea1746
else (GFLAGS)
Packit ea1746
  message("-- Google Flags disabled; no tests or tools will be built!")
Packit ea1746
  # Mark as advanced (remove from default GUI view) the gflags search
Packit ea1746
  # variables in case user enabled GFLAGS, FindGflags did not find it, so
Packit ea1746
  # made search variables visible in GUI for user to set, but then user disables
Packit ea1746
  # GFLAGS instead of setting them.
Packit ea1746
  mark_as_advanced(FORCE GFLAGS_INCLUDE_DIR
Packit ea1746
                         GFLAGS_LIBRARY
Packit ea1746
                         GFLAGS_NAMESPACE)
Packit ea1746
endif (GFLAGS)
Packit ea1746
Packit ea1746
# MiniGLog.
Packit ea1746
if (MINIGLOG)
Packit ea1746
  message("-- Compiling minimal glog substitute into Ceres.")
Packit ea1746
  set(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
Packit ea1746
  set(MINIGLOG_MAX_LOG_LEVEL 2 CACHE STRING "The maximum message severity level to be logged")
Packit ea1746
  add_definitions("-DMAX_LOG_LEVEL=${MINIGLOG_MAX_LOG_LEVEL}")
Packit ea1746
  message("-- Using minimal glog substitute (include): ${GLOG_INCLUDE_DIRS}")
Packit ea1746
  message("-- Max log level for minimal glog substitute: ${MINIGLOG_MAX_LOG_LEVEL}")
Packit ea1746
Packit ea1746
  # Mark as advanced (remove from default GUI view) the glog search
Packit ea1746
  # variables in case user disables MINIGLOG, FindGlog did not find it, so
Packit ea1746
  # made search variables visible in GUI for user to set, but then user enables
Packit ea1746
  # MINIGLOG instead of setting them.
Packit ea1746
  mark_as_advanced(FORCE GLOG_INCLUDE_DIR
Packit ea1746
                         GLOG_LIBRARY)
Packit ea1746
else (MINIGLOG)
Packit ea1746
  unset(MINIGLOG_MAX_LOG_LEVEL CACHE)
Packit ea1746
  # Don't search with REQUIRED so that configuration continues if not found and
Packit ea1746
  # we can output an error messages explaining MINIGLOG option.
Packit ea1746
  find_package(Glog)
Packit ea1746
  if (NOT GLOG_FOUND)
Packit ea1746
    message(FATAL_ERROR "Can't find Google Log (glog). Please set either: "
Packit ea1746
      "glog_DIR (newer CMake built versions of glog) or GLOG_INCLUDE_DIR & "
Packit ea1746
      "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
Packit ea1746
      "implementation.")
Packit ea1746
  endif(NOT GLOG_FOUND)
Packit ea1746
  # By default, assume gflags was found, updating the message if it was not.
Packit ea1746
  set(GLOG_GFLAGS_DEPENDENCY_MESSAGE
Packit ea1746
    " Assuming glog was built with gflags support as gflags was found. "
Packit ea1746
    "This will make gflags a public dependency of Ceres.")
Packit ea1746
  if (NOT GFLAGS_FOUND)
Packit ea1746
    set(GLOG_GFLAGS_DEPENDENCY_MESSAGE
Packit ea1746
      " Assuming glog was NOT built with gflags support as gflags was "
Packit ea1746
      "not found.  If glog was built with gflags, please set the "
Packit ea1746
      "gflags search locations such that it can be found by Ceres.  "
Packit ea1746
      "Otherwise, Ceres may fail to link due to missing gflags symbols.")
Packit ea1746
  endif(NOT GFLAGS_FOUND)
Packit ea1746
  message("-- Found Google Log (glog)." ${GLOG_GFLAGS_DEPENDENCY_MESSAGE})
Packit ea1746
endif (MINIGLOG)
Packit ea1746
Packit ea1746
if (NOT SCHUR_SPECIALIZATIONS)
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_RESTRICT_SCHUR_SPECIALIZATION)
Packit ea1746
  message("-- Disabling Schur specializations (faster compiles)")
Packit ea1746
endif (NOT SCHUR_SPECIALIZATIONS)
Packit ea1746
Packit ea1746
if (NOT CUSTOM_BLAS)
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_NO_CUSTOM_BLAS)
Packit ea1746
  message("-- Disabling custom blas")
Packit ea1746
endif (NOT CUSTOM_BLAS)
Packit ea1746
Packit ea1746
if (OPENMP)
Packit ea1746
  # Find quietly, as we can continue without OpenMP if it is not found.
Packit ea1746
  find_package(OpenMP QUIET)
Packit ea1746
  if (OPENMP_FOUND)
Packit ea1746
    message("-- Building with OpenMP.")
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_USE_OPENMP)
Packit ea1746
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
Packit ea1746
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
Packit ea1746
    if (UNIX)
Packit ea1746
      # At least on Linux, we need pthreads to be enabled for mutex to
Packit ea1746
      # compile.  This may not work on Windows or Android.
Packit ea1746
      find_package(Threads REQUIRED)
Packit ea1746
      list(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_PTHREAD)
Packit ea1746
      list(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_RWLOCK)
Packit ea1746
    endif (UNIX)
Packit ea1746
  else (OPENMP_FOUND)
Packit ea1746
    message("-- Failed to find OpenMP, disabling. This is expected on "
Packit ea1746
      "Clang < 3.8, and at least Xcode <= 7.")
Packit ea1746
    update_cache_variable(OPENMP OFF)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
Packit ea1746
  endif (OPENMP_FOUND)
Packit ea1746
else (OPENMP)
Packit ea1746
  message("-- Building without OpenMP (disabling multithreading).")
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
Packit ea1746
endif (OPENMP)
Packit ea1746
Packit ea1746
# Initialise CMAKE_REQUIRED_FLAGS used by CheckCXXSourceCompiles with the
Packit ea1746
# contents of CMAKE_CXX_FLAGS such that if the user has passed extra flags
Packit ea1746
# they are used when discovering shared_ptr/unordered_map.
Packit ea1746
set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})
Packit ea1746
Packit ea1746
include(CheckCXXCompilerFlag)
Packit ea1746
check_cxx_compiler_flag("-std=c++11" COMPILER_HAS_CXX11_FLAG)
Packit ea1746
if (CXX11 AND COMPILER_HAS_CXX11_FLAG)
Packit ea1746
  # Update CMAKE_REQUIRED_FLAGS used by CheckCXXSourceCompiles to include
Packit ea1746
  # -std=c++11 s/t we will detect the C++11 versions of unordered_map &
Packit ea1746
  # shared_ptr if they exist.
Packit ea1746
  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
Packit ea1746
endif (CXX11 AND COMPILER_HAS_CXX11_FLAG)
Packit ea1746
Packit ea1746
# Set the Ceres compile definitions for the unordered_map configuration.
Packit ea1746
include(FindUnorderedMap)
Packit ea1746
find_unordered_map()
Packit ea1746
if (UNORDERED_MAP_FOUND)
Packit ea1746
  if (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP)
Packit ea1746
  endif(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
Packit ea1746
  if (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
Packit ea1746
  endif(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
Packit ea1746
  if (HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_UNORDERED_MAP)
Packit ea1746
  endif(HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE)
Packit ea1746
else (UNORDERED_MAP_FOUND)
Packit ea1746
  message("-- Replacing unordered_map/set with map/set (warning: slower!), "
Packit ea1746
    "try enabling CXX11 option if you expect C++11 to be available.")
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP)
Packit ea1746
endif()
Packit ea1746
Packit ea1746
# Set the Ceres compile definitions for the shared_ptr configuration.
Packit ea1746
include(FindSharedPtr)
Packit ea1746
find_shared_ptr()
Packit ea1746
if (SHARED_PTR_FOUND)
Packit ea1746
  if (SHARED_PTR_TR1_MEMORY_HEADER)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_MEMORY_HEADER)
Packit ea1746
  endif (SHARED_PTR_TR1_MEMORY_HEADER)
Packit ea1746
  if (SHARED_PTR_TR1_NAMESPACE)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_SHARED_PTR)
Packit ea1746
  endif (SHARED_PTR_TR1_NAMESPACE)
Packit ea1746
else (SHARED_PTR_FOUND)
Packit ea1746
  message(FATAL_ERROR "Unable to find shared_ptr, try enabling CXX11 option "
Packit ea1746
    "if you expect C++11 to be available.")
Packit ea1746
endif (SHARED_PTR_FOUND)
Packit ea1746
Packit ea1746
# To ensure that CXX11 accurately reflects whether we are using C++11,
Packit ea1746
# check if it is required given where the potentially C++11 features Ceres
Packit ea1746
# uses were found, and disable it if C++11 is not being used.
Packit ea1746
if (CXX11)
Packit ea1746
  if (NOT HAVE_SHARED_PTR_IN_STD_NAMESPACE AND
Packit ea1746
      NOT HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
Packit ea1746
    message("-- Failed to find C++11 components in C++11 locations & "
Packit ea1746
      "namespaces, disabling CXX11.")
Packit ea1746
    update_cache_variable(CXX11 OFF)
Packit ea1746
  else()
Packit ea1746
    message("   ==============================================================")
Packit ea1746
    message("   Compiling Ceres using C++11.  This will result in a version ")
Packit ea1746
    message("   of Ceres that will require the use of C++11 in client code.")
Packit ea1746
    message("   ==============================================================")
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX11)
Packit ea1746
    if (COMPILER_HAS_CXX11_FLAG AND
Packit ea1746
        CMAKE_VERSION VERSION_LESS "2.8.12")
Packit ea1746
      # For CMake versions > 2.8.12, the C++11 dependency is rolled into the
Packit ea1746
      # Ceres target, and all dependent targets, but for older versions of CMake
Packit ea1746
      # the flag must be specified explicitly both for Ceres and the
Packit ea1746
      # examples/tests.
Packit ea1746
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Packit ea1746
    endif()
Packit ea1746
  endif()
Packit ea1746
endif(CXX11)
Packit ea1746
Packit ea1746
include_directories(
Packit ea1746
  include
Packit ea1746
  internal
Packit ea1746
  internal/ceres
Packit ea1746
  ${GLOG_INCLUDE_DIRS})
Packit ea1746
# Eigen SparseQR generates various compiler warnings related to unused and
Packit ea1746
# uninitialised local variables.  To avoid having to individually suppress these
Packit ea1746
# warnings around the #include statments for Eigen headers across all GCC/Clang
Packit ea1746
# versions, we tell CMake to treat Eigen headers as system headers.  This
Packit ea1746
# results in all compiler warnings from them being suppressed.
Packit ea1746
#
Packit ea1746
# Note that this is *not* propagated to clients, ie CERES_INCLUDE_DIRS
Packit ea1746
# used by clients after find_package(Ceres) does not identify Eigen as
Packit ea1746
# as system headers.
Packit ea1746
include_directories(SYSTEM ${EIGEN_INCLUDE_DIRS})
Packit ea1746
Packit ea1746
if (SUITESPARSE)
Packit ea1746
  include_directories(${SUITESPARSE_INCLUDE_DIRS})
Packit ea1746
endif (SUITESPARSE)
Packit ea1746
Packit ea1746
if (CXSPARSE)
Packit ea1746
  include_directories(${CXSPARSE_INCLUDE_DIRS})
Packit ea1746
endif (CXSPARSE)
Packit ea1746
Packit ea1746
if (GFLAGS)
Packit ea1746
  include_directories(${GFLAGS_INCLUDE_DIRS})
Packit ea1746
endif (GFLAGS)
Packit ea1746
Packit ea1746
if (BUILD_SHARED_LIBS)
Packit ea1746
  message("-- Building Ceres as a shared library.")
Packit ea1746
  # The CERES_BUILDING_SHARED_LIBRARY compile definition is NOT stored in
Packit ea1746
  # CERES_COMPILE_OPTIONS as it must only be defined when Ceres is compiled
Packit ea1746
  # not when it is used as it controls the CERES_EXPORT macro which provides
Packit ea1746
  # dllimport/export support in MSVC.
Packit ea1746
  add_definitions(-DCERES_BUILDING_SHARED_LIBRARY)
Packit ea1746
  list(APPEND CERES_COMPILE_OPTIONS CERES_USING_SHARED_LIBRARY)
Packit ea1746
else (BUILD_SHARED_LIBS)
Packit ea1746
  message("-- Building Ceres as a static library.")
Packit ea1746
endif (BUILD_SHARED_LIBS)
Packit ea1746
Packit ea1746
# Change the default build type from Debug to Release, while still
Packit ea1746
# supporting overriding the build type.
Packit ea1746
#
Packit ea1746
# The CACHE STRING logic here and elsewhere is needed to force CMake
Packit ea1746
# to pay attention to the value of these variables.
Packit ea1746
if (NOT CMAKE_BUILD_TYPE)
Packit ea1746
  message("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.")
Packit ea1746
  set(CMAKE_BUILD_TYPE Release CACHE STRING
Packit ea1746
    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
Packit ea1746
    FORCE)
Packit ea1746
else (NOT CMAKE_BUILD_TYPE)
Packit ea1746
  if (CMAKE_BUILD_TYPE STREQUAL "Debug")
Packit ea1746
    message("\n=================================================================================")
Packit ea1746
    message("\n-- Build type: Debug. Performance will be terrible!")
Packit ea1746
    message("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.")
Packit ea1746
    message("\n=================================================================================")
Packit ea1746
  endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
Packit ea1746
endif (NOT CMAKE_BUILD_TYPE)
Packit ea1746
Packit ea1746
# Set the default Ceres flags to an empty string.
Packit ea1746
set (CERES_CXX_FLAGS)
Packit ea1746
Packit ea1746
if (CMAKE_BUILD_TYPE STREQUAL "Release")
Packit ea1746
  if (CMAKE_COMPILER_IS_GNUCXX)
Packit ea1746
    # Linux
Packit ea1746
    if (CMAKE_SYSTEM_NAME MATCHES "Linux")
Packit ea1746
      if (NOT GCC_VERSION VERSION_LESS 4.2)
Packit ea1746
        set (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -march=native -mtune=native")
Packit ea1746
      endif (NOT GCC_VERSION VERSION_LESS 4.2)
Packit ea1746
    endif (CMAKE_SYSTEM_NAME MATCHES "Linux")
Packit ea1746
    # Mac OS X
Packit ea1746
    if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
Packit ea1746
      set (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -msse3")
Packit ea1746
      # Use of -fast only applicable for Apple's GCC
Packit ea1746
      # Assume this is being used if GCC version < 4.3 on OSX
Packit ea1746
      execute_process(COMMAND ${CMAKE_C_COMPILER}
Packit ea1746
        ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
Packit ea1746
        OUTPUT_VARIABLE GCC_VERSION
Packit ea1746
        OUTPUT_STRIP_TRAILING_WHITESPACE)
Packit ea1746
      if (GCC_VERSION VERSION_LESS 4.3)
Packit ea1746
        set (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -fast")
Packit ea1746
      endif (GCC_VERSION VERSION_LESS 4.3)
Packit ea1746
    endif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
Packit ea1746
  endif (CMAKE_COMPILER_IS_GNUCXX)
Packit ea1746
endif (CMAKE_BUILD_TYPE STREQUAL "Release")
Packit ea1746
Packit ea1746
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CERES_CXX_FLAGS}")
Packit ea1746
Packit ea1746
if (MINGW)
Packit ea1746
  # MinGW produces code that segfaults when performing matrix multiplications
Packit ea1746
  # in Eigen when compiled with -O3 (see [1]), as such force the use of -O2
Packit ea1746
  # which works.
Packit ea1746
  #
Packit ea1746
  # [1] http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556
Packit ea1746
  message("-- MinGW detected, forcing -O2 instead of -O3 in Release for Eigen due "
Packit ea1746
          "to a MinGW bug: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556")
Packit ea1746
  string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
Packit ea1746
  update_cache_variable(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
Packit ea1746
endif (MINGW)
Packit ea1746
Packit ea1746
# After the tweaks for the compile settings, disable some warnings on MSVC.
Packit ea1746
if (MSVC)
Packit ea1746
  # On MSVC, math constants are not included in <cmath> or <math.h> unless
Packit ea1746
  # _USE_MATH_DEFINES is defined [1].  As we use M_PI in the examples, ensure
Packit ea1746
  # that _USE_MATH_DEFINES is defined before the first inclusion of <cmath>.
Packit ea1746
  #
Packit ea1746
  # [1] https://msdn.microsoft.com/en-us/library/4hwaceh6.aspx
Packit ea1746
  add_definitions("-D_USE_MATH_DEFINES")
Packit ea1746
  # Disable signed/unsigned int conversion warnings.
Packit ea1746
  add_definitions("/wd4018")
Packit ea1746
  # Disable warning about using struct/class for the same symobl.
Packit ea1746
  add_definitions("/wd4099")
Packit ea1746
  # Disable warning about the insecurity of using "std::copy".
Packit ea1746
  add_definitions("/wd4996")
Packit ea1746
  # Disable performance warning about int-to-bool conversion.
Packit ea1746
  add_definitions("/wd4800")
Packit ea1746
  # Disable performance warning about fopen insecurity.
Packit ea1746
  add_definitions("/wd4996")
Packit ea1746
  # Disable warning about int64 to int32 conversion. Disabling
Packit ea1746
  # this warning may not be correct; needs investigation.
Packit ea1746
  # TODO(keir): Investigate these warnings in more detail.
Packit ea1746
  add_definitions("/wd4244")
Packit ea1746
  # It's not possible to use STL types in DLL interfaces in a portable and
Packit ea1746
  # reliable way. However, that's what happens with Google Log and Google Flags
Packit ea1746
  # on Windows. MSVC gets upset about this and throws warnings that we can't do
Packit ea1746
  # much about. The real solution is to link static versions of Google Log and
Packit ea1746
  # Google Test, but that seems tricky on Windows. So, disable the warning.
Packit ea1746
  add_definitions("/wd4251")
Packit ea1746
Packit ea1746
  # Google Flags doesn't have their DLL import/export stuff set up correctly,
Packit ea1746
  # which results in linker warnings. This is irrelevant for Ceres, so ignore
Packit ea1746
  # the warnings.
Packit ea1746
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049")
Packit ea1746
Packit ea1746
  # Update the C/CXX flags for MSVC to use either the static or shared
Packit ea1746
  # C-Run Time (CRT) library based on the user option: MSVC_USE_STATIC_CRT.
Packit ea1746
  list(APPEND C_CXX_FLAGS
Packit ea1746
    CMAKE_CXX_FLAGS
Packit ea1746
    CMAKE_CXX_FLAGS_DEBUG
Packit ea1746
    CMAKE_CXX_FLAGS_RELEASE
Packit ea1746
    CMAKE_CXX_FLAGS_MINSIZEREL
Packit ea1746
    CMAKE_CXX_FLAGS_RELWITHDEBINFO)
Packit ea1746
Packit ea1746
  foreach(FLAG_VAR ${C_CXX_FLAGS})
Packit ea1746
    if (MSVC_USE_STATIC_CRT)
Packit ea1746
      # Use static CRT.
Packit ea1746
      if (${FLAG_VAR} MATCHES "/MD")
Packit ea1746
        string(REGEX REPLACE "/MD" "/MT" ${FLAG_VAR} "${${FLAG_VAR}}")
Packit ea1746
      endif (${FLAG_VAR} MATCHES "/MD")
Packit ea1746
    else (MSVC_USE_STATIC_CRT)
Packit ea1746
      # Use shared, not static, CRT.
Packit ea1746
      if (${FLAG_VAR} MATCHES "/MT")
Packit ea1746
        string(REGEX REPLACE "/MT" "/MD" ${FLAG_VAR} "${${FLAG_VAR}}")
Packit ea1746
      endif (${FLAG_VAR} MATCHES "/MT")
Packit ea1746
    endif (MSVC_USE_STATIC_CRT)
Packit ea1746
  endforeach()
Packit ea1746
Packit ea1746
  # Tuple sizes of 10 are used by Gtest.
Packit ea1746
  add_definitions("-D_VARIADIC_MAX=10")
Packit ea1746
Packit ea1746
  include(CheckIfUnderscorePrefixedBesselFunctionsExist)
Packit ea1746
  check_if_underscore_prefixed_bessel_functions_exist(
Packit ea1746
    HAVE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
Packit ea1746
  if (HAVE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
Packit ea1746
    list(APPEND CERES_COMPILE_OPTIONS
Packit ea1746
      CERES_MSVC_USE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
Packit ea1746
  endif()
Packit ea1746
endif (MSVC)
Packit ea1746
Packit ea1746
if (UNIX)
Packit ea1746
  # GCC is not strict enough by default, so enable most of the warnings.
Packit ea1746
  set(CMAKE_CXX_FLAGS
Packit ea1746
    "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
Packit ea1746
endif (UNIX)
Packit ea1746
Packit ea1746
# Use a larger inlining threshold for Clang, since it hobbles Eigen,
Packit ea1746
# resulting in an unreasonably slow version of the blas routines. The
Packit ea1746
# -Qunused-arguments is needed because CMake passes the inline
Packit ea1746
# threshold to the linker and clang complains about it and dies.
Packit ea1746
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
Packit ea1746
  set(CMAKE_CXX_FLAGS
Packit ea1746
    "${CMAKE_CXX_FLAGS} -Qunused-arguments -mllvm -inline-threshold=600")
Packit ea1746
Packit ea1746
  # Older versions of Clang (<= 2.9) do not support the 'return-type-c-linkage'
Packit ea1746
  # option, so check for its presence before adding it to the default flags set.
Packit ea1746
  include(CheckCXXCompilerFlag)
Packit ea1746
  check_cxx_compiler_flag("-Wno-return-type-c-linkage"
Packit ea1746
                          HAVE_RETURN_TYPE_C_LINKAGE)
Packit ea1746
  if (HAVE_RETURN_TYPE_C_LINKAGE)
Packit ea1746
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage")
Packit ea1746
  endif(HAVE_RETURN_TYPE_C_LINKAGE)
Packit ea1746
endif ()
Packit ea1746
Packit ea1746
# Xcode 4.5.x used Clang 4.1 (Apple version), this has a bug that prevents
Packit ea1746
# compilation of Ceres.
Packit ea1746
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
Packit ea1746
  execute_process(COMMAND ${CMAKE_CXX_COMPILER}
Packit ea1746
    ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
Packit ea1746
    OUTPUT_VARIABLE CLANG_VERSION
Packit ea1746
    OUTPUT_STRIP_TRAILING_WHITESPACE)
Packit ea1746
  # Use version > 4.0 & < 4.2 to catch all 4.1(.x) versions.
Packit ea1746
  if (CLANG_VERSION VERSION_GREATER 4.0 AND
Packit ea1746
      CLANG_VERSION VERSION_LESS 4.2)
Packit ea1746
    message(FATAL_ERROR "You are attempting to build Ceres on OS X using Xcode "
Packit ea1746
      "4.5.x (Clang version: ${CLANG_VERSION}). This version of Clang has a "
Packit ea1746
      "bug that prevents compilation of Ceres, please update to "
Packit ea1746
      "Xcode >= 4.6.3.")
Packit ea1746
  endif (CLANG_VERSION VERSION_GREATER 4.0 AND
Packit ea1746
    CLANG_VERSION VERSION_LESS 4.2)
Packit ea1746
endif (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
Packit ea1746
Packit ea1746
# Configure the Ceres config.h compile options header using the current
Packit ea1746
# compile options and put the configured header into the Ceres build
Packit ea1746
# directory.  Note that the ceres/internal subdir in <build>/config where
Packit ea1746
# the configured config.h is placed is important, because Ceres will be
Packit ea1746
# built against this configured header, it needs to have the same relative
Packit ea1746
# include path as it would if it were in the source tree (or installed).
Packit ea1746
list(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
Packit ea1746
include(CreateCeresConfig)
Packit ea1746
create_ceres_config("${CERES_COMPILE_OPTIONS}"
Packit ea1746
  ${Ceres_BINARY_DIR}/config/ceres/internal)
Packit ea1746
# Force the location containing the configured config.h to the front of the
Packit ea1746
# include_directories list (by default it is appended to the back) to ensure
Packit ea1746
# that if the user has an installed version of Ceres in the same location as one
Packit ea1746
# of the dependencies (e.g. /usr/local) that we find the config.h we just
Packit ea1746
# configured, not the (older) installed config.h.
Packit ea1746
include_directories(BEFORE ${Ceres_BINARY_DIR}/config)
Packit ea1746
Packit ea1746
add_subdirectory(internal/ceres)
Packit ea1746
Packit ea1746
if (BUILD_DOCUMENTATION)
Packit ea1746
  set(CERES_DOCS_INSTALL_DIR "share/doc/ceres" CACHE STRING
Packit ea1746
      "Ceres docs install path relative to CMAKE_INSTALL_PREFIX")
Packit ea1746
Packit ea1746
  find_package(Sphinx QUIET)
Packit ea1746
  if (NOT SPHINX_FOUND)
Packit ea1746
    message("-- Failed to find Sphinx, disabling build of documentation.")
Packit ea1746
    update_cache_variable(BUILD_DOCUMENTATION OFF)
Packit ea1746
  else()
Packit ea1746
    # Generate the User's Guide (html).
Packit ea1746
    # The corresponding target is ceres_docs, but is included in ALL.
Packit ea1746
    message("-- Build the HTML documentation.")
Packit ea1746
    add_subdirectory(docs)
Packit ea1746
  endif()
Packit ea1746
endif (BUILD_DOCUMENTATION)
Packit ea1746
Packit ea1746
if (BUILD_EXAMPLES)
Packit ea1746
  message("-- Build the examples.")
Packit ea1746
  add_subdirectory(examples)
Packit ea1746
else (BUILD_EXAMPLES)
Packit ea1746
  message("-- Do not build any example.")
Packit ea1746
endif (BUILD_EXAMPLES)
Packit ea1746
Packit ea1746
# Setup installation of Ceres public headers.
Packit ea1746
file(GLOB CERES_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
Packit ea1746
install(FILES ${CERES_HDRS} DESTINATION include/ceres)
Packit ea1746
Packit ea1746
file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
Packit ea1746
install(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
Packit ea1746
Packit ea1746
# Also setup installation of Ceres config.h configured with the current
Packit ea1746
# build options into the installed headers directory.
Packit ea1746
install(FILES ${Ceres_BINARY_DIR}/config/ceres/internal/config.h
Packit ea1746
        DESTINATION include/ceres/internal)
Packit ea1746
Packit ea1746
if (MINIGLOG)
Packit ea1746
  # Install miniglog header if being used as logging #includes appear in
Packit ea1746
  # installed public Ceres headers.
Packit ea1746
  install(FILES ${Ceres_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
Packit ea1746
          DESTINATION include/ceres/internal/miniglog/glog)
Packit ea1746
endif (MINIGLOG)
Packit ea1746
Packit ea1746
# Ceres supports two mechanisms by which it can be detected & imported into
Packit ea1746
# client code which uses CMake via find_package(Ceres):
Packit ea1746
#
Packit ea1746
#   1) Installation (e.g. to /usr/local), using CMake's install() function.
Packit ea1746
#
Packit ea1746
#   2) (Optional) Export of the current build directory into the local CMake
Packit ea1746
#      package registry, using CMake's export() function.  This allows use of
Packit ea1746
#      Ceres from other projects without requiring installation.
Packit ea1746
#
Packit ea1746
# In both cases, we need to generate a configured CeresConfig.cmake which
Packit ea1746
# includes additional autogenerated files which in concert create an imported
Packit ea1746
# target for Ceres in a client project when find_package(Ceres) is invoked.
Packit ea1746
# The key distinctions are where this file is located, and whether client code
Packit ea1746
# references installed copies of the compiled Ceres headers/libraries,
Packit ea1746
# (option #1: installation), or the originals in the source/build directories
Packit ea1746
# (option #2: export of build directory).
Packit ea1746
#
Packit ea1746
# NOTE: If Ceres is both exported and installed, provided that the installation
Packit ea1746
#       path is present in CMAKE_MODULE_PATH when find_package(Ceres) is called,
Packit ea1746
#       the installed version is preferred.
Packit ea1746
Packit ea1746
# Build the list of Ceres components for CeresConfig.cmake from the current set
Packit ea1746
# of compile options.
Packit ea1746
include(CeresCompileOptionsToComponents)
Packit ea1746
ceres_compile_options_to_components("${CERES_COMPILE_OPTIONS}"
Packit ea1746
  CERES_COMPILED_COMPONENTS)
Packit ea1746
Packit ea1746
# Create a CeresConfigVersion.cmake file containing the version information,
Packit ea1746
# used by both export() & install().
Packit ea1746
configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
Packit ea1746
               "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
Packit ea1746
Packit ea1746
# Install method #1: Put Ceres in CMAKE_INSTALL_PREFIX: /usr/local or equivalent.
Packit ea1746
Packit ea1746
# Set the install path for the installed CeresConfig.cmake configuration file
Packit ea1746
# relative to CMAKE_INSTALL_PREFIX.
Packit ea1746
if (WIN32)
Packit ea1746
  set(RELATIVE_CMAKECONFIG_INSTALL_DIR CMake)
Packit ea1746
else ()
Packit ea1746
  set(RELATIVE_CMAKECONFIG_INSTALL_DIR lib${LIB_SUFFIX}/cmake/Ceres)
Packit ea1746
endif ()
Packit ea1746
Packit ea1746
# This "exports" for installation all targets which have been put into the
Packit ea1746
# export set "CeresExport". This generates a CeresTargets.cmake file which,
Packit ea1746
# when read in by a client project as part of find_package(Ceres) creates
Packit ea1746
# imported library targets for Ceres (with dependency relations) which can be
Packit ea1746
# used in target_link_libraries() calls in the client project to use Ceres.
Packit ea1746
install(EXPORT CeresExport
Packit ea1746
        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR} FILE CeresTargets.cmake)
Packit ea1746
Packit ea1746
# Save the relative path from the installed CeresConfig.cmake file to the
Packit ea1746
# install prefix.  We do not save an absolute path in case the installed package
Packit ea1746
# is subsequently relocated after installation (on Windows).
Packit ea1746
file(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
Packit ea1746
     ${CMAKE_INSTALL_PREFIX}/${RELATIVE_CMAKECONFIG_INSTALL_DIR}
Packit ea1746
     ${CMAKE_INSTALL_PREFIX})
Packit ea1746
Packit ea1746
# Configure a CeresConfig.cmake file for an installed version of Ceres from the
Packit ea1746
# template, reflecting the current build options.
Packit ea1746
#
Packit ea1746
# NOTE: The -install suffix is necessary to distinguish the install version from
Packit ea1746
#       the exported version, which must be named CeresConfig.cmake in
Packit ea1746
#       Ceres_BINARY_DIR to be detected.  The suffix is removed when
Packit ea1746
#       it is installed.
Packit ea1746
set(SETUP_CERES_CONFIG_FOR_INSTALLATION TRUE)
Packit ea1746
configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
Packit ea1746
               "${Ceres_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
Packit ea1746
Packit ea1746
# Install the configuration files into the same directory as the autogenerated
Packit ea1746
# CeresTargets.cmake file.  We include the find_package() scripts for libraries
Packit ea1746
# whose headers are included in the public API of Ceres and should thus be
Packit ea1746
# present in CERES_INCLUDE_DIRS.
Packit ea1746
install(FILES "${Ceres_BINARY_DIR}/CeresConfig-install.cmake"
Packit ea1746
        RENAME CeresConfig.cmake
Packit ea1746
        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
Packit ea1746
install(FILES "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake"
Packit ea1746
              "${Ceres_SOURCE_DIR}/cmake/FindEigen.cmake"
Packit ea1746
              "${Ceres_SOURCE_DIR}/cmake/FindGlog.cmake"
Packit ea1746
              "${Ceres_SOURCE_DIR}/cmake/FindGflags.cmake"
Packit ea1746
        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
Packit ea1746
Packit ea1746
# Create an uninstall target to remove all installed files.
Packit ea1746
configure_file("${Ceres_SOURCE_DIR}/cmake/uninstall.cmake.in"
Packit ea1746
               "${Ceres_BINARY_DIR}/cmake/uninstall.cmake"
Packit ea1746
               @ONLY)
Packit ea1746
add_custom_target(uninstall
Packit ea1746
                  COMMAND ${CMAKE_COMMAND} -P ${Ceres_BINARY_DIR}/cmake/uninstall.cmake)
Packit ea1746
Packit ea1746
# Install method #2: Put Ceres build into local CMake registry.
Packit ea1746
#
Packit ea1746
# Optionally export the Ceres build directory into the local CMake package
Packit ea1746
# registry (~/.cmake/packages on *nix & OS X).  This allows the detection &
Packit ea1746
# use of Ceres without requiring that it be installed.
Packit ea1746
if (EXPORT_BUILD_DIR)
Packit ea1746
  message("-- Export Ceres build directory to local CMake package registry.")
Packit ea1746
Packit ea1746
  # Save the relative path from the build directory to the source directory.
Packit ea1746
  file(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
Packit ea1746
    ${Ceres_BINARY_DIR}
Packit ea1746
    ${Ceres_SOURCE_DIR})
Packit ea1746
Packit ea1746
  # Analogously to install(EXPORT ...), export the Ceres target from the build
Packit ea1746
  # directory as a package called Ceres into the local CMake package registry.
Packit ea1746
  export(TARGETS ceres FILE ${Ceres_BINARY_DIR}/CeresTargets.cmake)
Packit ea1746
  export(PACKAGE ${CMAKE_PROJECT_NAME})
Packit ea1746
Packit ea1746
  # Configure a CeresConfig.cmake file for the export of the Ceres build
Packit ea1746
  # directory from the template, reflecting the current build options.
Packit ea1746
  set(SETUP_CERES_CONFIG_FOR_INSTALLATION FALSE)
Packit ea1746
  configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
Packit ea1746
    "${Ceres_BINARY_DIR}/CeresConfig.cmake" @ONLY)
Packit ea1746
Packit ea1746
endif (EXPORT_BUILD_DIR)