Fix Abseil usage of installed cmake-config

Fix the generated cmake-config file to look for the used Abseil-cpp
config files providing the needed targets.

When using Abseil from system (or locally installed and set via
`absl_DIR`) the used targets like `absl::log` need to be made available
in downstream projects using `ceres-solver`.

For system packages with no `absl_VERSION` info check for the required
target `absl::absl_vlog_is_on`, just like we do in `CMakeLists.txt`.

Error on installation/export of "no-absl-VERSION" as we can't check
version mismatches.

When using `abseil-cpp` as submodule the abseil-configs are added to the
install target as well. Use these config files to make the needed Abseil
targets available.

In the submodule case extract the `absl_VERSION` variable from its
`CMakeLists.txt` file for us to check against in the generated
cmake-config-file.

Fixes: https://github.com/ceres-solver/ceres-solver/issues/1089

Change-Id: I3e3d079ddf931e7fe1b57783471c32c19e4d31b6
This commit is contained in:
Reinhold Gschweicher
2024-09-09 11:54:34 +02:00
parent 8c740b83ee
commit a0dc19eb52
2 changed files with 49 additions and 1 deletions
+26 -1
View File
@@ -124,7 +124,23 @@ endif()
# Abseil
if (EXISTS "${Ceres_SOURCE_DIR}/third_party/abseil-cpp/CMakeLists.txt")
message("-- Using the version of abseil in ceres-solver/third_party/abseil-cpp")
# extract submodule absl_VERSION
file(STRINGS "${Ceres_SOURCE_DIR}/third_party/abseil-cpp/CMakeLists.txt" project_calls REGEX "[ \t]*project\\([ \t]*absl")
foreach(project_call IN LISTS project_calls)
string(REGEX MATCH "VERSION[ ]+([0-9]+(\.(rc)?[0-9]+)?)" version_param "${project_call}")
if (version_param)
set(absl_VERSION "${CMAKE_MATCH_1}")
message("-- Using the version of abseil in ceres-solver/third_party/abseil-cpp with version ${absl_VERSION}")
break ()
endif()
endforeach()
unset(project_calls)
unset(project_call)
unset(version_param)
if (NOT absl_VERSION)
message("-- Using the version of abseil in ceres-solver/third_party/abseil-cpp")
endif()
# In the normal course of things, we would not need the following constraint.
# However, if we do not set the standard, then std::basic_string_view is not
# available, which absl depends on and linking the test fails.
@@ -150,6 +166,8 @@ if (EXISTS "${Ceres_SOURCE_DIR}/third_party/abseil-cpp/CMakeLists.txt")
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
set(CERES_USE_SYSTEM_ABSL NO)
else()
message("-- ceres-solver/third_party/abseil-cpp is empty, so falling back to system installed abseil")
find_package(absl REQUIRED 20240116)
@@ -162,6 +180,13 @@ else()
message(FATAL_ERROR "The version of abseil installed on the system provides no version info and is missing TARGET 'absl::absl_vlog_is_on', need at least 20240116")
endif()
endif()
set(CERES_USE_SYSTEM_ABSL YES)
endif()
if (NOT absl_VERSION)
if (EXPORT_BUILD_DIR)
message(FATAL_ERROR "Cannot generate CeresConfig.cmake due to missing Abseil version. Using resulting package configuration will likely result in integration errors. Set absl_VERSION manually to disable this error message")
endif()
install (CODE [=[message (FATAL_ERROR "Cannot generate CeresConfig.cmake due to missing Abseil version. Using resulting package configuration will likely result in integration errors. Set absl_VERSION manually to disable this error message.")]=])
endif()
# Google Test
+23
View File
@@ -190,6 +190,29 @@ include(CMakeFindDependencyMacro)
# defined, and so CMake will assume that they refer to a library name and
# fail to link correctly.
# Abseil
set(_CERES_ABSL_VERSION @absl_VERSION@)
set(_CERES_USE_SYSTEM_ABSL @CERES_USE_SYSTEM_ABSL@)
if (_CERES_USE_SYSTEM_ABSL)
find_dependency(absl ${_CERES_ABSL_VERSION})
if (NOT absl_VERSION)
if (NOT TARGET absl::absl_vlog_is_on)
ceres_report_not_found("The version of abseil installed on the system "
"provides no version info and is missing TARGET 'absl::absl_vlog_is_on'")
endif ()
endif ()
else ()
# absl from submodule, configs installed with ceres-solver
get_filename_component(_ABSL_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_ABSL_IMPORT_PREFIX "${_ABSL_IMPORT_PREFIX}" PATH)
set(_ABSL_IMPORT_PREFIX "${_ABSL_IMPORT_PREFIX}/absl")
find_dependency(absl ${_CERES_ABSL_VERSION} HINTS "${_ABSL_IMPORT_PREFIX}")
endif ()
ceres_message(STATUS "Found required Ceres dependency: "
"absl version ${_CERES_ABSL_VERSION} in ${absl_DIR}")
unset(_CERES_ABSL_VERSION)
unset(_CERES_USE_SYSTEM_ABSL)
# Eigen.
# Flag set during configuration and build of Ceres.
set(CERES_EIGEN_VERSION @Eigen3_VERSION@)