Only use LTO when compiling Ceres itself, not tests or examples. - If Ceres is built as a shared library, and LTO is enabled for Ceres and the tests, then type_info::operator==() incorrectly returns false in gtests' CheckedDowncastToActualType() in the following tests: -- levenberg_marquardt_strategy_test. -- gradient_checking_cost_function_test. on at least Xcode 6 & 7 as reported here: https://github.com/google/googletest/issues/595. - This does not appear to be a gtest issue, but is perhaps an LLVM bug or an RTTI shared library issue. Either way, disabling the use of LTO when compiling the test application resolves the issue. - Allow LTO to be enabled for GCC, if it is supported. - Add CMake function to allow easy appending to target properties s/t Ceres library-specific compile flags can be iteratively constructed. Change-Id: I923e6aae4f7cefa098cf32b2f8fc19389e7918c9
diff --git a/CMakeLists.txt b/CMakeLists.txt index 22a6a0b..8581b4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -558,19 +558,6 @@ endif (GCC_VERSION VERSION_LESS 4.3) endif (CMAKE_SYSTEM_NAME MATCHES "Darwin") endif (CMAKE_COMPILER_IS_GNUCXX) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - # Use of -flto requires use of gold linker & LLVM-gold plugin, which might - # well not be present / in use and without which files will compile, but - # not link ('file not recognized') so explicitly check for support - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("-flto" HAVE_LTO_SUPPORT) - if (HAVE_LTO_SUPPORT) - message(STATUS "Enabling link-time optimization (-flto)") - set(CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -flto") - else () - message(STATUS "Compiler/linker does not support link-time optimization (-flto), disabling.") - endif (HAVE_LTO_SUPPORT) - endif () endif (CMAKE_BUILD_TYPE STREQUAL "Release") set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CERES_CXX_FLAGS}")
diff --git a/cmake/AppendTargetProperty.cmake b/cmake/AppendTargetProperty.cmake new file mode 100644 index 0000000..e0bc3a4 --- /dev/null +++ b/cmake/AppendTargetProperty.cmake
@@ -0,0 +1,61 @@ +# 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) + +# Append item(s) to a property on a declared CMake target: +# +# append_target_property(target property item_to_append1 +# [... item_to_appendN]) +# +# The set_target_properties() CMake function will overwrite the contents of the +# specified target property. This function instead appends to it, so can +# be called multiple times with the same target & property to iteratively +# populate it. +function(append_target_property TARGET PROPERTY) + if (NOT TARGET ${TARGET}) + message(FATAL_ERROR "Invalid target: ${TARGET} cannot append: ${ARGN} " + "to property: ${PROPERTY}") + endif() + if (NOT PROPERTY) + message(FATAL_ERROR "Invalid property to update for target: ${TARGET}") + endif() + # Get the initial state of the specified property for the target s/t + # we can append to it (not overwrite it). + get_target_property(INITIAL_PROPERTY_STATE ${TARGET} ${PROPERTY}) + if (NOT INITIAL_PROPERTY_STATE) + # Ensure that if the state is unset, we do not insert the XXX-NOTFOUND + # returned by CMake into the property. + set(INITIAL_PROPERTY_STATE "") + endif() + # Delistify (remove ; separators) the potentially set of items to append + # to the specified target property. + string(REPLACE ";" " " ITEMS_TO_APPEND "${ARGN}") + set_target_properties(${TARGET} PROPERTIES ${PROPERTY} + "${INITIAL_PROPERTY_STATE} ${ITEMS_TO_APPEND}") +endfunction()
diff --git a/docs/source/version_history.rst b/docs/source/version_history.rst index c32b4f1..d1a1990 100644 --- a/docs/source/version_history.rst +++ b/docs/source/version_history.rst
@@ -27,6 +27,8 @@ Bug Fixes & Minor Changes ------------------------- +#. Use link-time optimisation (LTO) only when compiling Ceres itself, + not tests or examples, to bypass gtest / type_info::operator== issue. #. Use old minimum iOS version flags on Xcode < 7.0. #. Add gtest-specific flags when building/using as a shared library. #. Clean up iOS.cmake to use xcrun/xcodebuild & libtool.
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt index 00377e2..cc2cb89 100644 --- a/internal/ceres/CMakeLists.txt +++ b/internal/ceres/CMakeLists.txt
@@ -184,6 +184,7 @@ VERSION ${CERES_VERSION} SOVERSION ${CERES_VERSION_MAJOR}) +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). @@ -192,12 +193,31 @@ # 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") - set_target_properties(ceres PROPERTIES COMPILE_FLAGS "-fPIC") + 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() +# Use of -flto requires use of gold linker & LLVM-gold plugin, which might +# well not be present / in use and without which files will compile, but +# not link ('file not recognized') so explicitly check for support. +# +# Only use link-time optimisation (LTO) flags when building Ceres itself, as it +# causes an issue with type_info::operator==() in gtest's +# CheckedDowncastToActualType() in levenberg_marquardt_strategy_test & +# gradient_checking_cost_function_test if enabled for the tests as well. +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag("-flto" HAVE_LTO_SUPPORT) +if (HAVE_LTO_SUPPORT) + message(STATUS "Enabling link-time optimization (-flto)") + append_target_property(ceres COMPILE_FLAGS "-flto") +else () + message(STATUS "Compiler/linker does not support link-time optimization (-flto).") +endif (HAVE_LTO_SUPPORT) + 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 @@ -254,7 +274,7 @@ add_library(gtest gmock_gtest_all.cc gmock_main.cc) if (BUILD_SHARED_LIBS) # Define gtest-specific shared library flags for compilation. - set_target_properties(gtest PROPERTIES COMPILE_DEFINITIONS + append_target_property(gtest COMPILE_DEFINITIONS GTEST_CREATE_SHARED_LIBRARY) endif() @@ -278,7 +298,7 @@ target_link_libraries(${NAME}_test test_util ceres gtest) if (BUILD_SHARED_LIBS) # Define gtest-specific shared library flags for linking. - set_target_properties(${NAME}_test PROPERTIES COMPILE_DEFINITIONS + append_target_property(${NAME}_test COMPILE_DEFINITIONS GTEST_LINKED_AS_SHARED_LIBRARY) endif() add_test(NAME ${NAME}_test