1 # Ceres Solver - A fast non-linear least squares minimizer
2 # Copyright 2015 Google Inc. All rights reserved.
3 # http://ceres-solver.org/
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
8 # * Redistributions of source code must retain the above copyright notice,
9 # this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above copyright notice,
11 # this list of conditions and the following disclaimer in the documentation
12 # and/or other materials provided with the distribution.
13 # * Neither the name of Google Inc. nor the names of its contributors may be
14 # used to endorse or promote products derived from this software without
15 # specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
29 # Authors: keir@google.com (Keir Mierle)
30 # alexs.mac@gmail.com (Alex Stewart)
32 cmake_minimum_required(VERSION 2.8.0)
33 cmake_policy(VERSION 2.8)
35 cmake_policy(SET CMP0003 NEW)
37 cmake_policy(SET CMP0042 NEW)
42 # NOTE: The 'generic' CMake variables CMAKE_[SOURCE/BINARY]_DIR should not be
43 # used. Always use the project-specific variants (generated by CMake):
44 # <PROJECT_NAME_MATCHING_CASE>_[SOURCE/BINARY]_DIR, e.g.
45 # Ceres_SOURCE_DIR (note, *not* CERES_SOURCE_DIR) instead, as these will
46 # always point to the correct directories for the Ceres project, even if
47 # it is nested inside another source tree, whereas the 'generic'
48 # CMake variables refer to the *first* project() declaration, i.e. the
49 # top-level project, not Ceres, if Ceres is nested.
51 # Make CMake aware of the cmake folder for local FindXXX scripts,
52 # append rather than set in case the user has passed their own
53 # additional paths via -D.
54 list(APPEND CMAKE_MODULE_PATH "${Ceres_SOURCE_DIR}/cmake")
55 include(UpdateCacheVariable)
57 # Set up the git hook to make Gerrit Change-Id: lines in commit messages.
58 include(AddGerritCommitHook)
59 add_gerrit_commit_hook(${Ceres_SOURCE_DIR} ${Ceres_BINARY_DIR})
61 # On OS X, add the Homebrew prefix to the set of prefixes searched by
62 # CMake in find_path & find_library. This should ensure that we can
63 # still build Ceres even if Homebrew is installed in a non-standard
64 # location (not /usr/local).
65 if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
66 find_program(HOMEBREW_EXECUTABLE brew)
67 mark_as_advanced(FORCE HOMEBREW_EXECUTABLE)
68 if (HOMEBREW_EXECUTABLE)
69 # Detected a Homebrew install, query for its install prefix.
70 execute_process(COMMAND ${HOMEBREW_EXECUTABLE} --prefix
71 OUTPUT_VARIABLE HOMEBREW_INSTALL_PREFIX
72 OUTPUT_STRIP_TRAILING_WHITESPACE)
73 message(STATUS "Detected Homebrew with install prefix: "
74 "${HOMEBREW_INSTALL_PREFIX}, adding to CMake search paths.")
75 list(APPEND CMAKE_PREFIX_PATH "${HOMEBREW_INSTALL_PREFIX}")
79 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/bin)
80 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
81 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
82 # Set postfixes for generated libraries based on buildtype.
83 set(CMAKE_RELEASE_POSTFIX "")
84 set(CMAKE_DEBUG_POSTFIX "-debug")
86 # Read the Ceres version from the source, such that we only ever have a single
87 # definition of the Ceres version.
88 include(ReadCeresVersionFromSource)
89 read_ceres_version_from_source(${Ceres_SOURCE_DIR})
93 option(MINIGLOG "Use a stripped down version of glog." OFF)
94 option(GFLAGS "Enable Google Flags." ON)
95 option(SUITESPARSE "Enable SuiteSparse." ON)
96 option(CXSPARSE "Enable CXSparse." ON)
97 option(LAPACK "Enable use of LAPACK." ON)
98 # Template specializations for the Schur complement based solvers. If
99 # compile time, binary size or compiler performance is an issue, you
100 # may consider disabling this.
101 option(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
103 "Use handcoded BLAS routines (usually faster) instead of Eigen."
105 # Multithreading using OpenMP
106 option(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON)
107 # Enable the use of Eigen as a sparse linear algebra library for
108 # solving the nonlinear least squares problems. Enabling this
109 # option will result in an LGPL licensed version of Ceres Solver
110 # as the Simplicial Cholesky factorization in Eigen is licensed under the LGPL.
111 # This does not affect the covariance estimation algorithm, as it
112 # depends on the sparse QR factorization algorithm, which is licensed
115 "Enable Eigen as a sparse linear algebra library, WARNING: results in an LGPL licensed Ceres." OFF)
117 # Ceres does not use C++11 internally, however it does use shared_ptr
118 # (required) and unordered_map (if available), both of which were present in
119 # previous iterations of what became C++11. GCC & Clang can have both TR1 &
120 # C++11 versions of both shared_ptr & unordered_map and by default on Linux,
121 # we will detect the TR1 versions if they exist, as they do NOT require
122 # -std=c++11 to be passed when compiling Ceres, and any client code that uses
123 # Ceres. This will result in conflicts if the client code uses C++11.
124 # Enabling this option forces the use of the C++11 versions (& -std=c++11) if
127 # This option is not available on Windows when using MSVC, as there, any new
128 # (C++11 etc) features available are on by default and there is no analogue to
129 # -std=c++11. It will however be available for MinGW & CygWin, which can
130 # support -std=c++11.
131 option(CXX11 "Enable use of C++11 headers if available (requires client code use C++11)." OFF)
133 option(EXPORT_BUILD_DIR
134 "Export build directory using CMake (enables external use without install)." OFF)
135 option(BUILD_TESTING "Enable tests" ON)
136 option(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
137 option(BUILD_EXAMPLES "Build examples" ON)
138 option(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
140 option(MSVC_USE_STATIC_CRT
141 "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
143 if (BUILD_TESTING AND BUILD_SHARED_LIBS)
145 "-- Disabling tests. The flags BUILD_TESTING and BUILD_SHARED_LIBS"
146 " are incompatible with MSVC.")
147 update_cache_variable(BUILD_TESTING OFF)
148 endif (BUILD_TESTING AND BUILD_SHARED_LIBS)
150 # Allow user to specify a suffix for the library install directory, the only
151 # really sensible option (other than "") being "64", such that:
152 # ${CMAKE_INSTALL_PREFIX}/lib -> ${CMAKE_INSTALL_PREFIX}/lib64.
154 # Heuristic for determining LIB_SUFFIX. FHS recommends that 64-bit systems
155 # install native libraries to lib64 rather than lib. Most distros seem to
156 # follow this convention with a couple notable exceptions (Debian-based and
157 # Arch-based distros) which we try to detect here.
158 if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
159 NOT DEFINED LIB_SUFFIX AND
160 NOT CMAKE_CROSSCOMPILING AND
161 CMAKE_SIZEOF_VOID_P EQUAL "8" AND
162 NOT EXISTS "/etc/debian_version" AND
163 NOT EXISTS "/etc/arch-release")
164 message("-- Detected non-Debian/Arch-based 64-bit Linux distribution. "
165 "Defaulting to library install directory: lib${LIB_SUFFIX}. You can "
166 "override this by specifying LIB_SUFFIX.")
169 # Only create the cache variable (for the CMake GUI) after attempting to detect
170 # the suffix *if not specified by the user* (NOT DEFINED LIB_SUFFIX in if())
171 # s/t the user could override our autodetected suffix with "" if desired.
172 set(LIB_SUFFIX "${LIB_SUFFIX}" CACHE STRING
173 "Suffix of library install directory (to support lib/lib64)." FORCE)
175 # IOS is defined iff using the iOS.cmake CMake toolchain to build a static
178 message(STATUS "Building Ceres for iOS platform: ${IOS_PLATFORM}")
180 # Ceres requires at least iOS 7.0+.
181 if (IOS_DEPLOYMENT_TARGET VERSION_LESS 7.0)
182 message(FATAL_ERROR "Unsupported iOS version: ${IOS_DEPLOYMENT_TARGET}, Ceres "
183 "requires at least iOS version 7.0")
186 update_cache_variable(MINIGLOG ON)
187 message(STATUS "Building for iOS: Forcing use of miniglog instead of glog.")
189 update_cache_variable(SUITESPARSE OFF)
190 update_cache_variable(CXSPARSE OFF)
191 update_cache_variable(GFLAGS OFF)
192 update_cache_variable(OPENMP OFF)
193 # Apple claims that the BLAS call dsyrk_ is a private API, and will not allow
194 # you to submit to the Apple Store if the symbol is present.
195 update_cache_variable(LAPACK OFF)
196 message(STATUS "Building for iOS: SuiteSparse, CXSparse, LAPACK, gflags, "
197 "and OpenMP are not available.")
199 update_cache_variable(BUILD_EXAMPLES OFF)
200 message(STATUS "Building for iOS: Will not build examples.")
203 unset(CERES_COMPILE_OPTIONS)
206 find_package(Eigen REQUIRED)
208 if (EIGEN_VERSION VERSION_LESS 3.1.0)
209 message(FATAL_ERROR "-- Ceres requires Eigen version >= 3.1.0 in order "
210 "that Eigen/SparseCore be available, detected version of Eigen is: "
212 endif (EIGEN_VERSION VERSION_LESS 3.1.0)
214 message("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}")
215 # Ensure that only MPL2 licensed code is part of the default build.
217 message(" ===============================================================")
219 list(APPEND CERES_COMPILE_OPTIONS CERES_USE_EIGEN_SPARSE)
220 message(" Enabling the use of Eigen as a sparse linear algebra library ")
221 message(" for solving the nonlinear least squares problems. Enabling ")
222 message(" this option results in an LGPL licensed version of ")
223 message(" Ceres Solver as the Simplicial Cholesky factorization in Eigen")
224 message(" is licensed under the LGPL. ")
226 if (EIGEN_VERSION VERSION_LESS 3.2.2)
229 message(" Your version of Eigen is older than version 3.2.2.")
230 message(" The performance of SPARSE_NORMAL_CHOLESKY and SPARSE_SCHUR")
231 message(" linear solvers will suffer. ")
232 endif (EIGEN_VERSION VERSION_LESS 3.2.2)
235 message(" Disabling the use of Eigen as a sparse linear algebra library.")
236 message(" This does not affect the covariance estimation algorithm ")
237 message(" which can still use the EIGEN_SPARSE_QR algorithm.")
238 add_definitions(-DEIGEN_MPL2_ONLY)
240 message(" ===============================================================")
246 find_package(LAPACK QUIET)
248 message("-- Found LAPACK library: ${LAPACK_LIBRARIES}")
250 message("-- Did not find LAPACK library, disabling LAPACK support.")
253 find_package(BLAS QUIET)
255 message("-- Found BLAS library: ${BLAS_LIBRARIES}")
257 message("-- Did not find BLAS library, disabling LAPACK support.")
260 if (NOT (LAPACK_FOUND AND BLAS_FOUND))
261 update_cache_variable(LAPACK OFF)
262 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
263 endif (NOT (LAPACK_FOUND AND BLAS_FOUND))
265 message("-- Building without LAPACK.")
266 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
270 if (SUITESPARSE AND NOT LAPACK)
271 # If user has disabled LAPACK, but left SUITESPARSE ON, turn it OFF,
272 # LAPACK controls whether Ceres will be linked, directly or indirectly
273 # via SuiteSparse to LAPACK.
274 message("-- Disabling SuiteSparse as use of LAPACK has been disabled, "
275 "turn ON LAPACK to enable (optional) building with SuiteSparse.")
276 update_cache_variable(SUITESPARSE OFF)
277 endif (SUITESPARSE AND NOT LAPACK)
279 # By default, if SuiteSparse and all dependencies are found, Ceres is
280 # built with SuiteSparse support.
282 # Check for SuiteSparse and dependencies.
283 find_package(SuiteSparse)
284 if (SUITESPARSE_FOUND)
285 # On Ubuntu the system install of SuiteSparse (v3.4.0) up to at least
286 # Ubuntu 13.10 cannot be used to link shared libraries.
287 if (BUILD_SHARED_LIBS AND
288 SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
289 message(FATAL_ERROR "You are attempting to build Ceres as a shared "
290 "library on Ubuntu using a system package install of SuiteSparse "
291 "3.4.0. This package is broken and does not support the "
292 "construction of shared libraries (you can still build Ceres as "
293 "a static library). If you wish to build a shared version of Ceres "
294 "you should uninstall the system install of SuiteSparse "
295 "(libsuitesparse-dev) and perform a source install of SuiteSparse "
296 "(we recommend that you use the latest version), "
297 "see http://ceres-solver.org/building.html for more information.")
298 endif (BUILD_SHARED_LIBS AND
299 SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
301 # By default, if all of SuiteSparse's dependencies are found, Ceres is
302 # built with SuiteSparse support.
303 message("-- Found SuiteSparse ${SUITESPARSE_VERSION}, "
304 "building with SuiteSparse.")
305 else (SUITESPARSE_FOUND)
306 # Disable use of SuiteSparse if it cannot be found and continue.
307 message("-- Did not find all SuiteSparse dependencies, disabling "
308 "SuiteSparse support.")
309 update_cache_variable(SUITESPARSE OFF)
310 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
311 endif (SUITESPARSE_FOUND)
313 message("-- Building without SuiteSparse.")
314 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
319 # Don't search with REQUIRED as we can continue without CXSparse.
320 find_package(CXSparse)
322 # By default, if CXSparse and all dependencies are found, Ceres is
323 # built with CXSparse support.
324 message("-- Found CXSparse version: ${CXSPARSE_VERSION}, "
325 "building with CXSparse.")
326 else (CXSPARSE_FOUND)
327 # Disable use of CXSparse if it cannot be found and continue.
328 message("-- Did not find CXSparse, Building without CXSparse.")
329 update_cache_variable(CXSPARSE OFF)
330 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
331 endif (CXSPARSE_FOUND)
333 message("-- Building without CXSparse.")
334 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
335 # Mark as advanced (remove from default GUI view) the CXSparse search
336 # variables in case user enabled CXSPARSE, FindCXSparse did not find it, so
337 # made search variables visible in GUI for user to set, but then user disables
338 # CXSPARSE instead of setting them.
339 mark_as_advanced(FORCE CXSPARSE_INCLUDE_DIR
343 # Ensure that the user understands they have disabled all sparse libraries.
344 if (NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
345 message(" ===============================================================")
346 message(" Compiling without any sparse library: SuiteSparse, CXSparse ")
347 message(" & Eigen (Sparse) are all disabled or unavailable. No sparse ")
348 message(" linear solvers (SPARSE_NORMAL_CHOLESKY & SPARSE_SCHUR)")
349 message(" will be available when Ceres is used.")
350 message(" ===============================================================")
351 endif(NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
355 # Don't search with REQUIRED as we can continue without gflags.
358 message("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}, "
359 "in namespace: ${GFLAGS_NAMESPACE}")
360 add_definitions(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
362 message("-- Did not find Google Flags (gflags), Building without gflags "
363 "- no tests or tools will be built!")
364 update_cache_variable(GFLAGS OFF)
367 message("-- Google Flags disabled; no tests or tools will be built!")
368 # Mark as advanced (remove from default GUI view) the gflags search
369 # variables in case user enabled GFLAGS, FindGflags did not find it, so
370 # made search variables visible in GUI for user to set, but then user disables
371 # GFLAGS instead of setting them.
372 mark_as_advanced(FORCE GFLAGS_INCLUDE_DIR
379 message("-- Compiling minimal glog substitute into Ceres.")
380 set(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
381 set(MINIGLOG_MAX_LOG_LEVEL 2 CACHE STRING "The maximum message severity level to be logged")
382 add_definitions("-DMAX_LOG_LEVEL=${MINIGLOG_MAX_LOG_LEVEL}")
383 message("-- Using minimal glog substitute (include): ${GLOG_INCLUDE_DIRS}")
384 message("-- Max log level for minimal glog substitute: ${MINIGLOG_MAX_LOG_LEVEL}")
386 # Mark as advanced (remove from default GUI view) the glog search
387 # variables in case user disables MINIGLOG, FindGlog did not find it, so
388 # made search variables visible in GUI for user to set, but then user enables
389 # MINIGLOG instead of setting them.
390 mark_as_advanced(FORCE GLOG_INCLUDE_DIR
393 unset(MINIGLOG_MAX_LOG_LEVEL CACHE)
394 # Don't search with REQUIRED so that configuration continues if not found and
395 # we can output an error messages explaining MINIGLOG option.
398 message(FATAL_ERROR "Can't find Google Log (glog). Please set either: "
399 "glog_DIR (newer CMake built versions of glog) or GLOG_INCLUDE_DIR & "
400 "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
402 endif(NOT GLOG_FOUND)
403 # By default, assume gflags was found, updating the message if it was not.
404 set(GLOG_GFLAGS_DEPENDENCY_MESSAGE
405 " Assuming glog was built with gflags support as gflags was found. "
406 "This will make gflags a public dependency of Ceres.")
407 if (NOT GFLAGS_FOUND)
408 set(GLOG_GFLAGS_DEPENDENCY_MESSAGE
409 " Assuming glog was NOT built with gflags support as gflags was "
410 "not found. If glog was built with gflags, please set the "
411 "gflags search locations such that it can be found by Ceres. "
412 "Otherwise, Ceres may fail to link due to missing gflags symbols.")
413 endif(NOT GFLAGS_FOUND)
414 message("-- Found Google Log (glog)." ${GLOG_GFLAGS_DEPENDENCY_MESSAGE})
417 if (NOT SCHUR_SPECIALIZATIONS)
418 list(APPEND CERES_COMPILE_OPTIONS CERES_RESTRICT_SCHUR_SPECIALIZATION)
419 message("-- Disabling Schur specializations (faster compiles)")
420 endif (NOT SCHUR_SPECIALIZATIONS)
423 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_CUSTOM_BLAS)
424 message("-- Disabling custom blas")
425 endif (NOT CUSTOM_BLAS)
428 # Find quietly, as we can continue without OpenMP if it is not found.
429 find_package(OpenMP QUIET)
431 message("-- Building with OpenMP.")
432 list(APPEND CERES_COMPILE_OPTIONS CERES_USE_OPENMP)
433 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
434 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
436 # At least on Linux, we need pthreads to be enabled for mutex to
437 # compile. This may not work on Windows or Android.
438 find_package(Threads REQUIRED)
439 list(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_PTHREAD)
440 list(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_RWLOCK)
443 message("-- Failed to find OpenMP, disabling. This is expected on "
444 "Clang < 3.8, and at least Xcode <= 7.")
445 update_cache_variable(OPENMP OFF)
446 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
449 message("-- Building without OpenMP (disabling multithreading).")
450 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
453 # Initialise CMAKE_REQUIRED_FLAGS used by CheckCXXSourceCompiles with the
454 # contents of CMAKE_CXX_FLAGS such that if the user has passed extra flags
455 # they are used when discovering shared_ptr/unordered_map.
456 set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})
458 include(CheckCXXCompilerFlag)
459 check_cxx_compiler_flag("-std=c++11" COMPILER_HAS_CXX11_FLAG)
460 if (CXX11 AND COMPILER_HAS_CXX11_FLAG)
461 # Update CMAKE_REQUIRED_FLAGS used by CheckCXXSourceCompiles to include
462 # -std=c++11 s/t we will detect the C++11 versions of unordered_map &
463 # shared_ptr if they exist.
464 set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
465 endif (CXX11 AND COMPILER_HAS_CXX11_FLAG)
467 # Set the Ceres compile definitions for the unordered_map configuration.
468 include(FindUnorderedMap)
470 if (UNORDERED_MAP_FOUND)
471 if (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
472 list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP)
473 endif(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
474 if (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
475 list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
476 endif(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
477 if (HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE)
478 list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_UNORDERED_MAP)
479 endif(HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE)
480 else (UNORDERED_MAP_FOUND)
481 message("-- Replacing unordered_map/set with map/set (warning: slower!), "
482 "try enabling CXX11 option if you expect C++11 to be available.")
483 list(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP)
486 # Set the Ceres compile definitions for the shared_ptr configuration.
487 include(FindSharedPtr)
489 if (SHARED_PTR_FOUND)
490 if (SHARED_PTR_TR1_MEMORY_HEADER)
491 list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_MEMORY_HEADER)
492 endif (SHARED_PTR_TR1_MEMORY_HEADER)
493 if (SHARED_PTR_TR1_NAMESPACE)
494 list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_SHARED_PTR)
495 endif (SHARED_PTR_TR1_NAMESPACE)
496 else (SHARED_PTR_FOUND)
497 message(FATAL_ERROR "Unable to find shared_ptr, try enabling CXX11 option "
498 "if you expect C++11 to be available.")
499 endif (SHARED_PTR_FOUND)
501 # To ensure that CXX11 accurately reflects whether we are using C++11,
502 # check if it is required given where the potentially C++11 features Ceres
503 # uses were found, and disable it if C++11 is not being used.
505 if (NOT HAVE_SHARED_PTR_IN_STD_NAMESPACE AND
506 NOT HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
507 message("-- Failed to find C++11 components in C++11 locations & "
508 "namespaces, disabling CXX11.")
509 update_cache_variable(CXX11 OFF)
511 message(" ==============================================================")
512 message(" Compiling Ceres using C++11. This will result in a version ")
513 message(" of Ceres that will require the use of C++11 in client code.")
514 message(" ==============================================================")
515 list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX11)
516 if (COMPILER_HAS_CXX11_FLAG AND
517 CMAKE_VERSION VERSION_LESS "2.8.12")
518 # For CMake versions > 2.8.12, the C++11 dependency is rolled into the
519 # Ceres target, and all dependent targets, but for older versions of CMake
520 # the flag must be specified explicitly both for Ceres and the
522 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
531 ${GLOG_INCLUDE_DIRS})
532 # Eigen SparseQR generates various compiler warnings related to unused and
533 # uninitialised local variables. To avoid having to individually suppress these
534 # warnings around the #include statments for Eigen headers across all GCC/Clang
535 # versions, we tell CMake to treat Eigen headers as system headers. This
536 # results in all compiler warnings from them being suppressed.
538 # Note that this is *not* propagated to clients, ie CERES_INCLUDE_DIRS
539 # used by clients after find_package(Ceres) does not identify Eigen as
541 include_directories(SYSTEM ${EIGEN_INCLUDE_DIRS})
544 include_directories(${SUITESPARSE_INCLUDE_DIRS})
548 include_directories(${CXSPARSE_INCLUDE_DIRS})
552 include_directories(${GFLAGS_INCLUDE_DIRS})
555 if (BUILD_SHARED_LIBS)
556 message("-- Building Ceres as a shared library.")
557 # The CERES_BUILDING_SHARED_LIBRARY compile definition is NOT stored in
558 # CERES_COMPILE_OPTIONS as it must only be defined when Ceres is compiled
559 # not when it is used as it controls the CERES_EXPORT macro which provides
560 # dllimport/export support in MSVC.
561 add_definitions(-DCERES_BUILDING_SHARED_LIBRARY)
562 list(APPEND CERES_COMPILE_OPTIONS CERES_USING_SHARED_LIBRARY)
563 else (BUILD_SHARED_LIBS)
564 message("-- Building Ceres as a static library.")
565 endif (BUILD_SHARED_LIBS)
567 # Change the default build type from Debug to Release, while still
568 # supporting overriding the build type.
570 # The CACHE STRING logic here and elsewhere is needed to force CMake
571 # to pay attention to the value of these variables.
572 if (NOT CMAKE_BUILD_TYPE)
573 message("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.")
574 set(CMAKE_BUILD_TYPE Release CACHE STRING
575 "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
577 else (NOT CMAKE_BUILD_TYPE)
578 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
579 message("\n=================================================================================")
580 message("\n-- Build type: Debug. Performance will be terrible!")
581 message("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.")
582 message("\n=================================================================================")
583 endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
584 endif (NOT CMAKE_BUILD_TYPE)
586 # Set the default Ceres flags to an empty string.
587 set (CERES_CXX_FLAGS)
589 if (CMAKE_BUILD_TYPE STREQUAL "Release")
590 if (CMAKE_COMPILER_IS_GNUCXX)
592 if (CMAKE_SYSTEM_NAME MATCHES "Linux")
593 if (NOT GCC_VERSION VERSION_LESS 4.2)
594 set (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -march=native -mtune=native")
595 endif (NOT GCC_VERSION VERSION_LESS 4.2)
596 endif (CMAKE_SYSTEM_NAME MATCHES "Linux")
598 if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
599 set (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -msse3")
600 # Use of -fast only applicable for Apple's GCC
601 # Assume this is being used if GCC version < 4.3 on OSX
602 execute_process(COMMAND ${CMAKE_C_COMPILER}
603 ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
604 OUTPUT_VARIABLE GCC_VERSION
605 OUTPUT_STRIP_TRAILING_WHITESPACE)
606 if (GCC_VERSION VERSION_LESS 4.3)
607 set (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -fast")
608 endif (GCC_VERSION VERSION_LESS 4.3)
609 endif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
610 endif (CMAKE_COMPILER_IS_GNUCXX)
611 endif (CMAKE_BUILD_TYPE STREQUAL "Release")
613 set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CERES_CXX_FLAGS}")
616 # MinGW produces code that segfaults when performing matrix multiplications
617 # in Eigen when compiled with -O3 (see [1]), as such force the use of -O2
620 # [1] http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556
621 message("-- MinGW detected, forcing -O2 instead of -O3 in Release for Eigen due "
622 "to a MinGW bug: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556")
623 string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
624 update_cache_variable(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
627 # After the tweaks for the compile settings, disable some warnings on MSVC.
629 # On MSVC, math constants are not included in <cmath> or <math.h> unless
630 # _USE_MATH_DEFINES is defined [1]. As we use M_PI in the examples, ensure
631 # that _USE_MATH_DEFINES is defined before the first inclusion of <cmath>.
633 # [1] https://msdn.microsoft.com/en-us/library/4hwaceh6.aspx
634 add_definitions("-D_USE_MATH_DEFINES")
635 # Disable signed/unsigned int conversion warnings.
636 add_definitions("/wd4018")
637 # Disable warning about using struct/class for the same symobl.
638 add_definitions("/wd4099")
639 # Disable warning about the insecurity of using "std::copy".
640 add_definitions("/wd4996")
641 # Disable performance warning about int-to-bool conversion.
642 add_definitions("/wd4800")
643 # Disable performance warning about fopen insecurity.
644 add_definitions("/wd4996")
645 # Disable warning about int64 to int32 conversion. Disabling
646 # this warning may not be correct; needs investigation.
647 # TODO(keir): Investigate these warnings in more detail.
648 add_definitions("/wd4244")
649 # It's not possible to use STL types in DLL interfaces in a portable and
650 # reliable way. However, that's what happens with Google Log and Google Flags
651 # on Windows. MSVC gets upset about this and throws warnings that we can't do
652 # much about. The real solution is to link static versions of Google Log and
653 # Google Test, but that seems tricky on Windows. So, disable the warning.
654 add_definitions("/wd4251")
656 # Google Flags doesn't have their DLL import/export stuff set up correctly,
657 # which results in linker warnings. This is irrelevant for Ceres, so ignore
659 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049")
661 # Update the C/CXX flags for MSVC to use either the static or shared
662 # C-Run Time (CRT) library based on the user option: MSVC_USE_STATIC_CRT.
663 list(APPEND C_CXX_FLAGS
665 CMAKE_CXX_FLAGS_DEBUG
666 CMAKE_CXX_FLAGS_RELEASE
667 CMAKE_CXX_FLAGS_MINSIZEREL
668 CMAKE_CXX_FLAGS_RELWITHDEBINFO)
670 foreach(FLAG_VAR ${C_CXX_FLAGS})
671 if (MSVC_USE_STATIC_CRT)
673 if (${FLAG_VAR} MATCHES "/MD")
674 string(REGEX REPLACE "/MD" "/MT" ${FLAG_VAR} "${${FLAG_VAR}}")
675 endif (${FLAG_VAR} MATCHES "/MD")
676 else (MSVC_USE_STATIC_CRT)
677 # Use shared, not static, CRT.
678 if (${FLAG_VAR} MATCHES "/MT")
679 string(REGEX REPLACE "/MT" "/MD" ${FLAG_VAR} "${${FLAG_VAR}}")
680 endif (${FLAG_VAR} MATCHES "/MT")
681 endif (MSVC_USE_STATIC_CRT)
684 # Tuple sizes of 10 are used by Gtest.
685 add_definitions("-D_VARIADIC_MAX=10")
687 include(CheckIfUnderscorePrefixedBesselFunctionsExist)
688 check_if_underscore_prefixed_bessel_functions_exist(
689 HAVE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
690 if (HAVE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
691 list(APPEND CERES_COMPILE_OPTIONS
692 CERES_MSVC_USE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
697 # GCC is not strict enough by default, so enable most of the warnings.
699 "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
702 # Use a larger inlining threshold for Clang, since it hobbles Eigen,
703 # resulting in an unreasonably slow version of the blas routines. The
704 # -Qunused-arguments is needed because CMake passes the inline
705 # threshold to the linker and clang complains about it and dies.
706 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
708 "${CMAKE_CXX_FLAGS} -Qunused-arguments -mllvm -inline-threshold=600")
710 # Older versions of Clang (<= 2.9) do not support the 'return-type-c-linkage'
711 # option, so check for its presence before adding it to the default flags set.
712 include(CheckCXXCompilerFlag)
713 check_cxx_compiler_flag("-Wno-return-type-c-linkage"
714 HAVE_RETURN_TYPE_C_LINKAGE)
715 if (HAVE_RETURN_TYPE_C_LINKAGE)
716 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage")
717 endif(HAVE_RETURN_TYPE_C_LINKAGE)
720 # Xcode 4.5.x used Clang 4.1 (Apple version), this has a bug that prevents
721 # compilation of Ceres.
722 if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
723 execute_process(COMMAND ${CMAKE_CXX_COMPILER}
724 ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
725 OUTPUT_VARIABLE CLANG_VERSION
726 OUTPUT_STRIP_TRAILING_WHITESPACE)
727 # Use version > 4.0 & < 4.2 to catch all 4.1(.x) versions.
728 if (CLANG_VERSION VERSION_GREATER 4.0 AND
729 CLANG_VERSION VERSION_LESS 4.2)
730 message(FATAL_ERROR "You are attempting to build Ceres on OS X using Xcode "
731 "4.5.x (Clang version: ${CLANG_VERSION}). This version of Clang has a "
732 "bug that prevents compilation of Ceres, please update to "
734 endif (CLANG_VERSION VERSION_GREATER 4.0 AND
735 CLANG_VERSION VERSION_LESS 4.2)
736 endif (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
738 # Configure the Ceres config.h compile options header using the current
739 # compile options and put the configured header into the Ceres build
740 # directory. Note that the ceres/internal subdir in <build>/config where
741 # the configured config.h is placed is important, because Ceres will be
742 # built against this configured header, it needs to have the same relative
743 # include path as it would if it were in the source tree (or installed).
744 list(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
745 include(CreateCeresConfig)
746 create_ceres_config("${CERES_COMPILE_OPTIONS}"
747 ${Ceres_BINARY_DIR}/config/ceres/internal)
748 # Force the location containing the configured config.h to the front of the
749 # include_directories list (by default it is appended to the back) to ensure
750 # that if the user has an installed version of Ceres in the same location as one
751 # of the dependencies (e.g. /usr/local) that we find the config.h we just
752 # configured, not the (older) installed config.h.
753 include_directories(BEFORE ${Ceres_BINARY_DIR}/config)
755 add_subdirectory(internal/ceres)
757 if (BUILD_DOCUMENTATION)
758 set(CERES_DOCS_INSTALL_DIR "share/doc/ceres" CACHE STRING
759 "Ceres docs install path relative to CMAKE_INSTALL_PREFIX")
761 find_package(Sphinx QUIET)
762 if (NOT SPHINX_FOUND)
763 message("-- Failed to find Sphinx, disabling build of documentation.")
764 update_cache_variable(BUILD_DOCUMENTATION OFF)
766 # Generate the User's Guide (html).
767 # The corresponding target is ceres_docs, but is included in ALL.
768 message("-- Build the HTML documentation.")
769 add_subdirectory(docs)
771 endif (BUILD_DOCUMENTATION)
774 message("-- Build the examples.")
775 add_subdirectory(examples)
776 else (BUILD_EXAMPLES)
777 message("-- Do not build any example.")
778 endif (BUILD_EXAMPLES)
780 # Setup installation of Ceres public headers.
781 file(GLOB CERES_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
782 install(FILES ${CERES_HDRS} DESTINATION include/ceres)
784 file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
785 install(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
787 # Also setup installation of Ceres config.h configured with the current
788 # build options into the installed headers directory.
789 install(FILES ${Ceres_BINARY_DIR}/config/ceres/internal/config.h
790 DESTINATION include/ceres/internal)
793 # Install miniglog header if being used as logging #includes appear in
794 # installed public Ceres headers.
795 install(FILES ${Ceres_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
796 DESTINATION include/ceres/internal/miniglog/glog)
799 # Ceres supports two mechanisms by which it can be detected & imported into
800 # client code which uses CMake via find_package(Ceres):
802 # 1) Installation (e.g. to /usr/local), using CMake's install() function.
804 # 2) (Optional) Export of the current build directory into the local CMake
805 # package registry, using CMake's export() function. This allows use of
806 # Ceres from other projects without requiring installation.
808 # In both cases, we need to generate a configured CeresConfig.cmake which
809 # includes additional autogenerated files which in concert create an imported
810 # target for Ceres in a client project when find_package(Ceres) is invoked.
811 # The key distinctions are where this file is located, and whether client code
812 # references installed copies of the compiled Ceres headers/libraries,
813 # (option #1: installation), or the originals in the source/build directories
814 # (option #2: export of build directory).
816 # NOTE: If Ceres is both exported and installed, provided that the installation
817 # path is present in CMAKE_MODULE_PATH when find_package(Ceres) is called,
818 # the installed version is preferred.
820 # Build the list of Ceres components for CeresConfig.cmake from the current set
821 # of compile options.
822 include(CeresCompileOptionsToComponents)
823 ceres_compile_options_to_components("${CERES_COMPILE_OPTIONS}"
824 CERES_COMPILED_COMPONENTS)
826 # Create a CeresConfigVersion.cmake file containing the version information,
827 # used by both export() & install().
828 configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
829 "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
831 # Install method #1: Put Ceres in CMAKE_INSTALL_PREFIX: /usr/local or equivalent.
833 # Set the install path for the installed CeresConfig.cmake configuration file
834 # relative to CMAKE_INSTALL_PREFIX.
836 set(RELATIVE_CMAKECONFIG_INSTALL_DIR CMake)
838 set(RELATIVE_CMAKECONFIG_INSTALL_DIR lib${LIB_SUFFIX}/cmake/Ceres)
841 # This "exports" for installation all targets which have been put into the
842 # export set "CeresExport". This generates a CeresTargets.cmake file which,
843 # when read in by a client project as part of find_package(Ceres) creates
844 # imported library targets for Ceres (with dependency relations) which can be
845 # used in target_link_libraries() calls in the client project to use Ceres.
846 install(EXPORT CeresExport
847 DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR} FILE CeresTargets.cmake)
849 # Save the relative path from the installed CeresConfig.cmake file to the
850 # install prefix. We do not save an absolute path in case the installed package
851 # is subsequently relocated after installation (on Windows).
852 file(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
853 ${CMAKE_INSTALL_PREFIX}/${RELATIVE_CMAKECONFIG_INSTALL_DIR}
854 ${CMAKE_INSTALL_PREFIX})
856 # Configure a CeresConfig.cmake file for an installed version of Ceres from the
857 # template, reflecting the current build options.
859 # NOTE: The -install suffix is necessary to distinguish the install version from
860 # the exported version, which must be named CeresConfig.cmake in
861 # Ceres_BINARY_DIR to be detected. The suffix is removed when
863 set(SETUP_CERES_CONFIG_FOR_INSTALLATION TRUE)
864 configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
865 "${Ceres_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
867 # Install the configuration files into the same directory as the autogenerated
868 # CeresTargets.cmake file. We include the find_package() scripts for libraries
869 # whose headers are included in the public API of Ceres and should thus be
870 # present in CERES_INCLUDE_DIRS.
871 install(FILES "${Ceres_BINARY_DIR}/CeresConfig-install.cmake"
872 RENAME CeresConfig.cmake
873 DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
874 install(FILES "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake"
875 "${Ceres_SOURCE_DIR}/cmake/FindEigen.cmake"
876 "${Ceres_SOURCE_DIR}/cmake/FindGlog.cmake"
877 "${Ceres_SOURCE_DIR}/cmake/FindGflags.cmake"
878 DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
880 # Create an uninstall target to remove all installed files.
881 configure_file("${Ceres_SOURCE_DIR}/cmake/uninstall.cmake.in"
882 "${Ceres_BINARY_DIR}/cmake/uninstall.cmake"
884 add_custom_target(uninstall
885 COMMAND ${CMAKE_COMMAND} -P ${Ceres_BINARY_DIR}/cmake/uninstall.cmake)
887 # Install method #2: Put Ceres build into local CMake registry.
889 # Optionally export the Ceres build directory into the local CMake package
890 # registry (~/.cmake/packages on *nix & OS X). This allows the detection &
891 # use of Ceres without requiring that it be installed.
892 if (EXPORT_BUILD_DIR)
893 message("-- Export Ceres build directory to local CMake package registry.")
895 # Save the relative path from the build directory to the source directory.
896 file(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
900 # Analogously to install(EXPORT ...), export the Ceres target from the build
901 # directory as a package called Ceres into the local CMake package registry.
902 export(TARGETS ceres FILE ${Ceres_BINARY_DIR}/CeresTargets.cmake)
903 export(PACKAGE ${CMAKE_PROJECT_NAME})
905 # Configure a CeresConfig.cmake file for the export of the Ceres build
906 # directory from the template, reflecting the current build options.
907 set(SETUP_CERES_CONFIG_FOR_INSTALLATION FALSE)
908 configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
909 "${Ceres_BINARY_DIR}/CeresConfig.cmake" @ONLY)
911 endif (EXPORT_BUILD_DIR)