diff --git a/CMakeLists.txt b/CMakeLists.txt index 5110d26d1..d95966971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -647,6 +647,23 @@ IF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") CLANG_VERSION VERSION_LESS 4.2) ENDIF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +# Get the complete list of any added compile definitions so that we can +# export them. Currently we export all Ceres compile definitions to users +# of Ceres via FindPackage() except CERES_BUILDING_SHARED_LIBRARY (if present) +# which controls the behaviour of the CERES_EXPORT macro for MSVC, which +# we substitute for CERES_USING_SHARED_LIBRARY, which is what users of +# Ceres should call in MSVC. +GET_DIRECTORY_PROPERTY(CERES_INTERFACE_COMPILE_DEFINITIONS + DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS) +# Substitute CERES_BUILDING_SHARED_LIBRARY with CERES_USING_SHARED_LIBRARY +# if building Ceres as a shared library. +IF (BUILD_SHARED_LIBS) + LIST(REMOVE_ITEM CERES_INTERFACE_COMPILE_DEFINITIONS + CERES_BUILDING_SHARED_LIBRARY) + LIST(APPEND CERES_INTERFACE_COMPILE_DEFINITIONS + CERES_USING_SHARED_LIBRARY) +ENDIF() + ADD_SUBDIRECTORY(internal/ceres) IF (BUILD_DOCUMENTATION) diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in index 02da76648..56a21941e 100644 --- a/cmake/CeresConfig.cmake.in +++ b/cmake/CeresConfig.cmake.in @@ -51,6 +51,15 @@ # was compiled. This will not include any optional dependencies # that were disabled when Ceres was compiled. # +# CERES_INTERFACE_COMPILE_DEFINITIONS: List of compile definitions which should be +# used when compiling a target that uses Ceres +# Note that these variables will NOT have a -D +# prefix appended. +# IMPORTANT: The contents of CERES_INTERFACE_COMPILE_DEFINITIONS will be +# AUTOMATICALLY added for you, either via the CMake function +# target_compile_definitions() in CMake >= 2.8.11, or via a call to +# add_definitions() in CMake < 2.8.11. +# # 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. @@ -67,6 +76,7 @@ MACRO(CERES_REPORT_NOT_FOUND REASON_MSG) SET(CERES_FOUND FALSE) UNSET(CERES_INCLUDE_DIRS) UNSET(CERES_LIBRARIES) + UNSET(CERES_INTERFACE_COMPILE_DEFINITIONS) # Reset the CMake module path to its state when this script was called. SET(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH}) @@ -190,6 +200,24 @@ ENDIF (NOT TARGET ceres AND NOT Ceres_BINARY_DIR) # Set the expected XX_LIBRARIES variable for FindPackage(). SET(CERES_LIBRARIES ceres) +# If Ceres was compiled with CMake < 2.8.11, we were not able to use the +# new (in 2.8.11) target_compile_definitions() function to append the +# required compile definitions to use when compiling a target that uses +# Ceres to the Ceres library target. As such, we need to use add_definitions() +# to ensure that they will be present. This is a blunt instrument, as it +# will add the Ceres definitions to _all_ targets declared from this point +# on in the caller's project. Hoever, without requiring the user to +# explicitly set the flags themselves, this is the only way in CMake +# versions < 2.8.11. +SET (CERES_COMPILED_CMAKE_VERSION @CMAKE_VERSION@) +SET (CERES_INTERFACE_COMPILE_DEFINITIONS @CERES_INTERFACE_COMPILE_DEFINITIONS@) +IF (CERES_COMPILED_CMAKE_VERSION VERSION_LESS 2.8.11) + # The definitions will have been stripped of -D, add it back. + FOREACH(DEF ${CERES_INTERFACE_COMPILE_DEFINITIONS}) + ADD_DEFINITIONS("-D${DEF}") + ENDFOREACH() +ENDIF() + # Set legacy include directories variable for backwards compatibility. SET(CERES_INCLUDES ${CERES_INCLUDE_DIRS}) diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt index b95976829..7b7f21d7a 100644 --- a/internal/ceres/CMakeLists.txt +++ b/internal/ceres/CMakeLists.txt @@ -177,6 +177,22 @@ SET_TARGET_PROPERTIES(ceres PROPERTIES VERSION ${CERES_VERSION} SOVERSION ${CERES_VERSION_MAJOR} ) + +# If we are using CMake >= 2.8.11, make use of the target_compile_definitions() +# function to append the compile definitions to the exported ceres target, thus +# any library that finds Ceres via CMake, then adds Ceres to one of its own +# targets will be compiled with the Ceres compile definitions defined. This +# is important for any defines that appear in the installed Ceres header files +# e.g those related to shared_ptr. +# +# If we are using CMake < 2.8.11, then we will have added an add_definitions() +# call in the CeresConfig.cmake file, which whilst achieving a similar effect, +# is more of a blunt instrument, as the Ceres definitions will also be added +# to targets in the users project that do not use Ceres. +IF (CMAKE_VERSION VERSION_EQUAL 2.8.11 OR + CMAKE_VERSION VERSION_GREATER 2.8.11) + TARGET_COMPILE_DEFINITIONS(ceres INTERFACE ${CERES_INTERFACE_COMPILE_DEFINITIONS}) +ENDIF() TARGET_LINK_LIBRARIES(ceres ${CERES_LIBRARY_DEPENDENCIES}) INSTALL(TARGETS ceres