diff --git a/CMakeLists.txt b/CMakeLists.txt index 02c72b5cf..845745dfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,12 +29,37 @@ # Authors: keir@google.com (Keir Mierle) # alexs.mac@gmail.com (Alex Stewart) -cmake_minimum_required(VERSION 2.8.0) -cmake_policy(VERSION 2.8) +cmake_minimum_required(VERSION 3.5) +cmake_policy(VERSION 3.5) -cmake_policy(SET CMP0003 NEW) -if (POLICY CMP0042) - cmake_policy(SET CMP0042 NEW) +# Set the C++ version (must be >= C++11) when compiling Ceres. +# +# Reflect a user-specified (via -D) CMAKE_CXX_STANDARD if present, otherwise +# default to C++11. +set(DEFAULT_CXX_STANDARD ${CMAKE_CXX_STANDARD}) +if (NOT DEFAULT_CXX_STANDARD) + set(DEFAULT_CXX_STANDARD 11) +endif() +set(CMAKE_CXX_STANDARD ${DEFAULT_CXX_STANDARD} CACHE STRING + "C++ standard (minimum 11)" FORCE) +# Restrict CMAKE_CXX_STANDARD to the valid versions permitted and ensure that +# if one was forced via -D that it is in the valid set. +set(ALLOWED_CXX_STANDARDS 11 14 17) +set_property(CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS ${ALLOWED_CXX_STANDARDS}) +list(FIND ALLOWED_CXX_STANDARDS ${CMAKE_CXX_STANDARD} POSITION) +if (POSITION LESS 0) + message(FATAL_ERROR "Invalid CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}. " + "Must be one of: ${ALLOWED_CXX_STANDARDS}") +endif() +# Specify the standard as a hard requirement, otherwise CMAKE_CXX_STANDARD is +# interpreted as a suggestion that can decay *back* to lower versions. +set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "") +mark_as_advanced(CMAKE_CXX_STANDARD_REQUIRED) + +# MSVC versions < 2013 did not fully support >= C++11. +if (MSVC AND MSVC_VERSION VERSION_LESS 1800) + message(FATAL_ERROR "Invalid MSVC_VERSION: ${MSVC_VERSION}. Ceres requires at " + "least MSVC 2013 Update 4+") endif() project(Ceres C CXX) @@ -103,16 +128,6 @@ option(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON) option(CUSTOM_BLAS "Use handcoded BLAS routines (usually faster) instead of Eigen." ON) -# Ceres does not use C++11 internally, however it does use shared_ptr -# (required) and unordered_map (if available), both of which were present in -# previous iterations of what became C++11. GCC & Clang can have both TR1 & -# C++11 versions of both shared_ptr & unordered_map and by default on Linux, -# we will detect the TR1 versions if they exist, as they do NOT require -# -std=c++11 to be passed when compiling Ceres, and any client code that uses -# Ceres. This will result in conflicts if the client code uses C++11. -# Enabling this option forces the use of the C++11 versions (& -std=c++11) if -# available. -option(CXX11 "Enable use of C++11 headers if available (requires client code use C++11)." OFF) # Multithreading using OpenMP cmake_dependent_option( OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON @@ -120,11 +135,11 @@ cmake_dependent_option( # Multithreading using TBB cmake_dependent_option( TBB "Enable threaded solving in Ceres with TBB (requires TBB and C++11)" OFF - "CXX11;NOT OPENMP;NOT CXX11_THREADS" OFF) + "NOT OPENMP;NOT CXX11_THREADS" OFF) # Multithreading using C++11 primitives. cmake_dependent_option( CXX11_THREADS "Enable threaded solving in Ceres with C++11 primitives" OFF - "CXX11;NOT OPENMP;NOT TBB" OFF) + "NOT OPENMP;NOT TBB" OFF) # Enable the use of Eigen as a sparse linear algebra library for # solving the nonlinear least squares problems. option(EIGENSPARSE "Enable Eigen as a sparse linear algebra library." ON) @@ -133,15 +148,9 @@ option(EXPORT_BUILD_DIR option(BUILD_TESTING "Enable tests" ON) option(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF) option(BUILD_EXAMPLES "Build examples" ON) -cmake_dependent_option( - BUILD_BENCHMARKS "Build Ceres benchmarking suite" ON "CXX11" OFF) +option(BUILD_BENCHMARKS "Build Ceres benchmarking suite" ON) option(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF) if (MSVC) - # MSVC has no analogue of -std=c++11, as all features available are on by - # default. Enable CXX11 by default and disable if the required features - # are not found (<= VS2010). - update_cache_variable(CXX11 ON) - option(MSVC_USE_STATIC_CRT "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF) @@ -207,6 +216,7 @@ if (IOS) endif (IOS) unset(CERES_COMPILE_OPTIONS) +message("-- Building with C++${CMAKE_CXX_STANDARD}") # Eigen. find_package(Eigen REQUIRED) @@ -427,105 +437,15 @@ endif (OPENMP) # Initialise CMAKE_REQUIRED_FLAGS used by CheckCXXSourceCompiles with the # contents of CMAKE_CXX_FLAGS such that if the user has passed extra flags -# they are used when discovering shared_ptr/unordered_map. +# they are used when checking for compiler features. set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS}) -include(CheckCXXCompilerFlag) -check_cxx_compiler_flag("-std=c++11" COMPILER_HAS_CXX11_FLAG) -if (CXX11 AND COMPILER_HAS_CXX11_FLAG) - # Update CMAKE_REQUIRED_FLAGS used by CheckCXXSourceCompiles to include - # -std=c++11 s/t we will detect the C++11 versions of unordered_map & - # shared_ptr if they exist. - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11") -endif (CXX11 AND COMPILER_HAS_CXX11_FLAG) -# Set the Ceres compile definitions for the unordered_map configuration. -include(FindUnorderedMap) -find_unordered_map() -if (UNORDERED_MAP_FOUND) - if (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP) - endif(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - if (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) - endif(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - if (HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE) - list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_UNORDERED_MAP) - endif(HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE) -else (UNORDERED_MAP_FOUND) - message("-- Replacing unordered_map/set with map/set (warning: slower!), " - "try enabling CXX11 option if you expect C++11 to be available.") - list(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP) -endif() +# Set the Ceres option for C++11. +# TODO(alex): Remove when #defines are removed from source & config.h +list(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP) +list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX11) -# Set the Ceres compile definitions for the shared_ptr configuration. -include(FindSharedPtr) -find_shared_ptr() -if (SHARED_PTR_FOUND) - if (SHARED_PTR_TR1_MEMORY_HEADER) - list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_MEMORY_HEADER) - endif (SHARED_PTR_TR1_MEMORY_HEADER) - if (SHARED_PTR_TR1_NAMESPACE) - list(APPEND CERES_COMPILE_OPTIONS CERES_TR1_SHARED_PTR) - endif (SHARED_PTR_TR1_NAMESPACE) -else (SHARED_PTR_FOUND) - message(FATAL_ERROR "Unable to find shared_ptr, try enabling CXX11 option " - "if you expect C++11 to be available.") -endif (SHARED_PTR_FOUND) - -include(FindCXX11MathFunctions) -find_cxx11_math_functions() -if (CXX11 AND NOT CXX11_MATH_FUNCTIONS_FOUND) - message("-- Failed to find C++11 math functions (cbrt(), exp2() etc). " - "Disabling C++11.") - update_cache_variable(CXX11 OFF) -endif() - -# To ensure that CXX11 accurately reflects whether we are using C++11, -# check if it is required given where the potentially C++11 features Ceres -# uses were found, and disable it if C++11 is not being used. -if (CXX11) - if (NOT HAVE_SHARED_PTR_IN_STD_NAMESPACE AND - NOT HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - message("-- Failed to find C++11 components in C++11 locations & " - "namespaces, disabling CXX11.") - update_cache_variable(CXX11 OFF) - else() - message(" ==============================================================") - message(" Compiling Ceres using C++11. This will result in a version ") - message(" of Ceres that will require the use of C++11 in client code.") - message(" ==============================================================") - list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX11) - if (COMPILER_HAS_CXX11_FLAG AND - CMAKE_VERSION VERSION_LESS "2.8.12") - # For CMake versions > 2.8.12, the C++11 dependency is rolled into the - # Ceres target, and all dependent targets, but for older versions of CMake - # the flag must be specified explicitly both for Ceres and the - # examples/tests. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif() - endif() -endif(CXX11) - -if (CXX11 AND (TBB OR CXX11_THREADS)) - # We require for both TBB & CXX11_THREADS. Not all compilers - # (MSVC 2010) have even if they have other C++11 features. - check_include_file_cxx(atomic HAVE_STD_ATOMIC_HEADER) - if (NOT HAVE_STD_ATOMIC_HEADER) - message("-- Failed to find (C++11) header. Disabling " - "TBB and C++11 threads.") - # update_cache_variable() requires that the variable exists in the - # cache. As TBB & CXX11_THREADS are dependent-options they might not - # exist at this point so check before disabling. - if (TBB) - update_cache_variable(TBB OFF) - endif() - if (CXX11_THREADS) - update_cache_variable(CXX11_THREADS OFF) - endif() - endif() -endif() - -if (CXX11 AND TBB) +if (TBB) find_package(TBB QUIET) if (TBB_FOUND) message("-- Building with TBB (version: ${TBB_VERSION}).") @@ -537,7 +457,7 @@ if (CXX11 AND TBB) endif (TBB_FOUND) endif() -if (CXX11 AND CXX11_THREADS) +if (CXX11_THREADS) message("-- Building with C++11 threads.") list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX11_THREADS) endif() diff --git a/cmake/AddCeresCXX11RequirementsToTarget.cmake b/cmake/AddCeresCXX11RequirementsToTarget.cmake deleted file mode 100644 index 107eb582e..000000000 --- a/cmake/AddCeresCXX11RequirementsToTarget.cmake +++ /dev/null @@ -1,84 +0,0 @@ -# Ceres Solver - A fast non-linear least squares minimizer -# Copyright 2017 Google Inc. All rights reserved. -# http://ceres-solver.org/ -# -# 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) - -# Adds Ceres' C++11 requirements to a target such that they are exported when -# the target is exported (if the version of CMake supports it). -# -# add_ceres_cxx11_requirements_to_target( [target1 [target2 [...]]] ) -function(add_ceres_cxx11_requirements_to_target) - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("-std=c++11" COMPILER_HAS_CXX11_FLAG) - - foreach(TARGET ${ARGN}) - if (NOT TARGET ${TARGET}) - message(FATAL_ERROR "Specified target to append Ceres C++11 requirements " - "to: ${TARGET} is not a declared CMake target.") - endif() - - if (COMPILER_HAS_CXX11_FLAG) - # IMPORTANT: It is not sufficient to specify the - # CXX_STANDARD/CXX_STANDARD_REQUIRED target properties - # as these target properties are NOT exported. - if (CMAKE_VERSION VERSION_LESS "2.8.12") - # CMake version < 2.8.12 does not support target_compile_options(), warn - # user that they will have to add compile flags to their own projects - # manually. - message(WARNING "-- Warning: Detected CMake version: ${CMAKE_VERSION} " - "< 2.8.12, which is the minimum required for compile options to be " - "included in an exported CMake target and the detected. compiler " - "requires -std=c++11. The client is responsible for adding " - "-std=c++11 when linking against: ${TARGET}.") - elseif (COMMAND target_compile_features) - # CMake >= 3.1, use new target_compile_features() to specify Ceres' - # C++11 requirements as used in the public API. This assumes that - # C++11 STL features are available if the specified features are - # available. We do not use the cxx_std_11 feature to specify this as - # this did not come in until CMake 3.8. - # - # The reason to prefer using target_compile_features() if it exists is - # that this handles 'upgrading' of the C++ standard required more - # gracefully, e.g. if a client of Ceres requires C++14, but Ceres was - # compiled against C++11 then target_compile_options() may not work as - # expected. - target_compile_features( - ${TARGET} PUBLIC cxx_alignas cxx_alignof cxx_constexpr) - else() - # CMake version >= 2.8.12 && < 3.1 supports target_compile_options() - # but not target_compile_features(). For these intermediary versions, - # we use target_compile_options() to manually specify the C++11 flag and - # export it for client targets that depend on the target iff they are - # NOT compiling for C. We check for not C, rather than C++ as - # LINKER_LANGUAGE is often NOTFOUND and then uses the default (C++). - target_compile_options(${TARGET} PUBLIC - $<$,C>>:-std=c++11>) - endif() - endif() - endforeach() -endfunction() diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in index d0380de40..9fc69715e 100644 --- a/cmake/CeresConfig.cmake.in +++ b/cmake/CeresConfig.cmake.in @@ -324,26 +324,6 @@ endif (NOT TARGET ceres AND NOT Ceres_BINARY_DIR) # Set the expected XX_LIBRARIES variable for FindPackage(). set(CERES_LIBRARIES ceres) -# Make user aware of any compile flags that will be added to their targets -# which use Ceres (i.e. flags exported in the Ceres target). Only CMake -# versions >= 2.8.12 support target_compile_options/features(). -if (CERES_COMPILED_COMPONENTS MATCHES ".*C\\+\\+11.*") # Search for C++11. - set(CERES_WAS_COMPILED_WITH_CXX11 TRUE) -endif() -if (TARGET ${CERES_LIBRARIES} AND - CERES_WAS_COMPILED_WITH_CXX11 AND - NOT CMAKE_VERSION VERSION_LESS "2.8.12") - if (CERES_WAS_INSTALLED) - set(CERES_LOCATION "${CURRENT_ROOT_INSTALL_DIR}") - else() - set(CERES_LOCATION "${CERES_EXPORTED_BUILD_DIR}") - endif() - message(STATUS "Ceres version ${CERES_VERSION} detected here: " - "${CERES_LOCATION} was built with C++11. Ceres " - "target will add C++11 flags to compile options for " - "targets using it.") -endif() - # Set legacy include directories variable for backwards compatibility. set(CERES_INCLUDES ${CERES_INCLUDE_DIRS}) diff --git a/cmake/FindCXX11MathFunctions.cmake b/cmake/FindCXX11MathFunctions.cmake deleted file mode 100644 index 3beb6fc97..000000000 --- a/cmake/FindCXX11MathFunctions.cmake +++ /dev/null @@ -1,58 +0,0 @@ -# Ceres Solver - A fast non-linear least squares minimizer -# Copyright 2015 Google Inc. All rights reserved. -# http://ceres-solver.org/ -# -# 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) -# - -# FindCXX11MathFunctions.cmake - Find C++11 math functions. -# -# This module defines the following variables: -# -# CXX11_MATH_FUNCTIONS_FOUND: TRUE if C++11 math functions are found. - -macro(find_cxx11_math_functions) - # To support CXX11 option, clear the results of all check_xxx() functions - # s/t we always perform the checks each time, otherwise CMake fails to - # detect that the tests should be performed again after CXX11 is toggled. - unset(CXX11_MATH_FUNCTIONS_FOUND CACHE) - - # Verify that all C++11-specific math functions used by jet.h exist. - check_cxx_source_compiles("#include - #include - static constexpr size_t kMaxAlignBytes = alignof(std::max_align_t); - int main() { - std::cbrt(1.0); - std::exp2(1.0); - std::log2(1.0); - std::hypot(1.0, 1.0); - std::fmax(1.0, 1.0); - std::fmin(1.0, 1.0); - return 0; - }" - CXX11_MATH_FUNCTIONS_FOUND) -endmacro() diff --git a/cmake/FindSharedPtr.cmake b/cmake/FindSharedPtr.cmake deleted file mode 100644 index e37c969da..000000000 --- a/cmake/FindSharedPtr.cmake +++ /dev/null @@ -1,108 +0,0 @@ -# Ceres Solver - A fast non-linear least squares minimizer -# Copyright 2015 Google Inc. All rights reserved. -# http://ceres-solver.org/ -# -# 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: sergey.vfx@gmail.com (Sergey Sharybin) -# - -# FindSharedPtr.cmake - Find shared pointer header and namespace. -# -# This module defines the following variables: -# -# SHARED_PTR_FOUND: TRUE if shared_ptr found. -# SHARED_PTR_TR1_MEMORY_HEADER: True if header is to be used -# for the shared_ptr object, otherwise use . -# SHARED_PTR_TR1_NAMESPACE: TRUE if shared_ptr is defined in std::tr1 namespace, -# otherwise it's assumed to be defined in std namespace. - -macro(FIND_SHARED_PTR) - # To support CXX11 option, clear the results of all check_xxx() functions - # s/t we always perform the checks each time, otherwise CMake fails to - # detect that the tests should be performed again after CXX11 is toggled. - unset(HAVE_STD_MEMORY_HEADER CACHE) - unset(HAVE_SHARED_PTR_IN_STD_NAMESPACE CACHE) - unset(HAVE_SHARED_PTR_IN_TR1_NAMESPACE CACHE) - unset(HAVE_TR1_MEMORY_HEADER CACHE) - unset(HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER CACHE) - - set(SHARED_PTR_FOUND FALSE) - check_include_file_cxx(memory HAVE_STD_MEMORY_HEADER) - if (HAVE_STD_MEMORY_HEADER) - # Finding the memory header doesn't mean that shared_ptr is in std - # namespace. - # - # In particular, MSVC 2008 has shared_ptr declared in std::tr1. In - # order to support this, we do an extra check to see which namespace - # should be used. - include(CheckCXXSourceCompiles) - check_cxx_source_compiles("#include - int main() { - std::shared_ptr int_ptr; - return 0; - }" - HAVE_SHARED_PTR_IN_STD_NAMESPACE) - - if (HAVE_SHARED_PTR_IN_STD_NAMESPACE) - message("-- Found shared_ptr in std namespace using header.") - set(SHARED_PTR_FOUND TRUE) - else (HAVE_SHARED_PTR_IN_STD_NAMESPACE) - check_cxx_source_compiles("#include - int main() { - std::tr1::shared_ptr int_ptr; - return 0; - }" - HAVE_SHARED_PTR_IN_TR1_NAMESPACE) - if (HAVE_SHARED_PTR_IN_TR1_NAMESPACE) - message("-- Found shared_ptr in std::tr1 namespace using header.") - set(SHARED_PTR_TR1_NAMESPACE TRUE) - set(SHARED_PTR_FOUND TRUE) - endif (HAVE_SHARED_PTR_IN_TR1_NAMESPACE) - endif (HAVE_SHARED_PTR_IN_STD_NAMESPACE) - endif (HAVE_STD_MEMORY_HEADER) - - if (NOT SHARED_PTR_FOUND) - # Further, gcc defines shared_ptr in std::tr1 namespace and - # is to be included for this. And what makes things - # even more tricky is that gcc does have header, so - # all the checks above wouldn't find shared_ptr. - check_include_file_cxx("tr1/memory" HAVE_TR1_MEMORY_HEADER) - if (HAVE_TR1_MEMORY_HEADER) - check_cxx_source_compiles("#include - int main() { - std::tr1::shared_ptr int_ptr; - return 0; - }" - HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER) - if (HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER) - message("-- Found shared_ptr in std::tr1 namespace using header.") - set(SHARED_PTR_TR1_MEMORY_HEADER TRUE) - set(SHARED_PTR_TR1_NAMESPACE TRUE) - set(SHARED_PTR_FOUND TRUE) - endif (HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER) - endif (HAVE_TR1_MEMORY_HEADER) - endif (NOT SHARED_PTR_FOUND) -endmacro(FIND_SHARED_PTR) diff --git a/cmake/FindUnorderedMap.cmake b/cmake/FindUnorderedMap.cmake deleted file mode 100644 index 6ba07fd52..000000000 --- a/cmake/FindUnorderedMap.cmake +++ /dev/null @@ -1,94 +0,0 @@ -# Ceres Solver - A fast non-linear least squares minimizer -# Copyright 2015 Google Inc. All rights reserved. -# http://ceres-solver.org/ -# -# 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) -# - -# FindUnorderedMap.cmake - Find unordered_map header and namespace. -# -# This module defines the following variables: -# -# UNORDERED_MAP_FOUND: TRUE if unordered_map is found. -# HAVE_UNORDERED_MAP_IN_STD_NAMESPACE: Use & std. -# HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE: Use & std::tr1. -# HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE: & std::tr1. -macro(FIND_UNORDERED_MAP) - # To support CXX11 option, clear the results of all check_xxx() functions - # s/t we always perform the checks each time, otherwise CMake fails to - # detect that the tests should be performed again after CXX11 is toggled. - unset(HAVE_STD_UNORDERED_MAP_HEADER CACHE) - unset(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE CACHE) - unset(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE CACHE) - unset(HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE CACHE) - - set(UNORDERED_MAP_FOUND FALSE) - include(CheckIncludeFileCXX) - check_include_file_cxx(unordered_map HAVE_STD_UNORDERED_MAP_HEADER) - if (HAVE_STD_UNORDERED_MAP_HEADER) - # Finding the unordered_map header doesn't mean that unordered_map - # is in std namespace. - # - # In particular, MSVC 2008 has unordered_map declared in std::tr1. - # In order to support this, we do an extra check to see which - # namespace should be used. - include(CheckCXXSourceCompiles) - check_cxx_source_compiles("#include - int main() { - std::unordered_map map; - return 0; - }" - HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - if (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - set(UNORDERED_MAP_FOUND TRUE) - message("-- Found unordered_map/set in std namespace.") - else (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - check_cxx_source_compiles("#include - int main() { - std::tr1::unordered_map map; - return 0; - }" - HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - if (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - set(UNORDERED_MAP_FOUND TRUE) - message("-- Found unordered_map/set in std::tr1 namespace.") - else (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - message("-- Found but cannot find either " - "std::unordered_map or std::tr1::unordered_map.") - endif (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - endif (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - else (HAVE_STD_UNORDERED_MAP_HEADER) - check_include_file_cxx("tr1/unordered_map" - HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE) - if (HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE) - set(UNORDERED_MAP_FOUND TRUE) - message("-- Found tr1/unordered_map/set in std::tr1 namespace.") - else (HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE) - message("-- Unable to find or .") - endif (HAVE_TR1_UNORDERED_MAP_IN_TR1_NAMESPACE) - endif (HAVE_STD_UNORDERED_MAP_HEADER) -endmacro(FIND_UNORDERED_MAP) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 9298ff8f7..f9a770150 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -21,6 +21,12 @@ the latest version, you can clone the git repository Dependencies ============ + .. NOTE :: + + All versions of Ceres > 1.14 require a **fully C++11-compliant** + compiler. In versions <= 1.14, C++11 was an optional requirement + controlled by the ``CXX11 [Default: OFF]`` build option. + Ceres relies on a number of open source libraries, some of which are optional. For details on customizing the build process, see :ref:`section-customizing` . @@ -34,7 +40,7 @@ optional. For details on customizing the build process, see library. Please see the documentation for ``EIGENSPARSE`` for more details. -- `CMake `_ 2.8.0 or later. +- `CMake `_ 3.5 or later. **Required on all platforms except for Android.** - `glog `_ 0.3.1 or @@ -373,7 +379,7 @@ Windows `_ for Ceres Solver by Tal Ben-Nun. -On Windows, we support building with Visual Studio 2010 or newer. Note +On Windows, we support building with Visual Studio 2013 Release 4 or newer. Note that the Windows port is less featureful and less tested than the Linux or Mac OS X versions due to the lack of an officially supported way of building SuiteSparse and CXSparse. There are however a number @@ -635,8 +641,8 @@ Options controlling Ceres configuration to disable multi-threading. #. ``TBB [Default: OFF]``: An alternative to ``OpenMP`` threading library that - requires C++11. This option is mutually exclusive to ``OPENMP`` and - ``CXX11_THREADS``. + uses Intel's Thread Building Blocks. This option is mutually + exclusive to ``OPENMP`` and ``CXX11_THREADS``. .. NOTE:: @@ -646,50 +652,7 @@ Options controlling Ceres configuration #. ``CXX11_THREADS [Default: OFF]``: An alternative to ``OpenMP`` threading library that uses a C++11 thread-pool. This option - requires C++11 and is mutually exclusive to ``OPENMP`` and ``TBB``. - -#. ``CXX11 [Default: OFF]`` - - Although Ceres does not currently require C++11, it does use - ``shared_ptr`` (required) and ``unordered_map`` (if available); - both of which existed in the previous iterations of what became the - C++11 standard: TR1 & C++0x. As such, Ceres can compile on - pre-C++11 compilers, using the TR1/C++0x versions of ``shared_ptr`` - & ``unordered_map``. - - Note that when using GCC & Clang, compiling against the TR1/C++0x - versions: ``CXX11=OFF`` (the default) *does not* require - ``-std=c++11`` when compiling Ceres, *nor* does it require that any - client code using Ceres use ``-std=c++11``. However, this will - cause compile errors if any client code that uses Ceres also uses - C++11 (mismatched versions of ``shared_ptr`` & ``unordered_map``). - - Enabling this option: ``CXX11=ON`` forces Ceres to use the C++11 - versions of ``shared_ptr`` & ``unordered_map`` if they are - available, and thus imposes the requirement that all client code - using Ceres also compile with ``-std=c++11``. This requirement is - handled automatically through CMake target properties on the - exported Ceres target for CMake >= 2.8.12 (when it was introduced). - Thus, any client code which uses CMake will automatically be - compiled with ``-std=c++11``. **On CMake versions < 2.8.12, you - are responsible for ensuring that any code which uses Ceres is - compiled with** ``-std=c++11``. - - On OS X 10.9+, Clang will use the C++11 versions of ``shared_ptr`` - & ``unordered_map`` without ``-std=c++11`` and so this option does - not change the versions detected, although enabling it *will* - require that client code compile with ``-std=c++11``. - - The following table summarises the effects of the ``CXX11`` option: - - =================== ========== ================ ====================================== - OS CXX11 Detected Version Ceres & client code require ``-std=c++11`` - =================== ========== ================ ====================================== - Linux (GCC & Clang) OFF tr1 **No** - Linux (GCC & Clang) ON std **Yes** - OS X 10.9+ OFF std **No** - OS X 10.9+ ON std **Yes** - =================== ========== ================ ====================================== + is mutually exclusive to ``OPENMP`` and ``TBB``. #. ``BUILD_SHARED_LIBS [Default: OFF]``: By default Ceres is built as a static library, turn this ``ON`` to instead build Ceres as a @@ -875,7 +838,7 @@ The Ceres components which can be specified are: #. ``Multithreading``: Ceres built with *a* multithreading library. This is equivalent to ``OpenMP`` **OR** ``TBB``. -#. ``C++11``: Ceres built with C++11 (``CXX11=ON``). +#. ``C++11``: Ceres built with C++11. To specify one/multiple Ceres components use the ``COMPONENTS`` argument to `find_package() diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt index cc43fec24..a70f973a0 100644 --- a/internal/ceres/CMakeLists.txt +++ b/internal/ceres/CMakeLists.txt @@ -215,26 +215,26 @@ set_target_properties(ceres PROPERTIES VERSION ${CERES_VERSION} SOVERSION ${CERES_VERSION_MAJOR}) +# The ability to specify a minimum language version via cxx_std_[11,14,17] +# requires CMake >= 3.8. Prior to that we have to specify the compiler features +# we require. +if (CMAKE_VERSION VERSION_LESS 3.8) + set(REQUIRED_PUBLIC_CXX_FEATURES cxx_alignas cxx_alignof cxx_constexpr) +else() + # Forward whatever C++ version Ceres was compiled with as our requirement + # for downstream clients. + set(REQUIRED_PUBLIC_CXX_FEATURES cxx_std_${CMAKE_CXX_STANDARD}) +endif() +target_compile_features(ceres PUBLIC ${REQUIRED_PUBLIC_CXX_FEATURES}) + include(AppendTargetProperty) # Always build position-independent code (PIC), even when building Ceres as a # static library so that shared libraries can link against it, not just # executables (PIC does not apply on Windows). if (NOT WIN32 AND NOT BUILD_SHARED_LIBS) - # Use the explicit POSITION_INDEPENDENT_CODE target property on CMake versions - # that support it (>= 2.8.9). Otherwise, manually add the -fPIC flag as an - # additional compile definitions for the target. - if (CMAKE_VERSION VERSION_LESS "2.8.9") - append_target_property(ceres COMPILE_FLAGS "-fPIC") - else() - # Use set_target_properties() not append_target_property() here as - # POSITION_INDEPENDENT_CODE is a binary ON/OFF switch. - set_target_properties(ceres PROPERTIES POSITION_INDEPENDENT_CODE ON) - endif() -endif() - -if (CXX11) - include(AddCeresCXX11RequirementsToTarget) - add_ceres_cxx11_requirements_to_target(ceres) + # Use set_target_properties() not append_target_property() here as + # POSITION_INDEPENDENT_CODE is a binary ON/OFF switch. + set_target_properties(ceres PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() if (BUILD_SHARED_LIBS)