Add the ability to use system installed versions of abseil and googletest

If the user has checked out the submodules in third_party, they will be
used, otherwise we will try and find the system installed versions of
these dependencies and use them if they are modern enough.

Change-Id: I52164bc48a6ea804b85cdda05fee9cb94632f6c0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7b926c5..529c99b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,41 +32,12 @@
 cmake_minimum_required(VERSION 3.16...3.29)
 project(Ceres C CXX)
 
-# NOTE: The following CMake variables (and those further below) must be applied
-# consistently to all targets in project to avoid visibility warnings by placing
-# the variables at the project top.
-
 # 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). Global variable can be overridden
 # by the user whereas target properties can be not.
 set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 
-# Abseil
-
-# 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.
-set(CMAKE_CXX_STANDARD 17)
-# Abseil does not handle symbol visibility correctly. As a workaround, we let it
-# expose all the symbols to avoid linker errors.
-set(CMAKE_CXX_VISIBILITY_PRESET default)
-# ABSL plans to enable this flag to be on by default in the future. If it is not
-# set, then it issues a warning. We force enable it, both to silence the warning
-# but to also be safe going forward.
-option(ABSL_PROPAGATE_CXX_STD "Use CMake C++ standard meta features
-(e.g. cxx_std_14) that propagate to targets that link to Abseil" ON)
-option(ABSL_ENABLE_INSTALL "Enable install rules" ON)
-add_subdirectory(third_party/abseil-cpp)
-unset(CMAKE_CXX_STANDARD)
-unset(CMAKE_CXX_VISIBILITY_PRESET)
-
-# Set the default symbol visibility to hidden to unify the behavior among
-# the various compilers and to get smaller binaries
-set(CMAKE_C_VISIBILITY_PRESET hidden)
-set(CMAKE_CXX_VISIBILITY_PRESET hidden)
-set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
-
 # NOTE: The 'generic' CMake variables CMAKE_[SOURCE/BINARY]_DIR should not be
 #       used.  Always use the project-specific variants (generated by CMake):
 #       <PROJECT_NAME_MATCHING_CASE>_[SOURCE/BINARY]_DIR, e.g.
@@ -151,6 +122,67 @@
   option(ANDROID_STRIP_DEBUG_SYMBOLS "Strip debug symbols from Android builds (reduces file sizes)" ON)
 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")
+  # 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.
+  set(CMAKE_CXX_STANDARD 17)
+  # Abseil does not handle symbol visibility correctly. As a workaround, we let it
+  # expose all the symbols to avoid linker errors.
+  set(CMAKE_CXX_VISIBILITY_PRESET default)
+  # ABSL plans to enable this flag to be on by default in the future. If it is not
+  # set, then it issues a warning. We force enable it, both to silence the warning
+  # but to also be safe going forward.
+
+  option(ABSL_PROPAGATE_CXX_STD "Use CMake C++ standard meta features
+  (e.g. cxx_std_14) that propagate to targets that link to Abseil" ON)
+  option(ABSL_ENABLE_INSTALL "Enable install rules" ON)
+
+  add_subdirectory(third_party/abseil-cpp)
+
+  unset(CMAKE_CXX_STANDARD)
+  unset(CMAKE_CXX_VISIBILITY_PRESET)
+
+  # Set the default symbol visibility to hidden to unify the behavior among
+  # the various compilers and to get smaller binaries
+  set(CMAKE_C_VISIBILITY_PRESET hidden)
+  set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+  set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
+else()
+  message("-- ceres-solver/third_party/abseil-cpp is empty, so falling back to system installed abseil")
+  find_package(absl REQUIRED)
+  message("-- Found abseil version ${absl_VERSION}: ${absl_DIR}")
+  # For some reason unknown to me having the version number in the
+  # find_package call fails. So we check for he minimum version
+  # manually.
+  if (absl_VERSION VERSION_LESS 20240116.2)
+    message(FATAL_ERROR "The version of abseil installed on the system is " ${absl_VERSION} " need at least 20240116.2")
+  endif()
+endif()
+
+# Google Test
+if (BUILD_TESTING)
+  if (EXISTS "${Ceres_SOURCE_DIR}/third_party/googletest/CMakeLists.txt")
+    message("-- Using the version of googletest in ceres-solver/third_party/googletest")
+    # Now that we have absl as a dependency, it would make sense to tell
+    # googletest to use absl also, but doing so seems to be problematic
+    # for now, since if there is a version of absl and re2 installed in
+    # the system then we start getting errors because we maybe using the
+    # absl from our submodule, but the re2 installed on the system only
+    # sees the absl installed on the system. It is possible that we will
+    # need to include re2 as a submodule also, for the following to
+    # work.
+
+    # set(GTEST_HAS_ABSL ON CACHE BOOL "Use ABSL when building gtest")
+    add_subdirectory(${Ceres_SOURCE_DIR}/third_party/googletest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/googletest)
+  else()
+    message("-- ceres-solver/third_party/googletest is empty, so falling back to system installed googletest")
+    find_package(GTest 1.14.0 REQUIRED)
+  endif()
+endif(BUILD_TESTING)
+
 # IOS is defined iff using the iOS.cmake CMake toolchain to build a static
 # library for iOS.
 if (IOS)
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index c997a4d..5331843 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -362,18 +362,6 @@
         ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
 if (BUILD_TESTING)
-  # Now that we have absl as a dependency, it would make sense to tell
-  # googletest to use absl also, but doing so seems to be problematic
-  # for now, since if there is a version of absl and re2 installed in
-  # the system then we start getting errors because we maybe using the
-  # absl from our submodule, but the re2 installed on the system only
-  # sees the absl installed on the system. It is possible that we will
-  # need to include re2 as a submodule also, for the following to
-  # work.
-
-  # set(GTEST_HAS_ABSL ON CACHE BOOL "Use ABSL when building gtest")
-  add_subdirectory(${Ceres_SOURCE_DIR}/third_party/googletest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/googletest)
-
   add_library(test_util STATIC
               evaluator_test_utils.cc
               numeric_diff_test_utils.cc