Fix missing gflags imported target definition in CeresConfig.cmake
- If gflags was built & exported with CMake but glog was not, but both
were found then as we now make gflags a public dependency of Ceres if
both it and glog are found, the *name* of the exported gflags CMake
target (gflags-shared or similar) will appear in CERES_LIBRARIES.
- However, as imported targets are not re-exported, this results in a
linker error when compiling client code, as the name of the exported
gflags target is not known to CMake, it assumes it is a library name,
which it is not.
- Confusingly, if glog was built with CMake, this problem would not
occur, as in that case glog’s CMake target would bring in gflags’.
- Now we explicitly call find_package(Gflags) in CeresConfig.cmake if
Ceres was built with gflags as a public dependency (via glog).
Change-Id: I5cc9483a1fae50f4e9e3a8fbba491b645fd45db6
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 89d0bf0..eda2aec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -842,6 +842,7 @@
install(FILES "${CMAKE_BINARY_DIR}/CeresConfigVersion.cmake"
"${CMAKE_SOURCE_DIR}/cmake/FindEigen.cmake"
"${CMAKE_SOURCE_DIR}/cmake/FindGlog.cmake"
+ "${CMAKE_SOURCE_DIR}/cmake/FindGflags.cmake"
DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
# Create an uninstall target to remove all installed files.
diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in
index cdb3797..c0e7767 100644
--- a/cmake/CeresConfig.cmake.in
+++ b/cmake/CeresConfig.cmake.in
@@ -233,6 +233,7 @@
# Glog.
# Flag set during configuration and build of Ceres.
set(CERES_USES_MINIGLOG @MINIGLOG@)
+set(CERES_USES_GFLAGS @GFLAGS@)
if (CERES_USES_MINIGLOG)
set(MINIGLOG_INCLUDE_DIR ${CERES_INCLUDE_DIR}/ceres/internal/miniglog)
if (NOT EXISTS ${MINIGLOG_INCLUDE_DIR})
@@ -248,20 +249,59 @@
"for glog, beware this will likely cause problems if glog is later linked.")
else (CERES_USES_MINIGLOG)
# Append the locations of glog when Ceres was built to the search path hints.
- list(APPEND GLOG_INCLUDE_DIR_HINTS @GLOG_INCLUDE_DIR@)
- get_filename_component(CERES_BUILD_GLOG_LIBRARY_DIR @GLOG_LIBRARY@ PATH)
- list(APPEND GLOG_LIBRARY_DIR_HINTS ${CERES_BUILD_GLOG_LIBRARY_DIR})
+ set(GLOG_WAS_BUILT_WITH_CMAKE @FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION@)
+ if (GLOG_WAS_BUILT_WITH_CMAKE)
+ set(glog_DIR @glog_DIR@)
+ set(GLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION TRUE)
+ else()
+ list(APPEND GLOG_INCLUDE_DIR_HINTS @GLOG_INCLUDE_DIR@)
+ get_filename_component(CERES_BUILD_GLOG_LIBRARY_DIR @GLOG_LIBRARY@ PATH)
+ list(APPEND GLOG_LIBRARY_DIR_HINTS ${CERES_BUILD_GLOG_LIBRARY_DIR})
+ endif()
# 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}")
+ message(STATUS "Found required Ceres dependency: glog")
else (GLOG_FOUND)
ceres_report_not_found("Missing required Ceres "
- "dependency: Glog, please set GLOG_INCLUDE_DIR.")
+ "dependency: glog. Searched using GLOG_INCLUDE_DIR_HINTS: "
+ "${GLOG_INCLUDE_DIR_HINTS} and glog_DIR: ${glog_DIR}.")
endif (GLOG_FOUND)
list(APPEND CERES_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS})
+
+ # gflags is only a public dependency of Ceres via glog, thus is not required
+ # if Ceres was built with MINIGLOG.
+ if (CERES_USES_GFLAGS)
+ # If gflags was found as an imported CMake target, we need to call
+ # find_packge(Gflags) again here, as imported CMake targets are not
+ # re-exported. Without this, the 'gflags-shared' target name which is
+ # present in CERES_LIBRARIES in this case would not be defined, and so
+ # CMake will assume it is a library name (which it is not) and fail to link.
+ #
+ # Append the locations of gflags when Ceres was built to the search path
+ # hints.
+ set(GFLAGS_WAS_BUILT_WITH_CMAKE @FOUND_INSTALLED_GFLAGS_CMAKE_CONFIGURATION@)
+ if (GFLAGS_WAS_BUILT_WITH_CMAKE)
+ set(gflags_DIR @gflags_DIR@)
+ set(GFLAGS_PREFER_EXPORTED_GFLAGS_CMAKE_CONFIGURATION TRUE)
+ else()
+ list(APPEND GFLAGS_INCLUDE_DIR_HINTS @GFLAGS_INCLUDE_DIR@)
+ get_filename_component(CERES_BUILD_GFLAGS_LIBRARY_DIR @GFLAGS_LIBRARY@ PATH)
+ list(APPEND GFLAGS_LIBRARY_DIR_HINTS ${CERES_BUILD_GFLAGS_LIBRARY_DIR})
+ endif()
+
+ # Search quietly s/t we control the timing of the error message if not found.
+ find_package(Gflags QUIET)
+ if (GFLAGS_FOUND)
+ message(STATUS "Found required Ceres dependency: gflags")
+ else()
+ ceres_report_not_found("Missing required Ceres "
+ "dependency: gflags. Searched using GFLAGS_INCLUDE_DIR_HINTS: "
+ "${GFLAGS_INCLUDE_DIR_HINTS} and gflags_DIR: ${gflags_DIR}.")
+ endif()
+ list(APPEND CERES_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR_HINTS})
+ endif()
endif (CERES_USES_MINIGLOG)
# Import exported Ceres targets, if they have not already been imported.
diff --git a/cmake/FindGflags.cmake b/cmake/FindGflags.cmake
index 8f5cd3c..751771d 100644
--- a/cmake/FindGflags.cmake
+++ b/cmake/FindGflags.cmake
@@ -47,6 +47,9 @@
# by default gflags, although can be configured when building
# gflags to be something else (i.e. google for legacy
# compatibility).
+# FOUND_INSTALLED_GFLAGS_CMAKE_CONFIGURATION: True iff the version of gflags
+# found was built & installed /
+# exported as a CMake package.
#
# The following variables control the behaviour of this module when an exported
# gflags CMake configuration is not found.
diff --git a/cmake/FindGlog.cmake b/cmake/FindGlog.cmake
index 3a6f796..17b8bc5 100644
--- a/cmake/FindGlog.cmake
+++ b/cmake/FindGlog.cmake
@@ -36,6 +36,9 @@
# GLOG_FOUND: TRUE iff glog is found.
# GLOG_INCLUDE_DIRS: Include directories for glog.
# GLOG_LIBRARIES: Libraries required to link glog.
+# FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION: True iff the version of glog found
+# was built & installed / exported
+# as a CMake package.
#
# The following variables control the behaviour of this module:
#