Cleaning up exported CeresConfig.cmake.
- Adding FindPackage scripts for all of Ceres dependencies.
- Moving depend.cmake contents to CeresConfig.cmake and cleaning up
search for Ceres & required dependencies, no longer push Ceres
options into client.
- Fixing uninstall to remove ceres include root directory.
- Fixing main CMakeLists to install miniglog header if enabled.
- Making miniglog library shared/static with Ceres library.
Change-Id: If926bebd11720230c5136597ccba672394ed9777
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb022ca..6f267b2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,6 +69,9 @@
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+# Set postfixes for generated libraries based on buildtype.
+SET(CMAKE_RELEASE_POSTFIX "")
+SET(CMAKE_DEBUG_POSTFIX "-debug")
# Important: Always bump the second number (e.g. 1.3.x to 1.4.0) for any
# release that changes the ABI. The ABI changes for almost any modification to
@@ -114,35 +117,67 @@
OPTION(BUILD_EXAMPLES "Build examples" ON)
OPTION(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
-# Default locations to search for on various platforms.
+# Prior to October 2013, Ceres used some non-CMake standardised variables to
+# hold user-specified (as opposed to FindPackage found) include directory and
+# library paths for Ceres dependencies. These were were of the form:
+# <DEPENDENCY>_LIB / <DEPENDENCY>_INCLUDE. Since then, Ceres now has
+# FindPackage() scripts for all of its dependencies which obey the standard
+# CMake variables: <DEPENDENCY>_LIBRARIES & <DEPENDENCY>_INCLUDE_DIRS. In order
+# to ensure backwards compatibility, we use convert any legacy variables to
+# _directory_ hints for the FindPackage() scripts.
+MACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT
+ LEGACY_VAR DIRECTORY_HINT_VAR)
+ IF (DEFINED ${LEGACY_VAR})
+ # Get the dependency name (all caps) from the hint directory variable
+ # for the warning message.
+ STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
+ MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
+ "to specify the include directory for ${DEPENDENCY_NAME}. This is "
+ "deprecated and support for it will be removed in a future release. "
+ "Please use either the search directory hints variable: "
+ "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_INCLUDE_DIR to specify "
+ "exactly the directory used (no search performed), see: "
+ "http://homes.cs.washington.edu/~sagarwal/ceres-solver/dev/building.html "
+ "for more information.")
+ LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
+ ENDIF (DEFINED ${LEGACY_VAR})
+ENDMACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT)
-# Libraries
-LIST(APPEND CMAKE_LIBRARY_PATH /opt/local/lib)
-LIST(APPEND CMAKE_LIBRARY_PATH /usr/lib)
-LIST(APPEND CMAKE_LIBRARY_PATH /usr/lib/atlas)
-LIST(APPEND CMAKE_LIBRARY_PATH /usr/lib64/atlas)
-LIST(APPEND CMAKE_LIBRARY_PATH /usr/local/homebrew/lib) # Mac OS X
-LIST(APPEND CMAKE_LIBRARY_PATH /usr/local/lib)
-
-# Headers
-LIST(APPEND CMAKE_INCLUDE_PATH /opt/local/include)
-LIST(APPEND CMAKE_INCLUDE_PATH /opt/local/var/macports/software/eigen3) # Mac OS X
-LIST(APPEND CMAKE_INCLUDE_PATH /opt/local/include/eigen3) # Mac OS X
-LIST(APPEND CMAKE_INCLUDE_PATH /usr/include)
-LIST(APPEND CMAKE_INCLUDE_PATH /usr/include/eigen3) # Ubuntu 10.04's default location.
-LIST(APPEND CMAKE_INCLUDE_PATH /usr/local/homebrew/include) # Mac OS X
-LIST(APPEND CMAKE_INCLUDE_PATH /usr/local/homebrew/include/eigen3) # Mac OS X
-LIST(APPEND CMAKE_INCLUDE_PATH /usr/local/include)
-LIST(APPEND CMAKE_INCLUDE_PATH /usr/local/include/eigen3)
+MACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT
+ LEGACY_VAR DIRECTORY_HINT_VAR)
+ IF (DEFINED ${LEGACY_VAR})
+ # Get the dependency name (all caps) from the hint directory variable
+ # for the warning message.
+ STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
+ MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
+ "to specify the library for ${DEPENDENCY_NAME}. This is "
+ "deprecated and support for it will be removed in a future release. "
+ "Please use either the search directory hints variable: "
+ "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_LIBRARY to specify "
+ "exactly the library used (no search performed), see: "
+ "http://homes.cs.washington.edu/~sagarwal/ceres-solver/dev/building.html "
+ "for more information.")
+ IF (EXISTS ${${LEGACY_VAR}} AND
+ NOT IS_DIRECTORY ${${LEGACY_VAR}})
+ # User specified an explicit (library) file using the legacy variable
+ # interface, hints to FindPackage() scripts are directories so add the
+ # parent directory of the specified file.
+ GET_FILENAME_COMPONENT(DIR_HINT ${${LEGACY_VAR}} PATH)
+ LIST(APPEND ${DIRECTORY_HINT_VAR} ${DIR_HINT})
+ ELSEIF (EXISTS ${${LEGACY_VAR}} AND
+ IS_DIRECTORY ${${LEGACY_VAR}})
+ # User specified a directory hint using the legacy variable, use it.
+ LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
+ ENDIF()
+ ENDIF (DEFINED ${LEGACY_VAR})
+ENDMACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT)
# Eigen.
-FIND_PATH(EIGEN_INCLUDE NAMES Eigen/Core)
-IF (NOT EXISTS ${EIGEN_INCLUDE})
- MESSAGE(FATAL_ERROR "Can't find Eigen. Try passing -DEIGEN_INCLUDE=...")
-ELSE (NOT EXISTS ${EIGEN_INCLUDE})
- MESSAGE("-- Found Eigen 3.x: ${EIGEN_INCLUDE}")
-ENDIF (NOT EXISTS ${EIGEN_INCLUDE})
-MARK_AS_ADVANCED(EIGEN_INCLUDE)
+HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS)
+FIND_PACKAGE(Eigen REQUIRED)
+IF (EIGEN_FOUND)
+ MESSAGE("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}")
+ENDIF (EIGEN_FOUND)
# LAPACK (& BLAS).
IF (LAPACK)
@@ -210,7 +245,8 @@
# By default, if all of SuiteSparse's dependencies are found, Ceres is
# built with SuiteSparse support.
- MESSAGE("-- Found all SuiteSparse dependencies. Building with SuiteSparse.")
+ MESSAGE("-- Found SuiteSparse ${SUITESPARSE_VERSION}, "
+ "building with SuiteSparse.")
ELSE (SUITESPARSE_FOUND)
# Disable use of SuiteSparse if it cannot be found and continue.
MESSAGE("-- Did not find all SuiteSparse dependencies, disabling "
@@ -228,29 +264,13 @@
# CXSparse.
IF (CXSPARSE)
- SET(CXSPARSE_FOUND ON)
- FIND_LIBRARY(CXSPARSE_LIB NAMES cxsparse)
- IF (EXISTS ${CXSPARSE_LIB})
- MESSAGE("-- Found CXSparse library in: ${CXSPARSE_LIB}")
- ELSE (EXISTS ${CXSPARSE_LIB})
- MESSAGE("-- Did not find CXSparse header")
- SET(CXSPARSE_FOUND FALSE)
- ENDIF (EXISTS ${CXSPARSE_LIB})
- MARK_AS_ADVANCED(CXSPARSE_LIB)
-
- FIND_PATH(CXSPARSE_INCLUDE NAMES cs.h)
- IF (EXISTS ${CXSPARSE_INCLUDE})
- MESSAGE("-- Found CXSparse header in: ${CXSPARSE_INCLUDE}")
- ELSE (EXISTS ${CXSPARSE_INCLUDE})
- MESSAGE("-- Did not find CXSparse header")
- SET(CXSPARSE_FOUND FALSE)
- ENDIF (EXISTS ${CXSPARSE_INCLUDE})
- MARK_AS_ADVANCED(CXSPARSE_INCLUDE)
-
+ # Don't search with REQUIRED as we can continue without CXSparse.
+ FIND_PACKAGE(CXSparse)
IF (CXSPARSE_FOUND)
# By default, if CXSparse and all dependencies are found, Ceres is
# built with CXSparse support.
- MESSAGE("-- Building with CXSparse.")
+ MESSAGE("-- Found CXSparse version: ${CXSPARSE_VERSION}, "
+ "building with CXSparse.")
ELSE (CXSPARSE_FOUND)
# Disable use of CXSparse if it cannot be found and continue.
MESSAGE("-- Did not find CXSparse, Building without CXSparse.")
@@ -263,55 +283,70 @@
ELSE (CXSPARSE)
MESSAGE("-- Building without CXSparse.")
ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
+ # Mark as advanced (remove from default GUI view) the CXSparse search
+ # variables in case user enabled CXSPARSE, FindCXSparse did not find it, so
+ # made search variables visible in GUI for user to set, but then user disables
+ # CXSPARSE instead of setting them.
+ MARK_AS_ADVANCED(FORCE CXSPARSE_INCLUDE_DIR
+ CXSPARSE_LIBRARY)
ENDIF (CXSPARSE)
# GFlags.
IF (GFLAGS)
- FIND_LIBRARY(GFLAGS_LIB NAMES gflags)
- IF (NOT EXISTS ${GFLAGS_LIB})
- MESSAGE(FATAL_ERROR
- "Can't find Google Flags. Please specify: "
- "-DGFLAGS_LIB=...")
- ENDIF (NOT EXISTS ${GFLAGS_LIB})
- MARK_AS_ADVANCED(GFLAGS_LIB)
- MESSAGE("-- Found Google Flags library: ${GFLAGS_LIB}")
- FIND_PATH(GFLAGS_INCLUDE NAMES gflags/gflags.h)
- IF (NOT EXISTS ${GFLAGS_INCLUDE})
- MESSAGE(FATAL_ERROR
- "Can't find Google Flags. Please specify: "
- "-DGFLAGS_INCLUDE=...")
- ENDIF (NOT EXISTS ${GFLAGS_INCLUDE})
- MARK_AS_ADVANCED(GFLAGS_INCLUDE)
- MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE}")
+ HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GFLAGS_INCLUDE GFLAGS_INCLUDE_DIR_HINTS)
+ HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GFLAGS_LIB GFLAGS_LIBRARY_DIR_HINTS)
+
+ # Don't search with REQUIRED as we can continue without gflags.
+ FIND_PACKAGE(Gflags)
+ IF (GFLAGS_FOUND)
+ MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}")
+ ELSE (GFLAGS_FOUND)
+ MESSAGE("-- Did not find Google Flags (gflags), Building without gflags "
+ "- no tests or tools will be built!")
+ # Retain the help string associated with the GFLAGS option
+ # when updating it to disable use of gflags.
+ GET_PROPERTY(HELP_STRING CACHE GFLAGS PROPERTY HELPSTRING)
+ SET(GFLAGS OFF CACHE BOOL "${HELP_STRING}" FORCE)
+ ADD_DEFINITIONS(-DCERES_NO_GFLAGS)
+ ENDIF (GFLAGS_FOUND)
ELSE (GFLAGS)
MESSAGE("-- Google Flags disabled; no tests or tools will be built!")
ADD_DEFINITIONS(-DCERES_NO_GFLAGS)
+ # Mark as advanced (remove from default GUI view) the gflags search
+ # variables in case user enabled GFLAGS, FindGflags did not find it, so
+ # made search variables visible in GUI for user to set, but then user disables
+ # GFLAGS instead of setting them.
+ MARK_AS_ADVANCED(FORCE GFLAGS_INCLUDE_DIR
+ GFLAGS_LIBRARY)
ENDIF (GFLAGS)
# MiniGLog.
IF (MINIGLOG)
- SET(GLOG_LIB miniglog)
- MESSAGE("-- Using minimal Glog substitute (library): ${GLOG_LIB}")
- SET(GLOG_INCLUDE internal/ceres/miniglog)
- MESSAGE("-- Using minimal Glog substitute (include): ${GLOG_INCLUDE}")
-ELSE (MINIGLOG)
- FIND_LIBRARY(GLOG_LIB NAMES glog)
- IF (EXISTS ${GLOG_LIB})
- MESSAGE("-- Found Google Log library: ${GLOG_LIB}")
- ELSE (EXISTS ${GLOG_LIB})
- MESSAGE(FATAL_ERROR
- "Can't find Google Log. Please specify: -DGLOG_LIB=...")
- ENDIF (EXISTS ${GLOG_LIB})
- MARK_AS_ADVANCED(GLOG_LIB)
+ SET(GLOG_LIBRARIES miniglog)
+ MESSAGE("-- Using minimal Glog substitute (library): ${GLOG_LIBRARIES}")
+ SET(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
+ MESSAGE("-- Using minimal Glog substitute (include): ${GLOG_INCLUDE_DIRS}")
- FIND_PATH(GLOG_INCLUDE NAMES glog/logging.h)
- IF (EXISTS ${GLOG_INCLUDE})
- MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE}")
- ELSE (EXISTS ${GLOG_INCLUDE})
- MESSAGE(FATAL_ERROR
- "Can't find Google Log. Please specify: -DGLOG_INCLUDE=...")
- ENDIF (EXISTS ${GLOG_INCLUDE})
- MARK_AS_ADVANCED(GLOG_INCLUDE)
+ # Mark as advanced (remove from default GUI view) the glog search
+ # variables in case user disables MINIGLOG, FindGlog did not find it, so
+ # made search variables visible in GUI for user to set, but then user enables
+ # MINIGLOG instead of setting them.
+ MARK_AS_ADVANCED(FORCE GLOG_INCLUDE_DIR
+ GLOG_LIBRARY)
+ELSE (MINIGLOG)
+ HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GLOG_INCLUDE GLOG_INCLUDE_DIR_HINTS)
+ HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GLOG_LIB GLOG_LIBRARY_DIR_HINTS)
+
+ # Don't search with REQUIRED so that configuration continues if not found and
+ # we can output an error messages explaining MINIGLOG option.
+ FIND_PACKAGE(Glog)
+ IF (GLOG_FOUND)
+ MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE_DIRS}")
+ ELSE (GLOG_FOUND)
+ MESSAGE(FATAL_ERROR "Can't find Google Log. Please set GLOG_INCLUDE_DIR & "
+ "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
+ "implementation.")
+ ENDIF (GLOG_FOUND)
ENDIF (MINIGLOG)
IF (NOT SCHUR_SPECIALIZATIONS)
@@ -393,15 +428,8 @@
include
internal
internal/ceres
- ${GLOG_INCLUDE}
- ${EIGEN_INCLUDE}
- )
-
-FILE(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
-INSTALL(FILES ${CERES_HDRS} DESTINATION include/ceres)
-
-FILE(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
-INSTALL(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
+ ${GLOG_INCLUDE_DIRS}
+ ${EIGEN_INCLUDE_DIRS})
IF (SUITESPARSE)
INCLUDE_DIRECTORIES(${SUITESPARSE_INCLUDE_DIRS})
@@ -412,7 +440,7 @@
ENDIF (CXSPARSE)
IF (GFLAGS)
- INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE})
+ INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE_DIRS})
ENDIF (GFLAGS)
IF (BUILD_SHARED_LIBS)
@@ -529,6 +557,7 @@
"${CMAKE_CXX_FLAGS} -Qunused-arguments -mllvm -inline-threshold=600")
# Older versions of Clang (<= 2.9) do not support the 'return-type-c-linkage'
# option, so check for its presence before adding it to the default flags set.
+ INCLUDE(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-Wno-return-type-c-linkage"
HAVE_RETURN_TYPE_C_LINKAGE)
IF (HAVE_RETURN_TYPE_C_LINKAGE)
@@ -571,6 +600,20 @@
MESSAGE("-- Do not build any example.")
ENDIF (BUILD_EXAMPLES)
+# Setup installation of Ceres public headers.
+FILE(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
+INSTALL(FILES ${CERES_HDRS} DESTINATION include/ceres)
+
+FILE(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
+INSTALL(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
+
+IF (MINIGLOG)
+ # Install miniglog header if being used as logging #includes appear in
+ # installed public Ceres headers.
+ INSTALL(FILES ${CMAKE_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
+ DESTINATION include/ceres/internal/miniglog/glog)
+ENDIF (MINIGLOG)
+
# Add an uninstall target to remove all installed files.
CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
"${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
@@ -605,7 +648,7 @@
# install prefix (which may be at runtime different from the chosen
# CMAKE_INSTALL_PREFIX if under Windows the package was installed anywhere)
# This relative path will be configured into the CeresConfig.cmake.
-FILE(RELATIVE_PATH relInstallDir
+FILE(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
${CMAKE_INSTALL_PREFIX}/${CMAKECONFIG_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
# Create a CeresConfig.cmake file. <name>Config.cmake files are searched by
@@ -621,8 +664,11 @@
CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
-# Install these two files into the same directory as the generated exports-file.
+# Install these files into the same directory as the generated exports-file,
+# we include the FindPackage scripts for libraries whose headers are included
+# in the public API of Ceres and should thus be present in CERES_INCLUDE_DIRS.
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CeresConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/CeresConfigVersion.cmake"
- "${CMAKE_SOURCE_DIR}/cmake/depend.cmake"
+ "${CMAKE_SOURCE_DIR}/cmake/FindEigen.cmake"
+ "${CMAKE_SOURCE_DIR}/cmake/FindGlog.cmake"
DESTINATION ${CMAKECONFIG_INSTALL_DIR})
diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in
index d000046..6044700 100644
--- a/cmake/CeresConfig.cmake.in
+++ b/cmake/CeresConfig.cmake.in
@@ -26,24 +26,161 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
-# Author: pablo.speciale@gmail.com (Pablo Speciale)
+# Authors: pablo.speciale@gmail.com (Pablo Speciale)
+# alexs.mac@gmail.com (Alex Stewart)
#
-# Get the directory
-GET_FILENAME_COMPONENT(currentDir ${CMAKE_CURRENT_LIST_FILE} PATH)
+# Config file for Ceres Solver - Find Ceres & dependencies.
+#
+# This file is used by CMake when FIND_PACKAGE( Ceres ) is invoked (and
+# the directory containing this file is present in CMAKE_MODULE_PATH).
+#
+# This module defines the following variables:
+#
+# CERES_VERSION
+# CERES_INCLUDE_DIRS: Include directories for Ceres and the dependencies which
+# appear in the Ceres public API and are thus required to
+# use Ceres.
+# CERES_LIBRARIES: Libraries for Ceres and all dependencies against which Ceres
+# was compiled. This will not include any optional dependencies
+# that were disabled when Ceres was compiled.
+#
+# The following variables are also defined for legacy compatibility only.
+# Any new code should not use them as they do not conform to the standard CMake
+# FindPackage naming conventions.
+#
+# CERES_INCLUDES = ${CERES_INCLUDE_DIRS}.
-# Get the chosen install prefix
-GET_FILENAME_COMPONENT(rootDir ${currentDir}/@relInstallDir@ ABSOLUTE)
+# Called if we failed to find Ceres or any of it's required dependencies,
+# unsets all public (designed to be used externally) variables and reports
+# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
+MACRO(CERES_REPORT_NOT_FOUND REASON_MSG)
+ UNSET(CERES_FOUND)
+ UNSET(CERES_INCLUDE_DIRS)
+ UNSET(CERES_LIBRARIES)
-# Set the version
+ # Reset the CMake module path to its state when this script was called.
+ SET(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH})
+
+ # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
+ # use the camelcase library name, not uppercase.
+ IF (Ceres_FIND_QUIETLY)
+ MESSAGE(STATUS "Failed to find Ceres - " ${REASON_MSG} ${ARGN})
+ ELSE (Ceres_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Failed to find Ceres - " ${REASON_MSG} ${ARGN})
+ ELSE()
+ # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error
+ # that prevents generation, but continues configuration.
+ MESSAGE(SEND_ERROR "Failed to find Ceres - " ${REASON_MSG} ${ARGN})
+ ENDIF ()
+ RETURN()
+ENDMACRO(CERES_REPORT_NOT_FOUND)
+
+# Get the (current, i.e. installed) directory containing this file.
+SET(CURRENT_CONFIG_INSTALL_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+# Record the state of the CMake module path when this script was called so
+# that we can ensure that we leave it in the same state on exit as it was
+# on entry, but modify it locally.
+SET(CALLERS_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+# Reset CMake module path to the installation directory of this script,
+# thus we will use the FindPackage() scripts shipped with Ceres to find
+# Ceres' dependencies, even if the user has equivalently named FindPackage()
+# scripts in their project.
+SET(CMAKE_MODULE_PATH ${CURRENT_CONFIG_INSTALL_DIR})
+
+# Build the absolute root install directory as a relative path (determined when
+# Ceres was configured & built) from the current install directory for this
+# this file. This allows for the install tree to be relocated, after Ceres was
+# built, outside of CMake.
+GET_FILENAME_COMPONENT(CURRENT_ROOT_INSTALL_DIR
+ ${CURRENT_CONFIG_INSTALL_DIR}/@INSTALL_ROOT_REL_CONFIG_INSTALL_DIR@ ABSOLUTE)
+IF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
+ CERES_REPORT_NOT_FOUND(
+ "Ceres install root: ${CURRENT_ROOT_INSTALL_DIR}, "
+ "determined from relative path from CeresConfg.cmake install location: "
+ "${CURRENT_CONFIG_INSTALL_DIR}, does not exist. Either the install "
+ "directory was deleted, or the install tree was only partially relocated "
+ "outside of CMake after Ceres was built.")
+ENDIF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
+
+# Set the version.
SET(CERES_VERSION @CERES_VERSION@ )
-# What is my include directory
-SET(CERES_INCLUDES "${rootDir}/@INCLUDE_INSTALL_DIR@")
+# Set the include directories for Ceres (itself).
+SET(CERES_INCLUDE_DIR "${CURRENT_ROOT_INSTALL_DIR}/@INCLUDE_INSTALL_DIR@")
+IF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
+ CERES_REPORT_NOT_FOUND(
+ "Ceres install root: ${CURRENT_ROOT_INSTALL_DIR}, "
+ "determined from relative path from CeresConfg.cmake install location: "
+ "${CURRENT_CONFIG_INSTALL_DIR}, does not contain Ceres headers. "
+ "Either the install directory was deleted, or the install tree was only "
+ "partially relocated outside of CMake after Ceres was built.")
+ENDIF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
-# Import the exported targets
-INCLUDE(${currentDir}/CeresTargets.cmake)
-INCLUDE(${currentDir}/depend.cmake)
+# Append the include directories for all (potentially optional) dependencies
+# with which Ceres was compiled, the libraries themselves come in via
+# CeresTargets-<release/debug>.cmake as link libraries for Ceres target.
+SET(CERES_INCLUDE_DIRS ${CERES_INCLUDE_DIR})
-# Set the expected library variable
+# Eigen.
+# Flag set during configuration and build of Ceres.
+SET(CERES_EIGEN_VERSION @EIGEN_VERSION@)
+# Search quietly s/t we control the timing of the error message if not found.
+FIND_PACKAGE(Eigen ${CERES_EIGEN_VERSION} EXACT QUIET)
+IF (EIGEN_FOUND)
+ MESSAGE(STATUS "Found required Ceres dependency: "
+ "Eigen version ${CERES_EIGEN_VERSION} in ${EIGEN_INCLUDE_DIRS}")
+ELSE (EIGEN_FOUND)
+ CERES_REPORT_NOT_FOUND("Missing required Ceres "
+ "dependency: Eigen version ${CERES_EIGEN_VERSION}, please set "
+ "EIGEN_INCLUDE_DIR.")
+ENDIF (EIGEN_FOUND)
+LIST(APPEND CERES_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS})
+
+# Glog.
+# Flag set during configuration and build of Ceres.
+SET(CERES_USES_MINIGLOG @MINIGLOG@)
+IF (CERES_USES_MINIGLOG)
+ SET(MINIGLOG_INCLUDE_DIR ${CERES_INCLUDE_DIR}/ceres/internal/miniglog)
+ IF (NOT EXISTS ${MINIGLOG_INCLUDE_DIR})
+ CERES_REPORT_NOT_FOUND(
+ "Ceres install include directory: "
+ "${CERES_INCLUDE_DIR} does not include miniglog, but Ceres was "
+ "compiled with MINIGLOG enabled (in place of Glog).")
+ ENDIF (NOT EXISTS ${MINIGLOG_INCLUDE_DIR})
+ LIST(APPEND CERES_INCLUDE_DIRS ${MINIGLOG_INCLUDE_DIR})
+ # Output message at standard log level (not the lower STATUS) so that
+ # the message is output in GUI during configuration to warn user.
+ MESSAGE("-- Found Ceres installation compiled with miniglog substitute "
+ "for glog, beware this will likely cause problems if glog is later linked.")
+ELSE (CERES_USES_MINIGLOG)
+ # Search quietly s/t we control the timing of the error message if not found.
+ FIND_PACKAGE(Glog QUIET)
+ IF (GLOG_FOUND)
+ MESSAGE(STATUS "Found required Ceres dependency: "
+ "Glog in ${GLOG_INCLUDE_DIRS}")
+ ELSE (GLOG_FOUND)
+ CERES_REPORT_NOT_FOUND("Missing required Ceres "
+ "dependency: Glog, please set GLOG_INCLUDE_DIR.")
+ ENDIF (GLOG_FOUND)
+ LIST(APPEND CERES_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS})
+ENDIF (CERES_USES_MINIGLOG)
+
+# Import exported Ceres targets.
+IF (NOT TARGET ceres AND NOT Ceres_BINARY_DIR)
+ INCLUDE(${CURRENT_CONFIG_INSTALL_DIR}/CeresTargets.cmake)
+ENDIF (NOT TARGET ceres AND NOT Ceres_BINARY_DIR)
+# Set the expected XX_LIBRARIES variable for FindPackage().
SET(CERES_LIBRARIES ceres)
+
+# Set legacy include directories variable for backwards compatibility.
+SET(CERES_INCLUDES ${CERES_INCLUDE_DIRS})
+
+# Reset CMake module path to its state when this script was called.
+SET(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH})
+
+# As we use CERES_REPORT_NOT_FOUND() to abort, if we reach this point we have
+# found Ceres and all required dependencies.
+MESSAGE(STATUS "Found Ceres version: ${CERES_VERSION} "
+ "installed in: ${CURRENT_ROOT_INSTALL_DIR}")
diff --git a/cmake/FindCXSparse.cmake b/cmake/FindCXSparse.cmake
new file mode 100644
index 0000000..cebddb5
--- /dev/null
+++ b/cmake/FindCXSparse.cmake
@@ -0,0 +1,198 @@
+# Ceres Solver - A fast non-linear least squares minimizer
+# Copyright 2013 Google Inc. All rights reserved.
+# http://code.google.com/p/ceres-solver/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Google Inc. nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: alexs.mac@gmail.com (Alex Stewart)
+#
+
+# FindCXSparse.cmake - Find CXSparse libraries & dependencies.
+#
+# This module defines the following variables which should be referenced
+# by the caller to use the library.
+#
+# CXSPARSE_FOUND: TRUE iff CXSparse and all dependencies have been found.
+# CXSPARSE_INCLUDE_DIRS: Include directories for CXSparse.
+# CXSPARSE_LIBRARIES: Libraries for CXSparse and all dependencies.
+#
+# CXSPARSE_VERSION: Extracted from cs.h.
+# CXSPARSE_MAIN_VERSION: Equal to 3 if CXSPARSE_VERSION = 3.1.2
+# CXSPARSE_SUB_VERSION: Equal to 1 if CXSPARSE_VERSION = 3.1.2
+# CXSPARSE_SUBSUB_VERSION: Equal to 2 if CXSPARSE_VERSION = 3.1.2
+#
+# The following variables control the behaviour of this module:
+#
+# CXSPARSE_INCLUDE_DIR_HINTS: List of additional directories in which to
+# search for CXSparse includes,
+# e.g: /timbuktu/include.
+# CXSPARSE_LIBRARY_DIR_HINTS: List of additional directories in which to
+# search for CXSparse libraries, e.g: /timbuktu/lib.
+#
+# The following variables are also defined by this module, but in line with
+# CMake recommended FindPackage() module style should NOT be referenced directly
+# by callers (use the plural variables detailed above instead). These variables
+# do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which
+# are NOT re-called (i.e. search for library is not repeated) if these variables
+# are set with valid values _in the CMake cache_. This means that if these
+# variables are set directly in the cache, either by the user in the CMake GUI,
+# or by the user passing -DVAR=VALUE directives to CMake when called (which
+# explicitly defines a cache variable), then they will be used verbatim,
+# bypassing the HINTS variables and other hard-coded search locations.
+#
+# CXSPARSE_INCLUDE_DIR: Include directory for CXSparse, not including the
+# include directory of any dependencies.
+# CXSPARSE_LIBRARY: CXSparse library, not including the libraries of any
+# dependencies.
+
+# Called if we failed to find CXSparse or any of it's required dependencies,
+# unsets all public (designed to be used externally) variables and reports
+# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
+MACRO(CXSPARSE_REPORT_NOT_FOUND REASON_MSG)
+ UNSET(CXSPARSE_FOUND)
+ UNSET(CXSPARSE_INCLUDE_DIRS)
+ UNSET(CXSPARSE_LIBRARIES)
+ # Make results of search visible in the CMake GUI if CXSparse has not
+ # been found so that user does not have to toggle to advanced view.
+ MARK_AS_ADVANCED(CLEAR CXSPARSE_INCLUDE_DIR
+ CXSPARSE_LIBRARY)
+ # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
+ # use the camelcase library name, not uppercase.
+ IF (CXSparse_FIND_QUIETLY)
+ MESSAGE(STATUS "Failed to find CXSparse - " ${REASON_MSG} ${ARGN})
+ ELSEIF (CXSparse_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Failed to find CXSparse - " ${REASON_MSG} ${ARGN})
+ ELSE()
+ # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error
+ # that prevents generation, but continues configuration.
+ MESSAGE(SEND_ERROR "Failed to find CXSparse - " ${REASON_MSG} ${ARGN})
+ ENDIF ()
+ENDMACRO(CXSPARSE_REPORT_NOT_FOUND)
+
+# TODO: Add standard Windows search locations for CXSparse.
+LIST(APPEND CXSPARSE_CHECK_INCLUDE_DIRS
+ /usr/include
+ /usr/local/include
+ /usr/local/homebrew/include # Mac OS X
+ /opt/local/var/macports/software # Mac OS X.
+ /opt/local/include)
+LIST(APPEND CXSPARSE_CHECK_LIBRARY_DIRS
+ /usr/lib
+ /usr/local/lib
+ /usr/local/homebrew/lib # Mac OS X.
+ /opt/local/lib)
+
+# Search supplied hint directories first if supplied.
+FIND_PATH(CXSPARSE_INCLUDE_DIR
+ NAMES cs.h
+ PATHS ${CXSPARSE_INCLUDE_DIR_HINTS}
+ ${CXSPARSE_CHECK_INCLUDE_DIRS})
+IF (NOT CXSPARSE_INCLUDE_DIR OR
+ NOT EXISTS ${CXSPARSE_INCLUDE_DIR})
+ CXSPARSE_REPORT_NOT_FOUND(
+ "Could not find CXSparse include directory, set CXSPARSE_INCLUDE_DIR "
+ "to directory containing cs.h")
+ENDIF (NOT CXSPARSE_INCLUDE_DIR OR
+ NOT EXISTS ${CXSPARSE_INCLUDE_DIR})
+
+FIND_LIBRARY(CXSPARSE_LIBRARY NAMES cxsparse
+ PATHS ${CXSPARSE_LIBRARY_DIR_HINTS}
+ ${CXSPARSE_CHECK_LIBRARY_DIRS})
+IF (NOT CXSPARSE_LIBRARY OR
+ NOT EXISTS ${CXSPARSE_LIBRARY})
+ CXSPARSE_REPORT_NOT_FOUND(
+ "Could not find CXSparse library, set CXSPARSE_LIBRARY "
+ "to full path to libcxsparse.")
+ENDIF (NOT CXSPARSE_LIBRARY OR
+ NOT EXISTS ${CXSPARSE_LIBRARY})
+
+# Mark internally as found, then verify. CXSPARSE_REPORT_NOT_FOUND() unsets
+# if called.
+SET(CXSPARSE_FOUND TRUE)
+
+# Extract CXSparse version from cs.h
+IF (CXSPARSE_INCLUDE_DIR)
+ SET(CXSPARSE_VERSION_FILE ${CXSPARSE_INCLUDE_DIR}/cs.h)
+ IF (NOT EXISTS ${CXSPARSE_VERSION_FILE})
+ CXSPARSE_REPORT_NOT_FOUND(
+ "Could not find file: ${CXSPARSE_VERSION_FILE} "
+ "containing version information in CXSparse install located at: "
+ "${CXSPARSE_INCLUDE_DIR}.")
+ ELSE (NOT EXISTS ${CXSPARSE_VERSION_FILE})
+ FILE(READ ${CXSPARSE_INCLUDE_DIR}/cs.h CXSPARSE_VERSION_FILE_CONTENTS)
+
+ STRING(REGEX MATCH "#define CS_VER [0-9]+"
+ CXSPARSE_MAIN_VERSION "${CXSPARSE_VERSION_FILE_CONTENTS}")
+ STRING(REGEX REPLACE "#define CS_VER ([0-9]+)" "\\1"
+ CXSPARSE_MAIN_VERSION "${CXSPARSE_MAIN_VERSION}")
+
+ STRING(REGEX MATCH "#define CS_SUBVER [0-9]+"
+ CXSPARSE_SUB_VERSION "${CXSPARSE_VERSION_FILE_CONTENTS}")
+ STRING(REGEX REPLACE "#define CS_SUBVER ([0-9]+)" "\\1"
+ CXSPARSE_SUB_VERSION "${CXSPARSE_SUB_VERSION}")
+
+ STRING(REGEX MATCH "#define CS_SUBSUB [0-9]+"
+ CXSPARSE_SUBSUB_VERSION "${CXSPARSE_VERSION_FILE_CONTENTS}")
+ STRING(REGEX REPLACE "#define CS_SUBSUB ([0-9]+)" "\\1"
+ CXSPARSE_SUBSUB_VERSION "${CXSPARSE_SUBSUB_VERSION}")
+
+ # This is on a single line s/t CMake does not interpret it as a list of
+ # elements and insert ';' separators which would result in 3.;1.;2 nonsense.
+ SET(CXSPARSE_VERSION "${CXSPARSE_MAIN_VERSION}.${CXSPARSE_SUB_VERSION}.${CXSPARSE_SUBSUB_VERSION}")
+ ENDIF (NOT EXISTS ${CXSPARSE_VERSION_FILE})
+ENDIF (CXSPARSE_INCLUDE_DIR)
+
+# Catch the case when the caller has set CXSPARSE_LIBRARY in the cache / GUI and
+# thus FIND_LIBRARY was not called, but specified library is invalid, otherwise
+# we would report CXSparse as found.
+# TODO: This regex for CXSparse library is pretty primitive, could it be better?
+IF (CXSPARSE_LIBRARY AND
+ EXISTS ${CXSPARSE_LIBRARY} AND
+ NOT ${CXSPARSE_LIBRARY} MATCHES ".*cxsparse[^/]*")
+ CXSPARSE_REPORT_NOT_FOUND(
+ "Caller defined CXSPARSE_LIBRARY: "
+ "${CXSPARSE_LIBRARY} does not match CXSparse.")
+ENDIF (CXSPARSE_LIBRARY AND
+ EXISTS ${CXSPARSE_LIBRARY} AND
+ NOT ${CXSPARSE_LIBRARY} MATCHES ".*cxsparse[^/]*")
+
+# Set standard CMake FindPackage variables if found.
+IF (CXSPARSE_FOUND)
+ SET(CXSPARSE_INCLUDE_DIRS ${CXSPARSE_INCLUDE_DIR})
+ SET(CXSPARSE_LIBRARIES ${CXSPARSE_LIBRARY})
+ENDIF (CXSPARSE_FOUND)
+
+# Handle REQUIRED / QUIET optional arguments and version.
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CXSparse
+ REQUIRED_VARS CXSPARSE_INCLUDE_DIRS CXSPARSE_LIBRARIES
+ VERSION_VAR CXSPARSE_VERSION)
+
+# Only mark internal variables as advanced if we found CXSparse, otherwise
+# leave them visible in the standard GUI for the user to set manually.
+IF (CXSPARSE_FOUND)
+ MARK_AS_ADVANCED(FORCE CXSPARSE_INCLUDE_DIR
+ CXSPARSE_LIBRARY)
+ENDIF (CXSPARSE_FOUND)
diff --git a/cmake/FindEigen.cmake b/cmake/FindEigen.cmake
new file mode 100644
index 0000000..26a2a06
--- /dev/null
+++ b/cmake/FindEigen.cmake
@@ -0,0 +1,157 @@
+# Ceres Solver - A fast non-linear least squares minimizer
+# Copyright 2013 Google Inc. All rights reserved.
+# http://code.google.com/p/ceres-solver/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Google Inc. nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: alexs.mac@gmail.com (Alex Stewart)
+#
+
+# FindEigen.cmake - Find Eigen library, version >= 3.
+#
+# This module defines the following variables:
+#
+# EIGEN_FOUND: TRUE iff Eigen is found.
+# EIGEN_INCLUDE_DIRS: Include directories for Eigen.
+#
+# EIGEN_VERSION: Extracted from Eigen/src/Core/util/Macros.h
+# EIGEN_WORLD_VERSION: Equal to 3 if EIGEN_VERSION = 3.2.0
+# EIGEN_MAJOR_VERSION: Equal to 2 if EIGEN_VERSION = 3.2.0
+# EIGEN_MINOR_VERSION: Equal to 0 if EIGEN_VERSION = 3.2.0
+#
+# The following variables control the behaviour of this module:
+#
+# EIGEN_INCLUDE_DIR_HINTS: List of additional directories in which to
+# search for eigen includes, e.g: /timbuktu/eigen3.
+#
+# The following variables are also defined by this module, but in line with
+# CMake recommended FindPackage() module style should NOT be referenced directly
+# by callers (use the plural variables detailed above instead). These variables
+# do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which
+# are NOT re-called (i.e. search for library is not repeated) if these variables
+# are set with valid values _in the CMake cache_. This means that if these
+# variables are set directly in the cache, either by the user in the CMake GUI,
+# or by the user passing -DVAR=VALUE directives to CMake when called (which
+# explicitly defines a cache variable), then they will be used verbatim,
+# bypassing the HINTS variables and other hard-coded search locations.
+#
+# EIGEN_INCLUDE_DIR: Include directory for CXSparse, not including the
+# include directory of any dependencies.
+
+# Called if we failed to find Eigen or any of it's required dependencies,
+# unsets all public (designed to be used externally) variables and reports
+# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
+MACRO(EIGEN_REPORT_NOT_FOUND REASON_MSG)
+ UNSET(EIGEN_FOUND)
+ UNSET(EIGEN_INCLUDE_DIRS)
+ # Make results of search visible in the CMake GUI if Eigen has not
+ # been found so that user does not have to toggle to advanced view.
+ MARK_AS_ADVANCED(CLEAR EIGEN_INCLUDE_DIR)
+ # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
+ # use the camelcase library name, not uppercase.
+ IF (Eigen_FIND_QUIETLY)
+ MESSAGE(STATUS "Failed to find Eigen - " ${REASON_MSG} ${ARGN})
+ ELSEIF (Eigen_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Failed to find Eigen - " ${REASON_MSG} ${ARGN})
+ ELSE()
+ # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error
+ # that prevents generation, but continues configuration.
+ MESSAGE(SEND_ERROR "Failed to find Eigen - " ${REASON_MSG} ${ARGN})
+ ENDIF ()
+ENDMACRO(EIGEN_REPORT_NOT_FOUND)
+
+# TODO: Add standard Windows search locations for Eigen.
+LIST(APPEND EIGEN_CHECK_INCLUDE_DIRS
+ /usr/include/eigen3
+ /usr/local/include/eigen3
+ /usr/local/homebrew/include/eigen3 # Mac OS X
+ /opt/local/var/macports/software/eigen3 # Mac OS X.
+ /opt/local/include/eigen3)
+
+# Search supplied hint directories first if supplied.
+FIND_PATH(EIGEN_INCLUDE_DIR
+ NAMES Eigen/Core
+ PATHS ${EIGEN_INCLUDE_DIR_HINTS}
+ ${EIGEN_CHECK_INCLUDE_DIRS})
+IF (NOT EIGEN_INCLUDE_DIR OR
+ NOT EXISTS ${EIGEN_INCLUDE_DIR})
+ EIGEN_REPORT_NOT_FOUND(
+ "Could not find eigen3 include directory, set EIGEN_INCLUDE_DIR to "
+ "path to eigen3 include directory, e.g. /usr/local/include/eigen3.")
+ENDIF (NOT EIGEN_INCLUDE_DIR OR
+ NOT EXISTS ${EIGEN_INCLUDE_DIR})
+
+# Mark internally as found, then verify. EIGEN_REPORT_NOT_FOUND() unsets
+# if called.
+SET(EIGEN_FOUND TRUE)
+
+# Extract Eigen version from Eigen/src/Core/util/Macros.h
+IF (EIGEN_INCLUDE_DIR)
+ SET(EIGEN_VERSION_FILE ${EIGEN_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h)
+ IF (NOT EXISTS ${EIGEN_VERSION_FILE})
+ EIGEN_REPORT_NOT_FOUND(
+ "Could not find file: ${EIGEN_VERSION_FILE} "
+ "containing version information in Eigen install located at: "
+ "${EIGEN_INCLUDE_DIR}.")
+ ELSE (NOT EXISTS ${EIGEN_VERSION_FILE})
+ FILE(READ ${EIGEN_VERSION_FILE} EIGEN_VERSION_FILE_CONTENTS)
+
+ STRING(REGEX MATCH "#define EIGEN_WORLD_VERSION [0-9]+"
+ EIGEN_WORLD_VERSION "${EIGEN_VERSION_FILE_CONTENTS}")
+ STRING(REGEX REPLACE "#define EIGEN_WORLD_VERSION ([0-9]+)" "\\1"
+ EIGEN_WORLD_VERSION "${EIGEN_WORLD_VERSION}")
+
+ STRING(REGEX MATCH "#define EIGEN_MAJOR_VERSION [0-9]+"
+ EIGEN_MAJOR_VERSION "${EIGEN_VERSION_FILE_CONTENTS}")
+ STRING(REGEX REPLACE "#define EIGEN_MAJOR_VERSION ([0-9]+)" "\\1"
+ EIGEN_MAJOR_VERSION "${EIGEN_MAJOR_VERSION}")
+
+ STRING(REGEX MATCH "#define EIGEN_MINOR_VERSION [0-9]+"
+ EIGEN_MINOR_VERSION "${EIGEN_VERSION_FILE_CONTENTS}")
+ STRING(REGEX REPLACE "#define EIGEN_MINOR_VERSION ([0-9]+)" "\\1"
+ EIGEN_MINOR_VERSION "${EIGEN_MINOR_VERSION}")
+
+ # This is on a single line s/t CMake does not interpret it as a list of
+ # elements and insert ';' separators which would result in 3.;2.;0 nonsense.
+ SET(EIGEN_VERSION "${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}")
+ ENDIF (NOT EXISTS ${EIGEN_VERSION_FILE})
+ENDIF (EIGEN_INCLUDE_DIR)
+
+# Set standard CMake FindPackage variables if found.
+IF (EIGEN_FOUND)
+ SET(EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR})
+ENDIF (EIGEN_FOUND)
+
+# Handle REQUIRED / QUIET optional arguments and version.
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Eigen
+ REQUIRED_VARS EIGEN_INCLUDE_DIRS
+ VERSION_VAR EIGEN_VERSION)
+
+# Only mark internal variables as advanced if we found Eigen, otherwise
+# leave it visible in the standard GUI for the user to set manually.
+IF (EIGEN_FOUND)
+ MARK_AS_ADVANCED(FORCE EIGEN_INCLUDE_DIR)
+ENDIF (EIGEN_FOUND)
diff --git a/cmake/FindGflags.cmake b/cmake/FindGflags.cmake
new file mode 100644
index 0000000..17fc70a
--- /dev/null
+++ b/cmake/FindGflags.cmake
@@ -0,0 +1,166 @@
+# Ceres Solver - A fast non-linear least squares minimizer
+# Copyright 2013 Google Inc. All rights reserved.
+# http://code.google.com/p/ceres-solver/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Google Inc. nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: alexs.mac@gmail.com (Alex Stewart)
+#
+
+# FindGflags.cmake - Find Google gflags logging library.
+#
+# This module defines the following variables:
+#
+# GFLAGS_FOUND: TRUE iff gflags is found.
+# GFLAGS_INCLUDE_DIRS: Include directories for gflags.
+# GFLAGS_LIBRARIES: Libraries required to link gflags.
+#
+# The following variables control the behaviour of this module:
+#
+# GFLAGS_INCLUDE_DIR_HINTS: List of additional directories in which to
+# search for gflags includes, e.g: /timbuktu/include.
+# GFLAGS_LIBRARY_DIR_HINTS: List of additional directories in which to
+# search for gflags libraries, e.g: /timbuktu/lib.
+#
+# The following variables are also defined by this module, but in line with
+# CMake recommended FindPackage() module style should NOT be referenced directly
+# by callers (use the plural variables detailed above instead). These variables
+# do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which
+# are NOT re-called (i.e. search for library is not repeated) if these variables
+# are set with valid values _in the CMake cache_. This means that if these
+# variables are set directly in the cache, either by the user in the CMake GUI,
+# or by the user passing -DVAR=VALUE directives to CMake when called (which
+# explicitly defines a cache variable), then they will be used verbatim,
+# bypassing the HINTS variables and other hard-coded search locations.
+#
+# GFLAGS_INCLUDE_DIR: Include directory for gflags, not including the
+# include directory of any dependencies.
+# GFLAGS_LIBRARY: gflags library, not including the libraries of any
+# dependencies.
+
+# Called if we failed to find gflags or any of it's required dependencies,
+# unsets all public (designed to be used externally) variables and reports
+# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
+MACRO(GFLAGS_REPORT_NOT_FOUND REASON_MSG)
+ UNSET(GFLAGS_FOUND)
+ UNSET(GFLAGS_INCLUDE_DIRS)
+ UNSET(GFLAGS_LIBRARIES)
+ # Make results of search visible in the CMake GUI if gflags has not
+ # been found so that user does not have to toggle to advanced view.
+ MARK_AS_ADVANCED(CLEAR GFLAGS_INCLUDE_DIR
+ GFLAGS_LIBRARY)
+ # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
+ # use the camelcase library name, not uppercase.
+ IF (Gflags_FIND_QUIETLY)
+ MESSAGE(STATUS "Failed to find gflags - " ${REASON_MSG} ${ARGN})
+ ELSEIF (Gflags_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Failed to find gflags - " ${REASON_MSG} ${ARGN})
+ ELSE()
+ # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error
+ # that prevents generation, but continues configuration.
+ MESSAGE(SEND_ERROR "Failed to find gflags - " ${REASON_MSG} ${ARGN})
+ ENDIF ()
+ENDMACRO(GFLAGS_REPORT_NOT_FOUND)
+
+# TODO: Add standard Windows search locations for gflags.
+LIST(APPEND GFLAGS_CHECK_INCLUDE_DIRS
+ /usr/include
+ /usr/local/include
+ /usr/local/homebrew/include # Mac OS X
+ /opt/local/var/macports/software # Mac OS X.
+ /opt/local/include)
+LIST(APPEND GFLAGS_CHECK_LIBRARY_DIRS
+ /usr/lib
+ /usr/local/lib
+ /usr/local/homebrew/lib # Mac OS X.
+ /opt/local/lib)
+
+# Search supplied hint directories first if supplied.
+FIND_PATH(GFLAGS_INCLUDE_DIR
+ NAMES gflags/gflags.h
+ PATHS ${GFLAGS_INCLUDE_HINTS}
+ ${GFLAGS_CHECK_INCLUDE_DIRS})
+IF (NOT GFLAGS_INCLUDE_DIR OR
+ NOT EXISTS ${GFLAGS_INCLUDE_DIR})
+ GFLAGS_REPORT_NOT_FOUND(
+ "Could not find gflags include directory, set GFLAGS_INCLUDE_DIR "
+ "to directory containing gflags/gflags.h")
+ENDIF (NOT GFLAGS_INCLUDE_DIR OR
+ NOT EXISTS ${GFLAGS_INCLUDE_DIR})
+
+FIND_LIBRARY(GFLAGS_LIBRARY NAMES gflags
+ PATHS ${GFLAGS_LIBRARY_HINTS}
+ ${GFLAGS_CHECK_LIBRARY_DIRS})
+IF (NOT GFLAGS_LIBRARY OR
+ NOT EXISTS ${GFLAGS_LIBRARY})
+ GFLAGS_REPORT_NOT_FOUND(
+ "Could not find gflags library, set GFLAGS_LIBRARY "
+ "to full path to libgflags.")
+ENDIF (NOT GFLAGS_LIBRARY OR
+ NOT EXISTS ${GFLAGS_LIBRARY})
+
+# Mark internally as found, then verify. GFLAGS_REPORT_NOT_FOUND() unsets
+# if called.
+SET(GFLAGS_FOUND TRUE)
+
+# gflags does not seem to provide any record of the version in its
+# source tree, thus cannot extract version.
+
+# Catch case when caller has set GFLAGS_INCLUDE_DIR in the cache / GUI and
+# thus FIND_[PATH/LIBRARY] are not called, but specified locations are
+# invalid, otherwise we would report the library as found.
+IF (GFLAGS_INCLUDE_DIR AND
+ NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
+ GFLAGS_REPORT_NOT_FOUND(
+ "Caller defined GFLAGS_INCLUDE_DIR:"
+ " ${GFLAGS_INCLUDE_DIR} does not contain gflags/gflags.h header.")
+ENDIF (GFLAGS_INCLUDE_DIR AND
+ NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
+# TODO: This regex for gflags library is pretty primitive, could it be better?
+IF (GFLAGS_LIBRARY AND
+ NOT ${GFLAGS_LIBRARY} MATCHES ".*gflags[^/]*")
+ GFLAGS_REPORT_NOT_FOUND(
+ "Caller defined GFLAGS_LIBRARY: "
+ "${GFLAGS_LIBRARY} does not match gflags.")
+ENDIF (GFLAGS_LIBRARY AND
+ NOT ${GFLAGS_LIBRARY} MATCHES ".*gflags[^/]*")
+
+# Set standard CMake FindPackage variables if found.
+IF (GFLAGS_FOUND)
+ SET(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR})
+ SET(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY})
+ENDIF (GFLAGS_FOUND)
+
+# Handle REQUIRED / QUIET optional arguments.
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gflags DEFAULT_MSG
+ GFLAGS_INCLUDE_DIRS GFLAGS_LIBRARIES)
+
+# Only mark internal variables as advanced if we found gflags, otherwise
+# leave them visible in the standard GUI for the user to set manually.
+IF (GFLAGS_FOUND)
+ MARK_AS_ADVANCED(FORCE GFLAGS_INCLUDE_DIR
+ GFLAGS_LIBRARY)
+ENDIF (GFLAGS_FOUND)
diff --git a/cmake/FindGlog.cmake b/cmake/FindGlog.cmake
new file mode 100644
index 0000000..30b95e2
--- /dev/null
+++ b/cmake/FindGlog.cmake
@@ -0,0 +1,166 @@
+# Ceres Solver - A fast non-linear least squares minimizer
+# Copyright 2013 Google Inc. All rights reserved.
+# http://code.google.com/p/ceres-solver/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Google Inc. nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: alexs.mac@gmail.com (Alex Stewart)
+#
+
+# FindGlog.cmake - Find Google glog logging library.
+#
+# This module defines the following variables:
+#
+# GLOG_FOUND: TRUE iff glog is found.
+# GLOG_INCLUDE_DIRS: Include directories for glog.
+# GLOG_LIBRARIES: Libraries required to link glog.
+#
+# The following variables control the behaviour of this module:
+#
+# GLOG_INCLUDE_DIRS_HINTS: List of additional directories in which to
+# search for glog includes, e.g: /timbuktu/include.
+# GLOG_LIBRARY_DIRS_HINTS: List of additional directories in which to
+# search for glog libraries, e.g: /timbuktu/lib.
+#
+# The following variables are also defined by this module, but in line with
+# CMake recommended FindPackage() module style should NOT be referenced directly
+# by callers (use the plural variables detailed above instead). These variables
+# do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which
+# are NOT re-called (i.e. search for library is not repeated) if these variables
+# are set with valid values _in the CMake cache_. This means that if these
+# variables are set directly in the cache, either by the user in the CMake GUI,
+# or by the user passing -DVAR=VALUE directives to CMake when called (which
+# explicitly defines a cache variable), then they will be used verbatim,
+# bypassing the HINTS variables and other hard-coded search locations.
+#
+# GLOG_INCLUDE_DIR: Include directory for glog, not including the
+# include directory of any dependencies.
+# GLOG_LIBRARY: glog library, not including the libraries of any
+# dependencies.
+
+# Called if we failed to find glog or any of it's required dependencies,
+# unsets all public (designed to be used externally) variables and reports
+# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
+MACRO(GLOG_REPORT_NOT_FOUND REASON_MSG)
+ UNSET(GLOG_FOUND)
+ UNSET(GLOG_INCLUDE_DIRS)
+ UNSET(GLOG_LIBRARIES)
+ # Make results of search visible in the CMake GUI if glog has not
+ # been found so that user does not have to toggle to advanced view.
+ MARK_AS_ADVANCED(CLEAR GLOG_INCLUDE_DIR
+ GLOG_LIBRARY)
+ # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
+ # use the camelcase library name, not uppercase.
+ IF (Glog_FIND_QUIETLY)
+ MESSAGE(STATUS "Failed to find glog - " ${REASON_MSG} ${ARGN})
+ ELSEIF (Glog_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Failed to find glog - " ${REASON_MSG} ${ARGN})
+ ELSE()
+ # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error
+ # that prevents generation, but continues configuration.
+ MESSAGE(SEND_ERROR "Failed to find glog - " ${REASON_MSG} ${ARGN})
+ ENDIF ()
+ENDMACRO(GLOG_REPORT_NOT_FOUND)
+
+# TODO: Add standard Windows search locations for glog.
+LIST(APPEND GLOG_CHECK_INCLUDE_DIRS
+ /usr/include
+ /usr/local/include
+ /usr/local/homebrew/include # Mac OS X
+ /opt/local/var/macports/software # Mac OS X.
+ /opt/local/include)
+LIST(APPEND GLOG_CHECK_LIBRARY_DIRS
+ /usr/lib
+ /usr/local/lib
+ /usr/local/homebrew/lib # Mac OS X.
+ /opt/local/lib)
+
+# Search supplied hint directories first if supplied.
+FIND_PATH(GLOG_INCLUDE_DIR
+ NAMES glog/logging.h
+ PATHS ${GLOG_INCLUDE_DIR_HINTS}
+ ${GLOG_CHECK_INCLUDE_DIRS})
+IF (NOT GLOG_INCLUDE_DIR OR
+ NOT EXISTS ${GLOG_INCLUDE_DIR})
+ GLOG_REPORT_NOT_FOUND(
+ "Could not find glog include directory, set GLOG_INCLUDE_DIR "
+ "to directory containing glog/logging.h")
+ENDIF (NOT GLOG_INCLUDE_DIR OR
+ NOT EXISTS ${GLOG_INCLUDE_DIR})
+
+FIND_LIBRARY(GLOG_LIBRARY NAMES glog
+ PATHS ${GLOG_LIBRARY_DIR_HINTS}
+ ${GLOG_CHECK_LIBRARY_DIRS})
+IF (NOT GLOG_LIBRARY OR
+ NOT EXISTS ${GLOG_LIBRARY})
+ GLOG_REPORT_NOT_FOUND(
+ "Could not find glog library, set GLOG_LIBRARY "
+ "to full path to libglog.")
+ENDIF (NOT GLOG_LIBRARY OR
+ NOT EXISTS ${GLOG_LIBRARY})
+
+# Mark internally as found, then verify. GLOG_REPORT_NOT_FOUND() unsets
+# if called.
+SET(GLOG_FOUND TRUE)
+
+# Glog does not seem to provide any record of the version in its
+# source tree, thus cannot extract version.
+
+# Catch case when caller has set GLOG_INCLUDE_DIR in the cache / GUI and
+# thus FIND_[PATH/LIBRARY] are not called, but specified locations are
+# invalid, otherwise we would report the library as found.
+IF (GLOG_INCLUDE_DIR AND
+ NOT EXISTS ${GLOG_INCLUDE_DIR}/glog/logging.h)
+ GLOG_REPORT_NOT_FOUND(
+ "Caller defined GLOG_INCLUDE_DIR:"
+ " ${GLOG_INCLUDE_DIR} does not contain glog/logging.h header.")
+ENDIF (GLOG_INCLUDE_DIR AND
+ NOT EXISTS ${GLOG_INCLUDE_DIR}/glog/logging.h)
+# TODO: This regex for glog library is pretty primitive, could it be better?
+IF (GLOG_LIBRARY AND
+ NOT ${GLOG_LIBRARY} MATCHES ".*glog[^/]*")
+ GLOG_REPORT_NOT_FOUND(
+ "Caller defined GLOG_LIBRARY: "
+ "${GLOG_LIBRARY} does not match glog.")
+ENDIF (GLOG_LIBRARY AND
+ NOT ${GLOG_LIBRARY} MATCHES ".*glog[^/]*")
+
+# Set standard CMake FindPackage variables if found.
+IF (GLOG_FOUND)
+ SET(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
+ SET(GLOG_LIBRARIES ${GLOG_LIBRARY})
+ENDIF (GLOG_FOUND)
+
+# Handle REQUIRED / QUIET optional arguments.
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Glog DEFAULT_MSG
+ GLOG_INCLUDE_DIRS GLOG_LIBRARIES)
+
+# Only mark internal variables as advanced if we found glog, otherwise
+# leave them visible in the standard GUI for the user to set manually.
+IF (GLOG_FOUND)
+ MARK_AS_ADVANCED(FORCE GLOG_INCLUDE_DIR
+ GLOG_LIBRARY)
+ENDIF (GLOG_FOUND)
diff --git a/cmake/FindSuiteSparse.cmake b/cmake/FindSuiteSparse.cmake
index a0beab9..4dc6c7e 100644
--- a/cmake/FindSuiteSparse.cmake
+++ b/cmake/FindSuiteSparse.cmake
@@ -48,6 +48,15 @@
# install, in which case found version of SuiteSparse cannot be used to link
# a shared library due to a bug (static linking is unaffected).
#
+# The following variables control the behaviour of this module:
+#
+# SUITESPARSE_INCLUDE_DIR_HINTS: List of additional directories in which to
+# search for SuiteSparse includes,
+# e.g: /timbuktu/include.
+# SUITESPARSE_LIBRARY_DIR_HINTS: List of additional directories in which to
+# search for SuiteSparse libraries,
+# e.g: /timbuktu/lib.
+#
# The following variables define the presence / includes & libraries for the
# SuiteSparse components searched for, the SUITESPARSE_XX variables are the
# union of the variables for all components.
@@ -101,9 +110,31 @@
# TBB_FOUND
# TBB_LIBRARIES
+# Called if we failed to find SuiteSparse or any of it's required dependencies,
+# unsets all public (designed to be used externally) variables and reports
+# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
+MACRO(SUITESPARSE_REPORT_NOT_FOUND REASON_MSG)
+ UNSET(SUITESPARSE_FOUND)
+ UNSET(SUITESPARSE_INCLUDE_DIRS)
+ UNSET(SUITESPARSE_LIBRARIES)
+ UNSET(SUITESPARSE_VERSION)
+ UNSET(SUITESPARSE_MAIN_VERSION)
+ UNSET(SUITESPARSE_SUB_VERSION)
+ UNSET(SUITESPARSE_SUBSUB_VERSION)
+ # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
+ # use the camelcase library name, not uppercase.
+ IF (SuiteSparse_FIND_QUIETLY)
+ MESSAGE(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
+ ELSE (SuiteSparse_FIND_QUIETLY)
+ MESSAGE(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
+ ENDIF (SuiteSparse_FIND_QUIETLY)
+ENDMACRO(SUITESPARSE_REPORT_NOT_FOUND)
+
# Specify search directories for include files and libraries (this is the union
-# of the search directories for all OSs).
+# of the search directories for all OSs). Search user-specified hint
+# directories first if supplied.
LIST(APPEND SUITESPARSE_CHECK_INCLUDE_DIRS
+ ${SUITESPARSE_INCLUDE_DIR_HINTS}
/opt/local/include
/opt/local/include/ufsparse # Mac OS X
/usr/include
@@ -112,6 +143,7 @@
/usr/local/include
/usr/local/include/suitesparse)
LIST(APPEND SUITESPARSE_CHECK_LIBRARY_DIRS
+ ${SUITESPARSE_LIBRARY_DIR_HINTS}
/opt/local/lib
/opt/local/lib/ufsparse # Mac OS X
/usr/lib
@@ -123,13 +155,15 @@
# BLAS.
FIND_PACKAGE(BLAS QUIET)
IF (NOT BLAS_FOUND)
- MESSAGE("-- Did not find BLAS library (required for SuiteSparse).")
+ SUITESPARSE_REPORT_NOT_FOUND(
+ "Did not find BLAS library (required for SuiteSparse).")
ENDIF (NOT BLAS_FOUND)
# LAPACK.
FIND_PACKAGE(LAPACK QUIET)
IF (NOT LAPACK_FOUND)
- MESSAGE("-- Did not find LAPACK library (required for SuiteSparse).")
+ SUITESPARSE_REPORT_NOT_FOUND(
+ "Did not find LAPACK library (required for SuiteSparse).")
ENDIF (NOT LAPACK_FOUND)
# AMD.
@@ -137,9 +171,9 @@
FIND_LIBRARY(AMD_LIBRARY NAMES amd
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${AMD_LIBRARY})
- MESSAGE("-- Found AMD library: ${AMD_LIBRARY}")
+ MESSAGE(STATUS "Found AMD library: ${AMD_LIBRARY}")
ELSE (EXISTS ${AMD_LIBRARY})
- MESSAGE("-- Did not find AMD library")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find AMD library.")
SET(AMD_FOUND FALSE)
ENDIF (EXISTS ${AMD_LIBRARY})
MARK_AS_ADVANCED(AMD_LIBRARY)
@@ -147,9 +181,9 @@
FIND_PATH(AMD_INCLUDE_DIR NAMES amd.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${AMD_INCLUDE_DIR})
- MESSAGE("-- Found AMD header in: ${AMD_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found AMD header in: ${AMD_INCLUDE_DIR}")
ELSE (EXISTS ${AMD_INCLUDE_DIR})
- MESSAGE("-- Did not find AMD header")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find AMD header.")
SET(AMD_FOUND FALSE)
ENDIF (EXISTS ${AMD_INCLUDE_DIR})
MARK_AS_ADVANCED(AMD_INCLUDE_DIR)
@@ -159,9 +193,9 @@
FIND_LIBRARY(CAMD_LIBRARY NAMES camd
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${CAMD_LIBRARY})
- MESSAGE("-- Found CAMD library: ${CAMD_LIBRARY}")
+ MESSAGE(STATUS "Found CAMD library: ${CAMD_LIBRARY}")
ELSE (EXISTS ${CAMD_LIBRARY})
- MESSAGE("-- Did not find CAMD library")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find CAMD library.")
SET(CAMD_FOUND FALSE)
ENDIF (EXISTS ${CAMD_LIBRARY})
MARK_AS_ADVANCED(CAMD_LIBRARY)
@@ -169,9 +203,9 @@
FIND_PATH(CAMD_INCLUDE_DIR NAMES camd.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${CAMD_INCLUDE_DIR})
- MESSAGE("-- Found CAMD header in: ${CAMD_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found CAMD header in: ${CAMD_INCLUDE_DIR}")
ELSE (EXISTS ${CAMD_INCLUDE_DIR})
- MESSAGE("-- Did not find CAMD header")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find CAMD header.")
SET(CAMD_FOUND FALSE)
ENDIF (EXISTS ${CAMD_INCLUDE_DIR})
MARK_AS_ADVANCED(CAMD_INCLUDE_DIR)
@@ -181,9 +215,9 @@
FIND_LIBRARY(COLAMD_LIBRARY NAMES colamd
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${COLAMD_LIBRARY})
- MESSAGE("-- Found COLAMD library: ${COLAMD_LIBRARY}")
+ MESSAGE(STATUS "Found COLAMD library: ${COLAMD_LIBRARY}")
ELSE (EXISTS ${COLAMD_LIBRARY})
- MESSAGE("-- Did not find COLAMD library")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find COLAMD library.")
SET(COLAMD_FOUND FALSE)
ENDIF (EXISTS ${COLAMD_LIBRARY})
MARK_AS_ADVANCED(COLAMD_LIBRARY)
@@ -191,9 +225,9 @@
FIND_PATH(COLAMD_INCLUDE_DIR NAMES colamd.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${COLAMD_INCLUDE_DIR})
- MESSAGE("-- Found COLAMD header in: ${COLAMD_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found COLAMD header in: ${COLAMD_INCLUDE_DIR}")
ELSE (EXISTS ${COLAMD_INCLUDE_DIR})
- MESSAGE("-- Did not find COLAMD header")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find COLAMD header.")
SET(COLAMD_FOUND FALSE)
ENDIF (EXISTS ${COLAMD_INCLUDE_DIR})
MARK_AS_ADVANCED(COLAMD_INCLUDE_DIR)
@@ -203,9 +237,9 @@
FIND_LIBRARY(CCOLAMD_LIBRARY NAMES ccolamd
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${CCOLAMD_LIBRARY})
- MESSAGE("-- Found CCOLAMD library: ${CCOLAMD_LIBRARY}")
+ MESSAGE(STATUS "Found CCOLAMD library: ${CCOLAMD_LIBRARY}")
ELSE (EXISTS ${CCOLAMD_LIBRARY})
- MESSAGE("-- Did not find CCOLAMD library")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find CCOLAMD library.")
SET(CCOLAMD_FOUND FALSE)
ENDIF (EXISTS ${CCOLAMD_LIBRARY})
MARK_AS_ADVANCED(CCOLAMD_LIBRARY)
@@ -213,9 +247,9 @@
FIND_PATH(CCOLAMD_INCLUDE_DIR NAMES ccolamd.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${CCOLAMD_INCLUDE_DIR})
- MESSAGE("-- Found CCOLAMD header in: ${CCOLAMD_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found CCOLAMD header in: ${CCOLAMD_INCLUDE_DIR}")
ELSE (EXISTS ${CCOLAMD_INCLUDE_DIR})
- MESSAGE("-- Did not find CCOLAMD header")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find CCOLAMD header.")
SET(CCOLAMD_FOUND FALSE)
ENDIF (EXISTS ${CCOLAMD_INCLUDE_DIR})
MARK_AS_ADVANCED(CCOLAMD_INCLUDE_DIR)
@@ -225,9 +259,9 @@
FIND_LIBRARY(CHOLMOD_LIBRARY NAMES cholmod
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${CHOLMOD_LIBRARY})
- MESSAGE("-- Found CHOLMOD library: ${CHOLMOD_LIBRARY}")
+ MESSAGE(STATUS "Found CHOLMOD library: ${CHOLMOD_LIBRARY}")
ELSE (EXISTS ${CHOLMOD_LIBRARY})
- MESSAGE("-- Did not find CHOLMOD library")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find CHOLMOD library.")
SET(CHOLMOD_FOUND FALSE)
ENDIF (EXISTS ${CHOLMOD_LIBRARY})
MARK_AS_ADVANCED(CHOLMOD_LIBRARY)
@@ -235,9 +269,9 @@
FIND_PATH(CHOLMOD_INCLUDE_DIR NAMES cholmod.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${CHOLMOD_INCLUDE_DIR})
- MESSAGE("-- Found CHOLMOD header in: ${CHOLMOD_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found CHOLMOD header in: ${CHOLMOD_INCLUDE_DIR}")
ELSE (EXISTS ${CHOLMOD_INCLUDE_DIR})
- MESSAGE("-- Did not find CHOLMOD header")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find CHOLMOD header.")
SET(CHOLMOD_FOUND FALSE)
ENDIF (EXISTS ${CHOLMOD_INCLUDE_DIR})
MARK_AS_ADVANCED(CHOLMOD_INCLUDE_DIR)
@@ -247,9 +281,9 @@
FIND_LIBRARY(SUITESPARSEQR_LIBRARY NAMES spqr
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${SUITESPARSEQR_LIBRARY})
- MESSAGE("-- Found SuiteSparseQR library: ${SUITESPARSEQR_LIBRARY}")
+ MESSAGE(STATUS "Found SuiteSparseQR library: ${SUITESPARSEQR_LIBRARY}")
ELSE (EXISTS ${SUITESPARSEQR_LIBRARY})
- MESSAGE("-- Did not find SUITESPARSEQR library")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find SUITESPARSEQR library.")
SET(SUITESPARSEQR_FOUND FALSE)
ENDIF (EXISTS ${SUITESPARSEQR_LIBRARY})
MARK_AS_ADVANCED(SUITESPARSEQR_LIBRARY)
@@ -257,9 +291,9 @@
FIND_PATH(SUITESPARSEQR_INCLUDE_DIR NAMES SuiteSparseQR.hpp
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
- MESSAGE("-- Found SuiteSparseQR header in: ${SUITESPARSEQR_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found SuiteSparseQR header in: ${SUITESPARSEQR_INCLUDE_DIR}")
ELSE (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
- MESSAGE("-- Did not find SUITESPARSEQR header")
+ SUITESPARSE_REPORT_NOT_FOUND("Did not find SUITESPARSEQR header.")
SET(SUITESPARSEQR_FOUND FALSE)
ENDIF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
MARK_AS_ADVANCED(SUITESPARSEQR_INCLUDE_DIR)
@@ -272,10 +306,11 @@
FIND_LIBRARY(TBB_LIBRARIES NAMES tbb
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${TBB_LIBRARIES})
- MESSAGE("-- Found Intel Thread Building Blocks (TBB) library: ${TBB_LIBRARIES}, "
- "assuming SuiteSparseQR was compiled with TBB.")
+ MESSAGE(STATUS "Found Intel Thread Building Blocks (TBB) library: "
+ "${TBB_LIBRARIES}, assuming SuiteSparseQR was compiled with TBB.")
ELSE (EXISTS ${TBB_LIBRARIES})
- MESSAGE("-- Did not find TBB library")
+ MESSAGE(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was "
+ "not compiled with TBB.")
SET(TBB_FOUND FALSE)
ENDIF (EXISTS ${TBB_LIBRARIES})
MARK_AS_ADVANCED(TBB_LIBRARIES)
@@ -284,7 +319,7 @@
FIND_LIBRARY(TBB_MALLOC_LIB NAMES tbbmalloc
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${TBB_MALLOC_LIB})
- MESSAGE("-- Found Intel Thread Building Blocks (TBB) Malloc library: "
+ MESSAGE(STATUS "Found Intel Thread Building Blocks (TBB) Malloc library: "
"${TBB_MALLOC_LIB}")
# Append TBB malloc library to TBB libraries list whilst retaining
# any CMake generated help string (cache variable).
@@ -299,7 +334,7 @@
ELSE (EXISTS ${TBB_MALLOC_LIB})
# If we cannot find all required TBB components do not include it as
# a dependency.
- MESSAGE("-- Did not find Intel Thread Building Blocks (TBB) Malloc "
+ MESSAGE(STATUS "Did not find Intel Thread Building Blocks (TBB) Malloc "
"Library, discarding TBB as a dependency.")
SET(TBB_FOUND FALSE)
ENDIF (EXISTS ${TBB_MALLOC_LIB})
@@ -317,19 +352,23 @@
FIND_LIBRARY(SUITESPARSE_CONFIG_LIBRARY NAMES suitesparseconfig
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
- MESSAGE("-- Found SuiteSparse_config library: ${SUITESPARSE_CONFIG_LIBRARY}")
+ MESSAGE(STATUS "Found SuiteSparse_config library: "
+ "${SUITESPARSE_CONFIG_LIBRARY}")
ELSE (EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
- MESSAGE("-- Did not find SuiteSparse_config library")
+ MESSAGE(STATUS "Did not find SuiteSparse_config library (should be present "
+ "in SuiteSparse >= v4 installs).")
ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
MARK_AS_ADVANCED(SUITESPARSE_CONFIG_LIBRARY)
FIND_PATH(SUITESPARSE_CONFIG_INCLUDE_DIR NAMES SuiteSparse_config.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
- MESSAGE("-- Found SuiteSparse_config header in: ${SUITESPARSE_CONFIG_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found SuiteSparse_config header in: "
+ "${SUITESPARSE_CONFIG_INCLUDE_DIR}")
SET(UFCONFIG_FOUND FALSE)
ELSE (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
- MESSAGE("-- Did not find SuiteSparse_config header")
+ MESSAGE(STATUS "Did not find SuiteSparse_config header (should be present "
+ "in SuiteSparse >= v4 installs).")
ENDIF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
MARK_AS_ADVANCED(SUITESPARSE_CONFIG_INCLUDE_DIR)
@@ -342,9 +381,11 @@
FIND_LIBRARY(LIBRT_LIBRARY NAMES rt
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (LIBRT_LIBRARY)
- MESSAGE("-- Adding librt: ${LIBRT_LIBRARY} to SuiteSparse_config libraries.")
+ MESSAGE(STATUS "Adding librt: ${LIBRT_LIBRARY} to "
+ "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if "
+ "SuiteSparse is compiled with timing).")
ELSE (LIBRT_LIBRARY)
- MESSAGE("-- Could not find librt, but found SuiteSparse_config, "
+ MESSAGE(STATUS "Could not find librt, but found SuiteSparse_config, "
"assuming that SuiteSparse was compiled without timing.")
ENDIF (LIBRT_LIBRARY)
MARK_AS_ADVANCED(LIBRT_LIBRARY)
@@ -356,9 +397,10 @@
FIND_PATH(UFCONFIG_INCLUDE_DIR NAMES UFconfig.h
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${UFCONFIG_INCLUDE_DIR})
- MESSAGE("-- Found UFconfig header in: ${UFCONFIG_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found UFconfig header in: ${UFCONFIG_INCLUDE_DIR}")
ELSE (EXISTS ${UFCONFIG_INCLUDE_DIR})
- MESSAGE("-- Did not find UFconfig header")
+ MESSAGE(STATUS "Did not find UFconfig header (should be present "
+ "in SuiteSparse < v4 installs)")
SET(UFCONFIG_FOUND FALSE)
ENDIF (EXISTS ${UFCONFIG_INCLUDE_DIR})
MARK_AS_ADVANCED(UFCONFIG_INCLUDE_DIR)
@@ -369,60 +411,83 @@
# <= v3, SuiteSparse_config.h for >= v4).
IF (UFCONFIG_FOUND)
# SuiteSparse version <= 3.
- FILE(READ "${UFCONFIG_INCLUDE_DIR}/UFconfig.h" UFCONFIG_CONTENTS)
+ SET(SUITESPARSE_VERSION_FILE ${UFCONFIG_INCLUDE_DIR}/UFconfig.h)
+ IF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
+ SUITESPARSE_REPORT_NOT_FOUND(
+ "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
+ "information for <= v3 SuiteSparse installs, but UFconfig was found "
+ "(only present in <= v3 installs).")
+ ELSE (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
+ FILE(READ ${SUITESPARSE_VERSION_FILE} UFCONFIG_CONTENTS)
- STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
- SUITESPARSE_MAIN_VERSION "${UFCONFIG_CONTENTS}")
- STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
- SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
+ STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
+ SUITESPARSE_MAIN_VERSION "${UFCONFIG_CONTENTS}")
+ STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
+ SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
- STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
- SUITESPARSE_SUB_VERSION "${UFCONFIG_CONTENTS}")
- STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
- SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
+ STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
+ SUITESPARSE_SUB_VERSION "${UFCONFIG_CONTENTS}")
+ STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
+ SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
- STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
- SUITESPARSE_SUBSUB_VERSION "${UFCONFIG_CONTENTS}")
- STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
- SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
+ STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
+ SUITESPARSE_SUBSUB_VERSION "${UFCONFIG_CONTENTS}")
+ STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
+ SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
+
+ # This is on a single line s/t CMake does not interpret it as a list of
+ # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
+ SET(SUITESPARSE_VERSION
+ "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
+ ENDIF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
ENDIF (UFCONFIG_FOUND)
IF (SUITESPARSE_CONFIG_FOUND)
# SuiteSparse version >= 4.
- FILE(READ "${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h"
- SUITESPARSE_CONFIG_CONTENTS)
+ SET(SUITESPARSE_VERSION_FILE
+ ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h)
+ IF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
+ SUITESPARSE_REPORT_NOT_FOUND(
+ "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
+ "information for >= v4 SuiteSparse installs, but SuiteSparse_config was "
+ "found (only present in >= v4 installs).")
+ ELSE (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
+ FILE(READ ${SUITESPARSE_VERSION_FILE} SUITESPARSE_CONFIG_CONTENTS)
- STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
- SUITESPARSE_MAIN_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
- STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
- SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
+ STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
+ SUITESPARSE_MAIN_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
+ STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
+ SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
- STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
- SUITESPARSE_SUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
- STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
- SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
+ STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
+ SUITESPARSE_SUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
+ STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
+ SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
- STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
- SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
- STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
- SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
+ STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
+ SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
+ STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
+ SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
+
+ # This is on a single line s/t CMake does not interpret it as a list of
+ # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
+ SET(SUITESPARSE_VERSION
+ "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
+ ENDIF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
ENDIF (SUITESPARSE_CONFIG_FOUND)
-# This is on a single line s/t CMake does not interpret it as a list of
-# elements and insert ';' separators which would result in 4.;2.;1 nonsense.
-SET(SUITESPARSE_VERSION
- "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
-
# METIS (Optional dependency).
FIND_LIBRARY(METIS_LIBRARY NAMES metis
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${METIS_LIBRARY})
- MESSAGE("-- Found METIS library: ${METIS_LIBRARY}")
+ MESSAGE(STATUS "Found METIS library: ${METIS_LIBRARY}.")
ELSE (EXISTS ${METIS_LIBRARY})
- MESSAGE("-- Did not find METIS library")
+ MESSAGE(STATUS "Did not find METIS library (optional SuiteSparse dependency)")
ENDIF (EXISTS ${METIS_LIBRARY})
MARK_AS_ADVANCED(METIS_LIBRARY)
+# Only mark SuiteSparse as found if all required dependencies have been found.
+SET(SUITESPARSE_FOUND FALSE)
IF (AMD_FOUND AND
CAMD_FOUND AND
COLAMD_FOUND AND
@@ -468,10 +533,10 @@
LIST(APPEND SUITESPARSE_LIBRARIES
${METIS_LIBRARY})
ENDIF (METIS_FOUND)
- MESSAGE("-- Found SuiteSparse version: ${SUITESPARSE_VERSION}")
+ MESSAGE(STATUS "Found SuiteSparse version: ${SUITESPARSE_VERSION}")
ELSE()
- SET(SUITESPARSE_FOUND FALSE)
- MESSAGE("-- Failed to find some/all required components of SuiteSparse.")
+ SUITESPARSE_REPORT_NOT_FOUND(
+ "Failed to find some/all required components of SuiteSparse.")
ENDIF()
# Determine if we are running on Ubuntu with the package install of SuiteSparse
@@ -494,6 +559,9 @@
# We are on Ubuntu, and the SuiteSparse version matches the broken
# system install version and is a system install.
SET(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION TRUE)
+ MESSAGE(STATUS "Found system install of SuiteSparse "
+ "${SUITESPARSE_VERSION} running on Ubuntu, which has a known bug "
+ "preventing linking of shared libraries (static linking unaffected).")
ENDIF (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd")
ENDIF (LSB_RELEASE_EXECUTABLE)
@@ -508,5 +576,6 @@
# by FindPackageHandleStandardArgs() in conjunction with handling the REQUIRED
# and QUIET optional arguments, as such we use an intermediary variable.
SET(SUITESPARSE_FOUND_COPY ${SUITESPARSE_FOUND})
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SuiteSparse DEFAULT_MSG
- SUITESPARSE_FOUND_COPY SUITESPARSE_INCLUDE_DIRS SUITESPARSE_LIBRARIES)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SuiteSparse
+ REQUIRED_VARS SUITESPARSE_FOUND_COPY SUITESPARSE_INCLUDE_DIRS SUITESPARSE_LIBRARIES
+ VERSION_VAR SUITESPARSE_VERSION)
diff --git a/cmake/depend.cmake b/cmake/depend.cmake
deleted file mode 100644
index 275a440..0000000
--- a/cmake/depend.cmake
+++ /dev/null
@@ -1,103 +0,0 @@
-# Ceres Solver - A fast non-linear least squares minimizer
-# Copyright 2013 Google Inc. All rights reserved.
-# http://code.google.com/p/ceres-solver/
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Google Inc. nor the names of its contributors may be
-# used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-# Author: pablo.speciale@gmail.com (Pablo Speciale)
-#
-
-# Default locations to search for on various platforms.
-LIST(APPEND SEARCH_LIBS /usr/lib)
-LIST(APPEND SEARCH_LIBS /usr/local/lib)
-LIST(APPEND SEARCH_LIBS /usr/local/homebrew/lib) # Mac OS X
-LIST(APPEND SEARCH_LIBS /opt/local/lib)
-
-LIST(APPEND SEARCH_HEADERS /usr/include)
-LIST(APPEND SEARCH_HEADERS /usr/local/include)
-LIST(APPEND SEARCH_HEADERS /usr/local/homebrew/include) # Mac OS X
-LIST(APPEND SEARCH_HEADERS /opt/local/include)
-
-# Locations to search for Eigen
-SET(EIGEN_SEARCH_HEADERS ${SEARCH_HEADERS})
-LIST(APPEND EIGEN_SEARCH_HEADERS /usr/include/eigen3) # Ubuntu 10.04's default location.
-LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/include/eigen3)
-LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/homebrew/include/eigen3) # Mac OS X
-LIST(APPEND EIGEN_SEARCH_HEADERS /opt/local/var/macports/software/eigen3/opt/local/include/eigen3) # Mac OS X
-
-# Google Flags
-OPTION(GFLAGS
- "Enable Google Flags."
- ON)
-
-IF (GFLAGS)
- MESSAGE("-- Check for Google Flags")
- FIND_LIBRARY(GFLAGS_LIB NAMES gflags PATHS ${SEARCH_LIBS})
- IF (NOT EXISTS ${GFLAGS_LIB})
- MESSAGE(FATAL_ERROR
- "Can't find Google Flags. Please specify: "
- "-DGFLAGS_LIB=...")
- ENDIF (NOT EXISTS ${GFLAGS_LIB})
- MESSAGE("-- Found Google Flags library: ${GFLAGS_LIB}")
- FIND_PATH(GFLAGS_INCLUDE NAMES gflags/gflags.h PATHS ${SEARCH_HEADERS})
- IF (NOT EXISTS ${GFLAGS_INCLUDE})
- MESSAGE(FATAL_ERROR
- "Can't find Google Flags. Please specify: "
- "-DGFLAGS_INCLUDE=...")
- ENDIF (NOT EXISTS ${GFLAGS_INCLUDE})
- MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE}")
-ENDIF (GFLAGS)
-
-# Google Logging
-MESSAGE("-- Check for Google Log")
-FIND_LIBRARY(GLOG_LIB NAMES glog PATHS ${SEARCH_LIBS})
-IF (NOT EXISTS ${GLOG_LIB})
- MESSAGE(FATAL_ERROR
- "Can't find Google Log. Please specify: "
- "-DGLOG_LIB=...")
-ENDIF (NOT EXISTS ${GLOG_LIB})
-MESSAGE("-- Found Google Log library: ${GLOG_LIB}")
-
-FIND_PATH(GLOG_INCLUDE NAMES glog/logging.h PATHS ${SEARCH_HEADERS})
-IF (NOT EXISTS ${GLOG_INCLUDE})
- MESSAGE(FATAL_ERROR
- "Can't find Google Log. Please specify: "
- "-DGLOG_INCLUDE=...")
-ENDIF (NOT EXISTS ${GLOG_INCLUDE})
-MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE}")
-
-# Eigen
-MESSAGE("-- Check for Eigen 3.x")
-FIND_PATH(EIGEN_INCLUDE NAMES Eigen/Core PATHS ${EIGEN_SEARCH_HEADERS})
-IF (NOT EXISTS ${EIGEN_INCLUDE})
- MESSAGE(FATAL_ERROR "Can't find Eigen. Try passing -DEIGEN_INCLUDE=...")
-ENDIF (NOT EXISTS ${EIGEN_INCLUDE})
-MESSAGE("-- Found Eigen 3.x: ${EIGEN_INCLUDE}")
-
-
-INCLUDE_DIRECTORIES(
- ${GLOG_INCLUDE}
- ${EIGEN_INCLUDE}
- )
diff --git a/cmake/uninstall.cmake.in b/cmake/uninstall.cmake.in
index 66c57f6..dce3284 100644
--- a/cmake/uninstall.cmake.in
+++ b/cmake/uninstall.cmake.in
@@ -27,25 +27,71 @@
# POSSIBILITY OF SUCH DAMAGE.
#
# Author: arnaudgelas@gmail.com (Arnaud Gelas)
+# alexs.mac@gmail.com (Alex Stewart)
+
+IF (COMMAND cmake_policy)
+ # Ignore empty elements in LIST() commands.
+ CMAKE_POLICY(SET CMP0007 OLD)
+ENDIF (COMMAND cmake_policy)
IF (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
- MESSAGE(FATAL_ERROR
- "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+ MESSAGE(FATAL_ERROR "Cannot find install manifest: "
+ "\"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
-FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
-STRING(REGEX REPLACE "\n" ";" files "${files}")
-LIST(REVERSE files)
-FOREACH (file ${files})
- MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
- IF (EXISTS "$ENV{DESTDIR}${file}")
- EXECUTE_PROCESS(COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
- OUTPUT_VARIABLE rm_out
- RESULT_VARIABLE rm_retval)
- IF (NOT ${rm_retval} EQUAL 0)
- MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
- ENDIF (NOT ${rm_retval} EQUAL 0)
- ELSE (EXISTS "$ENV{DESTDIR}${file}")
- MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
- ENDIF (EXISTS "$ENV{DESTDIR}${file}")
-ENDFOREACH(file)
+FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" INSTALL_MANIFEST)
+STRING(REGEX REPLACE "\n" ";" INSTALL_MANIFEST "${INSTALL_MANIFEST}")
+LIST(REVERSE INSTALL_MANIFEST)
+
+FOREACH (INSTALLED_FILE ${INSTALL_MANIFEST})
+ # Save the root ceres include install directory, e.g. /usr/local/include/ceres
+ # so that we can remove it at the end.
+ IF (NOT CERES_INCLUDE_INSTALL_ROOT)
+ GET_FILENAME_COMPONENT(FILE_NAME ${INSTALLED_FILE} NAME)
+ IF (FILE_NAME STREQUAL ceres.h)
+ # Ensure that the directory is nested as we expect, as we are going to
+ # remove it, and we do not want to remove files pertaining to anyone else.
+ GET_FILENAME_COMPONENT(PARENT_DIR ${INSTALLED_FILE} PATH)
+ GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR} NAME)
+ IF (PARENT_DIR_NAME STREQUAL ceres AND IS_DIRECTORY ${PARENT_DIR})
+ SET(CERES_INCLUDE_INSTALL_ROOT ${PARENT_DIR})
+ ENDIF (PARENT_DIR_NAME STREQUAL ceres AND IS_DIRECTORY ${PARENT_DIR})
+ ENDIF (FILE_NAME STREQUAL ceres.h)
+ ENDIF (NOT CERES_INCLUDE_INSTALL_ROOT)
+
+ MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${INSTALLED_FILE}\"")
+ IF (EXISTS "$ENV{DESTDIR}${INSTALLED_FILE}")
+ EXECUTE_PROCESS(COMMAND @CMAKE_COMMAND@
+ -E remove "$ENV{DESTDIR}${INSTALLED_FILE}"
+ OUTPUT_VARIABLE RM_OUT
+ RESULT_VARIABLE RM_RETVAL)
+ IF (NOT ${RM_RETVAL} EQUAL 0)
+ MESSAGE(FATAL_ERROR
+ "Problem when removing \"$ENV{DESTDIR}${INSTALLED_FILE}\"")
+ ENDIF (NOT ${RM_RETVAL} EQUAL 0)
+ ELSE (EXISTS "$ENV{DESTDIR}${INSTALLED_FILE}")
+ MESSAGE(STATUS "File \"$ENV{DESTDIR}${INSTALLED_FILE}\" does not exist.")
+ ENDIF (EXISTS "$ENV{DESTDIR}${INSTALLED_FILE}")
+ENDFOREACH(INSTALLED_FILE)
+
+# Removing Ceres include install directory.
+IF (CERES_INCLUDE_INSTALL_ROOT AND
+ EXISTS ${CERES_INCLUDE_INSTALL_ROOT})
+ MESSAGE(STATUS "Removing Ceres include install directory: "
+ "\"$ENV{DESTDIR}${CERES_INCLUDE_INSTALL_ROOT}\"")
+ EXECUTE_PROCESS(COMMAND @CMAKE_COMMAND@
+ -E remove_directory
+ "$ENV{DESTDIR}${CERES_INCLUDE_INSTALL_ROOT}"
+ OUTPUT_VARIABLE RM_OUT
+ RESULT_VARIABLE RM_RETVAL)
+ IF (NOT ${RM_RETVAL} EQUAL 0)
+ MESSAGE(FATAL_ERROR
+ "Failed to remove: \"$ENV{DESTDIR}${CERES_INCLUDE_INSTALL_ROOT\"")
+ ENDIF (NOT ${RM_RETVAL} EQUAL 0)
+ELSE (CERES_INCLUDE_INSTALL_ROOT AND
+ EXISTS ${CERES_INCLUDE_INSTALL_ROOT})
+ MESSAGE(FATAL_ERROR "Failed to find Ceres installed include directory "
+ "(e.g. /usr/local/include/ceres), candidate: "
+ "\"$ENV{DESTDIR}${CERES_INCLUDE_INSTALL_ROOT}\"")
+ENDIF (CERES_INCLUDE_INSTALL_ROOT AND
+ EXISTS ${CERES_INCLUDE_INSTALL_ROOT})
diff --git a/docs/source/building.rst b/docs/source/building.rst
index 49fdb3c..b276baa 100644
--- a/docs/source/building.rst
+++ b/docs/source/building.rst
@@ -262,12 +262,15 @@
#. Try running ``Configure``. It won't work. It'll show a bunch of options.
You'll need to set:
- #. ``GLOG_INCLUDE``
- #. ``GLOG_LIB``
- #. ``GFLAGS_LIB``
- #. ``GFLAGS_INCLUDE``
+ #. ``EIGEN_INCLUDE_DIR``
+ #. ``GLOG_INCLUDE_DIR``
+ #. ``GLOG_LIBRARY``
+ #. ``GFLAGS_INCLUDE_DIR``
+ #. ``GFLAGS_LIBRARY``
- to the appropriate place where you unpacked/built them.
+ to the appropriate place where you unpacked/built them. If any of the
+ variables are not visible in the ``CMake`` GUI, toggle to the
+ *Advanced View* with ``<t>``.
#. You may have to tweak some more settings to generate a MSVC
project. After each adjustment, try pressing Configure & Generate
@@ -317,6 +320,27 @@
command line. In general, you should only modify these options from
their defaults if you know what you are doing.
+.. NOTE::
+
+ If you are setting variables via ``-D<VARIABLE>=<VALUE>`` when calling
+ ``CMake``, it is important to understand that this forcibly **overwrites** the
+ variable ``<VARIABLE>`` in the ``CMake`` cache at the start of *every configure*.
+
+ This can lead to confusion if you are invoking the ``CMake``
+ `curses <http://www.gnu.org/software/ncurses/ncurses.html>`_ terminal GUI
+ (via ``ccmake``, e.g. ```ccmake -D<VARIABLE>=<VALUE> <PATH_TO_SRC>``).
+ In this case, even if you change the value of ``<VARIABLE>`` in the ``CMake``
+ GUI, your changes will be **overwritten** with the value passed via
+ ``-D<VARIABLE>=<VALUE>`` (if one exists) at the start of each configure.
+
+ As such, it is generally easier not to pass values to ``CMake`` via ``-D``
+ and instead interactively experiment with their values in the ``CMake`` GUI.
+ If they are not present in the *Standard View*, toggle to the *Advanced View*
+ with ``<t>``.
+
+Options controlling Ceres configuration
+--------------------
+
#. ``LAPACK [Default: ON]``: By default Ceres will use ``LAPACK`` (&
``BLAS``) if they are found. Turn this ``OFF`` to build Ceres
without ``LAPACK``. Turning this ``OFF`` also disables
@@ -365,6 +389,47 @@
addition, ``make ceres_docs`` can be used to build only the
documentation.
+
+Options controlling Ceres dependency locations
+--------------------
+
+Ceres uses the ``CMake``
+`find_package <http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:find_package>`_
+function to find all of its dependencies using
+``Find<DEPENDENCY_NAME>.cmake`` scripts which are either included in Ceres
+(for most dependencies) or are shipped as standard with ``CMake``
+(for ``LAPACK`` & ``BLAS``). These scripts will search all of the "standard"
+install locations for various OSs for each dependency. However, particularly
+for Windows, they may fail to find the library, in this case you will have to
+manually specify its installed location. The ``Find<DEPENDENCY_NAME>.cmake``
+scripts shipped with Ceres support two ways for you to do this:
+
+#. Set the *hints* variables specifying the *directories* to search in
+ preference, but in addition, to the search directories in the
+ ``Find<DEPENDENCY_NAME>.cmake`` script:
+
+ - ``<DEPENDENCY_NAME (CAPS)>_INCLUDE_DIR_HINTS``
+ - ``<DEPENDENCY_NAME (CAPS)>_LIBRARY_DIR_HINTS``
+
+ These variables should be set via ``-D<VAR>=<VALUE>``
+ ``CMake`` arguments as they are not visible in the GUI.
+
+#. Set the variables specifying the *explicit* include directory
+ and library file to use:
+
+ - ``<DEPENDENCY_NAME (CAPS)>_INCLUDE_DIR``
+ - ``<DEPENDENCY_NAME (CAPS)>_LIBRARY``
+
+ This bypasses *all* searching in the
+ ``Find<DEPENDENCY_NAME>.cmake`` script, but validation is still
+ performed.
+
+ These variables are available to set in the ``CMake`` GUI. They
+ are visible in the *Standard View* if the library has not been
+ found (but the current Ceres configuration requires it), but
+ are always visible in the *Advanced View*. They can also be
+ set directly via ``-D<VAR>=<VALUE>`` arguments to ``CMake``.
+
.. _section-using-ceres:
Using Ceres with CMake
@@ -385,7 +450,7 @@
PROJECT(helloworld)
FIND_PACKAGE(Ceres REQUIRED)
- INCLUDE_DIRECTORIES(${CERES_INCLUDES})
+ INCLUDE_DIRECTORIES(${CERES_INCLUDE_DIRS})
# helloworld
ADD_EXECUTABLE(helloworld helloworld.cc)
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 9dfc80b..5205ccb 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -53,26 +53,26 @@
IF (GFLAGS)
ADD_EXECUTABLE(powell powell.cc)
- TARGET_LINK_LIBRARIES(powell ceres)
+ TARGET_LINK_LIBRARIES(powell ceres ${GFLAGS_LIBRARIES})
ADD_EXECUTABLE(nist nist.cc)
- TARGET_LINK_LIBRARIES(nist ceres)
+ TARGET_LINK_LIBRARIES(nist ceres ${GFLAGS_LIBRARIES})
ADD_EXECUTABLE(circle_fit circle_fit.cc)
- TARGET_LINK_LIBRARIES(circle_fit ceres)
+ TARGET_LINK_LIBRARIES(circle_fit ceres ${GFLAGS_LIBRARIES})
ADD_EXECUTABLE(bundle_adjuster
bundle_adjuster.cc
bal_problem.cc)
- TARGET_LINK_LIBRARIES(bundle_adjuster ceres)
+ TARGET_LINK_LIBRARIES(bundle_adjuster ceres ${GFLAGS_LIBRARIES})
ADD_EXECUTABLE(libmv_bundle_adjuster
libmv_bundle_adjuster.cc)
- TARGET_LINK_LIBRARIES(libmv_bundle_adjuster ceres)
+ TARGET_LINK_LIBRARIES(libmv_bundle_adjuster ceres ${GFLAGS_LIBRARIES})
ADD_EXECUTABLE(denoising
denoising.cc
fields_of_experts.cc)
- TARGET_LINK_LIBRARIES(denoising ceres)
+ TARGET_LINK_LIBRARIES(denoising ceres ${GFLAGS_LIBRARIES})
ENDIF (GFLAGS)
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index cefe809..eee8abf 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -130,9 +130,10 @@
FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/schur_eliminator_d_d_d.cc)
ENDIF (SCHUR_SPECIALIZATIONS)
-# For Android, use the internal Glog implementation.
+# Primarily for Android, but optionally for others, use the minimal internal
+# Glog implementation.
IF (MINIGLOG)
- ADD_LIBRARY(miniglog STATIC miniglog/glog/logging.cc)
+ ADD_LIBRARY(miniglog miniglog/glog/logging.cc)
INSTALL(TARGETS miniglog
EXPORT CeresExport
RUNTIME DESTINATION bin
@@ -140,18 +141,14 @@
ARCHIVE DESTINATION lib${LIB_SUFFIX})
ENDIF (MINIGLOG)
-SET(CERES_LIBRARY_DEPENDENCIES ${GLOG_LIB})
-
-IF (GFLAGS)
- LIST(APPEND CERES_LIBRARY_DEPENDENCIES ${GFLAGS_LIB})
-ENDIF (GFLAGS)
+SET(CERES_LIBRARY_DEPENDENCIES ${GLOG_LIBRARIES})
IF (SUITESPARSE AND SUITESPARSE_FOUND)
LIST(APPEND CERES_LIBRARY_DEPENDENCIES ${SUITESPARSE_LIBRARIES})
ENDIF (SUITESPARSE AND SUITESPARSE_FOUND)
IF (CXSPARSE AND CXSPARSE_FOUND)
- LIST(APPEND CERES_LIBRARY_DEPENDENCIES ${CXSPARSE_LIB})
+ LIST(APPEND CERES_LIBRARY_DEPENDENCIES ${CXSPARSE_LIBRARIES})
ENDIF (CXSPARSE AND CXSPARSE_FOUND)
IF (BLAS_FOUND AND LAPACK_FOUND)
@@ -190,8 +187,8 @@
numeric_diff_test_utils.cc
test_util.cc)
- TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIB} ${GLOG_LIB})
- TARGET_LINK_LIBRARIES(test_util ceres gtest ${GLOG_LIB})
+ TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES})
+ TARGET_LINK_LIBRARIES(test_util ceres gtest ${GLOG_LIBRARIES})
MACRO (CERES_TEST NAME)
ADD_EXECUTABLE(${NAME}_test ${NAME}_test.cc)