Take abseil as a dependency

1. Add abseil-cpp as a submodule. We are tracking the latest LTS
release, which is lts_2024_01_16.
2. Replace glog/gflags with absl::log and absl::flags.
3. Remove miniglog
4. Also take a whack at making the bazel build work with
   abseil-cpp and gtest.

There are a number of TODOs in this CL that still need to be resolved.

Change-Id: I39355ed7d61375be4ebcbc8596d9cc70acc1c678
diff --git a/.gitmodules b/.gitmodules
index 9b2afbe..e15103c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,7 @@
 	path = third_party/googletest
 	url = https://github.com/google/googletest.git
 	branch = v1.14.x
+[submodule "third_party/abseil-cpp"]
+	path = third_party/abseil-cpp
+	url = https://github.com/abseil/abseil-cpp
+	branch = lts_2024_01_16
diff --git a/BUILD b/BUILD
index 4b18cb9..386fc58 100644
--- a/BUILD
+++ b/BUILD
@@ -30,7 +30,6 @@
 #
 # These are Bazel rules to build Ceres. It's currently in Alpha state, and does
 # not support parameterization around threading choice or sparse backends.
-
 load("//:bazel/ceres.bzl", "ceres_library")
 
 ceres_library(
@@ -44,20 +43,10 @@
         "evaluator_test_utils.cc",
         "numeric_diff_test_utils.cc",
         "test_util.cc",
-        "gmock_gtest_all.cc",
-        "gmock_main.cc",
-        "gmock/gmock.h",
-        "gmock/mock-log.h",
-        "gtest/gtest.h",
     ]],
-    hdrs = [
-        "internal/ceres/gmock/gmock.h",
-        "internal/ceres/gmock/mock-log.h",
-        "internal/ceres/gtest/gtest.h",
-    ],
     copts = [
         "-Wno-sign-compare",
-        "-DCERES_TEST_SRCDIR_SUFFIX=\\\"data/\\\"",
+        "-DCERES_TEST_SRCDIR_SUFFIX=\\\"_main/data/\\\"",
     ],
     includes = [
         "internal",
@@ -65,7 +54,7 @@
     ],
     deps = [
         "//:ceres",
-        "@com_github_gflags_gflags//:gflags",
+        "@googletest//:gtest_main",
     ],
 )
 
@@ -156,22 +145,10 @@
     "visibility",
 ]
 
-TEST_COPTS = [
-    # Needed to silence GFlags complaints.
-    "-Wno-sign-compare",
-
-    # These two warnings don't work well in conjunction with GMock, and
-    # trigger incorrectly on parts of rotation_test. For now, disable them,
-    # but in the future disable these warnings only for rotation_test.
-    # TODO(keir): When the tests are macro-ified, apply these selectively.
-    "-Wno-address",
-]
-
 TEST_DEPS = [
     "//:ceres",
     "//:test_util",
-    "@com_gitlab_libeigen_eigen//:eigen",
-    "@com_github_gflags_gflags//:gflags",
+    "@eigen//:eigen",
 ]
 
 # Instantiate all the tests with a template.
@@ -179,7 +156,6 @@
     name = test_name + "_test",
     timeout = "short",
     srcs = ["internal/ceres/" + test_name + "_test.cc"],
-    copts = TEST_COPTS,
     deps = TEST_DEPS,
 ) for test_name in CERES_TESTS]
 
@@ -193,8 +169,6 @@
     name = test_filename.split("/")[-1][:-3],  # Remove .cc.
     timeout = "long",
     srcs = [test_filename],
-    copts = TEST_COPTS,
-
     # This is the data set that is bundled for the testing.
     data = [":data/problem-16-22106-pre.txt"],
     deps = TEST_DEPS,
@@ -206,9 +180,16 @@
 [cc_binary(
     name = benchmark_name,
     srcs = ["internal/ceres/" + benchmark_name + ".cc"],
-    copts = TEST_COPTS,
-    deps = TEST_DEPS + ["@com_github_google_benchmark//:benchmark"],
+    copts = ["-mllvm -inlinehint-threshold=1000000"],
+    deps = TEST_DEPS + ["@google_benchmark//:benchmark"],
+
 ) for benchmark_name in [
+    "evaluation_benchmark",
+    "invert_psd_matrix_benchmark",
+    "schur_eliminator_benchmark",
+    "jet_operator_benchmark",
+    "dense_linear_solver_benchmark",
+    "parallel_vector_operations_benchmark",
     "small_blas_gemm_benchmark",
     "small_blas_gemv_benchmark",
 ]]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b92437c..8986f44 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,12 @@
 cmake_minimum_required(VERSION 3.16...3.29)
 project(Ceres C CXX)
 
+# 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)
+
 # NOTE: The following CMake variables must be applied consistently to all
 # targets in project to avoid visibility warnings by placing the variables at
 # the project top.
@@ -94,8 +100,6 @@
 include(CMakeDependentOption)
 include(PrettyPrintCMakeList)
 
-option(MINIGLOG "Use a stripped down version of glog." OFF)
-option(GFLAGS "Enable Google Flags." ON)
 option(SUITESPARSE "Enable SuiteSparse." ON)
 if (APPLE)
   option(ACCELERATESPARSE
@@ -144,14 +148,10 @@
       "requires at least iOS version 7.0")
   endif()
 
-  update_cache_variable(MINIGLOG ON)
-  message(STATUS "Building for iOS: Forcing use of miniglog instead of glog.")
-
   # Apple claims that the BLAS call dsyrk_ is a private API, and will not allow
   # you to submit to the Apple Store if the symbol is present.
   update_cache_variable(LAPACK OFF)
-  message(STATUS "Building for iOS: SuiteSparse, LAPACK, gflags "
-    "are not available.")
+  message(STATUS "Building for iOS: SuiteSparse, LAPACK are not available.")
 
   update_cache_variable(BUILD_EXAMPLES OFF)
   message(STATUS "Building for iOS: Will not build examples.")
@@ -159,6 +159,23 @@
 
 unset(CERES_COMPILE_OPTIONS)
 
+# Abseil
+#
+# TODO: We are currently adding the submodule unconditionally. Going
+# foward, this should be replaced with a more sophisticated logic,
+# where we use the system installed version of abseil if it is more
+# recent than the version we are tracking. This will also affect how
+# we are installing ceres.
+
+# 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.
+set(ABSL_PROPAGATE_CXX_STD ON CACHE BOOL "Use CMake C++ standard meta
+features (e.g. cxx_std_14) that propagate to targets that link to
+Abseil")
+add_subdirectory(third_party/abseil-cpp)
+
+
 # Eigen.
 # Eigen delivers Eigen3Config.cmake since v3.3.3
 find_package(Eigen3 3.3 REQUIRED)
@@ -419,68 +436,6 @@
   message("  ================================================================")
 endif()
 
-# GFlags.
-if (GFLAGS)
-  # Don't search with REQUIRED as we can continue without gflags.
-  find_package(gflags 2.2.0)
-  if (gflags_FOUND)
-    if (TARGET gflags)
-      message("-- Found Google Flags (gflags) version ${gflags_VERSION}: ${gflags_DIR}")
-    else()
-      message("-- Detected version of gflags: ${gflags_VERSION} does not define "
-        "expected gflags CMake target which should be exported by gflags 2.2+. "
-        "Building without gflags.")
-      update_cache_variable(GFLAGS OFF)
-    endif()
-  else (gflags_FOUND)
-    message("-- Did not find Google Flags (gflags), Building without gflags.")
-    update_cache_variable(GFLAGS OFF)
-  endif (gflags_FOUND)
-endif()
-if (NOT GFLAGS)
-  message("-- Use of gflags disabled - no tests or tools will be built!")
-endif()
-
-# MiniGLog.
-if (MINIGLOG)
-  message("-- Compiling minimal glog substitute into Ceres.")
-  set(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
-  set(MINIGLOG_MAX_LOG_LEVEL 2 CACHE STRING "The maximum message severity level to be logged")
-  add_definitions("-DMAX_LOG_LEVEL=${MINIGLOG_MAX_LOG_LEVEL}")
-  message("-- Using minimal glog substitute (include): ${GLOG_INCLUDE_DIRS}")
-  message("-- Max log level for minimal glog substitute: ${MINIGLOG_MAX_LOG_LEVEL}")
-
-  # Mark as advanced (remove from default GUI view) the glog search
-  # variables in case user disables MINIGLOG, FindGlog did not find it, so
-  # made search variables visible in GUI for user to set, but then user enables
-  # MINIGLOG instead of setting them.
-  mark_as_advanced(FORCE GLOG_INCLUDE_DIR
-                         GLOG_LIBRARY)
-else (MINIGLOG)
-  unset(MINIGLOG_MAX_LOG_LEVEL CACHE)
-  # Don't search with REQUIRED so that configuration continues if not found and
-  # we can output an error messages explaining MINIGLOG option.
-  find_package(Glog)
-  if (NOT GLOG_FOUND)
-    message(FATAL_ERROR "Can't find Google Log (glog). Please set either: "
-      "glog_DIR (newer CMake built versions of glog) or GLOG_INCLUDE_DIR & "
-      "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
-      "implementation.")
-  endif(NOT GLOG_FOUND)
-  # By default, assume gflags was found, updating the message if it was not.
-  set(GLOG_GFLAGS_DEPENDENCY_MESSAGE
-    " Assuming glog was built with gflags support as gflags was found. "
-    "This will make gflags a public dependency of Ceres.")
-  if (NOT gflags_FOUND)
-    set(GLOG_GFLAGS_DEPENDENCY_MESSAGE
-      " Assuming glog was NOT built with gflags support as gflags was "
-      "not found.  If glog was built with gflags, please set the "
-      "gflags search locations such that it can be found by Ceres.  "
-      "Otherwise, Ceres may fail to link due to missing gflags symbols.")
-  endif(NOT gflags_FOUND)
-  message("-- Found Google Log (glog)." ${GLOG_GFLAGS_DEPENDENCY_MESSAGE})
-endif (MINIGLOG)
-
 if (NOT SCHUR_SPECIALIZATIONS)
   list(APPEND CERES_COMPILE_OPTIONS CERES_RESTRICT_SCHUR_SPECIALIZATION)
   message("-- Disabling Schur specializations (faster compiles)")
@@ -669,13 +624,6 @@
 install(DIRECTORY ${Ceres_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/
         DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 
-if (MINIGLOG)
-  # Install miniglog header if being used as logging #includes appear in
-  # installed public Ceres headers.
-  install(FILES ${Ceres_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
-          DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal/miniglog/glog)
-endif (MINIGLOG)
-
 # Ceres supports two mechanisms by which it can be detected & imported into
 # client code which uses CMake via find_package(Ceres):
 #
@@ -718,9 +666,12 @@
 # when read in by a client project as part of find_package(Ceres) creates
 # imported library targets for Ceres (with dependency relations) which can be
 # used in target_link_libraries() calls in the client project to use Ceres.
-install(EXPORT CeresExport
-        NAMESPACE Ceres::
-        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR} FILE CeresTargets.cmake)
+#
+# TODO: Re-enable this
+#
+#install(EXPORT CeresExport
+#        NAMESPACE Ceres::
+#        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR} FILE CeresTargets.cmake)
 
 # Save the relative path from the installed CeresConfig.cmake file to the
 # install prefix.  We do not save an absolute path in case the installed package
@@ -749,12 +700,6 @@
         DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
 install(FILES "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake"
         DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
-if (GLOG_FOUND AND NOT FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
-  # Version of glog detected was not built with CMake, install our glog module
-  # file to enable detection in CeresConfig.
-  install(FILES "${Ceres_SOURCE_DIR}/cmake/FindGlog.cmake"
-          DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
-endif()
 
 if (PROVIDE_UNINSTALL_TARGET)
   # Create an uninstall target to remove all installed files.
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..aedb0dd
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,6 @@
+# MODULE.bazel
+
+bazel_dep(name = "abseil-cpp", version = "20240116.2")
+bazel_dep(name = "googletest", version = "1.14.0")
+bazel_dep(name = "eigen", version = "3.4.0")
+bazel_dep(name = "google_benchmark", version = "1.8.4")
diff --git a/WORKSPACE b/WORKSPACE
index 40a84a3..4622d4e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -31,74 +31,3 @@
 # Bazel workspace file to enable building Ceres with Bazel.
 
 workspace(name = "com_google_ceres_solver")
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-# External dependency: Google Flags; has Bazel build already.
-http_archive(
-    name = "com_github_gflags_gflags",
-    sha256 = "6e16c8bc91b1310a44f3965e616383dbda48f83e8c1eaa2370a215057b00cabe",
-    strip_prefix = "gflags-77592648e3f3be87d6c7123eb81cbad75f9aef5a",
-    urls = [
-        "https://mirror.bazel.build/github.com/gflags/gflags/archive/77592648e3f3be87d6c7123eb81cbad75f9aef5a.tar.gz",
-        "https://github.com/gflags/gflags/archive/77592648e3f3be87d6c7123eb81cbad75f9aef5a.tar.gz",
-    ],
-)
-
-# External dependency: Google Log; has Bazel build already.
-http_archive(
-    name = "com_github_google_glog",
-    sha256 = "7083af285bed3995b5dc2c982f7de39bced9f0e6fd78d631f3285490922a0c3d",
-    strip_prefix = "glog-3106945d8d3322e5cbd5658d482c9ffed2d892c0",
-    urls = [
-        "https://github.com/drigz/glog/archive/3106945d8d3322e5cbd5658d482c9ffed2d892c0.tar.gz",
-    ],
-)
-
-# External dependency: Eigen; has no Bazel build.
-http_archive(
-    name = "com_gitlab_libeigen_eigen",
-    sha256 = "0215c6593c4ee9f1f7f28238c4e8995584ebf3b556e9dbf933d84feb98d5b9ef",
-    strip_prefix = "eigen-3.3.8",
-    urls = [
-        "https://gitlab.com/libeigen/eigen/-/archive/3.3.8/eigen-3.3.8.tar.bz2",
-    ],
-    build_file_content =
-"""
-# TODO(keir): Replace this with a better version, like from TensorFlow.
-# See https://github.com/ceres-solver/ceres-solver/issues/337.
-cc_library(
-    name = 'eigen',
-    srcs = [],
-    includes = ['.'],
-    hdrs = glob(['Eigen/**']),
-    visibility = ['//visibility:public'],
-)
-"""
-)
-
-# External dependency: Google Benchmark; has no Bazel build.
-http_archive(
-    name = "com_github_google_benchmark",
-    urls = ["https://github.com/google/benchmark/archive/56f52ee228783547f544d9ac4a533574b9010e3f.zip"],
-    sha256 = "8c1c6e90cd320b07504fabb86400f390faff2e599183ebd9396908817968ae79",
-    strip_prefix = "benchmark-56f52ee228783547f544d9ac4a533574b9010e3f",
-    build_file_content =
-"""
-cc_library(
-    name = "benchmark",
-    srcs = glob([
-        "src/*.h",
-        "src/*.cc",
-    ]),
-    hdrs = glob(["include/benchmark/*.h"]),
-    copts = [
-        "-DHAVE_STD_REGEX",
-    ],
-    includes = [
-        "include",
-    ],
-    visibility = ["//visibility:public"],
-)
-"""
-)
diff --git a/bazel/ceres.bzl b/bazel/ceres.bzl
index 2e5759e..b0e4c5c 100644
--- a/bazel/ceres.bzl
+++ b/bazel/ceres.bzl
@@ -140,14 +140,15 @@
 # TODO(rodrigoq): add support to configure Ceres into various permutations,
 # like SuiteSparse or not, threading or not, glog or not, and so on.
 # See https://github.com/ceres-solver/ceres-solver/issues/335.
-def ceres_library(name,
-                  restrict_schur_specializations=False):
+def ceres_library(
+        name,
+        restrict_schur_specializations = False):
     # The path to internal/ depends on whether Ceres is the main workspace or
     # an external repository.
-    if native.repository_name() != '@':
-        internal = 'external/%s/internal' % native.repository_name().lstrip('@')
+    if native.repository_name() != "@":
+        internal = "external/%s/internal" % native.repository_name().lstrip("@")
     else:
-        internal = 'internal'
+        internal = "internal"
 
     # The fixed-size Schur eliminator template instantiations incur a large
     # binary size penalty, and are slow to compile, so support disabling them.
@@ -185,11 +186,7 @@
                 "config/ceres/internal/config.h",
                 "config/ceres/internal/export.h",
             ]),
-        copts = [
-            "-I" + internal,
-            "-Wunused-parameter",
-            "-Wno-sign-compare",
-        ] + schur_eliminator_copts,
+        copts = schur_eliminator_copts,
 
         # These include directories and defines are propagated to other targets
         # depending on Ceres.
@@ -198,23 +195,26 @@
         # part of a Skylark Ceres target macro.
         # https://github.com/ceres-solver/ceres-solver/issues/396
         defines = [
-            "CERES_EXPORT=",
             "CERES_NO_ACCELERATE_SPARSE",
             "CERES_NO_CHOLMOD_PARTITION",
             "CERES_NO_CUDA",
+            "CERES_NO_CUDSS",
             "CERES_NO_EIGEN_METIS",
             "CERES_NO_EXPORT=",
             "CERES_NO_LAPACK",
             "CERES_NO_SUITESPARSE",
             "CERES_USE_EIGEN_SPARSE",
+            "CERES_EXPORT=",
         ],
         includes = [
             "config",
             "include",
+            "internal",
         ],
         visibility = ["//visibility:public"],
         deps = [
-            "@com_gitlab_libeigen_eigen//:eigen",
-            "@com_github_google_glog//:glog",
+            "@eigen//:eigen",
+            "@abseil-cpp//absl/log",
+            "@abseil-cpp//absl/log:check",
         ],
     )
diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in
index b929c82..4acc8cf 100644
--- a/cmake/CeresConfig.cmake.in
+++ b/cmake/CeresConfig.cmake.in
@@ -217,57 +217,6 @@
     "Eigen3_DIR.")
 endif (Eigen3_FOUND)
 
-# glog (and maybe gflags).
-#
-# Flags set during configuration and build of Ceres.
-set(CERES_USES_MINIGLOG @MINIGLOG@)
-set(CERES_GLOG_VERSION @glog_VERSION@)
-set(CERES_GLOG_WAS_BUILT_WITH_CMAKE @FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION@)
-
-set(CERES_USES_GFLAGS @GFLAGS@)
-set(CERES_GFLAGS_VERSION @gflags_VERSION@)
-
-if (CERES_USES_MINIGLOG)
-  # Output message at standard log level (not the lower STATUS) so that
-  # the message is output in GUI during configuration to warn user.
-  ceres_message("-- Found Ceres compiled with miniglog substitute "
-    "for glog, beware this will likely cause problems if glog is later linked.")
-else(CERES_USES_MINIGLOG)
-  if (CERES_GLOG_WAS_BUILT_WITH_CMAKE)
-    find_package(glog ${CERES_GLOG_VERSION} CONFIG QUIET)
-    set(GLOG_FOUND ${glog_FOUND})
-  else()
-    # Version of glog against which Ceres was built was not built with CMake,
-    # use the exported glog find_package() module from Ceres to find it again.
-    # 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})
-
-    # Search quietly s/t we control the timing of the error message if not found.
-    find_package(Glog QUIET)
-  endif()
-
-  if (GLOG_FOUND)
-    ceres_message(STATUS "Found required Ceres dependency: glog")
-  else()
-    ceres_report_not_found("Missing required Ceres dependency: glog.")
-  endif()
-
-  # gflags is only a public dependency of Ceres via glog, thus is not required
-  # if Ceres was built with MINIGLOG.
-  if (CERES_USES_GFLAGS)
-    # Search quietly s/t we control the timing of the error message if not found.
-    find_package(gflags ${CERES_GFLAGS_VERSION} QUIET)
-    if (gflags_FOUND AND TARGET gflags)
-      ceres_message(STATUS "Found required Ceres dependency: gflags")
-    else()
-      ceres_report_not_found("Missing required Ceres "
-        "dependency: gflags (not found, or not found as exported CMake target).")
-    endif()
-  endif()
-endif(CERES_USES_MINIGLOG)
-
 # Import exported Ceres targets, if they have not already been imported.
 if (NOT TARGET ceres AND NOT Ceres_BINARY_DIR)
   include(${CERES_CURRENT_CONFIG_DIR}/CeresTargets.cmake)
diff --git a/cmake/FindGlog.cmake b/cmake/FindGlog.cmake
deleted file mode 100644
index 2ef6914..0000000
--- a/cmake/FindGlog.cmake
+++ /dev/null
@@ -1,384 +0,0 @@
-# Ceres Solver - A fast non-linear least squares minimizer
-# Copyright 2023 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)
-#
-
-# FindGlog.cmake - Find Google glog logging library.
-#
-# This module defines the following variables:
-#
-# 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:
-#
-# GLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION: TRUE/FALSE, iff TRUE then
-#                           then prefer using an exported CMake configuration
-#                           generated by glog > 0.3.4 over searching for the
-#                           glog components manually.  Otherwise (FALSE)
-#                           ignore any exported glog CMake configurations and
-#                           always perform a manual search for the components.
-#                           Default: TRUE iff user does not define this variable
-#                           before we are called, and does NOT specify either
-#                           GLOG_INCLUDE_DIR_HINTS or GLOG_LIBRARY_DIR_HINTS
-#                           otherwise FALSE.
-# GLOG_INCLUDE_DIR_HINTS: List of additional directories in which to
-#                         search for glog includes, e.g: /timbuktu/include.
-# GLOG_LIBRARY_DIR_HINTS: List of additional directories in which to
-#                         search for glog libraries, e.g: /timbuktu/lib.
-#
-# The following variables are also defined by this module, but in line with
-# CMake recommended FindPackage() module style should NOT be referenced directly
-# by callers (use the plural variables detailed above instead).  These variables
-# do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which
-# are NOT re-called (i.e. search for library is not repeated) if these variables
-# are set with valid values _in the CMake cache_. This means that if these
-# variables are set directly in the cache, either by the user in the CMake GUI,
-# or by the user passing -DVAR=VALUE directives to CMake when called (which
-# explicitly defines a cache variable), then they will be used verbatim,
-# bypassing the HINTS variables and other hard-coded search locations.
-#
-# GLOG_INCLUDE_DIR: Include directory for glog, not including the
-#                   include directory of any dependencies.
-# GLOG_LIBRARY: glog library, not including the libraries of any
-#               dependencies.
-
-# Reset CALLERS_CMAKE_FIND_LIBRARY_PREFIXES to its value when
-# FindGlog was invoked.
-macro(GLOG_RESET_FIND_LIBRARY_PREFIX)
-  if (MSVC AND CALLERS_CMAKE_FIND_LIBRARY_PREFIXES)
-    set(CMAKE_FIND_LIBRARY_PREFIXES "${CALLERS_CMAKE_FIND_LIBRARY_PREFIXES}")
-  endif()
-endmacro(GLOG_RESET_FIND_LIBRARY_PREFIX)
-
-# Called if we failed to find glog or any of it's required dependencies,
-# unsets all public (designed to be used externally) variables and reports
-# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
-macro(GLOG_REPORT_NOT_FOUND REASON_MSG)
-  unset(GLOG_FOUND)
-  unset(GLOG_INCLUDE_DIRS)
-  unset(GLOG_LIBRARIES)
-  # Make results of search visible in the CMake GUI if glog has not
-  # been found so that user does not have to toggle to advanced view.
-  mark_as_advanced(CLEAR GLOG_INCLUDE_DIR
-                         GLOG_LIBRARY)
-
-  glog_reset_find_library_prefix()
-
-  # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
-  # use the camelcase library name, not uppercase.
-  if (Glog_FIND_QUIETLY)
-    message(STATUS "Failed to find glog - " ${REASON_MSG} ${ARGN})
-  elseif (Glog_FIND_REQUIRED)
-    message(FATAL_ERROR "Failed to find glog - " ${REASON_MSG} ${ARGN})
-  else()
-    # Neither QUIETLY nor REQUIRED, use no priority which emits a message
-    # but continues configuration and allows generation.
-    message("-- Failed to find glog - " ${REASON_MSG} ${ARGN})
-  endif ()
-  return()
-endmacro(GLOG_REPORT_NOT_FOUND)
-
-# glog_message([mode] "message text")
-#
-# Wraps the standard cmake 'message' command, but suppresses output
-# if the QUIET flag was passed to the find_package(Glog ...) call.
-function(GLOG_MESSAGE)
-  if (NOT Glog_FIND_QUIETLY)
-    message(${ARGN})
-  endif()
-endfunction()
-
-# Protect against any alternative find_package scripts for this library having
-# been called previously (in a client project) which set GLOG_FOUND, but not
-# the other variables we require / set here which could cause the search logic
-# here to fail.
-unset(GLOG_FOUND)
-
-# -----------------------------------------------------------------
-# By default, if the user has expressed no preference for using an exported
-# glog CMake configuration over performing a search for the installed
-# components, and has not specified any hints for the search locations, then
-# prefer a glog exported configuration if available.
-if (NOT DEFINED GLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION
-    AND NOT GLOG_INCLUDE_DIR_HINTS
-    AND NOT GLOG_LIBRARY_DIR_HINTS)
-  glog_message(STATUS "No preference for use of exported glog CMake "
-    "configuration set, and no hints for include/library directories provided. "
-    "Defaulting to preferring an installed/exported glog CMake configuration "
-    "if available.")
-  set(GLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION TRUE)
-endif()
-
-# On macOS, add the Homebrew prefix (with appropriate suffixes) to the
-# respective HINTS directories (after any user-specified locations).  This
-# handles Homebrew installations into non-standard locations (not /usr/local).
-# We do not use CMAKE_PREFIX_PATH for this as given the search ordering of
-# find_xxx(), doing so would override any user-specified HINTS locations with
-# the Homebrew version if it exists.
-if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
-  find_program(HOMEBREW_EXECUTABLE brew)
-  mark_as_advanced(FORCE HOMEBREW_EXECUTABLE)
-  if (HOMEBREW_EXECUTABLE)
-    # Detected a Homebrew install, query for its install prefix.
-    execute_process(COMMAND ${HOMEBREW_EXECUTABLE} --prefix
-      OUTPUT_VARIABLE HOMEBREW_INSTALL_PREFIX
-      OUTPUT_STRIP_TRAILING_WHITESPACE)
-    glog_message(STATUS "Detected Homebrew with install prefix: "
-      "${HOMEBREW_INSTALL_PREFIX}, adding to CMake search paths.")
-    list(APPEND GLOG_INCLUDE_DIR_HINTS "${HOMEBREW_INSTALL_PREFIX}/include")
-    list(APPEND GLOG_LIBRARY_DIR_HINTS "${HOMEBREW_INSTALL_PREFIX}/lib")
-  endif()
-endif()
-
-if (GLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION)
-  # Try to find an exported CMake configuration for glog, as generated by
-  # glog versions > 0.3.4
-  #
-  # We search twice, s/t we can invert the ordering of precedence used by
-  # find_package() for exported package build directories, and installed
-  # packages (found via CMAKE_SYSTEM_PREFIX_PATH), listed as items 6) and 7)
-  # respectively in [1].
-  #
-  # By default, exported build directories are (in theory) detected first, and
-  # this is usually the case on Windows.  However, on OS X & Linux, the install
-  # path (/usr/local) is typically present in the PATH environment variable
-  # which is checked in item 4) in [1] (i.e. before both of the above, unless
-  # NO_SYSTEM_ENVIRONMENT_PATH is passed).  As such on those OSs installed
-  # packages are usually detected in preference to exported package build
-  # directories.
-  #
-  # To ensure a more consistent response across all OSs, and as users usually
-  # want to prefer an installed version of a package over a locally built one
-  # where both exist (esp. as the exported build directory might be removed
-  # after installation), we first search with NO_CMAKE_PACKAGE_REGISTRY which
-  # means any build directories exported by the user are ignored, and thus
-  # installed directories are preferred.  If this fails to find the package
-  # we then research again, but without NO_CMAKE_PACKAGE_REGISTRY, so any
-  # exported build directories will now be detected.
-  #
-  # To prevent confusion on Windows, we also pass NO_CMAKE_BUILDS_PATH (which
-  # is item 5) in [1]), to not preferentially use projects that were built
-  # recently with the CMake GUI to ensure that we always prefer an installed
-  # version if available.
-  #
-  # NOTE: We use the NAMES option as glog erroneously uses 'google-glog' as its
-  #       project name when built with CMake, but exports itself as just 'glog'.
-  #       On Linux/OS X this does not break detection as the project name is
-  #       not used as part of the install path for the CMake package files,
-  #       e.g. /usr/local/lib/cmake/glog, where the <glog> suffix is hardcoded
-  #       in glog's CMakeLists.  However, on Windows the project name *is*
-  #       part of the install prefix: C:/Program Files/google-glog/[include,lib].
-  #       However, by default CMake checks:
-  #       C:/Program Files/<FIND_PACKAGE_ARGUMENT_NAME='glog'> which does not
-  #       exist and thus detection fails.  Thus we use the NAMES to force the
-  #       search to use both google-glog & glog.
-  #
-  # [1] http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:find_package
-  find_package(glog QUIET
-                    NAMES google-glog glog
-                    HINTS ${glog_DIR} ${HOMEBREW_INSTALL_PREFIX}
-                    NO_MODULE
-                    NO_CMAKE_PACKAGE_REGISTRY
-                    NO_CMAKE_BUILDS_PATH)
-  if (glog_FOUND)
-    glog_message(STATUS "Found installed version of glog: ${glog_DIR}")
-  else()
-    # Failed to find an installed version of glog, repeat search allowing
-    # exported build directories.
-    glog_message(STATUS "Failed to find installed glog CMake configuration, "
-      "searching for glog build directories exported with CMake.")
-    # Again pass NO_CMAKE_BUILDS_PATH, as we know that glog is exported and
-    # do not want to treat projects built with the CMake GUI preferentially.
-    find_package(glog QUIET
-                      NAMES google-glog glog
-                      NO_MODULE
-                      NO_CMAKE_BUILDS_PATH)
-    if (glog_FOUND)
-      glog_message(STATUS "Found exported glog build directory: ${glog_DIR}")
-    endif(glog_FOUND)
-  endif(glog_FOUND)
-
-  set(FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION ${glog_FOUND})
-
-  if (FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
-    glog_message(STATUS "Detected glog version: ${glog_VERSION}")
-    set(GLOG_FOUND ${glog_FOUND})
-    # glog wraps the include directories into the exported glog::glog target.
-    set(GLOG_INCLUDE_DIR "")
-    set(GLOG_LIBRARY glog::glog)
-  else (FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
-    glog_message(STATUS "Failed to find an installed/exported CMake "
-      "configuration for glog, will perform search for installed glog "
-      "components.")
-  endif (FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
-endif(GLOG_PREFER_EXPORTED_GLOG_CMAKE_CONFIGURATION)
-
-if (NOT GLOG_FOUND)
-  # Either failed to find an exported glog CMake configuration, or user
-  # told us not to use one.  Perform a manual search for all glog components.
-
-  # Handle possible presence of lib prefix for libraries on MSVC, see
-  # also GLOG_RESET_FIND_LIBRARY_PREFIX().
-  if (MSVC)
-    # Preserve the caller's original values for CMAKE_FIND_LIBRARY_PREFIXES
-    # s/t we can set it back before returning.
-    set(CALLERS_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
-    # The empty string in this list is important, it represents the case when
-    # the libraries have no prefix (shared libraries / DLLs).
-    set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "" "${CMAKE_FIND_LIBRARY_PREFIXES}")
-  endif (MSVC)
-
-  # Search user-installed locations first, so that we prefer user installs
-  # to system installs where both exist.
-  list(APPEND GLOG_CHECK_INCLUDE_DIRS
-    /usr/local/include
-    /usr/local/homebrew/include # Mac OS X
-    /opt/local/var/macports/software # Mac OS X.
-    /opt/local/include
-    /usr/include)
-  # Windows (for C:/Program Files prefix).
-  list(APPEND GLOG_CHECK_PATH_SUFFIXES
-    glog/include
-    glog/Include
-    Glog/include
-    Glog/Include
-    google-glog/include # CMake installs with project name prefix.
-    google-glog/Include)
-
-  list(APPEND GLOG_CHECK_LIBRARY_DIRS
-    /usr/local/lib
-    /usr/local/homebrew/lib # Mac OS X.
-    /opt/local/lib
-    /usr/lib)
-  # Windows (for C:/Program Files prefix).
-  list(APPEND GLOG_CHECK_LIBRARY_SUFFIXES
-    glog/lib
-    glog/Lib
-    Glog/lib
-    Glog/Lib
-    google-glog/lib # CMake installs with project name prefix.
-    google-glog/Lib)
-
-  # Search supplied hint directories first if supplied.
-  find_path(GLOG_INCLUDE_DIR
-    NAMES glog/logging.h
-    HINTS ${GLOG_INCLUDE_DIR_HINTS}
-    PATHS ${GLOG_CHECK_INCLUDE_DIRS}
-    PATH_SUFFIXES ${GLOG_CHECK_PATH_SUFFIXES})
-  if (NOT GLOG_INCLUDE_DIR OR
-      NOT EXISTS ${GLOG_INCLUDE_DIR})
-    glog_report_not_found(
-      "Could not find glog include directory, set GLOG_INCLUDE_DIR "
-      "to directory containing glog/logging.h")
-  endif (NOT GLOG_INCLUDE_DIR OR
-    NOT EXISTS ${GLOG_INCLUDE_DIR})
-
-  find_library(GLOG_LIBRARY NAMES glog
-    HINTS ${GLOG_LIBRARY_DIR_HINTS}
-    PATHS ${GLOG_CHECK_LIBRARY_DIRS}
-    PATH_SUFFIXES ${GLOG_CHECK_LIBRARY_SUFFIXES})
-  if (NOT GLOG_LIBRARY OR
-      NOT EXISTS ${GLOG_LIBRARY})
-    glog_report_not_found(
-      "Could not find glog library, set GLOG_LIBRARY "
-      "to full path to libglog.")
-  endif (NOT GLOG_LIBRARY OR
-    NOT EXISTS ${GLOG_LIBRARY})
-
-  # Mark internally as found, then verify. GLOG_REPORT_NOT_FOUND() unsets
-  # if called.
-  set(GLOG_FOUND TRUE)
-
-  # Glog does not seem to provide any record of the version in its
-  # source tree, thus cannot extract version.
-
-  # Catch case when caller has set GLOG_INCLUDE_DIR in the cache / GUI and
-  # thus FIND_[PATH/LIBRARY] are not called, but specified locations are
-  # invalid, otherwise we would report the library as found.
-  if (GLOG_INCLUDE_DIR AND
-      NOT EXISTS ${GLOG_INCLUDE_DIR}/glog/logging.h)
-    glog_report_not_found(
-      "Caller defined GLOG_INCLUDE_DIR:"
-      " ${GLOG_INCLUDE_DIR} does not contain glog/logging.h header.")
-  endif (GLOG_INCLUDE_DIR AND
-    NOT EXISTS ${GLOG_INCLUDE_DIR}/glog/logging.h)
-  # TODO: This regex for glog library is pretty primitive, we use lowercase
-  #       for comparison to handle Windows using CamelCase library names, could
-  #       this check be better?
-  string(TOLOWER "${GLOG_LIBRARY}" LOWERCASE_GLOG_LIBRARY)
-  if (GLOG_LIBRARY AND
-      NOT "${LOWERCASE_GLOG_LIBRARY}" MATCHES ".*glog[^/]*")
-    glog_report_not_found(
-      "Caller defined GLOG_LIBRARY: "
-      "${GLOG_LIBRARY} does not match glog.")
-  endif (GLOG_LIBRARY AND
-    NOT "${LOWERCASE_GLOG_LIBRARY}" MATCHES ".*glog[^/]*")
-
-  # add glog::glog target
-  add_library(glog::glog INTERFACE IMPORTED)
-  target_include_directories(glog::glog INTERFACE ${GLOG_INCLUDE_DIRS})
-  target_link_libraries(glog::glog INTERFACE ${GLOG_LIBRARY})
-
-  glog_reset_find_library_prefix()
-
-endif(NOT GLOG_FOUND)
-
-# Set standard CMake FindPackage variables if found.
-if (GLOG_FOUND)
-  set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
-  set(GLOG_LIBRARIES ${GLOG_LIBRARY})
-endif (GLOG_FOUND)
-
-# If we are using an exported CMake glog target, the include directories are
-# wrapped into the target itself, and do not have to be (and are not)
-# separately specified.  In which case, we should not add GLOG_INCLUDE_DIRS
-# to the list of required variables in order that glog be reported as found.
-if (FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
-  set(GLOG_REQUIRED_VARIABLES GLOG_LIBRARIES)
-else()
-  set(GLOG_REQUIRED_VARIABLES GLOG_INCLUDE_DIRS GLOG_LIBRARIES)
-endif()
-
-# Handle REQUIRED / QUIET optional arguments.
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Glog DEFAULT_MSG
-  ${GLOG_REQUIRED_VARIABLES})
-
-# Only mark internal variables as advanced if we found glog, otherwise
-# leave them visible in the standard GUI for the user to set manually.
-if (GLOG_FOUND)
-  mark_as_advanced(FORCE GLOG_INCLUDE_DIR
-                         GLOG_LIBRARY
-                         glog_DIR) # Autogenerated by find_package(glog)
-endif (GLOG_FOUND)
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 8af2077..27a903c 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -29,28 +29,28 @@
 # Author: keir@google.com (Keir Mierle)
 
 add_executable(helloworld helloworld.cc)
-target_link_libraries(helloworld PRIVATE Ceres::ceres)
+target_link_libraries(helloworld PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(helloworld_numeric_diff helloworld_numeric_diff.cc)
-target_link_libraries(helloworld_numeric_diff PRIVATE Ceres::ceres)
+target_link_libraries(helloworld_numeric_diff PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(helloworld_analytic_diff helloworld_analytic_diff.cc)
-target_link_libraries(helloworld_analytic_diff PRIVATE Ceres::ceres)
+target_link_libraries(helloworld_analytic_diff PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(curve_fitting curve_fitting.cc)
-target_link_libraries(curve_fitting PRIVATE Ceres::ceres)
+target_link_libraries(curve_fitting PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(rosenbrock rosenbrock.cc)
-target_link_libraries(rosenbrock PRIVATE Ceres::ceres)
+target_link_libraries(rosenbrock PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(rosenbrock_analytic_diff rosenbrock_analytic_diff.cc)
-target_link_libraries(rosenbrock_analytic_diff PRIVATE Ceres::ceres)
+target_link_libraries(rosenbrock_analytic_diff PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(rosenbrock_numeric_diff rosenbrock_numeric_diff.cc)
-target_link_libraries(rosenbrock_numeric_diff PRIVATE Ceres::ceres)
+target_link_libraries(rosenbrock_numeric_diff PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(curve_fitting_c curve_fitting.c)
-target_link_libraries(curve_fitting_c PRIVATE Ceres::ceres)
+target_link_libraries(curve_fitting_c PRIVATE absl::log_initialize Ceres::ceres)
 # Force CMake to link curve_fitting_c using the C++ linker.
 set_target_properties(curve_fitting_c PROPERTIES LINKER_LANGUAGE CXX)
 # As this is a C file #including <math.h> we have to explicitly add the math
@@ -61,64 +61,64 @@
 endif (HAVE_LIBM)
 
 add_executable(ellipse_approximation ellipse_approximation.cc)
-target_link_libraries(ellipse_approximation PRIVATE Ceres::ceres)
+target_link_libraries(ellipse_approximation PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(robust_curve_fitting robust_curve_fitting.cc)
-target_link_libraries(robust_curve_fitting PRIVATE Ceres::ceres)
+target_link_libraries(robust_curve_fitting PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(simple_bundle_adjuster simple_bundle_adjuster.cc)
-target_link_libraries(simple_bundle_adjuster PRIVATE Ceres::ceres)
+target_link_libraries(simple_bundle_adjuster PRIVATE absl::log_initialize Ceres::ceres )
 
 add_executable(bicubic_interpolation bicubic_interpolation.cc)
-target_link_libraries(bicubic_interpolation PRIVATE Ceres::ceres)
+target_link_libraries(bicubic_interpolation PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(bicubic_interpolation_analytic bicubic_interpolation_analytic.cc)
-target_link_libraries(bicubic_interpolation_analytic PRIVATE Ceres::ceres)
+target_link_libraries(bicubic_interpolation_analytic PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(iteration_callback_example iteration_callback_example.cc)
-target_link_libraries(iteration_callback_example PRIVATE Ceres::ceres)
+target_link_libraries(iteration_callback_example PRIVATE absl::log_initialize Ceres::ceres)
 
 add_executable(evaluation_callback_example evaluation_callback_example.cc)
-target_link_libraries(evaluation_callback_example PRIVATE Ceres::ceres)
+target_link_libraries(evaluation_callback_example PRIVATE absl::log_initialize Ceres::ceres)
 
-if (GFLAGS)
-  add_executable(powell powell.cc)
-  target_link_libraries(powell PRIVATE Ceres::ceres gflags)
 
-  add_executable(nist nist.cc)
-  target_link_libraries(nist PRIVATE Ceres::ceres gflags)
-  if (HAVE_BIGOBJ)
-    target_compile_options(nist PRIVATE /bigobj)
-  endif()
+add_executable(powell powell.cc)
+target_link_libraries(powell PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
 
-  add_executable(more_garbow_hillstrom more_garbow_hillstrom.cc)
-  target_link_libraries(more_garbow_hillstrom PRIVATE Ceres::ceres gflags)
+add_executable(nist nist.cc)
+target_link_libraries(nist PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
+if (HAVE_BIGOBJ)
+  target_compile_options(nist PRIVATE /bigobj)
+endif()
 
-  add_executable(circle_fit circle_fit.cc)
-  target_link_libraries(circle_fit PRIVATE Ceres::ceres gflags)
+add_executable(more_garbow_hillstrom more_garbow_hillstrom.cc)
+target_link_libraries(more_garbow_hillstrom PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
 
-  add_executable(bundle_adjuster
-                 bundle_adjuster.cc
-                 bal_problem.cc)
-  target_link_libraries(bundle_adjuster PRIVATE Ceres::ceres gflags)
+add_executable(circle_fit circle_fit.cc)
+target_link_libraries(circle_fit PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
 
-  add_executable(libmv_bundle_adjuster
-                 libmv_bundle_adjuster.cc)
-  target_link_libraries(libmv_bundle_adjuster PRIVATE Ceres::ceres gflags)
+add_executable(bundle_adjuster
+  bundle_adjuster.cc
+  bal_problem.cc)
+target_link_libraries(bundle_adjuster PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
 
-  add_executable(libmv_homography
-                 libmv_homography.cc)
-  target_link_libraries(libmv_homography PRIVATE Ceres::ceres gflags)
+add_executable(libmv_bundle_adjuster
+  libmv_bundle_adjuster.cc)
+target_link_libraries(libmv_bundle_adjuster PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
 
-  add_executable(denoising
-                 denoising.cc
-                 fields_of_experts.cc)
-  target_link_libraries(denoising PRIVATE Ceres::ceres gflags)
+add_executable(libmv_homography
+  libmv_homography.cc)
+target_link_libraries(libmv_homography PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
 
-  add_executable(robot_pose_mle
-                 robot_pose_mle.cc)
-  target_link_libraries(robot_pose_mle PRIVATE Ceres::ceres gflags)
-endif (GFLAGS)
+add_executable(denoising
+  denoising.cc
+  fields_of_experts.cc)
+target_link_libraries(denoising PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
+
+add_executable(robot_pose_mle
+  robot_pose_mle.cc)
+target_link_libraries(robot_pose_mle PRIVATE absl::log_initialize absl::flags absl::flags_parse Ceres::ceres)
+
 
 add_subdirectory(sampled_function)
 add_subdirectory(slam)
diff --git a/examples/bal_problem.cc b/examples/bal_problem.cc
index ccf7449..d6cb2b7 100644
--- a/examples/bal_problem.cc
+++ b/examples/bal_problem.cc
@@ -39,8 +39,9 @@
 #include <vector>
 
 #include "Eigen/Core"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/rotation.h"
-#include "glog/logging.h"
 
 namespace ceres::examples {
 namespace {
diff --git a/examples/bicubic_interpolation.cc b/examples/bicubic_interpolation.cc
index 21b3c7e..a5f4f19 100644
--- a/examples/bicubic_interpolation.cc
+++ b/examples/bicubic_interpolation.cc
@@ -39,9 +39,10 @@
 
 #include <utility>
 
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
 #include "ceres/cubic_interpolation.h"
-#include "glog/logging.h"
 
 using Grid = ceres::Grid2D<double>;
 using Interpolator = ceres::BiCubicInterpolator<Grid>;
@@ -87,7 +88,7 @@
 }
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
   // Problem sizes
   const int kGridRowsHalf = 9;
   const int kGridColsHalf = 11;
diff --git a/examples/bicubic_interpolation_analytic.cc b/examples/bicubic_interpolation_analytic.cc
index 4b79d56..716b4c8 100644
--- a/examples/bicubic_interpolation_analytic.cc
+++ b/examples/bicubic_interpolation_analytic.cc
@@ -39,9 +39,10 @@
 
 #include <utility>
 
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
 #include "ceres/cubic_interpolation.h"
-#include "glog/logging.h"
 
 using Grid = ceres::Grid2D<double>;
 using Interpolator = ceres::BiCubicInterpolator<Grid>;
@@ -98,7 +99,7 @@
 }
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
   // Problem sizes
   const int kGridRowsHalf = 9;
   const int kGridColsHalf = 11;
diff --git a/examples/bundle_adjuster.cc b/examples/bundle_adjuster.cc
index 8df0d8a..ecec6bf 100644
--- a/examples/bundle_adjuster.cc
+++ b/examples/bundle_adjuster.cc
@@ -60,85 +60,88 @@
 #include <thread>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "bal_problem.h"
 #include "ceres/ceres.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "snavely_reprojection_error.h"
 
 // clang-format makes the gflags definitions too verbose
 // clang-format off
 
-DEFINE_string(input, "", "Input File name");
-DEFINE_string(trust_region_strategy, "levenberg_marquardt",
+ABSL_FLAG(std::string, input, "", "Input File name");
+ABSL_FLAG(std::string, trust_region_strategy, "levenberg_marquardt",
               "Options are: levenberg_marquardt, dogleg.");
-DEFINE_string(dogleg, "traditional_dogleg", "Options are: traditional_dogleg,"
+ABSL_FLAG(std::string, dogleg, "traditional_dogleg", "Options are: traditional_dogleg,"
               "subspace_dogleg.");
 
-DEFINE_bool(inner_iterations, false, "Use inner iterations to non-linearly "
+ABSL_FLAG(bool, inner_iterations, false, "Use inner iterations to non-linearly "
             "refine each successful trust region step.");
 
-DEFINE_string(blocks_for_inner_iterations, "automatic", "Options are: "
+ABSL_FLAG(std::string, blocks_for_inner_iterations, "automatic", "Options are: "
               "automatic, cameras, points, cameras,points, points,cameras");
 
-DEFINE_string(linear_solver, "sparse_schur", "Options are: "
+ABSL_FLAG(std::string, linear_solver, "sparse_schur", "Options are: "
               "sparse_schur, dense_schur, iterative_schur, "
               "sparse_normal_cholesky, dense_qr, dense_normal_cholesky, "
               "and cgnr.");
-DEFINE_bool(explicit_schur_complement, false, "If using ITERATIVE_SCHUR "
+ABSL_FLAG(bool, explicit_schur_complement, false, "If using ITERATIVE_SCHUR "
             "then explicitly compute the Schur complement.");
-DEFINE_string(preconditioner, "jacobi", "Options are: "
+ABSL_FLAG(std::string, preconditioner, "jacobi", "Options are: "
               "identity, jacobi, schur_jacobi, schur_power_series_expansion, cluster_jacobi, "
               "cluster_tridiagonal.");
-DEFINE_string(visibility_clustering, "canonical_views",
+ABSL_FLAG(std::string, visibility_clustering, "canonical_views",
               "single_linkage, canonical_views");
-DEFINE_bool(use_spse_initialization, false,
+ABSL_FLAG(bool, use_spse_initialization, false,
             "Use power series expansion to initialize the solution in ITERATIVE_SCHUR linear solver.");
 
-DEFINE_string(sparse_linear_algebra_library, "suite_sparse",
+ABSL_FLAG(std::string, sparse_linear_algebra_library, "suite_sparse",
               "Options are: suite_sparse, accelerate_sparse, eigen_sparse and cuda_sparse");
-DEFINE_string(dense_linear_algebra_library, "eigen",
+ABSL_FLAG(std::string, dense_linear_algebra_library, "eigen",
               "Options are: eigen, lapack, and cuda");
-DEFINE_string(ordering_type, "amd", "Options are: amd, nesdis");
-DEFINE_string(linear_solver_ordering, "user",
+ABSL_FLAG(std::string, ordering_type, "amd", "Options are: amd, nesdis");
+ABSL_FLAG(std::string, linear_solver_ordering, "user",
               "Options are: automatic and user");
 
-DEFINE_bool(use_quaternions, false, "If true, uses quaternions to represent "
+ABSL_FLAG(bool, use_quaternions, false, "If true, uses quaternions to represent "
             "rotations. If false, angle axis is used.");
-DEFINE_bool(use_manifolds, false, "For quaternions, use a manifold.");
-DEFINE_bool(robustify, false, "Use a robust loss function.");
+ABSL_FLAG(bool, use_manifolds, false, "For quaternions, use a manifold.");
+ABSL_FLAG(bool, robustify, false, "Use a robust loss function.");
 
-DEFINE_double(eta, 1e-2, "Default value for eta. Eta determines the "
+ABSL_FLAG(double, eta, 1e-2, "Default value for eta. Eta determines the "
               "accuracy of each linear solve of the truncated newton step. "
               "Changing this parameter can affect solve performance.");
 
-DEFINE_int32(num_threads, -1, "Number of threads. -1 = std::thread::hardware_concurrency.");
-DEFINE_int32(num_iterations, 5, "Number of iterations.");
-DEFINE_int32(max_linear_solver_iterations, 500, "Maximum number of iterations"
+ABSL_FLAG(int32_t, num_threads, -1, "Number of threads. -1 = std::thread::hardware_concurrency.");
+ABSL_FLAG(int32_t, num_iterations, 5, "Number of iterations.");
+ABSL_FLAG(int32_t, max_linear_solver_iterations, 500, "Maximum number of iterations"
             " for solution of linear system.");
-DEFINE_double(spse_tolerance, 0.1,
+ABSL_FLAG(double, spse_tolerance, 0.1,
              "Tolerance to reach during the iterations of power series expansion initialization or preconditioning.");
-DEFINE_int32(max_num_spse_iterations, 5,
+ABSL_FLAG(int32_t, max_num_spse_iterations, 5,
              "Maximum number of iterations for power series expansion initialization or preconditioning.");
-DEFINE_double(max_solver_time, 1e32, "Maximum solve time in seconds.");
-DEFINE_bool(nonmonotonic_steps, false, "Trust region algorithm can use"
+ABSL_FLAG(double, max_solver_time, 1e32, "Maximum solve time in seconds.");
+ABSL_FLAG(bool, nonmonotonic_steps, false, "Trust region algorithm can use"
             " nonmonotic steps.");
 
-DEFINE_double(rotation_sigma, 0.0, "Standard deviation of camera rotation "
+ABSL_FLAG(double, rotation_sigma, 0.0, "Standard deviation of camera rotation "
               "perturbation.");
-DEFINE_double(translation_sigma, 0.0, "Standard deviation of the camera "
+ABSL_FLAG(double, translation_sigma, 0.0, "Standard deviation of the camera "
               "translation perturbation.");
-DEFINE_double(point_sigma, 0.0, "Standard deviation of the point "
+ABSL_FLAG(double, point_sigma, 0.0, "Standard deviation of the point "
               "perturbation.");
-DEFINE_int32(random_seed, 38401, "Random seed used to set the state "
+ABSL_FLAG(int32_t, random_seed, 38401, "Random seed used to set the state "
              "of the pseudo random number generator used to generate "
              "the perturbations.");
-DEFINE_bool(line_search, false, "Use a line search instead of trust region "
+ABSL_FLAG(bool, line_search, false, "Use a line search instead of trust region "
             "algorithm.");
-DEFINE_bool(mixed_precision_solves, false, "Use mixed precision solves.");
-DEFINE_int32(max_num_refinement_iterations, 0, "Iterative refinement iterations");
-DEFINE_string(initial_ply, "", "Export the BAL file data as a PLY file.");
-DEFINE_string(final_ply, "", "Export the refined BAL file data as a PLY "
+ABSL_FLAG(bool, mixed_precision_solves, false, "Use mixed precision solves.");
+ABSL_FLAG(int32_t, max_num_refinement_iterations, 0, "Iterative refinement iterations");
+ABSL_FLAG(std::string, initial_ply, "", "Export the BAL file data as a PLY file.");
+ABSL_FLAG(std::string, final_ply, "", "Export the refined BAL file data as a PLY "
               "file.");
 // clang-format on
 
@@ -146,35 +149,35 @@
 namespace {
 
 void SetLinearSolver(Solver::Options* options) {
-  CHECK(StringToLinearSolverType(CERES_GET_FLAG(FLAGS_linear_solver),
+  CHECK(StringToLinearSolverType(absl::GetFlag(FLAGS_linear_solver),
                                  &options->linear_solver_type));
-  CHECK(StringToPreconditionerType(CERES_GET_FLAG(FLAGS_preconditioner),
+  CHECK(StringToPreconditionerType(absl::GetFlag(FLAGS_preconditioner),
                                    &options->preconditioner_type));
   CHECK(StringToVisibilityClusteringType(
-      CERES_GET_FLAG(FLAGS_visibility_clustering),
+      absl::GetFlag(FLAGS_visibility_clustering),
       &options->visibility_clustering_type));
   CHECK(StringToSparseLinearAlgebraLibraryType(
-      CERES_GET_FLAG(FLAGS_sparse_linear_algebra_library),
+      absl::GetFlag(FLAGS_sparse_linear_algebra_library),
       &options->sparse_linear_algebra_library_type));
   CHECK(StringToDenseLinearAlgebraLibraryType(
-      CERES_GET_FLAG(FLAGS_dense_linear_algebra_library),
+      absl::GetFlag(FLAGS_dense_linear_algebra_library),
       &options->dense_linear_algebra_library_type));
   CHECK(
-      StringToLinearSolverOrderingType(CERES_GET_FLAG(FLAGS_ordering_type),
+      StringToLinearSolverOrderingType(absl::GetFlag(FLAGS_ordering_type),
                                        &options->linear_solver_ordering_type));
   options->use_explicit_schur_complement =
-      CERES_GET_FLAG(FLAGS_explicit_schur_complement);
+      absl::GetFlag(FLAGS_explicit_schur_complement);
   options->use_mixed_precision_solves =
-      CERES_GET_FLAG(FLAGS_mixed_precision_solves);
+      absl::GetFlag(FLAGS_mixed_precision_solves);
   options->max_num_refinement_iterations =
-      CERES_GET_FLAG(FLAGS_max_num_refinement_iterations);
+      absl::GetFlag(FLAGS_max_num_refinement_iterations);
   options->max_linear_solver_iterations =
-      CERES_GET_FLAG(FLAGS_max_linear_solver_iterations);
+      absl::GetFlag(FLAGS_max_linear_solver_iterations);
   options->use_spse_initialization =
-      CERES_GET_FLAG(FLAGS_use_spse_initialization);
-  options->spse_tolerance = CERES_GET_FLAG(FLAGS_spse_tolerance);
+      absl::GetFlag(FLAGS_use_spse_initialization);
+  options->spse_tolerance = absl::GetFlag(FLAGS_spse_tolerance);
   options->max_num_spse_iterations =
-      CERES_GET_FLAG(FLAGS_max_num_spse_iterations);
+      absl::GetFlag(FLAGS_max_num_spse_iterations);
 }
 
 void SetOrdering(BALProblem* bal_problem, Solver::Options* options) {
@@ -187,7 +190,7 @@
   double* cameras = bal_problem->mutable_cameras();
 
   if (options->use_inner_iterations) {
-    if (CERES_GET_FLAG(FLAGS_blocks_for_inner_iterations) == "cameras") {
+    if (absl::GetFlag(FLAGS_blocks_for_inner_iterations) == "cameras") {
       LOG(INFO) << "Camera blocks for inner iterations";
       options->inner_iteration_ordering =
           std::make_shared<ParameterBlockOrdering>();
@@ -195,7 +198,7 @@
         options->inner_iteration_ordering->AddElementToGroup(
             cameras + camera_block_size * i, 0);
       }
-    } else if (CERES_GET_FLAG(FLAGS_blocks_for_inner_iterations) == "points") {
+    } else if (absl::GetFlag(FLAGS_blocks_for_inner_iterations) == "points") {
       LOG(INFO) << "Point blocks for inner iterations";
       options->inner_iteration_ordering =
           std::make_shared<ParameterBlockOrdering>();
@@ -203,7 +206,7 @@
         options->inner_iteration_ordering->AddElementToGroup(
             points + point_block_size * i, 0);
       }
-    } else if (CERES_GET_FLAG(FLAGS_blocks_for_inner_iterations) ==
+    } else if (absl::GetFlag(FLAGS_blocks_for_inner_iterations) ==
                "cameras,points") {
       LOG(INFO) << "Camera followed by point blocks for inner iterations";
       options->inner_iteration_ordering =
@@ -216,7 +219,7 @@
         options->inner_iteration_ordering->AddElementToGroup(
             points + point_block_size * i, 1);
       }
-    } else if (CERES_GET_FLAG(FLAGS_blocks_for_inner_iterations) ==
+    } else if (absl::GetFlag(FLAGS_blocks_for_inner_iterations) ==
                "points,cameras") {
       LOG(INFO) << "Point followed by camera blocks for inner iterations";
       options->inner_iteration_ordering =
@@ -229,12 +232,12 @@
         options->inner_iteration_ordering->AddElementToGroup(
             points + point_block_size * i, 0);
       }
-    } else if (CERES_GET_FLAG(FLAGS_blocks_for_inner_iterations) ==
+    } else if (absl::GetFlag(FLAGS_blocks_for_inner_iterations) ==
                "automatic") {
       LOG(INFO) << "Choosing automatic blocks for inner iterations";
     } else {
       LOG(FATAL) << "Unknown block type for inner iterations: "
-                 << CERES_GET_FLAG(FLAGS_blocks_for_inner_iterations);
+                 << absl::GetFlag(FLAGS_blocks_for_inner_iterations);
     }
   }
 
@@ -247,7 +250,7 @@
   // This can either be done by specifying a
   // Options::linear_solver_ordering or having Ceres figure it out
   // automatically using a greedy maximum independent set algorithm.
-  if (CERES_GET_FLAG(FLAGS_linear_solver_ordering) == "user") {
+  if (absl::GetFlag(FLAGS_linear_solver_ordering) == "user") {
     auto* ordering = new ceres::ParameterBlockOrdering;
 
     // The points come before the cameras.
@@ -266,32 +269,31 @@
 }
 
 void SetMinimizerOptions(Solver::Options* options) {
-  options->max_num_iterations = CERES_GET_FLAG(FLAGS_num_iterations);
+  options->max_num_iterations = absl::GetFlag(FLAGS_num_iterations);
   options->minimizer_progress_to_stdout = true;
-  if (CERES_GET_FLAG(FLAGS_num_threads) == -1) {
+  if (absl::GetFlag(FLAGS_num_threads) == -1) {
     const int num_available_threads =
         static_cast<int>(std::thread::hardware_concurrency());
     if (num_available_threads > 0) {
       options->num_threads = num_available_threads;
     }
   } else {
-    options->num_threads = CERES_GET_FLAG(FLAGS_num_threads);
+    options->num_threads = absl::GetFlag(FLAGS_num_threads);
   }
   CHECK_GE(options->num_threads, 1);
 
-  options->eta = CERES_GET_FLAG(FLAGS_eta);
-  options->max_solver_time_in_seconds = CERES_GET_FLAG(FLAGS_max_solver_time);
-  options->use_nonmonotonic_steps = CERES_GET_FLAG(FLAGS_nonmonotonic_steps);
-  if (CERES_GET_FLAG(FLAGS_line_search)) {
+  options->eta = absl::GetFlag(FLAGS_eta);
+  options->max_solver_time_in_seconds = absl::GetFlag(FLAGS_max_solver_time);
+  options->use_nonmonotonic_steps = absl::GetFlag(FLAGS_nonmonotonic_steps);
+  if (absl::GetFlag(FLAGS_line_search)) {
     options->minimizer_type = ceres::LINE_SEARCH;
   }
 
   CHECK(StringToTrustRegionStrategyType(
-      CERES_GET_FLAG(FLAGS_trust_region_strategy),
+      absl::GetFlag(FLAGS_trust_region_strategy),
       &options->trust_region_strategy_type));
-  CHECK(
-      StringToDoglegType(CERES_GET_FLAG(FLAGS_dogleg), &options->dogleg_type));
-  options->use_inner_iterations = CERES_GET_FLAG(FLAGS_inner_iterations);
+  CHECK(StringToDoglegType(absl::GetFlag(FLAGS_dogleg), &options->dogleg_type));
+  options->use_inner_iterations = absl::GetFlag(FLAGS_inner_iterations);
 }
 
 void SetSolverOptionsFromFlags(BALProblem* bal_problem,
@@ -315,7 +317,7 @@
     CostFunction* cost_function;
     // Each Residual block takes a point and a camera as input and
     // outputs a 2 dimensional residual.
-    cost_function = (CERES_GET_FLAG(FLAGS_use_quaternions))
+    cost_function = (absl::GetFlag(FLAGS_use_quaternions))
                         ? SnavelyReprojectionErrorWithQuaternions::Create(
                               observations[2 * i + 0], observations[2 * i + 1])
                         : SnavelyReprojectionError::Create(
@@ -323,7 +325,7 @@
 
     // If enabled use Huber's loss function.
     LossFunction* loss_function =
-        CERES_GET_FLAG(FLAGS_robustify) ? new HuberLoss(1.0) : nullptr;
+        absl::GetFlag(FLAGS_robustify) ? new HuberLoss(1.0) : nullptr;
 
     // Each observation corresponds to a pair of a camera and a point
     // which are identified by camera_index()[i] and point_index()[i]
@@ -334,8 +336,8 @@
     problem->AddResidualBlock(cost_function, loss_function, camera, point);
   }
 
-  if (CERES_GET_FLAG(FLAGS_use_quaternions) &&
-      CERES_GET_FLAG(FLAGS_use_manifolds)) {
+  if (absl::GetFlag(FLAGS_use_quaternions) &&
+      absl::GetFlag(FLAGS_use_manifolds)) {
     Manifold* camera_manifold =
         new ProductManifold<QuaternionManifold, EuclideanManifold<6>>{};
     for (int i = 0; i < bal_problem->num_cameras(); ++i) {
@@ -345,19 +347,19 @@
 }
 
 void SolveProblem(const char* filename) {
-  BALProblem bal_problem(filename, CERES_GET_FLAG(FLAGS_use_quaternions));
+  BALProblem bal_problem(filename, absl::GetFlag(FLAGS_use_quaternions));
 
-  if (!CERES_GET_FLAG(FLAGS_initial_ply).empty()) {
-    bal_problem.WriteToPLYFile(CERES_GET_FLAG(FLAGS_initial_ply));
+  if (!absl::GetFlag(FLAGS_initial_ply).empty()) {
+    bal_problem.WriteToPLYFile(absl::GetFlag(FLAGS_initial_ply));
   }
 
   Problem problem;
 
-  srand(CERES_GET_FLAG(FLAGS_random_seed));
+  srand(absl::GetFlag(FLAGS_random_seed));
   bal_problem.Normalize();
-  bal_problem.Perturb(CERES_GET_FLAG(FLAGS_rotation_sigma),
-                      CERES_GET_FLAG(FLAGS_translation_sigma),
-                      CERES_GET_FLAG(FLAGS_point_sigma));
+  bal_problem.Perturb(absl::GetFlag(FLAGS_rotation_sigma),
+                      absl::GetFlag(FLAGS_translation_sigma),
+                      absl::GetFlag(FLAGS_point_sigma));
 
   BuildProblem(&bal_problem, &problem);
   Solver::Options options;
@@ -369,8 +371,8 @@
   Solve(options, &problem, &summary);
   std::cout << summary.FullReport() << "\n";
 
-  if (!CERES_GET_FLAG(FLAGS_final_ply).empty()) {
-    bal_problem.WriteToPLYFile(CERES_GET_FLAG(FLAGS_final_ply));
+  if (!absl::GetFlag(FLAGS_final_ply).empty()) {
+    bal_problem.WriteToPLYFile(absl::GetFlag(FLAGS_final_ply));
   }
 }
 
@@ -378,17 +380,17 @@
 }  // namespace ceres::examples
 
 int main(int argc, char** argv) {
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
 
-  if (CERES_GET_FLAG(FLAGS_input).empty()) {
+  if (absl::GetFlag(FLAGS_input).empty()) {
     LOG(ERROR) << "Usage: bundle_adjuster --input=bal_problem";
     return 1;
   }
 
-  CHECK(CERES_GET_FLAG(FLAGS_use_quaternions) ||
-        !CERES_GET_FLAG(FLAGS_use_manifolds))
+  CHECK(absl::GetFlag(FLAGS_use_quaternions) ||
+        !absl::GetFlag(FLAGS_use_manifolds))
       << "--use_manifolds can only be used with --use_quaternions.";
-  ceres::examples::SolveProblem(CERES_GET_FLAG(FLAGS_input).c_str());
+  ceres::examples::SolveProblem(absl::GetFlag(FLAGS_input).c_str());
   return 0;
 }
diff --git a/examples/circle_fit.cc b/examples/circle_fit.cc
index fd848d9..45cf5e3 100644
--- a/examples/circle_fit.cc
+++ b/examples/circle_fit.cc
@@ -53,14 +53,18 @@
 #include <cstdio>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
-DEFINE_double(robust_threshold,
-              0.0,
-              "Robust loss parameter. Set to 0 for normal squared error (no "
-              "robustification).");
+ABSL_FLAG(double,
+          robust_threshold,
+          0.0,
+          "Robust loss parameter. Set to 0 for normal squared error (no "
+          "robustification).");
 
 // The cost for a single sample. The returned residual is related to the
 // distance of the point from the circle (passed in as x, y, m parameters).
@@ -102,8 +106,8 @@
 };
 
 int main(int argc, char** argv) {
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
 
   double x, y, r;
   if (scanf("%lg %lg %lg", &x, &y, &r) != 3) {
@@ -124,8 +128,8 @@
 
   // Configure the loss function.
   ceres::LossFunction* loss = nullptr;
-  if (CERES_GET_FLAG(FLAGS_robust_threshold)) {
-    loss = new ceres::CauchyLoss(CERES_GET_FLAG(FLAGS_robust_threshold));
+  if (absl::GetFlag(FLAGS_robust_threshold)) {
+    loss = new ceres::CauchyLoss(absl::GetFlag(FLAGS_robust_threshold));
   }
 
   // Add the residuals.
diff --git a/examples/curve_fitting.cc b/examples/curve_fitting.cc
index 105402e..c7593fb 100644
--- a/examples/curve_fitting.cc
+++ b/examples/curve_fitting.cc
@@ -31,8 +31,8 @@
 // This example fits the curve f(x;m,c) = e^(m * x + c) to data, minimizing the
 // sum squared loss.
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // Data generated using the following octave code.
 //   randn('seed', 23497);
@@ -132,8 +132,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
-
+  absl::InitializeLog();
   const double initial_m = 0.0;
   const double initial_c = 0.0;
   double m = initial_m;
diff --git a/examples/denoising.cc b/examples/denoising.cc
index dc13d19..5f826d8 100644
--- a/examples/denoising.cc
+++ b/examples/denoising.cc
@@ -46,61 +46,81 @@
 #include <string>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
 #include "fields_of_experts.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "pgm_image.h"
 
-DEFINE_string(input, "", "File to which the output image should be written");
-DEFINE_string(foe_file, "", "FoE file to use");
-DEFINE_string(output, "", "File to which the output image should be written");
-DEFINE_double(sigma, 20.0, "Standard deviation of noise");
-DEFINE_string(trust_region_strategy,
-              "levenberg_marquardt",
-              "Options are: levenberg_marquardt, dogleg.");
-DEFINE_string(dogleg,
-              "traditional_dogleg",
-              "Options are: traditional_dogleg,"
-              "subspace_dogleg.");
-DEFINE_string(linear_solver,
-              "sparse_normal_cholesky",
-              "Options are: "
-              "sparse_normal_cholesky and cgnr.");
-DEFINE_string(preconditioner,
-              "jacobi",
-              "Options are: "
-              "identity, jacobi, subset");
-DEFINE_string(sparse_linear_algebra_library,
-              "suite_sparse",
-              "Options are: suite_sparse, cx_sparse and eigen_sparse");
-DEFINE_double(eta,
-              1e-2,
-              "Default value for eta. Eta determines the "
-              "accuracy of each linear solve of the truncated newton step. "
-              "Changing this parameter can affect solve performance.");
-DEFINE_int32(num_threads, 1, "Number of threads.");
-DEFINE_int32(num_iterations, 10, "Number of iterations.");
-DEFINE_bool(nonmonotonic_steps,
-            false,
-            "Trust region algorithm can use"
-            " nonmonotic steps.");
-DEFINE_bool(inner_iterations,
-            false,
-            "Use inner iterations to non-linearly "
-            "refine each successful trust region step.");
-DEFINE_bool(mixed_precision_solves, false, "Use mixed precision solves.");
-DEFINE_int32(max_num_refinement_iterations,
-             0,
-             "Iterative refinement iterations");
-DEFINE_bool(line_search,
-            false,
-            "Use a line search instead of trust region "
-            "algorithm.");
-DEFINE_double(subset_fraction,
-              0.2,
-              "The fraction of residual blocks to use for the"
-              " subset preconditioner.");
+ABSL_FLAG(std::string,
+          input,
+          "",
+          "File to which the output image should be written");
+ABSL_FLAG(std::string, foe_file, "", "FoE file to use");
+ABSL_FLAG(std::string,
+          output,
+          "",
+          "File to which the output image should be written");
+ABSL_FLAG(double, sigma, 20.0, "Standard deviation of noise");
+ABSL_FLAG(std::string,
+          trust_region_strategy,
+          "levenberg_marquardt",
+          "Options are: levenberg_marquardt, dogleg.");
+ABSL_FLAG(std::string,
+          dogleg,
+          "traditional_dogleg",
+          "Options are: traditional_dogleg,"
+          "subspace_dogleg.");
+ABSL_FLAG(std::string,
+          linear_solver,
+          "sparse_normal_cholesky",
+          "Options are: "
+          "sparse_normal_cholesky and cgnr.");
+ABSL_FLAG(std::string,
+          preconditioner,
+          "jacobi",
+          "Options are: "
+          "identity, jacobi, subset");
+ABSL_FLAG(std::string,
+          sparse_linear_algebra_library,
+          "suite_sparse",
+          "Options are: suite_sparse, cx_sparse and eigen_sparse");
+ABSL_FLAG(double,
+          eta,
+          1e-2,
+          "Default value for eta. Eta determines the "
+          "accuracy of each linear solve of the truncated newton step. "
+          "Changing this parameter can affect solve performance.");
+ABSL_FLAG(int32_t, num_threads, 1, "Number of threads.");
+ABSL_FLAG(int32_t, num_iterations, 10, "Number of iterations.");
+ABSL_FLAG(bool,
+          nonmonotonic_steps,
+          false,
+          "Trust region algorithm can use"
+          " nonmonotic steps.");
+ABSL_FLAG(bool,
+          inner_iterations,
+          false,
+          "Use inner iterations to non-linearly "
+          "refine each successful trust region step.");
+ABSL_FLAG(bool, mixed_precision_solves, false, "Use mixed precision solves.");
+ABSL_FLAG(int32_t,
+          max_num_refinement_iterations,
+          0,
+          "Iterative refinement iterations");
+ABSL_FLAG(bool,
+          line_search,
+          false,
+          "Use a line search instead of trust region "
+          "algorithm.");
+ABSL_FLAG(double,
+          subset_fraction,
+          0.2,
+          "The fraction of residual blocks to use for the"
+          " subset preconditioner.");
 
 namespace ceres::examples {
 namespace {
@@ -133,9 +153,9 @@
                    Problem* problem,
                    PGMImage<double>* solution) {
   // Create the data term
-  CHECK_GT(CERES_GET_FLAG(FLAGS_sigma), 0.0);
+  CHECK_GT(absl::GetFlag(FLAGS_sigma), 0.0);
   const double coefficient =
-      1 / (2.0 * CERES_GET_FLAG(FLAGS_sigma) * CERES_GET_FLAG(FLAGS_sigma));
+      1 / (2.0 * absl::GetFlag(FLAGS_sigma) * absl::GetFlag(FLAGS_sigma));
   for (int index = 0; index < image.NumPixels(); ++index) {
     ceres::CostFunction* cost_function = new QuadraticCostFunction(
         coefficient, image.PixelFromLinearIndex(index));
@@ -175,35 +195,34 @@
 }
 
 void SetLinearSolver(Solver::Options* options) {
-  CHECK(StringToLinearSolverType(CERES_GET_FLAG(FLAGS_linear_solver),
+  CHECK(StringToLinearSolverType(absl::GetFlag(FLAGS_linear_solver),
                                  &options->linear_solver_type));
-  CHECK(StringToPreconditionerType(CERES_GET_FLAG(FLAGS_preconditioner),
+  CHECK(StringToPreconditionerType(absl::GetFlag(FLAGS_preconditioner),
                                    &options->preconditioner_type));
   CHECK(StringToSparseLinearAlgebraLibraryType(
-      CERES_GET_FLAG(FLAGS_sparse_linear_algebra_library),
+      absl::GetFlag(FLAGS_sparse_linear_algebra_library),
       &options->sparse_linear_algebra_library_type));
   options->use_mixed_precision_solves =
-      CERES_GET_FLAG(FLAGS_mixed_precision_solves);
+      absl::GetFlag(FLAGS_mixed_precision_solves);
   options->max_num_refinement_iterations =
-      CERES_GET_FLAG(FLAGS_max_num_refinement_iterations);
+      absl::GetFlag(FLAGS_max_num_refinement_iterations);
 }
 
 void SetMinimizerOptions(Solver::Options* options) {
-  options->max_num_iterations = CERES_GET_FLAG(FLAGS_num_iterations);
+  options->max_num_iterations = absl::GetFlag(FLAGS_num_iterations);
   options->minimizer_progress_to_stdout = true;
-  options->num_threads = CERES_GET_FLAG(FLAGS_num_threads);
-  options->eta = CERES_GET_FLAG(FLAGS_eta);
-  options->use_nonmonotonic_steps = CERES_GET_FLAG(FLAGS_nonmonotonic_steps);
-  if (CERES_GET_FLAG(FLAGS_line_search)) {
+  options->num_threads = absl::GetFlag(FLAGS_num_threads);
+  options->eta = absl::GetFlag(FLAGS_eta);
+  options->use_nonmonotonic_steps = absl::GetFlag(FLAGS_nonmonotonic_steps);
+  if (absl::GetFlag(FLAGS_line_search)) {
     options->minimizer_type = ceres::LINE_SEARCH;
   }
 
   CHECK(StringToTrustRegionStrategyType(
-      CERES_GET_FLAG(FLAGS_trust_region_strategy),
+      absl::GetFlag(FLAGS_trust_region_strategy),
       &options->trust_region_strategy_type));
-  CHECK(
-      StringToDoglegType(CERES_GET_FLAG(FLAGS_dogleg), &options->dogleg_type));
-  options->use_inner_iterations = CERES_GET_FLAG(FLAGS_inner_iterations);
+  CHECK(StringToDoglegType(absl::GetFlag(FLAGS_dogleg), &options->dogleg_type));
+  options->use_inner_iterations = absl::GetFlag(FLAGS_inner_iterations);
 }
 
 // Solves the FoE problem using Ceres and post-processes it to make sure the
@@ -230,7 +249,7 @@
     std::default_random_engine engine;
     std::uniform_real_distribution<> distribution(0, 1);  // rage 0 - 1
     for (auto residual_block : residual_blocks) {
-      if (distribution(engine) <= CERES_GET_FLAG(FLAGS_subset_fraction)) {
+      if (distribution(engine) <= absl::GetFlag(FLAGS_subset_fraction)) {
         options.residual_blocks_for_subset_preconditioner.insert(
             residual_block);
       }
@@ -255,15 +274,15 @@
 
 int main(int argc, char** argv) {
   using namespace ceres::examples;
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
 
-  if (CERES_GET_FLAG(FLAGS_input).empty()) {
+  if (absl::GetFlag(FLAGS_input).empty()) {
     std::cerr << "Please provide an image file name using -input.\n";
     return 1;
   }
 
-  if (CERES_GET_FLAG(FLAGS_foe_file).empty()) {
+  if (absl::GetFlag(FLAGS_foe_file).empty()) {
     std::cerr << "Please provide a Fields of Experts file name using -foe_file."
                  "\n";
     return 1;
@@ -271,16 +290,16 @@
 
   // Load the Fields of Experts filters from file.
   FieldsOfExperts foe;
-  if (!foe.LoadFromFile(CERES_GET_FLAG(FLAGS_foe_file))) {
-    std::cerr << "Loading \"" << CERES_GET_FLAG(FLAGS_foe_file)
+  if (!foe.LoadFromFile(absl::GetFlag(FLAGS_foe_file))) {
+    std::cerr << "Loading \"" << absl::GetFlag(FLAGS_foe_file)
               << "\" failed.\n";
     return 2;
   }
 
   // Read the images
-  PGMImage<double> image(CERES_GET_FLAG(FLAGS_input));
+  PGMImage<double> image(absl::GetFlag(FLAGS_input));
   if (image.width() == 0) {
-    std::cerr << "Reading \"" << CERES_GET_FLAG(FLAGS_input) << "\" failed.\n";
+    std::cerr << "Reading \"" << absl::GetFlag(FLAGS_input) << "\" failed.\n";
     return 3;
   }
   PGMImage<double> solution(image.width(), image.height());
@@ -291,9 +310,9 @@
 
   SolveProblem(&problem, &solution);
 
-  if (!CERES_GET_FLAG(FLAGS_output).empty()) {
-    CHECK(solution.WriteToFile(CERES_GET_FLAG(FLAGS_output)))
-        << "Writing \"" << CERES_GET_FLAG(FLAGS_output) << "\" failed.";
+  if (!absl::GetFlag(FLAGS_output).empty()) {
+    CHECK(solution.WriteToFile(absl::GetFlag(FLAGS_output)))
+        << "Writing \"" << absl::GetFlag(FLAGS_output) << "\" failed.";
   }
 
   return 0;
diff --git a/examples/ellipse_approximation.cc b/examples/ellipse_approximation.cc
index 6fa8f1c..1b462e7 100644
--- a/examples/ellipse_approximation.cc
+++ b/examples/ellipse_approximation.cc
@@ -39,8 +39,9 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // Data generated with the following Python code.
 //   import numpy as np
@@ -378,8 +379,7 @@
 }
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
-
+  absl::InitializeLog();
   // Problem configuration.
   const int num_segments = 151;
   const double regularization_weight = 1e-2;
diff --git a/examples/evaluation_callback_example.cc b/examples/evaluation_callback_example.cc
index 6dbf932..7ca1412 100644
--- a/examples/evaluation_callback_example.cc
+++ b/examples/evaluation_callback_example.cc
@@ -47,8 +47,9 @@
 #include <iostream>
 
 #include "Eigen/Core"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // Data generated using the following octave code.
 //   randn('seed', 23497);
@@ -224,7 +225,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   const double initial_m = 0.0;
   const double initial_c = 0.0;
diff --git a/examples/helloworld.cc b/examples/helloworld.cc
index 40c2f2c..48182ce 100644
--- a/examples/helloworld.cc
+++ b/examples/helloworld.cc
@@ -33,8 +33,8 @@
 // Minimize 0.5 (10 - x)^2 using jacobian matrix computed using
 // automatic differentiation.
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // A templated cost functor that implements the residual r = 10 -
 // x. The method operator() is templated so that we can then use an
@@ -49,7 +49,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   // The variable to solve for with its initial value. It will be
   // mutated in place by the solver.
diff --git a/examples/helloworld_analytic_diff.cc b/examples/helloworld_analytic_diff.cc
index b4826a2..dcbe2ad 100644
--- a/examples/helloworld_analytic_diff.cc
+++ b/examples/helloworld_analytic_diff.cc
@@ -34,8 +34,8 @@
 
 #include <vector>
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // A CostFunction implementing analytically derivatives for the
 // function f(x) = 10 - x.
@@ -72,7 +72,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   // The variable to solve for with its initial value. It will be
   // mutated in place by the solver.
diff --git a/examples/helloworld_numeric_diff.cc b/examples/helloworld_numeric_diff.cc
index 4ed9ca6..2b9894c 100644
--- a/examples/helloworld_numeric_diff.cc
+++ b/examples/helloworld_numeric_diff.cc
@@ -31,8 +31,8 @@
 // Minimize 0.5 (10 - x)^2 using jacobian matrix computed using
 // numeric differentiation.
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // A cost functor that implements the residual r = 10 - x.
 struct CostFunctor {
@@ -43,7 +43,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   // The variable to solve for with its initial value. It will be
   // mutated in place by the solver.
diff --git a/examples/iteration_callback_example.cc b/examples/iteration_callback_example.cc
index 0be2f36..e2deada 100644
--- a/examples/iteration_callback_example.cc
+++ b/examples/iteration_callback_example.cc
@@ -35,8 +35,8 @@
 
 #include <iostream>
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // Data generated using the following octave code.
 //   randn('seed', 23497);
@@ -156,7 +156,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   const double initial_m = 0.0;
   const double initial_c = 0.0;
diff --git a/examples/libmv_bundle_adjuster.cc b/examples/libmv_bundle_adjuster.cc
index 9315ed7..69a3e0e 100644
--- a/examples/libmv_bundle_adjuster.cc
+++ b/examples/libmv_bundle_adjuster.cc
@@ -113,20 +113,24 @@
 
 #endif
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
 #include "ceres/rotation.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 using Mat3 = Eigen::Matrix<double, 3, 3>;
 using Vec6 = Eigen::Matrix<double, 6, 1>;
 using Vec3 = Eigen::Vector3d;
 using Vec4 = Eigen::Vector4d;
 
-DEFINE_string(input, "", "Input File name");
-DEFINE_string(refine_intrinsics,
-              "",
-              "Camera intrinsics to be refined. Options are: none, radial.");
+ABSL_FLAG(std::string, input, "", "Input File name");
+ABSL_FLAG(std::string,
+          refine_intrinsics,
+          "",
+          "Camera intrinsics to be refined. Options are: none, radial.");
 
 namespace {
 
@@ -791,10 +795,10 @@
 }  // namespace
 
 int main(int argc, char** argv) {
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
 
-  if (CERES_GET_FLAG(FLAGS_input).empty()) {
+  if (absl::GetFlag(FLAGS_input).empty()) {
     LOG(ERROR) << "Usage: libmv_bundle_adjuster --input=blender_problem";
     return EXIT_FAILURE;
   }
@@ -805,7 +809,7 @@
   bool is_image_space;
   std::vector<Marker> all_markers;
 
-  if (!ReadProblemFromFile(CERES_GET_FLAG(FLAGS_input),
+  if (!ReadProblemFromFile(absl::GetFlag(FLAGS_input),
                            camera_intrinsics,
                            &all_cameras,
                            &all_points,
@@ -829,14 +833,14 @@
   // declare which intrinsics need to be refined and in this case
   // refining flags does not depend on problem at all.
   int bundle_intrinsics = BUNDLE_NO_INTRINSICS;
-  if (CERES_GET_FLAG(FLAGS_refine_intrinsics).empty()) {
+  if (absl::GetFlag(FLAGS_refine_intrinsics).empty()) {
     if (is_image_space) {
       bundle_intrinsics = BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL;
     }
   } else {
-    if (CERES_GET_FLAG(FLAGS_refine_intrinsics) == "radial") {
+    if (absl::GetFlag(FLAGS_refine_intrinsics) == "radial") {
       bundle_intrinsics = BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL;
-    } else if (CERES_GET_FLAG(FLAGS_refine_intrinsics) != "none") {
+    } else if (absl::GetFlag(FLAGS_refine_intrinsics) != "none") {
       LOG(ERROR) << "Unsupported value for refine-intrinsics";
       return EXIT_FAILURE;
     }
diff --git a/examples/libmv_homography.cc b/examples/libmv_homography.cc
index b7c9eda..951cf96 100644
--- a/examples/libmv_homography.cc
+++ b/examples/libmv_homography.cc
@@ -62,8 +62,9 @@
 
 #include <utility>
 
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 using EigenDouble = Eigen::NumTraits<double>;
 
@@ -358,7 +359,7 @@
 }  // namespace
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   Mat x1(2, 100);
   for (int i = 0; i < x1.cols(); ++i) {
diff --git a/examples/more_garbow_hillstrom.cc b/examples/more_garbow_hillstrom.cc
index f15e576..59f0abc 100644
--- a/examples/more_garbow_hillstrom.cc
+++ b/examples/more_garbow_hillstrom.cc
@@ -55,22 +55,28 @@
 #include <sstream>   // NOLINT
 #include <string>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
-DEFINE_string(problem, "all", "Which problem to solve");
-DEFINE_bool(use_numeric_diff,
-            false,
-            "Use numeric differentiation instead of automatic"
-            " differentiation.");
-DEFINE_string(numeric_diff_method,
-              "ridders",
-              "When using numeric differentiation, selects algorithm. Options "
-              "are: central, forward, ridders.");
-DEFINE_int32(ridders_extrapolations,
-             3,
-             "Maximal number of extrapolations in Ridders' method.");
+ABSL_FLAG(std::string, problem, "all", "Which problem to solve");
+ABSL_FLAG(bool,
+          use_numeric_diff,
+          false,
+          "Use numeric differentiation instead of automatic"
+          " differentiation.");
+ABSL_FLAG(std::string,
+          numeric_diff_method,
+          "ridders",
+          "When using numeric differentiation, selects algorithm. Options "
+          "are: central, forward, ridders.");
+ABSL_FLAG(int32_t,
+          ridders_extrapolations,
+          3,
+          "Maximal number of extrapolations in Ridders' method.");
 
 namespace ceres::examples {
 
@@ -78,50 +84,50 @@
 
 static void SetNumericDiffOptions(ceres::NumericDiffOptions* options) {
   options->max_num_ridders_extrapolations =
-      CERES_GET_FLAG(FLAGS_ridders_extrapolations);
+      absl::GetFlag(FLAGS_ridders_extrapolations);
 }
 
-#define BEGIN_MGH_PROBLEM(name, num_parameters, num_residuals)               \
-  struct name {                                                              \
-    static constexpr int kNumParameters = num_parameters;                    \
-    static const double initial_x[kNumParameters];                           \
-    static const double lower_bounds[kNumParameters];                        \
-    static const double upper_bounds[kNumParameters];                        \
-    static const double constrained_optimal_cost;                            \
-    static const double unconstrained_optimal_cost;                          \
-    static CostFunction* Create() {                                          \
-      if (CERES_GET_FLAG(FLAGS_use_numeric_diff)) {                          \
-        ceres::NumericDiffOptions options;                                   \
-        SetNumericDiffOptions(&options);                                     \
-        if (CERES_GET_FLAG(FLAGS_numeric_diff_method) == "central") {        \
-          return new NumericDiffCostFunction<name,                           \
-                                             ceres::CENTRAL,                 \
-                                             num_residuals,                  \
-                                             num_parameters>(                \
-              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);      \
-        } else if (CERES_GET_FLAG(FLAGS_numeric_diff_method) == "forward") { \
-          return new NumericDiffCostFunction<name,                           \
-                                             ceres::FORWARD,                 \
-                                             num_residuals,                  \
-                                             num_parameters>(                \
-              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);      \
-        } else if (CERES_GET_FLAG(FLAGS_numeric_diff_method) == "ridders") { \
-          return new NumericDiffCostFunction<name,                           \
-                                             ceres::RIDDERS,                 \
-                                             num_residuals,                  \
-                                             num_parameters>(                \
-              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);      \
-        } else {                                                             \
-          LOG(ERROR) << "Invalid numeric diff method specified";             \
-          return nullptr;                                                    \
-        }                                                                    \
-      } else {                                                               \
-        return new AutoDiffCostFunction<name,                                \
-                                        num_residuals,                       \
-                                        num_parameters>();                   \
-      }                                                                      \
-    }                                                                        \
-    template <typename T>                                                    \
+#define BEGIN_MGH_PROBLEM(name, num_parameters, num_residuals)              \
+  struct name {                                                             \
+    static constexpr int kNumParameters = num_parameters;                   \
+    static const double initial_x[kNumParameters];                          \
+    static const double lower_bounds[kNumParameters];                       \
+    static const double upper_bounds[kNumParameters];                       \
+    static const double constrained_optimal_cost;                           \
+    static const double unconstrained_optimal_cost;                         \
+    static CostFunction* Create() {                                         \
+      if (absl::GetFlag(FLAGS_use_numeric_diff)) {                          \
+        ceres::NumericDiffOptions options;                                  \
+        SetNumericDiffOptions(&options);                                    \
+        if (absl::GetFlag(FLAGS_numeric_diff_method) == "central") {        \
+          return new NumericDiffCostFunction<name,                          \
+                                             ceres::CENTRAL,                \
+                                             num_residuals,                 \
+                                             num_parameters>(               \
+              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);     \
+        } else if (absl::GetFlag(FLAGS_numeric_diff_method) == "forward") { \
+          return new NumericDiffCostFunction<name,                          \
+                                             ceres::FORWARD,                \
+                                             num_residuals,                 \
+                                             num_parameters>(               \
+              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);     \
+        } else if (absl::GetFlag(FLAGS_numeric_diff_method) == "ridders") { \
+          return new NumericDiffCostFunction<name,                          \
+                                             ceres::RIDDERS,                \
+                                             num_residuals,                 \
+                                             num_parameters>(               \
+              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);     \
+        } else {                                                            \
+          LOG(ERROR) << "Invalid numeric diff method specified";            \
+          return nullptr;                                                   \
+        }                                                                   \
+      } else {                                                              \
+        return new AutoDiffCostFunction<name,                               \
+                                        num_residuals,                      \
+                                        num_parameters>();                  \
+      }                                                                     \
+    }                                                                       \
+    template <typename T>                                                   \
     bool operator()(const T* const x, T* residual) const {
 // clang-format off
 
@@ -584,8 +590,8 @@
 }  // namespace ceres::examples
 
 int main(int argc, char** argv) {
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
   using ceres::examples::Solve;
 
   int unconstrained_problems = 0;
@@ -596,8 +602,8 @@
 
 #define UNCONSTRAINED_SOLVE(n)                              \
   ss << "Unconstrained Problem " << n << " : ";             \
-  if (CERES_GET_FLAG(FLAGS_problem) == #n ||                \
-      CERES_GET_FLAG(FLAGS_problem) == "all") {             \
+  if (absl::GetFlag(FLAGS_problem) == #n ||                 \
+      absl::GetFlag(FLAGS_problem) == "all") {              \
     unconstrained_problems += 3;                            \
     if (Solve<ceres::examples::TestProblem##n>(false, 0)) { \
       unconstrained_successes += 1;                         \
@@ -645,8 +651,8 @@
 
 #define CONSTRAINED_SOLVE(n)                               \
   ss << "Constrained Problem " << n << " : ";              \
-  if (CERES_GET_FLAG(FLAGS_problem) == #n ||               \
-      CERES_GET_FLAG(FLAGS_problem) == "all") {            \
+  if (absl::GetFlag(FLAGS_problem) == #n ||                \
+      absl::GetFlag(FLAGS_problem) == "all") {             \
     constrained_problems += 1;                             \
     if (Solve<ceres::examples::TestProblem##n>(true, 0)) { \
       constrained_successes += 1;                          \
diff --git a/examples/nist.cc b/examples/nist.cc
index b92c918..48d5697 100644
--- a/examples/nist.cc
+++ b/examples/nist.cc
@@ -79,80 +79,112 @@
 #include <vector>
 
 #include "Eigen/Core"
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
 #include "ceres/tiny_solver.h"
 #include "ceres/tiny_solver_cost_function_adapter.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
-DEFINE_bool(use_tiny_solver, false, "Use TinySolver instead of Ceres::Solver");
-DEFINE_string(nist_data_dir,
-              "",
-              "Directory containing the NIST non-linear regression examples");
-DEFINE_string(minimizer,
-              "trust_region",
-              "Minimizer type to use, choices are: line_search & trust_region");
-DEFINE_string(trust_region_strategy,
-              "levenberg_marquardt",
-              "Options are: levenberg_marquardt, dogleg");
-DEFINE_string(dogleg,
-              "traditional_dogleg",
-              "Options are: traditional_dogleg, subspace_dogleg");
-DEFINE_string(linear_solver,
-              "dense_qr",
-              "Options are: sparse_cholesky, dense_qr, dense_normal_cholesky "
-              "and cgnr");
-DEFINE_string(dense_linear_algebra_library,
-              "eigen",
-              "Options are: eigen, lapack, and cuda.");
-DEFINE_string(preconditioner, "jacobi", "Options are: identity, jacobi");
-DEFINE_string(line_search,
-              "wolfe",
-              "Line search algorithm to use, choices are: armijo and wolfe.");
-DEFINE_string(line_search_direction,
-              "lbfgs",
-              "Line search direction algorithm to use, choices: lbfgs, bfgs");
-DEFINE_int32(max_line_search_iterations,
-             20,
-             "Maximum number of iterations for each line search.");
-DEFINE_int32(max_line_search_restarts,
-             10,
-             "Maximum number of restarts of line search direction algorithm.");
-DEFINE_string(line_search_interpolation,
-              "cubic",
-              "Degree of polynomial approximation in line search, choices are: "
-              "bisection, quadratic & cubic.");
-DEFINE_int32(lbfgs_rank,
-             20,
-             "Rank of L-BFGS inverse Hessian approximation in line search.");
-DEFINE_bool(approximate_eigenvalue_bfgs_scaling,
-            false,
-            "Use approximate eigenvalue scaling in (L)BFGS line search.");
-DEFINE_double(sufficient_decrease,
-              1.0e-4,
-              "Line search Armijo sufficient (function) decrease factor.");
-DEFINE_double(sufficient_curvature_decrease,
-              0.9,
-              "Line search Wolfe sufficient curvature decrease factor.");
-DEFINE_int32(num_iterations, 10000, "Number of iterations");
-DEFINE_bool(nonmonotonic_steps,
-            false,
-            "Trust region algorithm can use nonmonotic steps");
-DEFINE_double(initial_trust_region_radius, 1e4, "Initial trust region radius");
-DEFINE_bool(use_numeric_diff,
-            false,
-            "Use numeric differentiation instead of automatic "
-            "differentiation.");
-DEFINE_string(numeric_diff_method,
-              "ridders",
-              "When using numeric differentiation, selects algorithm. Options "
-              "are: central, forward, ridders.");
-DEFINE_double(ridders_step_size,
-              1e-9,
-              "Initial step size for Ridders numeric differentiation.");
-DEFINE_int32(ridders_extrapolations,
-             3,
-             "Maximal number of Ridders extrapolations.");
+ABSL_FLAG(bool,
+          use_tiny_solver,
+          false,
+          "Use TinySolver instead of Ceres::Solver");
+ABSL_FLAG(std::string,
+          nist_data_dir,
+          "",
+          "Directory containing the NIST non-linear regression examples");
+ABSL_FLAG(std::string,
+          minimizer,
+          "trust_region",
+          "Minimizer type to use, choices are: line_search & trust_region");
+ABSL_FLAG(std::string,
+          trust_region_strategy,
+          "levenberg_marquardt",
+          "Options are: levenberg_marquardt, dogleg");
+ABSL_FLAG(std::string,
+          dogleg,
+          "traditional_dogleg",
+          "Options are: traditional_dogleg, subspace_dogleg");
+ABSL_FLAG(std::string,
+          linear_solver,
+          "dense_qr",
+          "Options are: sparse_cholesky, dense_qr, dense_normal_cholesky "
+          "and cgnr");
+ABSL_FLAG(std::string,
+          dense_linear_algebra_library,
+          "eigen",
+          "Options are: eigen, lapack, and cuda.");
+ABSL_FLAG(std::string,
+          preconditioner,
+          "jacobi",
+          "Options are: identity, jacobi");
+ABSL_FLAG(std::string,
+          line_search,
+          "wolfe",
+          "Line search algorithm to use, choices are: armijo and wolfe.");
+ABSL_FLAG(std::string,
+          line_search_direction,
+          "lbfgs",
+          "Line search direction algorithm to use, choices: lbfgs, bfgs");
+ABSL_FLAG(int32_t,
+          max_line_search_iterations,
+          20,
+          "Maximum number of iterations for each line search.");
+ABSL_FLAG(int32_t,
+          max_line_search_restarts,
+          10,
+          "Maximum number of restarts of line search direction algorithm.");
+ABSL_FLAG(std::string,
+          line_search_interpolation,
+          "cubic",
+          "Degree of polynomial approximation in line search, choices are: "
+          "bisection, quadratic & cubic.");
+ABSL_FLAG(int32_t,
+          lbfgs_rank,
+          20,
+          "Rank of L-BFGS inverse Hessian approximation in line search.");
+ABSL_FLAG(bool,
+          approximate_eigenvalue_bfgs_scaling,
+          false,
+          "Use approximate eigenvalue scaling in (L)BFGS line search.");
+ABSL_FLAG(double,
+          sufficient_decrease,
+          1.0e-4,
+          "Line search Armijo sufficient (function) decrease factor.");
+ABSL_FLAG(double,
+          sufficient_curvature_decrease,
+          0.9,
+          "Line search Wolfe sufficient curvature decrease factor.");
+ABSL_FLAG(int32_t, num_iterations, 10000, "Number of iterations");
+ABSL_FLAG(bool,
+          nonmonotonic_steps,
+          false,
+          "Trust region algorithm can use nonmonotic steps");
+ABSL_FLAG(double,
+          initial_trust_region_radius,
+          1e4,
+          "Initial trust region radius");
+ABSL_FLAG(bool,
+          use_numeric_diff,
+          false,
+          "Use numeric differentiation instead of automatic "
+          "differentiation.");
+ABSL_FLAG(std::string,
+          numeric_diff_method,
+          "ridders",
+          "When using numeric differentiation, selects algorithm. Options "
+          "are: central, forward, ridders.");
+ABSL_FLAG(double,
+          ridders_step_size,
+          1e-9,
+          "Initial step size for Ridders numeric differentiation.");
+ABSL_FLAG(int32_t,
+          ridders_extrapolations,
+          3,
+          "Maximal number of Ridders extrapolations.");
 
 namespace ceres::examples {
 namespace {
@@ -456,50 +488,50 @@
 
 static void SetNumericDiffOptions(ceres::NumericDiffOptions* options) {
   options->max_num_ridders_extrapolations =
-      CERES_GET_FLAG(FLAGS_ridders_extrapolations);
+      absl::GetFlag(FLAGS_ridders_extrapolations);
   options->ridders_relative_initial_step_size =
-      CERES_GET_FLAG(FLAGS_ridders_step_size);
+      absl::GetFlag(FLAGS_ridders_step_size);
 }
 
 void SetMinimizerOptions(ceres::Solver::Options* options) {
-  CHECK(ceres::StringToMinimizerType(CERES_GET_FLAG(FLAGS_minimizer),
+  CHECK(ceres::StringToMinimizerType(absl::GetFlag(FLAGS_minimizer),
                                      &options->minimizer_type));
-  CHECK(ceres::StringToLinearSolverType(CERES_GET_FLAG(FLAGS_linear_solver),
+  CHECK(ceres::StringToLinearSolverType(absl::GetFlag(FLAGS_linear_solver),
                                         &options->linear_solver_type));
   CHECK(StringToDenseLinearAlgebraLibraryType(
-      CERES_GET_FLAG(FLAGS_dense_linear_algebra_library),
+      absl::GetFlag(FLAGS_dense_linear_algebra_library),
       &options->dense_linear_algebra_library_type));
-  CHECK(ceres::StringToPreconditionerType(CERES_GET_FLAG(FLAGS_preconditioner),
+  CHECK(ceres::StringToPreconditionerType(absl::GetFlag(FLAGS_preconditioner),
                                           &options->preconditioner_type));
   CHECK(ceres::StringToTrustRegionStrategyType(
-      CERES_GET_FLAG(FLAGS_trust_region_strategy),
+      absl::GetFlag(FLAGS_trust_region_strategy),
       &options->trust_region_strategy_type));
-  CHECK(ceres::StringToDoglegType(CERES_GET_FLAG(FLAGS_dogleg),
+  CHECK(ceres::StringToDoglegType(absl::GetFlag(FLAGS_dogleg),
                                   &options->dogleg_type));
   CHECK(ceres::StringToLineSearchDirectionType(
-      CERES_GET_FLAG(FLAGS_line_search_direction),
+      absl::GetFlag(FLAGS_line_search_direction),
       &options->line_search_direction_type));
-  CHECK(ceres::StringToLineSearchType(CERES_GET_FLAG(FLAGS_line_search),
+  CHECK(ceres::StringToLineSearchType(absl::GetFlag(FLAGS_line_search),
                                       &options->line_search_type));
   CHECK(ceres::StringToLineSearchInterpolationType(
-      CERES_GET_FLAG(FLAGS_line_search_interpolation),
+      absl::GetFlag(FLAGS_line_search_interpolation),
       &options->line_search_interpolation_type));
 
-  options->max_num_iterations = CERES_GET_FLAG(FLAGS_num_iterations);
-  options->use_nonmonotonic_steps = CERES_GET_FLAG(FLAGS_nonmonotonic_steps);
+  options->max_num_iterations = absl::GetFlag(FLAGS_num_iterations);
+  options->use_nonmonotonic_steps = absl::GetFlag(FLAGS_nonmonotonic_steps);
   options->initial_trust_region_radius =
-      CERES_GET_FLAG(FLAGS_initial_trust_region_radius);
-  options->max_lbfgs_rank = CERES_GET_FLAG(FLAGS_lbfgs_rank);
+      absl::GetFlag(FLAGS_initial_trust_region_radius);
+  options->max_lbfgs_rank = absl::GetFlag(FLAGS_lbfgs_rank);
   options->line_search_sufficient_function_decrease =
-      CERES_GET_FLAG(FLAGS_sufficient_decrease);
+      absl::GetFlag(FLAGS_sufficient_decrease);
   options->line_search_sufficient_curvature_decrease =
-      CERES_GET_FLAG(FLAGS_sufficient_curvature_decrease);
+      absl::GetFlag(FLAGS_sufficient_curvature_decrease);
   options->max_num_line_search_step_size_iterations =
-      CERES_GET_FLAG(FLAGS_max_line_search_iterations);
+      absl::GetFlag(FLAGS_max_line_search_iterations);
   options->max_num_line_search_direction_restarts =
-      CERES_GET_FLAG(FLAGS_max_line_search_restarts);
+      absl::GetFlag(FLAGS_max_line_search_restarts);
   options->use_approximate_eigenvalue_bfgs_scaling =
-      CERES_GET_FLAG(FLAGS_approximate_eigenvalue_bfgs_scaling);
+      absl::GetFlag(FLAGS_approximate_eigenvalue_bfgs_scaling);
   options->function_tolerance = std::numeric_limits<double>::epsilon();
   options->gradient_tolerance = std::numeric_limits<double>::epsilon();
   options->parameter_tolerance = std::numeric_limits<double>::epsilon();
@@ -527,22 +559,22 @@
                                  const int num_observations) {
   auto* model = new Model(predictor.data(), response.data(), num_observations);
   ceres::CostFunction* cost_function = nullptr;
-  if (CERES_GET_FLAG(FLAGS_use_numeric_diff)) {
+  if (absl::GetFlag(FLAGS_use_numeric_diff)) {
     ceres::NumericDiffOptions options;
     SetNumericDiffOptions(&options);
-    if (CERES_GET_FLAG(FLAGS_numeric_diff_method) == "central") {
+    if (absl::GetFlag(FLAGS_numeric_diff_method) == "central") {
       cost_function = new NumericDiffCostFunction<Model,
                                                   ceres::CENTRAL,
                                                   ceres::DYNAMIC,
                                                   num_parameters>(
           model, ceres::TAKE_OWNERSHIP, num_observations, options);
-    } else if (CERES_GET_FLAG(FLAGS_numeric_diff_method) == "forward") {
+    } else if (absl::GetFlag(FLAGS_numeric_diff_method) == "forward") {
       cost_function = new NumericDiffCostFunction<Model,
                                                   ceres::FORWARD,
                                                   ceres::DYNAMIC,
                                                   num_parameters>(
           model, ceres::TAKE_OWNERSHIP, num_observations, options);
-    } else if (CERES_GET_FLAG(FLAGS_numeric_diff_method) == "ridders") {
+    } else if (absl::GetFlag(FLAGS_numeric_diff_method) == "ridders") {
       cost_function = new NumericDiffCostFunction<Model,
                                                   ceres::RIDDERS,
                                                   ceres::DYNAMIC,
@@ -583,7 +615,7 @@
 template <typename Model, int num_parameters>
 int RegressionDriver(const std::string& filename) {
   NISTProblem nist_problem(
-      JoinPath(CERES_GET_FLAG(FLAGS_nist_data_dir), filename));
+      JoinPath(absl::GetFlag(FLAGS_nist_data_dir), filename));
   CHECK_EQ(num_parameters, nist_problem.num_parameters());
 
   Matrix predictor = nist_problem.predictor();
@@ -604,7 +636,7 @@
     double initial_cost;
     double final_cost;
 
-    if (!CERES_GET_FLAG(FLAGS_use_tiny_solver)) {
+    if (!absl::GetFlag(FLAGS_use_tiny_solver)) {
       ceres::Problem problem;
       problem.AddResidualBlock(
           cost_function, nullptr, initial_parameters.data());
@@ -620,7 +652,7 @@
       using Solver = ceres::TinySolver<
           ceres::TinySolverCostFunctionAdapter<Eigen::Dynamic, num_parameters>>;
       Solver solver;
-      solver.options.max_num_iterations = CERES_GET_FLAG(FLAGS_num_iterations);
+      solver.options.max_num_iterations = absl::GetFlag(FLAGS_num_iterations);
       solver.options.gradient_tolerance =
           std::numeric_limits<double>::epsilon();
       solver.options.parameter_tolerance =
@@ -657,7 +689,7 @@
 }
 
 void SolveNISTProblems() {
-  if (CERES_GET_FLAG(FLAGS_nist_data_dir).empty()) {
+  if (absl::GetFlag(FLAGS_nist_data_dir).empty()) {
     LOG(FATAL) << "Must specify the directory containing the NIST problems";
   }
 
@@ -709,8 +741,8 @@
 }  // namespace ceres::examples
 
 int main(int argc, char** argv) {
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
   ceres::examples::SolveNISTProblems();
   return 0;
 }
diff --git a/examples/pgm_image.h b/examples/pgm_image.h
index 033ab4d..0f14901 100644
--- a/examples/pgm_image.h
+++ b/examples/pgm_image.h
@@ -41,7 +41,7 @@
 #include <string>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
 
 namespace ceres::examples {
 
diff --git a/examples/powell.cc b/examples/powell.cc
index a4ca1b7..c46cff7 100644
--- a/examples/powell.cc
+++ b/examples/powell.cc
@@ -46,9 +46,11 @@
 
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 struct F1 {
   template <typename T>
@@ -86,14 +88,14 @@
   }
 };
 
-DEFINE_string(minimizer,
-              "trust_region",
-              "Minimizer type to use, choices are: line_search & trust_region");
+ABSL_FLAG(std::string,
+          minimizer,
+          "trust_region",
+          "Minimizer type to use, choices are: line_search & trust_region");
 
 int main(int argc, char** argv) {
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  google::InitGoogleLogging(argv[0]);
-
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
   double x1 = 3.0;
   double x2 = -1.0;
   double x3 = 0.0;
@@ -114,9 +116,9 @@
 
   ceres::Solver::Options options;
   LOG_IF(FATAL,
-         !ceres::StringToMinimizerType(CERES_GET_FLAG(FLAGS_minimizer),
+         !ceres::StringToMinimizerType(absl::GetFlag(FLAGS_minimizer),
                                        &options.minimizer_type))
-      << "Invalid minimizer: " << CERES_GET_FLAG(FLAGS_minimizer)
+      << "Invalid minimizer: " << absl::GetFlag(FLAGS_minimizer)
       << ", valid options are: trust_region and line_search.";
 
   options.max_num_iterations = 100;
diff --git a/examples/robot_pose_mle.cc b/examples/robot_pose_mle.cc
index cc60e14..223a0bb 100644
--- a/examples/robot_pose_mle.cc
+++ b/examples/robot_pose_mle.cc
@@ -131,27 +131,34 @@
 #include <random>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
 #include "ceres/dynamic_autodiff_cost_function.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
-DEFINE_double(corridor_length,
-              30.0,
-              "Length of the corridor that the robot is travelling down.");
+ABSL_FLAG(double,
+          corridor_length,
+          30.0,
+          "Length of the corridor that the robot is travelling down.");
 
-DEFINE_double(pose_separation,
-              0.5,
-              "The distance that the robot traverses between successive "
-              "odometry updates.");
+ABSL_FLAG(double,
+          pose_separation,
+          0.5,
+          "The distance that the robot traverses between successive "
+          "odometry updates.");
 
-DEFINE_double(odometry_stddev,
-              0.1,
-              "The standard deviation of odometry error of the robot.");
+ABSL_FLAG(double,
+          odometry_stddev,
+          0.1,
+          "The standard deviation of odometry error of the robot.");
 
-DEFINE_double(range_stddev,
-              0.01,
-              "The standard deviation of range readings of the robot.");
+ABSL_FLAG(double,
+          range_stddev,
+          0.01,
+          "The standard deviation of range readings of the robot.");
 
 // The stride length of the dynamic_autodiff_cost_function evaluator.
 static constexpr int kStride = 10;
@@ -171,7 +178,7 @@
 
   static OdometryCostFunction* Create(const double odometry_value) {
     return new OdometryCostFunction(new OdometryConstraint(
-        odometry_value, CERES_GET_FLAG(FLAGS_odometry_stddev)));
+        odometry_value, absl::GetFlag(FLAGS_odometry_stddev)));
   }
 
   const double odometry_mean;
@@ -211,8 +218,8 @@
     auto* constraint =
         new RangeConstraint(pose_index,
                             range_reading,
-                            CERES_GET_FLAG(FLAGS_range_stddev),
-                            CERES_GET_FLAG(FLAGS_corridor_length));
+                            absl::GetFlag(FLAGS_range_stddev),
+                            absl::GetFlag(FLAGS_corridor_length));
     auto* cost_function = new RangeCostFunction(constraint);
     // Add all the parameter blocks that affect this constraint.
     parameter_blocks->clear();
@@ -235,23 +242,23 @@
 void SimulateRobot(std::vector<double>* odometry_values,
                    std::vector<double>* range_readings) {
   const int num_steps =
-      static_cast<int>(ceil(CERES_GET_FLAG(FLAGS_corridor_length) /
-                            CERES_GET_FLAG(FLAGS_pose_separation)));
+      static_cast<int>(ceil(absl::GetFlag(FLAGS_corridor_length) /
+                            absl::GetFlag(FLAGS_pose_separation)));
   std::mt19937 prng;
   std::normal_distribution<double> odometry_noise(
-      0.0, CERES_GET_FLAG(FLAGS_odometry_stddev));
+      0.0, absl::GetFlag(FLAGS_odometry_stddev));
   std::normal_distribution<double> range_noise(
-      0.0, CERES_GET_FLAG(FLAGS_range_stddev));
+      0.0, absl::GetFlag(FLAGS_range_stddev));
 
   // The robot starts out at the origin.
   double robot_location = 0.0;
   for (int i = 0; i < num_steps; ++i) {
     const double actual_odometry_value =
-        std::min(CERES_GET_FLAG(FLAGS_pose_separation),
-                 CERES_GET_FLAG(FLAGS_corridor_length) - robot_location);
+        std::min(absl::GetFlag(FLAGS_pose_separation),
+                 absl::GetFlag(FLAGS_corridor_length) - robot_location);
     robot_location += actual_odometry_value;
     const double actual_range =
-        CERES_GET_FLAG(FLAGS_corridor_length) - robot_location;
+        absl::GetFlag(FLAGS_corridor_length) - robot_location;
     const double observed_odometry =
         actual_odometry_value + odometry_noise(prng);
     const double observed_range = actual_range + range_noise(prng);
@@ -268,9 +275,9 @@
   for (int i = 0; i < odometry_readings.size(); ++i) {
     robot_location += odometry_readings[i];
     const double range_error = robot_location + range_readings[i] -
-                               CERES_GET_FLAG(FLAGS_corridor_length);
+                               absl::GetFlag(FLAGS_corridor_length);
     const double odometry_error =
-        CERES_GET_FLAG(FLAGS_pose_separation) - odometry_readings[i];
+        absl::GetFlag(FLAGS_pose_separation) - odometry_readings[i];
     printf("%4d: %8.3f %8.3f %8.3f %8.3f %8.3f\n",
            static_cast<int>(i),
            robot_location,
@@ -284,13 +291,13 @@
 }  // namespace
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
   // Make sure that the arguments parsed are all positive.
-  CHECK_GT(CERES_GET_FLAG(FLAGS_corridor_length), 0.0);
-  CHECK_GT(CERES_GET_FLAG(FLAGS_pose_separation), 0.0);
-  CHECK_GT(CERES_GET_FLAG(FLAGS_odometry_stddev), 0.0);
-  CHECK_GT(CERES_GET_FLAG(FLAGS_range_stddev), 0.0);
+  CHECK_GT(absl::GetFlag(FLAGS_corridor_length), 0.0);
+  CHECK_GT(absl::GetFlag(FLAGS_pose_separation), 0.0);
+  CHECK_GT(absl::GetFlag(FLAGS_odometry_stddev), 0.0);
+  CHECK_GT(absl::GetFlag(FLAGS_range_stddev), 0.0);
 
   std::vector<double> odometry_values;
   std::vector<double> range_readings;
diff --git a/examples/robust_curve_fitting.cc b/examples/robust_curve_fitting.cc
index e08b0df..dcb205e 100644
--- a/examples/robust_curve_fitting.cc
+++ b/examples/robust_curve_fitting.cc
@@ -34,8 +34,9 @@
 // the use of a robust loss function (CauchyLoss) to reduce the influence of the
 // outliers on the fit.
 
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // Data generated using the following octave code.
 //   randn('seed', 23497);
@@ -136,7 +137,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   const double initial_m = 0.0;
   const double initial_c = 0.0;
diff --git a/examples/rosenbrock.cc b/examples/rosenbrock.cc
index a382ccd..df609a0 100644
--- a/examples/rosenbrock.cc
+++ b/examples/rosenbrock.cc
@@ -32,8 +32,8 @@
 // (https://en.wikipedia.org/wiki/Rosenbrock_function) using
 // GradientProblemSolver using automatically computed derivatives.
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // f(x,y) = (1-x)^2 + 100(y - x^2)^2;
 struct Rosenbrock {
@@ -53,7 +53,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   double parameters[2] = {-1.2, 1.0};
 
diff --git a/examples/rosenbrock_analytic_diff.cc b/examples/rosenbrock_analytic_diff.cc
index 65e49eb..5b7c30d 100644
--- a/examples/rosenbrock_analytic_diff.cc
+++ b/examples/rosenbrock_analytic_diff.cc
@@ -32,8 +32,8 @@
 // (https://en.wikipedia.org/wiki/Rosenbrock_function) using
 // GradientProblemSolver using analytic derivatives.
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // f(x,y) = (1-x)^2 + 100(y - x^2)^2;
 class Rosenbrock final : public ceres::FirstOrderFunction {
@@ -58,7 +58,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   double parameters[2] = {-1.2, 1.0};
 
diff --git a/examples/rosenbrock_numeric_diff.cc b/examples/rosenbrock_numeric_diff.cc
index a711b2f..4115669 100644
--- a/examples/rosenbrock_numeric_diff.cc
+++ b/examples/rosenbrock_numeric_diff.cc
@@ -33,8 +33,10 @@
 // GradientProblemSolver using derivatives computed using numeric
 // differentiation.
 
+#include <iostream>
+
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 
 // f(x,y) = (1-x)^2 + 100(y - x^2)^2;
 struct Rosenbrock {
@@ -55,7 +57,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
 
   double parameters[2] = {-1.2, 1.0};
 
diff --git a/examples/sampled_function/CMakeLists.txt b/examples/sampled_function/CMakeLists.txt
index 1013753..65f9249 100644
--- a/examples/sampled_function/CMakeLists.txt
+++ b/examples/sampled_function/CMakeLists.txt
@@ -29,4 +29,4 @@
 # Author: vitus@google.com (Michael Vitus)
 
 add_executable(sampled_function sampled_function.cc)
-target_link_libraries(sampled_function PRIVATE Ceres::ceres)
+target_link_libraries(sampled_function PRIVATE absl::log_initialize Ceres::ceres)
diff --git a/examples/sampled_function/sampled_function.cc b/examples/sampled_function/sampled_function.cc
index 40e9c1f..9c4c970 100644
--- a/examples/sampled_function/sampled_function.cc
+++ b/examples/sampled_function/sampled_function.cc
@@ -31,9 +31,9 @@
 // A simple example of optimizing a sampled function by using cubic
 // interpolation.
 
+#include "absl/log/initialize.h"
 #include "ceres/ceres.h"
 #include "ceres/cubic_interpolation.h"
-#include "glog/logging.h"
 
 using Interpolator = ceres::CubicInterpolator<ceres::Grid1D<double>>;
 
@@ -59,8 +59,7 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
-
+  absl::InitializeLog();
   // Evaluate the function f(x) = (x - 4.5)^2;
   const int kNumSamples = 10;
   double values[kNumSamples];
diff --git a/examples/simple_bundle_adjuster.cc b/examples/simple_bundle_adjuster.cc
index bb0ba1c..3350e3d 100644
--- a/examples/simple_bundle_adjuster.cc
+++ b/examples/simple_bundle_adjuster.cc
@@ -39,6 +39,8 @@
 #include <cstdio>
 #include <iostream>
 
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
 #include "ceres/rotation.h"
 
@@ -173,7 +175,8 @@
 };
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
+  absl::InitializeLog();
+
   if (argc != 2) {
     std::cerr << "usage: simple_bundle_adjuster <bal_problem>\n";
     return 1;
diff --git a/examples/slam/common/read_g2o.h b/examples/slam/common/read_g2o.h
index 490b054..2999339 100644
--- a/examples/slam/common/read_g2o.h
+++ b/examples/slam/common/read_g2o.h
@@ -36,7 +36,8 @@
 #include <fstream>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace ceres::examples {
 
diff --git a/examples/slam/pose_graph_2d/CMakeLists.txt b/examples/slam/pose_graph_2d/CMakeLists.txt
index 87943ec..c6cfb80 100644
--- a/examples/slam/pose_graph_2d/CMakeLists.txt
+++ b/examples/slam/pose_graph_2d/CMakeLists.txt
@@ -28,12 +28,10 @@
 #
 # Author: vitus@google.com (Michael Vitus)
 
-if (GFLAGS)
-  add_executable(pose_graph_2d
-    angle_manifold.h
-    normalize_angle.h
-    pose_graph_2d.cc
-    pose_graph_2d_error_term.h
-    types.h)
-  target_link_libraries(pose_graph_2d PRIVATE Ceres::ceres gflags)
-endif (GFLAGS)
+add_executable(pose_graph_2d
+  angle_manifold.h
+  normalize_angle.h
+  pose_graph_2d.cc
+  pose_graph_2d_error_term.h
+  types.h)
+target_link_libraries(pose_graph_2d PRIVATE absl::flags absl::flags_parse absl::log absl::check absl::log_initialize Ceres::ceres)
diff --git a/examples/slam/pose_graph_2d/pose_graph_2d.cc b/examples/slam/pose_graph_2d/pose_graph_2d.cc
index 3ebae3f..fe7d16d 100644
--- a/examples/slam/pose_graph_2d/pose_graph_2d.cc
+++ b/examples/slam/pose_graph_2d/pose_graph_2d.cc
@@ -39,15 +39,21 @@
 #include <string>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "angle_manifold.h"
 #include "ceres/ceres.h"
 #include "common/read_g2o.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "pose_graph_2d_error_term.h"
 #include "types.h"
 
-DEFINE_string(input, "", "The pose graph definition filename in g2o format.");
+ABSL_FLAG(std::string,
+          input,
+          "",
+          "The pose graph definition filename in g2o format.");
 
 namespace ceres::examples {
 namespace {
@@ -143,16 +149,19 @@
 }  // namespace ceres::examples
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
 
-  CHECK(FLAGS_input != "") << "Need to specify the filename to read.";
+  if (absl::GetFlag(FLAGS_input).empty()) {
+    LOG(ERROR) << "Usage pose_graph_3d --input=<filename>";
+    return 1;
+  }
 
   std::map<int, ceres::examples::Pose2d> poses;
   std::vector<ceres::examples::Constraint2d> constraints;
-
-  CHECK(ceres::examples::ReadG2oFile(FLAGS_input, &poses, &constraints))
-      << "Error reading the file: " << FLAGS_input;
+  CHECK(ceres::examples::ReadG2oFile(
+      absl::GetFlag(FLAGS_input), &poses, &constraints))
+      << "Error reading the file: " << absl::GetFlag(FLAGS_input);
 
   std::cout << "Number of poses: " << poses.size() << '\n';
   std::cout << "Number of constraints: " << constraints.size() << '\n';
diff --git a/examples/slam/pose_graph_3d/CMakeLists.txt b/examples/slam/pose_graph_3d/CMakeLists.txt
index 544b00e..d1fbae6 100644
--- a/examples/slam/pose_graph_3d/CMakeLists.txt
+++ b/examples/slam/pose_graph_3d/CMakeLists.txt
@@ -28,7 +28,5 @@
 #
 # Author: vitus@google.com (Michael Vitus)
 
-if (GFLAGS)
-  add_executable(pose_graph_3d pose_graph_3d.cc)
-  target_link_libraries(pose_graph_3d PRIVATE Ceres::ceres gflags)
-endif (GFLAGS)
+add_executable(pose_graph_3d pose_graph_3d.cc)
+target_link_libraries(pose_graph_3d PRIVATE absl::flags absl::flags_parse absl::log absl::check absl::log_initialize Ceres::ceres)
diff --git a/examples/slam/pose_graph_3d/pose_graph_3d.cc b/examples/slam/pose_graph_3d/pose_graph_3d.cc
index 522e2a1..783f685 100644
--- a/examples/slam/pose_graph_3d/pose_graph_3d.cc
+++ b/examples/slam/pose_graph_3d/pose_graph_3d.cc
@@ -32,14 +32,20 @@
 #include <iostream>
 #include <string>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 #include "ceres/ceres.h"
 #include "common/read_g2o.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "pose_graph_3d_error_term.h"
 #include "types.h"
 
-DEFINE_string(input, "", "The pose graph definition filename in g2o format.");
+ABSL_FLAG(std::string,
+          input,
+          "",
+          "The pose graph definition filename in g2o format.");
 
 namespace ceres::examples {
 namespace {
@@ -135,16 +141,19 @@
 }  // namespace ceres::examples
 
 int main(int argc, char** argv) {
-  google::InitGoogleLogging(argv[0]);
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-
-  CHECK(FLAGS_input != "") << "Need to specify the filename to read.";
+  absl::InitializeLog();
+  absl::ParseCommandLine(argc, argv);
+  if (absl::GetFlag(FLAGS_input).empty()) {
+    LOG(ERROR) << "Usage pose_graph_3d --input=<filename>";
+    return 1;
+  }
 
   ceres::examples::MapOfPoses poses;
   ceres::examples::VectorOfConstraints constraints;
 
-  CHECK(ceres::examples::ReadG2oFile(FLAGS_input, &poses, &constraints))
-      << "Error reading the file: " << FLAGS_input;
+  CHECK(ceres::examples::ReadG2oFile(
+      absl::GetFlag(FLAGS_input), &poses, &constraints))
+      << "Error reading the file: " << absl::GetFlag(FLAGS_input);
 
   std::cout << "Number of poses: " << poses.size() << '\n';
   std::cout << "Number of constraints: " << constraints.size() << '\n';
diff --git a/include/ceres/cost_function_to_functor.h b/include/ceres/cost_function_to_functor.h
index 573508e..a2ca6d8 100644
--- a/include/ceres/cost_function_to_functor.h
+++ b/include/ceres/cost_function_to_functor.h
@@ -92,11 +92,11 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/cost_function.h"
 #include "ceres/dynamic_cost_function_to_functor.h"
 #include "ceres/internal/parameter_dims.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/cubic_interpolation.h b/include/ceres/cubic_interpolation.h
index f165d2b..29f246b 100644
--- a/include/ceres/cubic_interpolation.h
+++ b/include/ceres/cubic_interpolation.h
@@ -32,8 +32,8 @@
 #define CERES_PUBLIC_CUBIC_INTERPOLATION_H_
 
 #include "Eigen/Core"
+#include "absl/log/check.h"
 #include "ceres/internal/export.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/dynamic_autodiff_cost_function.h b/include/ceres/dynamic_autodiff_cost_function.h
index 2b8724d..7b4e876 100644
--- a/include/ceres/dynamic_autodiff_cost_function.h
+++ b/include/ceres/dynamic_autodiff_cost_function.h
@@ -38,11 +38,11 @@
 #include <type_traits>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/dynamic_cost_function.h"
 #include "ceres/internal/fixed_array.h"
 #include "ceres/jet.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/dynamic_cost_function_to_functor.h b/include/ceres/dynamic_cost_function_to_functor.h
index 45ed90f..331d367 100644
--- a/include/ceres/dynamic_cost_function_to_functor.h
+++ b/include/ceres/dynamic_cost_function_to_functor.h
@@ -36,11 +36,11 @@
 #include <numeric>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/dynamic_cost_function.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/internal/fixed_array.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/dynamic_numeric_diff_cost_function.h b/include/ceres/dynamic_numeric_diff_cost_function.h
index 1ce384f..2cd0e9c 100644
--- a/include/ceres/dynamic_numeric_diff_cost_function.h
+++ b/include/ceres/dynamic_numeric_diff_cost_function.h
@@ -40,13 +40,13 @@
 #include <type_traits>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/dynamic_cost_function.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/numeric_diff.h"
 #include "ceres/internal/parameter_dims.h"
 #include "ceres/numeric_diff_options.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/gradient_checker.h b/include/ceres/gradient_checker.h
index 77f2c8e..765d53c 100644
--- a/include/ceres/gradient_checker.h
+++ b/include/ceres/gradient_checker.h
@@ -45,7 +45,6 @@
 #include "ceres/internal/export.h"
 #include "ceres/internal/fixed_array.h"
 #include "ceres/manifold.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/internal/autodiff.h b/include/ceres/internal/autodiff.h
index 8b02a2b..e437417 100644
--- a/include/ceres/internal/autodiff.h
+++ b/include/ceres/internal/autodiff.h
@@ -144,6 +144,7 @@
 #include <cstddef>
 #include <utility>
 
+#include "absl/log/check.h"
 #include "ceres/internal/array_selector.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/fixed_array.h"
@@ -151,7 +152,6 @@
 #include "ceres/internal/variadic_evaluate.h"
 #include "ceres/jet.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 // If the number of parameters exceeds this values, the corresponding jets are
 // placed on the heap. This will reduce performance by a factor of 2-5 on
diff --git a/include/ceres/internal/fixed_array.h b/include/ceres/internal/fixed_array.h
index 0e35f63..7c1b65d 100644
--- a/include/ceres/internal/fixed_array.h
+++ b/include/ceres/internal/fixed_array.h
@@ -38,8 +38,8 @@
 #include <tuple>
 #include <type_traits>
 
+#include "absl/log/check.h"
 #include "ceres/internal/memory.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/include/ceres/internal/householder_vector.h b/include/ceres/internal/householder_vector.h
index dd8361c..3398d00 100644
--- a/include/ceres/internal/householder_vector.h
+++ b/include/ceres/internal/householder_vector.h
@@ -32,7 +32,7 @@
 #define CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
 
 #include "Eigen/Core"
-#include "glog/logging.h"
+#include "absl/log/check.h"
 
 namespace ceres::internal {
 
diff --git a/include/ceres/internal/numeric_diff.h b/include/ceres/internal/numeric_diff.h
index ba28bec..4031631 100644
--- a/include/ceres/internal/numeric_diff.h
+++ b/include/ceres/internal/numeric_diff.h
@@ -40,12 +40,12 @@
 
 #include "Eigen/Dense"
 #include "Eigen/StdVector"
+#include "absl/log/check.h"
 #include "ceres/cost_function.h"
 #include "ceres/internal/fixed_array.h"
 #include "ceres/internal/variadic_evaluate.h"
 #include "ceres/numeric_diff_options.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/include/ceres/internal/port.h b/include/ceres/internal/port.h
index d78ed51..b74ca21 100644
--- a/include/ceres/internal/port.h
+++ b/include/ceres/internal/port.h
@@ -45,10 +45,6 @@
 #define CERES_DEPRECATED_WITH_MSG(message) [[deprecated(message)]]
 #endif
 
-#ifndef CERES_GET_FLAG
-#define CERES_GET_FLAG(X) X
-#endif
-
 // Indicates whether C++20 is currently active
 #ifndef CERES_HAS_CPP20
 #if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
diff --git a/include/ceres/line_manifold.h b/include/ceres/line_manifold.h
index dad9737..64b61ba 100644
--- a/include/ceres/line_manifold.h
+++ b/include/ceres/line_manifold.h
@@ -38,13 +38,13 @@
 #include <memory>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/internal/householder_vector.h"
 #include "ceres/internal/sphere_manifold_functions.h"
 #include "ceres/manifold.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 // This provides a manifold for lines, where the line is
diff --git a/include/ceres/loss_function.h b/include/ceres/loss_function.h
index b8582f8..51e372d 100644
--- a/include/ceres/loss_function.h
+++ b/include/ceres/loss_function.h
@@ -80,7 +80,6 @@
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/manifold.h b/include/ceres/manifold.h
index 9bd6459..ec4eff0 100644
--- a/include/ceres/manifold.h
+++ b/include/ceres/manifold.h
@@ -38,10 +38,10 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/numeric_diff_first_order_function.h b/include/ceres/numeric_diff_first_order_function.h
index 525f197..612ace9 100644
--- a/include/ceres/numeric_diff_first_order_function.h
+++ b/include/ceres/numeric_diff_first_order_function.h
@@ -36,6 +36,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "absl/log/check.h"
 #include "ceres/first_order_function.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/fixed_array.h"
@@ -44,7 +45,6 @@
 #include "ceres/internal/variadic_evaluate.h"
 #include "ceres/numeric_diff_options.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/ordered_groups.h b/include/ceres/ordered_groups.h
index d15d22d..9ae8499 100644
--- a/include/ceres/ordered_groups.h
+++ b/include/ceres/ordered_groups.h
@@ -36,8 +36,8 @@
 #include <unordered_map>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/internal/export.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/problem.h b/include/ceres/problem.h
index 4c6fd1b..f587594 100644
--- a/include/ceres/problem.h
+++ b/include/ceres/problem.h
@@ -46,7 +46,6 @@
 #include "ceres/internal/export.h"
 #include "ceres/internal/port.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/rotation.h b/include/ceres/rotation.h
index 0cccfa7..367a7d0 100644
--- a/include/ceres/rotation.h
+++ b/include/ceres/rotation.h
@@ -48,9 +48,9 @@
 #include <algorithm>
 #include <cmath>
 
+#include "absl/log/check.h"
 #include "ceres/constants.h"
 #include "ceres/internal/euler_angles.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/sphere_manifold.h b/include/ceres/sphere_manifold.h
index 1c7458b..06983a0 100644
--- a/include/ceres/sphere_manifold.h
+++ b/include/ceres/sphere_manifold.h
@@ -38,13 +38,13 @@
 #include <memory>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/internal/householder_vector.h"
 #include "ceres/internal/sphere_manifold_functions.h"
 #include "ceres/manifold.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/include/ceres/tiny_solver_cost_function_adapter.h b/include/ceres/tiny_solver_cost_function_adapter.h
index 166f03f..39ba266 100644
--- a/include/ceres/tiny_solver_cost_function_adapter.h
+++ b/include/ceres/tiny_solver_cost_function_adapter.h
@@ -32,8 +32,8 @@
 #define CERES_PUBLIC_TINY_SOLVER_COST_FUNCTION_ADAPTER_H_
 
 #include "Eigen/Core"
+#include "absl/log/check.h"
 #include "ceres/cost_function.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 6c1fe93..f30ba00 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -19,7 +19,7 @@
 # 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
+# CONSEQUENTIAblockL 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)
@@ -37,6 +37,9 @@
 # Make dependency visible to the parent CMakeLists.txt
 set(Threads_DEPENDENCY "find_dependency (Threads)" PARENT_SCOPE)
 
+list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES absl::log)
+list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES absl::check)
+
 # Source files that contain public symbols and live in the ceres namespaces.
 # Such symbols are expected to be marked with CERES_EXPORT and the files below
 # sorted in lexicographical order.
@@ -54,14 +57,6 @@
 
 # Also depend on the header files so that they appear in IDEs.
 file(GLOB CERES_INTERNAL_HDRS *.h)
-if (MINIGLOG)
-  file(GLOB MINIGLOG_HDRS miniglog/glog/*.h)
-  list(APPEND CERES_INTERNAL_HDRS ${MINIGLOG_HDRS})
-  if (ANDROID)
-    list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES log)
-  endif()
-endif()
-
 # Depend also on public headers so they appear in IDEs.
 file(GLOB CERES_PUBLIC_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
 file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
@@ -85,18 +80,6 @@
 set_source_files_properties(${CERES_INTERNAL_SCHUR_FILES} PROPERTIES
   SKIP_UNITY_BUILD_INCLUSION ON)
 
-if (NOT MINIGLOG AND GLOG_FOUND)
-  list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GLOG_LIBRARIES})
-  if (gflags_FOUND)
-    # If glog & gflags are both found, we assume that glog was built with
-    # gflags, as it is awkward to perform a try_compile() to verify this
-    # when gflags is an imported target (as it is in newer versions).
-    # As glog #includes gflags/gflags.h in glog/logging.h if compiled with
-    # gflags, it is thus a public dependency for Ceres in this case.
-    list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES gflags)
-  endif()
-endif (NOT MINIGLOG AND GLOG_FOUND)
-
 if (SUITESPARSE AND SuiteSparse_FOUND)
   # Define version information for use in Solver::FullReport.
   add_definitions(-DCERES_SUITESPARSE_VERSION="${SuiteSparse_VERSION}")
@@ -253,11 +236,6 @@
     ${CERES_PUBLIC_HDRS}
     ${CERES_PUBLIC_INTERNAL_HDRS})
 
-# Primarily for Android, but optionally for others, compile the minimal
-# glog implementation into Ceres.
-if (MINIGLOG)
-  list(APPEND CERES_LIBRARY_SOURCE miniglog/glog/logging.cc)
-endif (MINIGLOG)
 
 # Ceres C++ compiler flags can be too strict for an external library code
 # which we do not maintain.
@@ -340,30 +318,12 @@
 # dependencies to be added to the Ceres target.
 set(CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS "")
 set(CERES_LIBRARY_PUBLIC_DEPENDENCIES_INCLUDE_DIRS "")
-if (MINIGLOG)
-  # Force the miniglog headers to the front of the public include directories
-  # to protect against the case when the user has glog installed in a standard
-  # location (specifically the same as the Ceres install location) but compiled
-  # Ceres with MINIGLOG anyway.  Otherwise: "glog/logging.h" in the public Ceres
-  # headers used in client code would match the installed version of glog, not
-  # the miniglog headers, and the client application would fail to link.
-  #
-  # Note that this is an imperfect fix, as we cannot control the include
-  # directories in client projects, and they could easily invert this ordering
-  # themselves (intentionally or otherwise) and so break their build.
-  target_include_directories(ceres BEFORE PUBLIC
-    $<BUILD_INTERFACE:${Ceres_SOURCE_DIR}/internal/ceres/miniglog>
-    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal/miniglog>)
-elseif (NOT FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
-  # Only append glog include directories if the glog found was not a CMake
-  # exported target that already includes them.
-  list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES_INCLUDE_DIRS
-    ${GLOG_INCLUDE_DIRS})
-endif()
+
 if (ACCELERATESPARSE)
   list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS
     ${AccelerateSparse_INCLUDE_DIRS})
 endif()
+
 # Add include locations for optional dependencies to the Ceres target without
 # duplication.
 list(REMOVE_DUPLICATES CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS)
@@ -391,6 +351,16 @@
         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
diff --git a/internal/ceres/accelerate_sparse.cc b/internal/ceres/accelerate_sparse.cc
index 0baadc0..753bf98 100644
--- a/internal/ceres/accelerate_sparse.cc
+++ b/internal/ceres/accelerate_sparse.cc
@@ -38,11 +38,12 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/accelerate_sparse.h"
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
+#include "ceres/stringprintf.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 
 #define CASESTR(x) \
   case x:          \
diff --git a/internal/ceres/block_jacobian_writer.cc b/internal/ceres/block_jacobian_writer.cc
index 5a769cb..e29bc1b 100644
--- a/internal/ceres/block_jacobian_writer.cc
+++ b/internal/ceres/block_jacobian_writer.cc
@@ -34,6 +34,8 @@
 #include <memory>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_evaluate_preparer.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
diff --git a/internal/ceres/block_random_access_dense_matrix.cc b/internal/ceres/block_random_access_dense_matrix.cc
index b8be51b..3e7d86a 100644
--- a/internal/ceres/block_random_access_dense_matrix.cc
+++ b/internal/ceres/block_random_access_dense_matrix.cc
@@ -35,7 +35,6 @@
 
 #include "ceres/internal/eigen.h"
 #include "ceres/parallel_vector_ops.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/block_random_access_diagonal_matrix.cc b/internal/ceres/block_random_access_diagonal_matrix.cc
index 643dbf1..b657266 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix.cc
@@ -37,13 +37,13 @@
 #include <vector>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/internal/export.h"
 #include "ceres/parallel_for.h"
 #include "ceres/parallel_vector_ops.h"
 #include "ceres/stl_util.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/block_random_access_diagonal_matrix_test.cc b/internal/ceres/block_random_access_diagonal_matrix_test.cc
index f665bd8..9590d1b 100644
--- a/internal/ceres/block_random_access_diagonal_matrix_test.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix_test.cc
@@ -36,7 +36,6 @@
 
 #include "Eigen/Cholesky"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/block_random_access_sparse_matrix.cc b/internal/ceres/block_random_access_sparse_matrix.cc
index b9f8b36..6694d06 100644
--- a/internal/ceres/block_random_access_sparse_matrix.cc
+++ b/internal/ceres/block_random_access_sparse_matrix.cc
@@ -36,11 +36,12 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/internal/export.h"
 #include "ceres/parallel_vector_ops.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/block_random_access_sparse_matrix_test.cc b/internal/ceres/block_random_access_sparse_matrix_test.cc
index 0bb39f1..3740682 100644
--- a/internal/ceres/block_random_access_sparse_matrix_test.cc
+++ b/internal/ceres/block_random_access_sparse_matrix_test.cc
@@ -37,7 +37,6 @@
 #include <vector>
 
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/block_sparse_matrix.cc b/internal/ceres/block_sparse_matrix.cc
index 2efee39..0878988 100644
--- a/internal/ceres/block_sparse_matrix.cc
+++ b/internal/ceres/block_sparse_matrix.cc
@@ -37,6 +37,8 @@
 #include <random>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_structure.h"
 #include "ceres/crs_matrix.h"
 #include "ceres/internal/eigen.h"
@@ -44,7 +46,6 @@
 #include "ceres/parallel_vector_ops.h"
 #include "ceres/small_blas.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 
 #ifndef CERES_NO_CUDA
 #include "cuda_runtime.h"
diff --git a/internal/ceres/block_sparse_matrix.h b/internal/ceres/block_sparse_matrix.h
index 2e45488..126b5aa 100644
--- a/internal/ceres/block_sparse_matrix.h
+++ b/internal/ceres/block_sparse_matrix.h
@@ -184,7 +184,7 @@
 class CERES_NO_EXPORT BlockSparseMatrixData {
  public:
   explicit BlockSparseMatrixData(const BlockSparseMatrix& m)
-      : block_structure_(m.block_structure()), values_(m.values()){};
+      : block_structure_(m.block_structure()), values_(m.values()) {};
 
   BlockSparseMatrixData(const CompressedRowBlockStructure* block_structure,
                         const double* values)
diff --git a/internal/ceres/block_sparse_matrix_test.cc b/internal/ceres/block_sparse_matrix_test.cc
index 4a524f9..c27146d 100644
--- a/internal/ceres/block_sparse_matrix_test.cc
+++ b/internal/ceres/block_sparse_matrix_test.cc
@@ -41,7 +41,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -158,16 +157,16 @@
   void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem =
         CreateLinearLeastSquaresProblemFromId(2);
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     a_.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
 
     problem = CreateLinearLeastSquaresProblemFromId(1);
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     b_.reset(down_cast<TripletSparseMatrix*>(problem->A.release()));
 
-    CHECK_EQ(a_->num_rows(), b_->num_rows());
-    CHECK_EQ(a_->num_cols(), b_->num_cols());
-    CHECK_EQ(a_->num_nonzeros(), b_->num_nonzeros());
+    ASSERT_EQ(a_->num_rows(), b_->num_rows());
+    ASSERT_EQ(a_->num_cols(), b_->num_cols());
+    ASSERT_EQ(a_->num_nonzeros(), b_->num_nonzeros());
     context_.EnsureMinimumThreads(kNumThreads);
 
     BlockSparseMatrix::RandomMatrixOptions options;
@@ -350,7 +349,7 @@
     if (t == -1) {
       a_->AppendRows(*m);
     } else if (t > 0) {
-      CHECK_GE(block_structure->rows.size(), t);
+      ASSERT_GE(block_structure->rows.size(), t);
       a_->DeleteRowBlocks(t);
     }
 
diff --git a/internal/ceres/block_structure.cc b/internal/ceres/block_structure.cc
index 70f68b2..b327453 100644
--- a/internal/ceres/block_structure.cc
+++ b/internal/ceres/block_structure.cc
@@ -32,7 +32,7 @@
 
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/bundle_adjustment_test_util.h b/internal/ceres/bundle_adjustment_test_util.h
index 48b833b..0b2b8fb 100644
--- a/internal/ceres/bundle_adjustment_test_util.h
+++ b/internal/ceres/bundle_adjustment_test_util.h
@@ -37,6 +37,7 @@
 #include <cstdlib>
 #include <string>
 
+#include "absl/log/log.h"
 #include "ceres/autodiff_cost_function.h"
 #include "ceres/internal/export.h"
 #include "ceres/ordered_groups.h"
@@ -46,7 +47,6 @@
 #include "ceres/stringprintf.h"
 #include "ceres/test_util.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/c_api.cc b/internal/ceres/c_api.cc
index 56e1324..13a1226 100644
--- a/internal/ceres/c_api.cc
+++ b/internal/ceres/c_api.cc
@@ -39,20 +39,21 @@
 #include <string>
 #include <vector>
 
+// #include "absl/log/initialize.h"
 #include "ceres/cost_function.h"
 #include "ceres/loss_function.h"
 #include "ceres/problem.h"
 #include "ceres/solver.h"
 #include "ceres/types.h"  // for std
-#include "glog/logging.h"
 
 using ceres::Problem;
 
 void ceres_init() {
-  // This is not ideal, but it's not clear what to do if there is no gflags and
-  // no access to command line arguments.
-  char message[] = "<unknown>";
-  google::InitGoogleLogging(message);
+  // TODO(sameeragarwal): This is currently broken, because if I include this,
+  // then I need to link absl::log_initialize into c_api_test, since
+  // Ceres::ceres does not link into it.
+  //
+  // absl::InitializeLog();
 }
 
 ceres_problem_t* ceres_create_problem() {
diff --git a/internal/ceres/c_api_test.cc b/internal/ceres/c_api_test.cc
index 9386765..7aab9f6 100644
--- a/internal/ceres/c_api_test.cc
+++ b/internal/ceres/c_api_test.cc
@@ -32,7 +32,6 @@
 
 #include <cmath>
 
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 // Duplicated from curve_fitting.cc.
diff --git a/internal/ceres/callbacks.cc b/internal/ceres/callbacks.cc
index e6e0644..9412431 100644
--- a/internal/ceres/callbacks.cc
+++ b/internal/ceres/callbacks.cc
@@ -34,9 +34,9 @@
 #include <iostream>  // NO LINT
 #include <string>
 
+#include "absl/log/log.h"
 #include "ceres/program.h"
 #include "ceres/stringprintf.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/canonical_views_clustering.cc b/internal/ceres/canonical_views_clustering.cc
index d74e570..15459e1 100644
--- a/internal/ceres/canonical_views_clustering.cc
+++ b/internal/ceres/canonical_views_clustering.cc
@@ -35,10 +35,11 @@
 #include <unordered_set>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/graph.h"
 #include "ceres/internal/export.h"
 #include "ceres/map_util.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/cgnr_solver.cc b/internal/ceres/cgnr_solver.cc
index da63484..06c19d6 100644
--- a/internal/ceres/cgnr_solver.cc
+++ b/internal/ceres/cgnr_solver.cc
@@ -33,6 +33,8 @@
 #include <memory>
 #include <utility>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_jacobi_preconditioner.h"
 #include "ceres/conjugate_gradients_solver.h"
 #include "ceres/cuda_sparse_matrix.h"
@@ -41,7 +43,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/subset_preconditioner.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/compressed_col_sparse_matrix_utils.cc b/internal/ceres/compressed_col_sparse_matrix_utils.cc
index 5a25e31..c4b7067 100644
--- a/internal/ceres/compressed_col_sparse_matrix_utils.cc
+++ b/internal/ceres/compressed_col_sparse_matrix_utils.cc
@@ -33,8 +33,8 @@
 #include <algorithm>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/internal/export.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/compressed_col_sparse_matrix_utils_test.cc b/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
index b1c8219..5e0601f 100644
--- a/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
+++ b/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
@@ -37,7 +37,6 @@
 #include "Eigen/SparseCore"
 #include "ceres/internal/export.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/compressed_row_sparse_matrix.cc b/internal/ceres/compressed_row_sparse_matrix.cc
index 21697f8..2e4d647 100644
--- a/internal/ceres/compressed_row_sparse_matrix.cc
+++ b/internal/ceres/compressed_row_sparse_matrix.cc
@@ -37,12 +37,13 @@
 #include <random>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/context_impl.h"
 #include "ceres/crs_matrix.h"
 #include "ceres/internal/export.h"
 #include "ceres/parallel_for.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 namespace {
diff --git a/internal/ceres/compressed_row_sparse_matrix.h b/internal/ceres/compressed_row_sparse_matrix.h
index 36c8895..1a83924 100644
--- a/internal/ceres/compressed_row_sparse_matrix.h
+++ b/internal/ceres/compressed_row_sparse_matrix.h
@@ -40,7 +40,6 @@
 #include "ceres/internal/export.h"
 #include "ceres/sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/compressed_row_sparse_matrix_test.cc b/internal/ceres/compressed_row_sparse_matrix_test.cc
index b6bcdb7..d528d1f 100644
--- a/internal/ceres/compressed_row_sparse_matrix_test.cc
+++ b/internal/ceres/compressed_row_sparse_matrix_test.cc
@@ -44,7 +44,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -74,7 +73,7 @@
   void SetUp() final {
     auto problem = CreateLinearLeastSquaresProblemFromId(1);
 
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
 
     tsm.reset(down_cast<TripletSparseMatrix*>(problem->A.release()));
     crsm = CompressedRowSparseMatrix::FromTripletSparseMatrix(*tsm);
diff --git a/internal/ceres/concurrent_queue.h b/internal/ceres/concurrent_queue.h
index 5f490ab..972781d 100644
--- a/internal/ceres/concurrent_queue.h
+++ b/internal/ceres/concurrent_queue.h
@@ -36,7 +36,7 @@
 #include <queue>
 #include <thread>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/conditioned_cost_function.cc b/internal/ceres/conditioned_cost_function.cc
index 5c826a9..8f42f4b 100644
--- a/internal/ceres/conditioned_cost_function.cc
+++ b/internal/ceres/conditioned_cost_function.cc
@@ -34,10 +34,10 @@
 
 #include <cstddef>
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/stl_util.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/conjugate_gradients_solver.h b/internal/ceres/conjugate_gradients_solver.h
index 84383ea..fb343ea 100644
--- a/internal/ceres/conjugate_gradients_solver.h
+++ b/internal/ceres/conjugate_gradients_solver.h
@@ -46,7 +46,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/corrector.cc b/internal/ceres/corrector.cc
index d9b80cd..0d3007c 100644
--- a/internal/ceres/corrector.cc
+++ b/internal/ceres/corrector.cc
@@ -33,8 +33,8 @@
 #include <cmath>
 #include <cstddef>
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/covariance_impl.cc b/internal/ceres/covariance_impl.cc
index 6e8362d..c9c292f 100644
--- a/internal/ceres/covariance_impl.cc
+++ b/internal/ceres/covariance_impl.cc
@@ -42,6 +42,8 @@
 #include "Eigen/SVD"
 #include "Eigen/SparseCore"
 #include "Eigen/SparseQR"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/covariance.h"
@@ -55,7 +57,6 @@
 #include "ceres/residual_block.h"
 #include "ceres/suitesparse.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/covariance_test.cc b/internal/ceres/covariance_test.cc
index 40d9b0e..49e5d6f 100644
--- a/internal/ceres/covariance_test.cc
+++ b/internal/ceres/covariance_test.cc
@@ -38,6 +38,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/autodiff_cost_function.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/cost_function.h"
diff --git a/internal/ceres/cubic_interpolation_test.cc b/internal/ceres/cubic_interpolation_test.cc
index c02951e..ace9b2b 100644
--- a/internal/ceres/cubic_interpolation_test.cc
+++ b/internal/ceres/cubic_interpolation_test.cc
@@ -33,7 +33,6 @@
 #include <memory>
 
 #include "ceres/jet.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/cuda_block_sparse_crs_view.cc b/internal/ceres/cuda_block_sparse_crs_view.cc
index 7564d52..c356005 100644
--- a/internal/ceres/cuda_block_sparse_crs_view.cc
+++ b/internal/ceres/cuda_block_sparse_crs_view.cc
@@ -32,6 +32,8 @@
 
 #ifndef CERES_NO_CUDA
 
+#include "absl/log/check.h"
+#include "absl/log/logging.h"
 #include "ceres/cuda_kernels_bsm_to_crs.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/cuda_block_sparse_crs_view_test.cc b/internal/ceres/cuda_block_sparse_crs_view_test.cc
index 7d7d46c..75643d7 100644
--- a/internal/ceres/cuda_block_sparse_crs_view_test.cc
+++ b/internal/ceres/cuda_block_sparse_crs_view_test.cc
@@ -30,11 +30,10 @@
 
 #include "ceres/cuda_block_sparse_crs_view.h"
 
-#include <glog/logging.h>
-#include <gtest/gtest.h>
-
 #include <numeric>
 
+#include "gtest/gtest.h"
+
 #ifndef CERES_NO_CUDA
 
 namespace ceres::internal {
@@ -42,7 +41,7 @@
  protected:
   void SetUp() final {
     std::string message;
-    CHECK(context_.InitCuda(&message))
+    ASSERT_TRUE(context_.InitCuda(&message))
         << "InitCuda() failed because: " << message;
 
     BlockSparseMatrix::RandomMatrixOptions options;
diff --git a/internal/ceres/cuda_block_structure_test.cc b/internal/ceres/cuda_block_structure_test.cc
index daff431..c5538d1 100644
--- a/internal/ceres/cuda_block_structure_test.cc
+++ b/internal/ceres/cuda_block_structure_test.cc
@@ -32,13 +32,11 @@
 
 #ifndef CERES_NO_CUDA
 
-#include <glog/logging.h>
-#include <gtest/gtest.h>
-
 #include <numeric>
 
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/cuda_block_structure.h"
+#include "gtest/gtest.h"
 
 namespace ceres::internal {
 
@@ -46,7 +44,7 @@
  protected:
   void SetUp() final {
     std::string message;
-    CHECK(context_.InitCuda(&message))
+    ASSERT_TRUE(context_.InitCuda(&message))
         << "InitCuda() failed because: " << message;
 
     BlockSparseMatrix::RandomMatrixOptions options;
diff --git a/internal/ceres/cuda_buffer.h b/internal/ceres/cuda_buffer.h
index 95504ca..c5756ea 100644
--- a/internal/ceres/cuda_buffer.h
+++ b/internal/ceres/cuda_buffer.h
@@ -40,8 +40,8 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "cuda_runtime.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 // An encapsulated buffer to maintain GPU memory, and handle transfers between
diff --git a/internal/ceres/cuda_dense_cholesky_test.cc b/internal/ceres/cuda_dense_cholesky_test.cc
index b74a75a..d767a89 100644
--- a/internal/ceres/cuda_dense_cholesky_test.cc
+++ b/internal/ceres/cuda_dense_cholesky_test.cc
@@ -33,7 +33,6 @@
 #include "ceres/dense_cholesky.h"
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/cuda_dense_qr_test.cc b/internal/ceres/cuda_dense_qr_test.cc
index b1f25e2..e833db0 100644
--- a/internal/ceres/cuda_dense_qr_test.cc
+++ b/internal/ceres/cuda_dense_qr_test.cc
@@ -32,7 +32,6 @@
 
 #include "ceres/dense_qr.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/cuda_kernels_vector_ops_test.cc b/internal/ceres/cuda_kernels_vector_ops_test.cc
index e6116f7..f32d1d2 100644
--- a/internal/ceres/cuda_kernels_vector_ops_test.cc
+++ b/internal/ceres/cuda_kernels_vector_ops_test.cc
@@ -40,7 +40,6 @@
 #include "ceres/cuda_buffer.h"
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/cuda_partitioned_block_sparse_crs_view_test.cc b/internal/ceres/cuda_partitioned_block_sparse_crs_view_test.cc
index ddfdeef..e23b429 100644
--- a/internal/ceres/cuda_partitioned_block_sparse_crs_view_test.cc
+++ b/internal/ceres/cuda_partitioned_block_sparse_crs_view_test.cc
@@ -30,8 +30,7 @@
 
 #include "ceres/cuda_partitioned_block_sparse_crs_view.h"
 
-#include <glog/logging.h>
-#include <gtest/gtest.h>
+#include "gtest/gtest.h"
 
 #ifndef CERES_NO_CUDA
 
@@ -122,13 +121,13 @@
   // Fill positions in E sub-matrix
   int num_nonzeros = 0;
   for (int i = 0; i < options.num_row_blocks_e; ++i) {
-    CHECK_GE(block_structure->rows[i].cells.size(), 1);
+    ASSERT_GE(block_structure->rows[i].cells.size(), 1);
     block_structure->rows[i].cells[0].position = num_nonzeros;
     const int col_block_size =
         block_structure->cols[block_structure->rows[i].cells[0].block_id].size;
     const int row_block_size = block_structure->rows[i].block.size;
     num_nonzeros += row_block_size * col_block_size;
-    CHECK_GE(num_nonzeros, 0);
+    ASSERT_GE(num_nonzeros, 0);
   }
   // Fill positions in F sub-matrix
   for (int i = 0; i < options.num_row_blocks_f; ++i) {
@@ -138,7 +137,7 @@
       cell.position = num_nonzeros;
       const int col_block_size = block_structure->cols[cell.block_id].size;
       num_nonzeros += row_block_size * col_block_size;
-      CHECK_GE(num_nonzeros, 0);
+      ASSERT_GE(num_nonzeros, 0);
     }
   }
   // Populate values
@@ -156,7 +155,7 @@
  protected:
   void SetUp() final {
     std::string message;
-    CHECK(context_.InitCuda(&message))
+    ASSERT_TRUE(context_.InitCuda(&message))
         << "InitCuda() failed because: " << message;
 
     RandomPartitionedMatrixOptions options;
diff --git a/internal/ceres/cuda_sparse_matrix_test.cc b/internal/ceres/cuda_sparse_matrix_test.cc
index 774829b..c8ee429 100644
--- a/internal/ceres/cuda_sparse_matrix_test.cc
+++ b/internal/ceres/cuda_sparse_matrix_test.cc
@@ -39,7 +39,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -51,15 +50,15 @@
  protected:
   void SetUp() final {
     std::string message;
-    CHECK(context_.InitCuda(&message))
+    ASSERT_TRUE(context_.InitCuda(&message))
         << "InitCuda() failed because: " << message;
     std::unique_ptr<LinearLeastSquaresProblem> problem =
         CreateLinearLeastSquaresProblemFromId(2);
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     A_.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
-    CHECK(A_ != nullptr);
-    CHECK(problem->b != nullptr);
-    CHECK(problem->x != nullptr);
+    ASSERT_TRUE(A_ != nullptr);
+    ASSERT_TRUE(problem->b != nullptr);
+    ASSERT_TRUE(problem->x != nullptr);
     b_.resize(A_->num_rows());
     for (int i = 0; i < A_->num_rows(); ++i) {
       b_[i] = problem->b[i];
@@ -68,8 +67,8 @@
     for (int i = 0; i < A_->num_cols(); ++i) {
       x_[i] = problem->x[i];
     }
-    CHECK_EQ(A_->num_rows(), b_.rows());
-    CHECK_EQ(A_->num_cols(), x_.rows());
+    ASSERT_EQ(A_->num_rows(), b_.rows());
+    ASSERT_EQ(A_->num_cols(), x_.rows());
   }
 
   std::unique_ptr<BlockSparseMatrix> A_;
@@ -119,7 +118,8 @@
 
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   auto A1_crs = CompressedRowSparseMatrix::FromTripletSparseMatrix(A1);
   CudaSparseMatrix A_gpu(&context, *A1_crs);
   CudaVector b_gpu(&context, A1.num_cols());
@@ -157,7 +157,8 @@
 
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   auto A_crs = CompressedRowSparseMatrix::FromTripletSparseMatrix(A);
   CudaSparseMatrix A_gpu(&context, *A_crs);
   CudaVector b_gpu(&context, A.num_cols());
@@ -187,7 +188,8 @@
 
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   auto A_crs = CompressedRowSparseMatrix::FromTripletSparseMatrix(A);
   CudaSparseMatrix A_gpu(&context, *A_crs);
   CudaVector b_gpu(&context, A.num_rows());
@@ -242,7 +244,8 @@
 
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   auto A_crs = CompressedRowSparseMatrix::FromTripletSparseMatrix(A);
   CudaSparseMatrix A_gpu(&context, *A_crs);
   CudaVector b_gpu(&context, N);
diff --git a/internal/ceres/cuda_streamed_buffer_test.cc b/internal/ceres/cuda_streamed_buffer_test.cc
index 4837005..02ce3eb 100644
--- a/internal/ceres/cuda_streamed_buffer_test.cc
+++ b/internal/ceres/cuda_streamed_buffer_test.cc
@@ -32,12 +32,10 @@
 
 #ifndef CERES_NO_CUDA
 
-#include <glog/logging.h>
-#include <gtest/gtest.h>
-
 #include <numeric>
 
 #include "ceres/cuda_streamed_buffer.h"
+#include "gtest/gtest.h"
 
 namespace ceres::internal {
 
@@ -48,7 +46,8 @@
   const int kInputSize = kMaxTemporaryArraySize * 7 + 3;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
 
   std::vector<int> inputs(kInputSize);
   std::vector<int> outputs(kInputSize, -1);
@@ -62,22 +61,22 @@
                                                  int offset,
                                                  cudaStream_t stream) {
                               batches.emplace_back(offset, size);
-                              CHECK_EQ(cudaSuccess,
-                                       cudaMemcpyAsync(outputs.data() + offset,
-                                                       device_pointer,
-                                                       sizeof(int) * size,
-                                                       cudaMemcpyDeviceToHost,
-                                                       stream));
+                              ASSERT_EQ(cudaSuccess,
+                                        cudaMemcpyAsync(outputs.data() + offset,
+                                                        device_pointer,
+                                                        sizeof(int) * size,
+                                                        cudaMemcpyDeviceToHost,
+                                                        stream));
                             });
   // All operations in all streams should be completed when CopyToGpu returns
   // control to the callee
   for (int i = 0; i < ContextImpl::kNumCudaStreams; ++i) {
-    CHECK_EQ(cudaSuccess, cudaStreamQuery(context.streams_[i]));
+    ASSERT_EQ(cudaSuccess, cudaStreamQuery(context.streams_[i]));
   }
 
   // Check if every element was visited
   for (int i = 0; i < kInputSize; ++i) {
-    CHECK_EQ(outputs[i], i);
+    ASSERT_EQ(outputs[i], i);
   }
 
   // Check if there is no overlap between batches
@@ -86,14 +85,14 @@
   for (int i = 0; i < num_batches; ++i) {
     const auto [begin, size] = batches[i];
     const int end = begin + size;
-    CHECK_GE(begin, 0);
-    CHECK_LT(begin, kInputSize);
+    ASSERT_GE(begin, 0);
+    ASSERT_LT(begin, kInputSize);
 
-    CHECK_GT(size, 0);
-    CHECK_LE(end, kInputSize);
+    ASSERT_GT(size, 0);
+    ASSERT_LE(end, kInputSize);
 
     if (i + 1 == num_batches) continue;
-    CHECK_EQ(end, batches[i + 1].first);
+    ASSERT_EQ(end, batches[i + 1].first);
   }
 }
 
@@ -104,14 +103,15 @@
   const int kInputSize = kMaxTemporaryArraySize * 7 + 3;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
 
   int* inputs;
   int* outputs;
-  CHECK_EQ(cudaSuccess,
-           cudaHostAlloc(
-               &inputs, sizeof(int) * kInputSize, cudaHostAllocWriteCombined));
-  CHECK_EQ(
+  ASSERT_EQ(cudaSuccess,
+            cudaHostAlloc(
+                &inputs, sizeof(int) * kInputSize, cudaHostAllocWriteCombined));
+  ASSERT_EQ(
       cudaSuccess,
       cudaHostAlloc(&outputs, sizeof(int) * kInputSize, cudaHostAllocDefault));
 
@@ -126,22 +126,22 @@
                                                 int offset,
                                                 cudaStream_t stream) {
                               batches.emplace_back(offset, size);
-                              CHECK_EQ(cudaSuccess,
-                                       cudaMemcpyAsync(outputs + offset,
-                                                       device_pointer,
-                                                       sizeof(int) * size,
-                                                       cudaMemcpyDeviceToHost,
-                                                       stream));
+                              ASSERT_EQ(cudaSuccess,
+                                        cudaMemcpyAsync(outputs + offset,
+                                                        device_pointer,
+                                                        sizeof(int) * size,
+                                                        cudaMemcpyDeviceToHost,
+                                                        stream));
                             });
   // All operations in all streams should be completed when CopyToGpu returns
   // control to the callee
   for (int i = 0; i < ContextImpl::kNumCudaStreams; ++i) {
-    CHECK_EQ(cudaSuccess, cudaStreamQuery(context.streams_[i]));
+    ASSERT_EQ(cudaSuccess, cudaStreamQuery(context.streams_[i]));
   }
 
   // Check if every element was visited
   for (int i = 0; i < kInputSize; ++i) {
-    CHECK_EQ(outputs[i], i);
+    ASSERT_EQ(outputs[i], i);
   }
 
   // Check if there is no overlap between batches
@@ -150,18 +150,18 @@
   for (int i = 0; i < num_batches; ++i) {
     const auto [begin, size] = batches[i];
     const int end = begin + size;
-    CHECK_GE(begin, 0);
-    CHECK_LT(begin, kInputSize);
+    ASSERT_GE(begin, 0);
+    ASSERT_LT(begin, kInputSize);
 
-    CHECK_GT(size, 0);
-    CHECK_LE(end, kInputSize);
+    ASSERT_GT(size, 0);
+    ASSERT_LE(end, kInputSize);
 
     if (i + 1 == num_batches) continue;
-    CHECK_EQ(end, batches[i + 1].first);
+    ASSERT_EQ(end, batches[i + 1].first);
   }
 
-  CHECK_EQ(cudaSuccess, cudaFreeHost(inputs));
-  CHECK_EQ(cudaSuccess, cudaFreeHost(outputs));
+  ASSERT_EQ(cudaSuccess, cudaFreeHost(inputs));
+  ASSERT_EQ(cudaSuccess, cudaFreeHost(outputs));
 }
 
 }  // namespace ceres::internal
diff --git a/internal/ceres/cuda_vector_test.cc b/internal/ceres/cuda_vector_test.cc
index 8dcb4b7..0ea4703 100644
--- a/internal/ceres/cuda_vector_test.cc
+++ b/internal/ceres/cuda_vector_test.cc
@@ -34,7 +34,6 @@
 
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -45,7 +44,8 @@
 TEST(CudaVector, Creation) {
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x(&context, 1000);
   EXPECT_EQ(x.num_rows(), 1000);
   EXPECT_NE(x.data(), nullptr);
@@ -56,7 +56,8 @@
   x << 1, 2, 3;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector y(&context, 10);
   y.CopyFromCpu(x);
   EXPECT_EQ(y.num_rows(), 3);
@@ -70,7 +71,8 @@
 TEST(CudaVector, Move) {
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector y(&context, 10);
   const auto y_data = y.data();
   const auto y_descr = y.descr();
@@ -89,7 +91,8 @@
   x << 1, 2, 3;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 3);
   x_gpu.CopyFromCpu(x);
 
@@ -111,7 +114,8 @@
   y << 100, 10, 1;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 10);
   CudaVector y_gpu(&context, 10);
   x_gpu.CopyFromCpu(x);
@@ -126,7 +130,8 @@
   x << 1, 2, 3;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 10);
   x_gpu.CopyFromCpu(x);
 
@@ -144,7 +149,8 @@
   x << 1, 1, 1, 1;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 10);
   x_gpu.CopyFromCpu(x);
 
@@ -162,7 +168,8 @@
 TEST(CudaVector, Resize) {
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 10);
   EXPECT_EQ(x_gpu.num_rows(), 10);
   x_gpu.Resize(4);
@@ -176,7 +183,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -197,7 +205,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -218,7 +227,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -239,7 +249,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -258,7 +269,8 @@
   x << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -279,7 +291,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   CudaVector z_gpu(&context, 4);
@@ -301,7 +314,8 @@
   x << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector z_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -322,7 +336,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 10);
   CudaVector y_gpu(&context, 10);
   x_gpu.CopyFromCpu(x);
@@ -343,7 +358,8 @@
   y << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
@@ -362,7 +378,8 @@
   x << 100, 10, 1, 0;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 10);
   x_gpu.CopyFromCpu(x);
 
@@ -383,7 +400,8 @@
   D << 4, 3, 2, 1;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   CudaVector y_gpu(&context, 4);
   CudaVector D_gpu(&context, 4);
@@ -404,7 +422,8 @@
   x << 1, 2, 3, 4;
   ContextImpl context;
   std::string message;
-  CHECK(context.InitCuda(&message)) << "InitCuda() failed because: " << message;
+  ASSERT_TRUE(context.InitCuda(&message))
+      << "InitCuda() failed because: " << message;
   CudaVector x_gpu(&context, 4);
   x_gpu.CopyFromCpu(x);
 
diff --git a/internal/ceres/dense_cholesky.cc b/internal/ceres/dense_cholesky.cc
index 5a3e7e2..7ecff03 100644
--- a/internal/ceres/dense_cholesky.cc
+++ b/internal/ceres/dense_cholesky.cc
@@ -36,8 +36,10 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/internal/config.h"
 #include "ceres/iterative_refiner.h"
+#include "ceres/stringprintf.h"
 
 #ifndef CERES_NO_CUDA
 #include "ceres/context_impl.h"
diff --git a/internal/ceres/dense_cholesky.h b/internal/ceres/dense_cholesky.h
index 04a5dd5..4f55c58 100644
--- a/internal/ceres/dense_cholesky.h
+++ b/internal/ceres/dense_cholesky.h
@@ -43,7 +43,7 @@
 #include "ceres/context_impl.h"
 #include "ceres/cuda_buffer.h"
 #include "ceres/linear_solver.h"
-#include "glog/logging.h"
+
 #ifndef CERES_NO_CUDA
 #include "ceres/context_impl.h"
 #include "cuda_runtime.h"
diff --git a/internal/ceres/dense_cholesky_test.cc b/internal/ceres/dense_cholesky_test.cc
index 1b2e42d..b5972ef 100644
--- a/internal/ceres/dense_cholesky_test.cc
+++ b/internal/ceres/dense_cholesky_test.cc
@@ -42,7 +42,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/iterative_refiner.h"
 #include "ceres/linear_solver.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -78,7 +77,7 @@
 #ifndef CERES_NO_CUDA
   options.context = &context;
   std::string error;
-  CHECK(context.InitCuda(&error)) << error;
+  ASSERT_TRUE(context.InitCuda(&error)) << error;
 #endif  // CERES_NO_CUDA
   options.dense_linear_algebra_library_type = ::testing::get<0>(GetParam());
   options.use_mixed_precision_solves = ::testing::get<1>(GetParam());
diff --git a/internal/ceres/dense_linear_solver_test.cc b/internal/ceres/dense_linear_solver_test.cc
index 79d2543..9cece56 100644
--- a/internal/ceres/dense_linear_solver_test.cc
+++ b/internal/ceres/dense_linear_solver_test.cc
@@ -37,7 +37,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/dense_qr.cc b/internal/ceres/dense_qr.cc
index fbbcadc..c4c7b6f 100644
--- a/internal/ceres/dense_qr.cc
+++ b/internal/ceres/dense_qr.cc
@@ -34,6 +34,8 @@
 #include <memory>
 #include <string>
 
+#include "absl/log/log.h"
+
 #ifndef CERES_NO_CUDA
 #include "ceres/context_impl.h"
 #include "cublas_v2.h"
diff --git a/internal/ceres/dense_qr.h b/internal/ceres/dense_qr.h
index 0ba17c4..af35827 100644
--- a/internal/ceres/dense_qr.h
+++ b/internal/ceres/dense_qr.h
@@ -45,7 +45,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/linear_solver.h"
-#include "glog/logging.h"
 
 #ifndef CERES_NO_CUDA
 #include "ceres/context_impl.h"
diff --git a/internal/ceres/dense_qr_test.cc b/internal/ceres/dense_qr_test.cc
index 155570c..f287d35 100644
--- a/internal/ceres/dense_qr_test.cc
+++ b/internal/ceres/dense_qr_test.cc
@@ -39,7 +39,6 @@
 #include "Eigen/Dense"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -70,7 +69,7 @@
 #ifndef CERES_NO_CUDA
   options.context = &context;
   std::string error;
-  CHECK(context.InitCuda(&error)) << error;
+  ASSERT_TRUE(context.InitCuda(&error)) << error;
 #endif  // CERES_NO_CUDA
   options.dense_linear_algebra_library_type = GetParam();
   const double kEpsilon = std::numeric_limits<double>::epsilon() * 1.5e4;
diff --git a/internal/ceres/dense_sparse_matrix.cc b/internal/ceres/dense_sparse_matrix.cc
index e0c917c..c33aa45 100644
--- a/internal/ceres/dense_sparse_matrix.cc
+++ b/internal/ceres/dense_sparse_matrix.cc
@@ -33,10 +33,10 @@
 #include <algorithm>
 #include <utility>
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/dense_sparse_matrix_test.cc b/internal/ceres/dense_sparse_matrix_test.cc
index 0e50b62..cead9dd 100644
--- a/internal/ceres/dense_sparse_matrix_test.cc
+++ b/internal/ceres/dense_sparse_matrix_test.cc
@@ -40,7 +40,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -72,7 +71,7 @@
     std::unique_ptr<LinearLeastSquaresProblem> problem =
         CreateLinearLeastSquaresProblemFromId(1);
 
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
 
     tsm.reset(down_cast<TripletSparseMatrix*>(problem->A.release()));
     dsm = std::make_unique<DenseSparseMatrix>(*tsm);
diff --git a/internal/ceres/detect_structure.cc b/internal/ceres/detect_structure.cc
index e82d70f..d2b4a4c 100644
--- a/internal/ceres/detect_structure.cc
+++ b/internal/ceres/detect_structure.cc
@@ -30,8 +30,9 @@
 
 #include "ceres/detect_structure.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/detect_structure_test.cc b/internal/ceres/detect_structure_test.cc
index e4e3f1d..155c025 100644
--- a/internal/ceres/detect_structure_test.cc
+++ b/internal/ceres/detect_structure_test.cc
@@ -32,7 +32,6 @@
 
 #include "Eigen/Core"
 #include "ceres/block_structure.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/dogleg_strategy.cc b/internal/ceres/dogleg_strategy.cc
index 877d8d9..ef45a0b 100644
--- a/internal/ceres/dogleg_strategy.cc
+++ b/internal/ceres/dogleg_strategy.cc
@@ -34,6 +34,8 @@
 #include <cmath>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/array_utils.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
@@ -42,7 +44,6 @@
 #include "ceres/sparse_matrix.h"
 #include "ceres/trust_region_strategy.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 namespace {
diff --git a/internal/ceres/dogleg_strategy_test.cc b/internal/ceres/dogleg_strategy_test.cc
index b256f3e..26db26c 100644
--- a/internal/ceres/dogleg_strategy_test.cc
+++ b/internal/ceres/dogleg_strategy_test.cc
@@ -37,7 +37,6 @@
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/trust_region_strategy.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/dynamic_compressed_row_sparse_matrix.cc b/internal/ceres/dynamic_compressed_row_sparse_matrix.cc
index 4081c9c..0eea9e5 100644
--- a/internal/ceres/dynamic_compressed_row_sparse_matrix.cc
+++ b/internal/ceres/dynamic_compressed_row_sparse_matrix.cc
@@ -32,6 +32,8 @@
 
 #include <cstring>
 
+#include "absl/log/check.h"
+
 namespace ceres::internal {
 
 DynamicCompressedRowSparseMatrix::DynamicCompressedRowSparseMatrix(
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc b/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
index 6dd0adf..0d147c4 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
@@ -38,6 +38,7 @@
 #include <utility>
 
 #include "Eigen/SparseCore"
+#include "absl/log/log.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
index e5e8a28..6b8fa52 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
@@ -71,7 +71,7 @@
                                             double* rhs_and_solution);
 
   LinearSolver::Summary SolveImplUsingCuda(CompressedRowSparseMatrix* A,
-                                            double* rhs_and_solution);
+                                           double* rhs_and_solution);
 
   const LinearSolver::Options options_;
 };
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc b/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc
index 4afd372..100d574 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc
@@ -39,7 +39,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/dynamic_sparsity_test.cc b/internal/ceres/dynamic_sparsity_test.cc
index ae56037..5928389 100644
--- a/internal/ceres/dynamic_sparsity_test.cc
+++ b/internal/ceres/dynamic_sparsity_test.cc
@@ -35,8 +35,8 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/eigensparse.cc b/internal/ceres/eigensparse.cc
index 7ed401d..67b6ec5 100644
--- a/internal/ceres/eigensparse.cc
+++ b/internal/ceres/eigensparse.cc
@@ -44,6 +44,7 @@
 
 #include "Eigen/SparseCholesky"
 #include "Eigen/SparseCore"
+#include "absl/log/log.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/linear_solver.h"
 
diff --git a/internal/ceres/evaluator.cc b/internal/ceres/evaluator.cc
index 9226dc5..516d701 100644
--- a/internal/ceres/evaluator.cc
+++ b/internal/ceres/evaluator.cc
@@ -33,6 +33,7 @@
 #include <memory>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/block_evaluate_preparer.h"
 #include "ceres/block_jacobian_writer.h"
 #include "ceres/compressed_row_jacobian_writer.h"
@@ -44,7 +45,6 @@
 #include "ceres/internal/export.h"
 #include "ceres/program_evaluator.h"
 #include "ceres/scratch_evaluate_preparer.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
@@ -65,8 +65,8 @@
     case SPARSE_SCHUR:
     case ITERATIVE_SCHUR: {
       return std::make_unique<
-            ProgramEvaluator<BlockEvaluatePreparer, BlockJacobianWriter>>(
-            options, program);
+          ProgramEvaluator<BlockEvaluatePreparer, BlockJacobianWriter>>(
+          options, program);
     }
     case CGNR: {
       if (options.sparse_linear_algebra_library_type == CUDA_SPARSE) {
diff --git a/internal/ceres/evaluator_test.cc b/internal/ceres/evaluator_test.cc
index 43e8872..8987d0b 100644
--- a/internal/ceres/evaluator_test.cc
+++ b/internal/ceres/evaluator_test.cc
@@ -37,6 +37,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/casts.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
diff --git a/internal/ceres/file.cc b/internal/ceres/file.cc
index 60d35fa..81b3160 100644
--- a/internal/ceres/file.cc
+++ b/internal/ceres/file.cc
@@ -35,7 +35,7 @@
 #include <cstdio>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/log.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/float_suitesparse.cc b/internal/ceres/float_suitesparse.cc
index 6016bad..cea5c4a 100644
--- a/internal/ceres/float_suitesparse.cc
+++ b/internal/ceres/float_suitesparse.cc
@@ -32,6 +32,8 @@
 
 #include <memory>
 
+#include "absl/log/log.h"
+
 #if !defined(CERES_NO_SUITESPARSE)
 
 namespace ceres::internal {
diff --git a/internal/ceres/gradient_checker.cc b/internal/ceres/gradient_checker.cc
index f49803c..131e4c2 100644
--- a/internal/ceres/gradient_checker.cc
+++ b/internal/ceres/gradient_checker.cc
@@ -39,6 +39,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/is_close.h"
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
diff --git a/internal/ceres/gradient_checker_test.cc b/internal/ceres/gradient_checker_test.cc
index 2a20470..509ea18 100644
--- a/internal/ceres/gradient_checker_test.cc
+++ b/internal/ceres/gradient_checker_test.cc
@@ -37,11 +37,11 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/cost_function.h"
 #include "ceres/problem.h"
 #include "ceres/solver.h"
 #include "ceres/test_util.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -176,7 +176,7 @@
                             const std::vector<int>& parameter_sizes,
                             const std::vector<int>& local_parameter_sizes,
                             int residual_size) {
-  CHECK_EQ(parameter_sizes.size(), local_parameter_sizes.size());
+  ASSERT_EQ(parameter_sizes.size(), local_parameter_sizes.size());
   int num_parameters = parameter_sizes.size();
   ASSERT_EQ(residual_size, results.residuals.size());
   ASSERT_EQ(num_parameters, results.local_jacobians.size());
@@ -329,7 +329,7 @@
   }
 
   void AddParameter(const Matrix& residual_J_param) {
-    CHECK_EQ(num_residuals(), residual_J_param.rows());
+    ASSERT_EQ(num_residuals(), residual_J_param.rows());
     residual_J_params_.push_back(residual_J_param);
     mutable_parameter_block_sizes()->push_back(residual_J_param.cols());
   }
@@ -337,9 +337,9 @@
   /// Add offset to the given Jacobian before returning it from Evaluate(),
   /// thus introducing an error in the computation.
   void SetJacobianOffset(size_t index, Matrix offset) {
-    CHECK_LT(index, residual_J_params_.size());
-    CHECK_EQ(residual_J_params_[index].rows(), offset.rows());
-    CHECK_EQ(residual_J_params_[index].cols(), offset.cols());
+    ASSERT_LT(index, residual_J_params_.size());
+    ASSERT_EQ(residual_J_params_[index].rows(), offset.rows());
+    ASSERT_EQ(residual_J_params_[index].cols(), offset.cols());
     jacobian_offsets_[index] = offset;
   }
 
diff --git a/internal/ceres/gradient_checking_cost_function.cc b/internal/ceres/gradient_checking_cost_function.cc
index 8ca449b..50a6447 100644
--- a/internal/ceres/gradient_checking_cost_function.cc
+++ b/internal/ceres/gradient_checking_cost_function.cc
@@ -40,6 +40,8 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/dynamic_numeric_diff_cost_function.h"
 #include "ceres/gradient_checker.h"
 #include "ceres/internal/eigen.h"
@@ -50,7 +52,6 @@
 #include "ceres/residual_block.h"
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/gradient_checking_cost_function_test.cc b/internal/ceres/gradient_checking_cost_function_test.cc
index 545fcd2..7dd334e 100644
--- a/internal/ceres/gradient_checking_cost_function_test.cc
+++ b/internal/ceres/gradient_checking_cost_function_test.cc
@@ -36,6 +36,8 @@
 #include <random>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/cost_function.h"
 #include "ceres/loss_function.h"
 #include "ceres/manifold.h"
@@ -45,7 +47,6 @@
 #include "ceres/residual_block.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -328,8 +329,8 @@
 // array and have the same Manifold objects.
 static void ParameterBlocksAreEquivalent(const ParameterBlock* left,
                                          const ParameterBlock* right) {
-  CHECK(left != nullptr);
-  CHECK(right != nullptr);
+  ASSERT_TRUE(left != nullptr);
+  ASSERT_TRUE(right != nullptr);
   EXPECT_EQ(left->user_state(), right->user_state());
   EXPECT_EQ(left->Size(), right->Size());
   EXPECT_EQ(left->Size(), right->Size());
diff --git a/internal/ceres/gradient_problem.cc b/internal/ceres/gradient_problem.cc
index ee228b8..486c99a 100644
--- a/internal/ceres/gradient_problem.cc
+++ b/internal/ceres/gradient_problem.cc
@@ -32,7 +32,7 @@
 
 #include <memory>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/gradient_problem_solver.cc b/internal/ceres/gradient_problem_solver.cc
index ad2ea13..d78a719 100644
--- a/internal/ceres/gradient_problem_solver.cc
+++ b/internal/ceres/gradient_problem_solver.cc
@@ -34,6 +34,7 @@
 #include <memory>
 #include <string>
 
+#include "absl/log/log.h"
 #include "ceres/callbacks.h"
 #include "ceres/gradient_problem.h"
 #include "ceres/gradient_problem_evaluator.h"
diff --git a/internal/ceres/graph.h b/internal/ceres/graph.h
index 4f8dfb9..9b28b06 100644
--- a/internal/ceres/graph.h
+++ b/internal/ceres/graph.h
@@ -36,11 +36,11 @@
 #include <unordered_set>
 #include <utility>
 
+#include "absl/log/check.h"
 #include "ceres/internal/export.h"
 #include "ceres/map_util.h"
 #include "ceres/pair_hash.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/graph_algorithms.h b/internal/ceres/graph_algorithms.h
index 4ebc8b3..3019f0b 100644
--- a/internal/ceres/graph_algorithms.h
+++ b/internal/ceres/graph_algorithms.h
@@ -40,10 +40,10 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/graph.h"
 #include "ceres/internal/export.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/householder_vector_test.cc b/internal/ceres/householder_vector_test.cc
index 7d69789..ff87ffd 100644
--- a/internal/ceres/householder_vector_test.cc
+++ b/internal/ceres/householder_vector_test.cc
@@ -31,7 +31,6 @@
 #include "ceres/internal/householder_vector.h"
 
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/implicit_schur_complement.cc b/internal/ceres/implicit_schur_complement.cc
index a633529..053a9e5 100644
--- a/internal/ceres/implicit_schur_complement.cc
+++ b/internal/ceres/implicit_schur_complement.cc
@@ -31,6 +31,7 @@
 #include "ceres/implicit_schur_complement.h"
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
 #include "ceres/internal/eigen.h"
@@ -38,7 +39,6 @@
 #include "ceres/parallel_for.h"
 #include "ceres/parallel_vector_ops.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/implicit_schur_complement_test.cc b/internal/ceres/implicit_schur_complement_test.cc
index 35519fc..1944e9d 100644
--- a/internal/ceres/implicit_schur_complement_test.cc
+++ b/internal/ceres/implicit_schur_complement_test.cc
@@ -44,7 +44,6 @@
 #include "ceres/schur_eliminator.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -58,7 +57,7 @@
   void SetUp() final {
     auto problem = CreateLinearLeastSquaresProblemFromId(2);
 
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     A_.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
     b_ = std::move(problem->b);
     D_ = std::move(problem->D);
@@ -86,7 +85,7 @@
 
     std::unique_ptr<SchurEliminatorBase> eliminator =
         SchurEliminatorBase::Create(options);
-    CHECK(eliminator != nullptr);
+    ASSERT_TRUE(eliminator != nullptr);
     const bool kFullRankETE = true;
     eliminator->Init(num_eliminate_blocks_, kFullRankETE, bs);
 
diff --git a/internal/ceres/inner_product_computer_test.cc b/internal/ceres/inner_product_computer_test.cc
index 89fe518..0b716ad 100644
--- a/internal/ceres/inner_product_computer_test.cc
+++ b/internal/ceres/inner_product_computer_test.cc
@@ -35,10 +35,10 @@
 #include <random>
 
 #include "Eigen/SparseCore"
+#include "absl/log/log.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/invert_psd_matrix.h b/internal/ceres/invert_psd_matrix.h
index bc74900..21ba2dc 100644
--- a/internal/ceres/invert_psd_matrix.h
+++ b/internal/ceres/invert_psd_matrix.h
@@ -33,7 +33,6 @@
 
 #include "Eigen/Dense"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/iterative_refiner_test.cc b/internal/ceres/iterative_refiner_test.cc
index 3b7bfd2..a2557f2 100644
--- a/internal/ceres/iterative_refiner_test.cc
+++ b/internal/ceres/iterative_refiner_test.cc
@@ -33,11 +33,12 @@
 #include <utility>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/dense_cholesky.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/sparse_cholesky.h"
 #include "ceres/sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/iterative_schur_complement_solver.cc b/internal/ceres/iterative_schur_complement_solver.cc
index bcfb6e4..23318bb 100644
--- a/internal/ceres/iterative_schur_complement_solver.cc
+++ b/internal/ceres/iterative_schur_complement_solver.cc
@@ -36,6 +36,8 @@
 #include <vector>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
 #include "ceres/conjugate_gradients_solver.h"
@@ -50,7 +52,6 @@
 #include "ceres/types.h"
 #include "ceres/visibility_based_preconditioner.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/iterative_schur_complement_solver_test.cc b/internal/ceres/iterative_schur_complement_solver_test.cc
index c5d67de..5529060 100644
--- a/internal/ceres/iterative_schur_complement_solver_test.cc
+++ b/internal/ceres/iterative_schur_complement_solver_test.cc
@@ -48,7 +48,6 @@
 #include "ceres/schur_eliminator.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -64,7 +63,7 @@
     std::unique_ptr<LinearLeastSquaresProblem> problem =
         CreateLinearLeastSquaresProblemFromId(problem_id);
 
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     A_.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
     b_ = std::move(problem->b);
     D_ = std::move(problem->D);
diff --git a/internal/ceres/jet_test.cc b/internal/ceres/jet_test.cc
index 7f67bd6..f94f995 100644
--- a/internal/ceres/jet_test.cc
+++ b/internal/ceres/jet_test.cc
@@ -35,9 +35,9 @@
 #include <cfenv>
 #include <cmath>
 
+#include "absl/log/log.h"
 #include "ceres/stringprintf.h"
 #include "ceres/test_util.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/internal/ceres/levenberg_marquardt_strategy.cc b/internal/ceres/levenberg_marquardt_strategy.cc
index 37bc6f4..9e25466 100644
--- a/internal/ceres/levenberg_marquardt_strategy.cc
+++ b/internal/ceres/levenberg_marquardt_strategy.cc
@@ -34,6 +34,8 @@
 #include <cmath>
 
 #include "Eigen/Core"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/array_utils.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
@@ -42,7 +44,6 @@
 #include "ceres/sparse_matrix.h"
 #include "ceres/trust_region_strategy.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/levenberg_marquardt_strategy_test.cc b/internal/ceres/levenberg_marquardt_strategy_test.cc
index 4be742c..78bbd8c 100644
--- a/internal/ceres/levenberg_marquardt_strategy_test.cc
+++ b/internal/ceres/levenberg_marquardt_strategy_test.cc
@@ -32,10 +32,10 @@
 
 #include <memory>
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/trust_region_strategy.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/internal/ceres/line_search.cc b/internal/ceres/line_search.cc
index eb2c7c9..749345a 100644
--- a/internal/ceres/line_search.cc
+++ b/internal/ceres/line_search.cc
@@ -39,6 +39,8 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/evaluator.h"
 #include "ceres/function_sample.h"
 #include "ceres/internal/eigen.h"
@@ -46,7 +48,6 @@
 #include "ceres/polynomial.h"
 #include "ceres/stringprintf.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/line_search_direction.cc b/internal/ceres/line_search_direction.cc
index 62fcc81..b4e8a33 100644
--- a/internal/ceres/line_search_direction.cc
+++ b/internal/ceres/line_search_direction.cc
@@ -32,11 +32,12 @@
 
 #include <memory>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/line_search_minimizer.h"
 #include "ceres/low_rank_inverse_hessian.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc
index 58a4bf9..41ca31a 100644
--- a/internal/ceres/line_search_minimizer.cc
+++ b/internal/ceres/line_search_minimizer.cc
@@ -48,6 +48,8 @@
 #include <vector>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/array_utils.h"
 #include "ceres/evaluator.h"
 #include "ceres/internal/eigen.h"
@@ -57,7 +59,6 @@
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 namespace {
diff --git a/internal/ceres/line_search_minimizer.h b/internal/ceres/line_search_minimizer.h
index f3621d9..af601d9 100644
--- a/internal/ceres/line_search_minimizer.h
+++ b/internal/ceres/line_search_minimizer.h
@@ -36,7 +36,6 @@
 #include "ceres/minimizer.h"
 #include "ceres/solver.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/line_search_minimizer_test.cc b/internal/ceres/line_search_minimizer_test.cc
index 3b15ae8..d5c2c69 100644
--- a/internal/ceres/line_search_minimizer_test.cc
+++ b/internal/ceres/line_search_minimizer_test.cc
@@ -32,7 +32,6 @@
 #include <cstdlib>
 
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/linear_least_squares_problems.cc b/internal/ceres/linear_least_squares_problems.cc
index 36cffec..3a525fd 100644
--- a/internal/ceres/linear_least_squares_problems.cc
+++ b/internal/ceres/linear_least_squares_problems.cc
@@ -35,6 +35,8 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
 #include "ceres/casts.h"
@@ -42,7 +44,6 @@
 #include "ceres/stringprintf.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/linear_operator.cc b/internal/ceres/linear_operator.cc
index f4c2c5e..669dbad 100644
--- a/internal/ceres/linear_operator.cc
+++ b/internal/ceres/linear_operator.cc
@@ -30,7 +30,7 @@
 
 #include "ceres/linear_operator.h"
 
-#include <glog/logging.h>
+#include "absl/log/log.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/linear_solver.cc b/internal/ceres/linear_solver.cc
index 4ba0b75..2200450 100644
--- a/internal/ceres/linear_solver.cc
+++ b/internal/ceres/linear_solver.cc
@@ -32,6 +32,8 @@
 
 #include <memory>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/cgnr_solver.h"
 #include "ceres/dense_normal_cholesky_solver.h"
 #include "ceres/dense_qr_solver.h"
@@ -41,7 +43,6 @@
 #include "ceres/schur_complement_solver.h"
 #include "ceres/sparse_normal_cholesky_solver.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/linear_solver.h b/internal/ceres/linear_solver.h
index 1d5338f..d6e0804 100644
--- a/internal/ceres/linear_solver.h
+++ b/internal/ceres/linear_solver.h
@@ -40,6 +40,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/casts.h"
 #include "ceres/compressed_row_sparse_matrix.h"
@@ -50,7 +51,6 @@
 #include "ceres/internal/export.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/loss_function.cc b/internal/ceres/loss_function.cc
index 82563c8..4af4f1a 100644
--- a/internal/ceres/loss_function.cc
+++ b/internal/ceres/loss_function.cc
@@ -37,6 +37,8 @@
 #include <cstddef>
 #include <limits>
 
+#include "absl/log/check.h"
+
 namespace ceres {
 
 LossFunction::~LossFunction() = default;
diff --git a/internal/ceres/loss_function_test.cc b/internal/ceres/loss_function_test.cc
index 1fd492b..743099f 100644
--- a/internal/ceres/loss_function_test.cc
+++ b/internal/ceres/loss_function_test.cc
@@ -32,7 +32,6 @@
 
 #include <cstddef>
 
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -45,7 +44,7 @@
 // callback with estimates obtained by symmetric finite differencing
 // of rho(s).
 void AssertLossFunctionIsValid(const LossFunction& loss, double s) {
-  CHECK_GT(s, 0);
+  ASSERT_GT(s, 0);
 
   // Evaluate rho(s), rho'(s) and rho''(s).
   double rho[3];
diff --git a/internal/ceres/low_rank_inverse_hessian.cc b/internal/ceres/low_rank_inverse_hessian.cc
index 14559b6..490f3d4 100644
--- a/internal/ceres/low_rank_inverse_hessian.cc
+++ b/internal/ceres/low_rank_inverse_hessian.cc
@@ -32,8 +32,8 @@
 
 #include <list>
 
+#include "absl/log/log.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/manifold.cc b/internal/ceres/manifold.cc
index c4895fd..bfb2a22 100644
--- a/internal/ceres/manifold.cc
+++ b/internal/ceres/manifold.cc
@@ -3,9 +3,9 @@
 #include <algorithm>
 #include <cmath>
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/fixed_array.h"
-#include "glog/logging.h"
 
 namespace ceres {
 namespace {
diff --git a/internal/ceres/map_util.h b/internal/ceres/map_util.h
index aee2bf5..c9adfd8 100644
--- a/internal/ceres/map_util.h
+++ b/internal/ceres/map_util.h
@@ -35,8 +35,8 @@
 
 #include <utility>
 
+#include "absl/log/check.h"
 #include "ceres/internal/export.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/miniglog/glog/logging.cc b/internal/ceres/miniglog/glog/logging.cc
deleted file mode 100644
index 0863f61..0000000
--- a/internal/ceres/miniglog/glog/logging.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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: keir@google.com (Keir Mierle)
-
-#include "glog/logging.h"
-
-namespace google {
-
-// This is the set of log sinks. This must be in a separate library to ensure
-// that there is only one instance of this across the entire program.
-std::set<google::LogSink*> log_sinks_global;
-
-}  // namespace google
diff --git a/internal/ceres/miniglog/glog/logging.h b/internal/ceres/miniglog/glog/logging.h
deleted file mode 100644
index 5604bd4..0000000
--- a/internal/ceres/miniglog/glog/logging.h
+++ /dev/null
@@ -1,438 +0,0 @@
-// 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: settinger@google.com (Scott Ettinger)
-//         mierle@gmail.com (Keir Mierle)
-//
-// Simplified Glog style logging with Android support. Supported macros in
-// decreasing severity level per line:
-//
-//   VLOG(2), VLOG(N)
-//   VLOG(1),
-//   LOG(INFO), VLOG(0), LG
-//   LOG(WARNING),
-//   LOG(ERROR),
-//   LOG(FATAL),
-//
-// With VLOG(n), the output is directed to one of the 5 Android log levels:
-//
-//   2 - Verbose
-//   1 - Debug
-//   0 - Info
-//  -1 - Warning
-//  -2 - Error
-//  -3 - Fatal
-//
-// Any logging of level 2 and above is directed to the Verbose level. All
-// Android log output is tagged with the string "native".
-//
-// If the symbol ANDROID is not defined, all output goes to std::cerr.
-// This allows code to be built on a different system for debug.
-//
-// Portions of this code are taken from the GLOG package.  This code is only a
-// small subset of the GLOG functionality. Notable differences from GLOG
-// behavior include lack of support for displaying unprintable characters and
-// lack of stack trace information upon failure of the CHECK macros.  On
-// non-Android systems, log output goes to std::cerr and is not written to a
-// file.
-//
-// CHECK macros are defined to test for conditions within code.  Any CHECK that
-// fails will log the failure and terminate the application.
-// e.g. CHECK_GE(3, 2) will pass while CHECK_GE(3, 4) will fail after logging
-//      "Check failed 3 >= 4".
-//
-// The following CHECK macros are defined:
-//
-//   CHECK(condition)        - fails if condition is false and logs condition.
-//   CHECK_NOTNULL(variable) - fails if the variable is nullptr.
-//
-// The following binary check macros are also defined :
-//
-//   Macro                     Operator equivalent
-//   --------------------      -------------------
-//   CHECK_EQ(val1, val2)      val1 == val2
-//   CHECK_NE(val1, val2)      val1 != val2
-//   CHECK_GT(val1, val2)      val1 > val2
-//   CHECK_GE(val1, val2)      val1 >= val2
-//   CHECK_LT(val1, val2)      val1 < val2
-//   CHECK_LE(val1, val2)      val1 <= val2
-//
-// Debug only versions of all of the check macros are also defined.  These
-// macros generate no code in a release build, but avoid unused variable
-// warnings / errors.
-//
-// To use the debug only versions, prepend a D to the normal check macros, e.g.
-// DCHECK_EQ(a, b).
-
-#ifndef CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_
-#define CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_
-
-#ifdef ANDROID
-#include <android/log.h>
-#endif  // ANDROID
-
-#include <algorithm>
-#include <ctime>
-#include <fstream>
-#include <iostream>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "ceres/internal/disable_warnings.h"
-#include "ceres/internal/export.h"
-
-// Log severity level constants.
-// clang-format off
-const int FATAL   = -3;
-const int ERROR   = -2;
-const int WARNING = -1;
-const int INFO    =  0;
-// clang-format on
-
-// ------------------------- Glog compatibility ------------------------------
-
-namespace google {
-
-using LogSeverity = int;
-// clang-format off
-const int INFO    = ::INFO;
-const int WARNING = ::WARNING;
-const int ERROR   = ::ERROR;
-const int FATAL   = ::FATAL;
-// clang-format on
-
-// Sink class used for integration with mock and test functions. If sinks are
-// added, all log output is also sent to each sink through the send function.
-// In this implementation, WaitTillSent() is called immediately after the send.
-// This implementation is not thread safe.
-class CERES_EXPORT LogSink {
- public:
-  virtual ~LogSink() = default;
-  virtual void send(LogSeverity severity,
-                    const char* full_filename,
-                    const char* base_filename,
-                    int line,
-                    const struct tm* tm_time,
-                    const char* message,
-                    size_t message_len) = 0;
-  virtual void WaitTillSent() = 0;
-};
-
-// Global set of log sinks. The actual object is defined in logging.cc.
-extern CERES_EXPORT std::set<LogSink*> log_sinks_global;
-
-inline void InitGoogleLogging(const char* /* argv */) {
-  // Do nothing; this is ignored.
-}
-
-// Note: the Log sink functions are not thread safe.
-inline void AddLogSink(LogSink* sink) {
-  // TODO(settinger): Add locks for thread safety.
-  log_sinks_global.insert(sink);
-}
-inline void RemoveLogSink(LogSink* sink) { log_sinks_global.erase(sink); }
-
-}  // namespace google
-
-// ---------------------------- Logger Class --------------------------------
-
-// Class created for each use of the logging macros.
-// The logger acts as a stream and routes the final stream contents to the
-// Android logcat output at the proper filter level.  If ANDROID is not
-// defined, output is directed to std::cerr.  This class should not
-// be directly instantiated in code, rather it should be invoked through the
-// use of the log macros LG, LOG, or VLOG.
-class CERES_EXPORT MessageLogger {
- public:
-  MessageLogger(const char* file, int line, const char* tag, int severity)
-      : file_(file), line_(line), tag_(tag), severity_(severity) {
-    // Pre-pend the stream with the file and line number.
-    StripBasename(std::string(file), &filename_only_);
-    stream_ << filename_only_ << ":" << line << " ";
-  }
-
-  // Output the contents of the stream to the proper channel on destruction.
-  ~MessageLogger() {
-    stream_ << "\n";
-
-#ifdef ANDROID
-    static const int android_log_levels[] = {
-        ANDROID_LOG_FATAL,    // LOG(FATAL)
-        ANDROID_LOG_ERROR,    // LOG(ERROR)
-        ANDROID_LOG_WARN,     // LOG(WARNING)
-        ANDROID_LOG_INFO,     // LOG(INFO), LG, VLOG(0)
-        ANDROID_LOG_DEBUG,    // VLOG(1)
-        ANDROID_LOG_VERBOSE,  // VLOG(2) .. VLOG(N)
-    };
-
-    // Bound the logging level.
-    const int kMaxVerboseLevel = 2;
-    int android_level_index =
-        std::min(std::max(FATAL, severity_), kMaxVerboseLevel) - FATAL;
-    int android_log_level = android_log_levels[android_level_index];
-
-    // Output the log string the Android log at the appropriate level.
-    __android_log_write(android_log_level, tag_.c_str(), stream_.str().c_str());
-
-    // Indicate termination if needed.
-    if (severity_ == FATAL) {
-      __android_log_write(ANDROID_LOG_FATAL, tag_.c_str(), "terminating.\n");
-    }
-#else
-    // If not building on Android, log all output to std::cerr.
-    std::cerr << stream_.str();
-#endif  // ANDROID
-
-    LogToSinks(severity_);
-    WaitForSinks();
-
-    // Android logging at level FATAL does not terminate execution, so abort()
-    // is still required to stop the program.
-    if (severity_ == FATAL) {
-      abort();
-    }
-  }
-
-  // Return the stream associated with the logger object.
-  std::stringstream& stream() { return stream_; }
-
- private:
-  void LogToSinks(int severity) {
-    time_t rawtime;
-    time(&rawtime);
-
-    struct tm timeinfo;
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-    // On Windows, use secure localtime_s not localtime.
-    localtime_s(&timeinfo, &rawtime);
-#else
-    // On non-Windows systems, use threadsafe localtime_r not localtime.
-    localtime_r(&rawtime, &timeinfo);
-#endif
-
-    std::set<google::LogSink*>::iterator iter;
-    // Send the log message to all sinks.
-    for (iter = google::log_sinks_global.begin();
-         iter != google::log_sinks_global.end();
-         ++iter) {
-      (*iter)->send(severity,
-                    file_.c_str(),
-                    filename_only_.c_str(),
-                    line_,
-                    &timeinfo,
-                    stream_.str().c_str(),
-                    stream_.str().size());
-    }
-  }
-
-  void WaitForSinks() {
-    // TODO(settinger): Add locks for thread safety.
-    std::set<google::LogSink*>::iterator iter;
-
-    // Call WaitTillSent() for all sinks.
-    for (iter = google::log_sinks_global.begin();
-         iter != google::log_sinks_global.end();
-         ++iter) {
-      (*iter)->WaitTillSent();
-    }
-  }
-
-  void StripBasename(const std::string& full_path, std::string* filename) {
-    // TODO(settinger): Add support for OSs with different path separators.
-    const char kSeparator = '/';
-    size_t pos = full_path.rfind(kSeparator);
-    if (pos != std::string::npos) {
-      *filename = full_path.substr(pos + 1, std::string::npos);
-    } else {
-      *filename = full_path;
-    }
-  }
-
-  std::string file_;
-  std::string filename_only_;
-  int line_;
-  std::string tag_;
-  std::stringstream stream_;
-  int severity_;
-};
-
-// ---------------------- Logging Macro definitions --------------------------
-
-// This class is used to explicitly ignore values in the conditional
-// logging macros.  This avoids compiler warnings like "value computed
-// is not used" and "statement has no effect".
-class CERES_EXPORT LoggerVoidify {
- public:
-  // This has to be an operator with a precedence lower than << but
-  // higher than ?:
-  void operator&(const std::ostream& s) {}
-};
-
-// Log only if condition is met.  Otherwise evaluates to void.
-// clang-format off
-#define LOG_IF(severity, condition) \
-    !(condition) ? (void) 0 : LoggerVoidify() & \
-      MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream()
-// clang-format on
-
-// Log only if condition is NOT met.  Otherwise evaluates to void.
-#define LOG_IF_FALSE(severity, condition) LOG_IF(severity, !(condition))
-
-// LG is a convenient shortcut for LOG(INFO). Its use is in new
-// google3 code is discouraged and the following shortcut exists for
-// backward compatibility with existing code.
-// clang-format off
-#ifdef MAX_LOG_LEVEL
-#  define LOG(n)  LOG_IF(n, n <= MAX_LOG_LEVEL)
-#  define VLOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL)
-#  define LG      LOG_IF(INFO, INFO <= MAX_LOG_LEVEL)
-#  define VLOG_IF(n, condition) LOG_IF(n, (n <= MAX_LOG_LEVEL) && condition)
-#else
-#  define LOG(n)  MessageLogger((char *)__FILE__, __LINE__, "native", n).stream()    // NOLINT
-#  define VLOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream()    // NOLINT
-#  define LG      MessageLogger((char *)__FILE__, __LINE__, "native", INFO).stream() // NOLINT
-#  define VLOG_IF(n, condition) LOG_IF(n, condition)
-#endif
-
-// Currently, VLOG is always on for levels below MAX_LOG_LEVEL.
-#ifndef MAX_LOG_LEVEL
-#  define VLOG_IS_ON(x) (1)
-#else
-#  define VLOG_IS_ON(x) (x <= MAX_LOG_LEVEL)
-#endif
-
-#ifndef NDEBUG
-#  define DLOG LOG
-#else
-#  define DLOG(severity) true ? (void) 0 : LoggerVoidify() & \
-      MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream()
-#endif
-// clang-format on
-
-// Log a message and terminate.
-template <class T>
-void LogMessageFatal(const char* file, int line, const T& message) {
-  MessageLogger((char*)__FILE__, __LINE__, "native", FATAL).stream() << message;
-}
-
-// ---------------------------- CHECK macros ---------------------------------
-
-// Check for a given boolean condition.
-#define CHECK(condition) \
-  LOG_IF_FALSE(FATAL, condition) << "Check failed: " #condition " "
-
-#ifndef NDEBUG
-// Debug only version of CHECK
-#define DCHECK(condition) \
-  LOG_IF_FALSE(FATAL, condition) << "Check failed: " #condition " "
-#else
-// Optimized version - generates no code.
-#define DCHECK(condition) \
-  if (false) LOG_IF_FALSE(FATAL, condition) << "Check failed: " #condition " "
-#endif  // NDEBUG
-
-// ------------------------- CHECK_OP macros ---------------------------------
-
-// Generic binary operator check macro. This should not be directly invoked,
-// instead use the binary comparison macros defined below.
-#define CHECK_OP(val1, val2, op)        \
-  LOG_IF_FALSE(FATAL, ((val1)op(val2))) \
-      << "Check failed: " #val1 " " #op " " #val2 " "
-
-// clang-format off
-
-// Check_op macro definitions
-#define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==)
-#define CHECK_NE(val1, val2) CHECK_OP(val1, val2, !=)
-#define CHECK_LE(val1, val2) CHECK_OP(val1, val2, <=)
-#define CHECK_LT(val1, val2) CHECK_OP(val1, val2, <)
-#define CHECK_GE(val1, val2) CHECK_OP(val1, val2, >=)
-#define CHECK_GT(val1, val2) CHECK_OP(val1, val2, >)
-
-#ifndef NDEBUG
-// Debug only versions of CHECK_OP macros.
-#  define DCHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==)
-#  define DCHECK_NE(val1, val2) CHECK_OP(val1, val2, !=)
-#  define DCHECK_LE(val1, val2) CHECK_OP(val1, val2, <=)
-#  define DCHECK_LT(val1, val2) CHECK_OP(val1, val2, <)
-#  define DCHECK_GE(val1, val2) CHECK_OP(val1, val2, >=)
-#  define DCHECK_GT(val1, val2) CHECK_OP(val1, val2, >)
-#else
-// These versions generate no code in optimized mode.
-#  define DCHECK_EQ(val1, val2) if (false) CHECK_OP(val1, val2, ==)
-#  define DCHECK_NE(val1, val2) if (false) CHECK_OP(val1, val2, !=)
-#  define DCHECK_LE(val1, val2) if (false) CHECK_OP(val1, val2, <=)
-#  define DCHECK_LT(val1, val2) if (false) CHECK_OP(val1, val2, <)
-#  define DCHECK_GE(val1, val2) if (false) CHECK_OP(val1, val2, >=)
-#  define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >)
-#endif  // NDEBUG
-
-// clang-format on
-
-// ---------------------------CHECK_NOTNULL macros ---------------------------
-
-// Helpers for CHECK_NOTNULL(). Two are necessary to support both raw pointers
-// and smart pointers.
-template <typename T>
-T& CheckNotNullCommon(const char* file, int line, const char* names, T& t) {
-  if (t == nullptr) {
-    LogMessageFatal(file, line, std::string(names));
-  }
-  return t;
-}
-
-template <typename T>
-T* CheckNotNull(const char* file, int line, const char* names, T* t) {
-  return CheckNotNullCommon(file, line, names, t);
-}
-
-template <typename T>
-T& CheckNotNull(const char* file, int line, const char* names, T& t) {
-  return CheckNotNullCommon(file, line, names, t);
-}
-
-// Check that a pointer is not null.
-#define CHECK_NOTNULL(val) \
-  CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non nullptr", (val))
-
-#ifndef NDEBUG
-// Debug only version of CHECK_NOTNULL
-#define DCHECK_NOTNULL(val) \
-  CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non nullptr", (val))
-#else
-// Optimized version - generates no code.
-#define DCHECK_NOTNULL(val) \
-  if (false)                \
-  CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non nullptr", (val))
-#endif  // NDEBUG
-
-#include "ceres/internal/reenable_warnings.h"
-
-#endif  // CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_
diff --git a/internal/ceres/minimizer.cc b/internal/ceres/minimizer.cc
index 5317388..1a8a3ba 100644
--- a/internal/ceres/minimizer.cc
+++ b/internal/ceres/minimizer.cc
@@ -32,10 +32,10 @@
 
 #include <memory>
 
+#include "absl/log/log.h"
 #include "ceres/line_search_minimizer.h"
 #include "ceres/trust_region_minimizer.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/normal_prior.cc b/internal/ceres/normal_prior.cc
index c8a7a27..29fb92c 100644
--- a/internal/ceres/normal_prior.cc
+++ b/internal/ceres/normal_prior.cc
@@ -34,9 +34,9 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/numeric_diff_cost_function_test.cc b/internal/ceres/numeric_diff_cost_function_test.cc
index 0c9074a..235c266 100644
--- a/internal/ceres/numeric_diff_cost_function_test.cc
+++ b/internal/ceres/numeric_diff_cost_function_test.cc
@@ -43,7 +43,6 @@
 #include "ceres/numeric_diff_test_utils.h"
 #include "ceres/test_util.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/parallel_for.h b/internal/ceres/parallel_for.h
index 11db1fb..97fc95e 100644
--- a/internal/ceres/parallel_for.h
+++ b/internal/ceres/parallel_for.h
@@ -35,12 +35,12 @@
 #include <mutex>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/context_impl.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/parallel_invoke.h"
 #include "ceres/partition_range_for_parallel_for.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/parallel_for_benchmark.cc b/internal/ceres/parallel_for_benchmark.cc
index 3bfdb87..870ef18 100644
--- a/internal/ceres/parallel_for_benchmark.cc
+++ b/internal/ceres/parallel_for_benchmark.cc
@@ -26,11 +26,11 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
+#include "absl/log/check.h"
 #include "benchmark/benchmark.h"
 #include "ceres/context_impl.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/parallel_for.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/parallel_for_test.cc b/internal/ceres/parallel_for_test.cc
index 46f5a0f..9b10ac5 100644
--- a/internal/ceres/parallel_for_test.cc
+++ b/internal/ceres/parallel_for_test.cc
@@ -40,10 +40,10 @@
 #include <tuple>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/context_impl.h"
 #include "ceres/internal/config.h"
 #include "ceres/parallel_vector_ops.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -489,7 +489,7 @@
     Vector x = Vector::Random(kVectorSize);
     ParallelSetZero(&context, num_threads, x);
 
-    CHECK_EQ(x.squaredNorm(), 0.);
+    ASSERT_EQ(x.squaredNorm(), 0.);
   }
 }
 
diff --git a/internal/ceres/parallel_invoke.cc b/internal/ceres/parallel_invoke.cc
index 0e387c5..79e4eeb 100644
--- a/internal/ceres/parallel_invoke.cc
+++ b/internal/ceres/parallel_invoke.cc
@@ -36,10 +36,10 @@
 #include <mutex>
 #include <tuple>
 
+#include "absl/log/check.h"
 #include "ceres/internal/config.h"
 #include "ceres/parallel_for.h"
 #include "ceres/parallel_vector_ops.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/parallel_utils_test.cc b/internal/ceres/parallel_utils_test.cc
index bea6f0d..b1f6b86 100644
--- a/internal/ceres/parallel_utils_test.cc
+++ b/internal/ceres/parallel_utils_test.cc
@@ -31,7 +31,6 @@
 #include "ceres/parallel_utils.h"
 
 #include "ceres/internal/config.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/parallel_vector_operations_benchmark.cc b/internal/ceres/parallel_vector_operations_benchmark.cc
index 8b55def..2f6e28f 100644
--- a/internal/ceres/parallel_vector_operations_benchmark.cc
+++ b/internal/ceres/parallel_vector_operations_benchmark.cc
@@ -36,7 +36,7 @@
 // Older versions of benchmark library (for example, one shipped with
 // ubuntu 20.04) do not support range generation and range products
 #define VECTOR_SIZES(num_threads)    \
-      Args({1 << 7, num_threads})    \
+  Args({1 << 7, num_threads})        \
       ->Args({1 << 8, num_threads})  \
       ->Args({1 << 9, num_threads})  \
       ->Args({1 << 10, num_threads}) \
diff --git a/internal/ceres/parameter_block.h b/internal/ceres/parameter_block.h
index 925d1c4..db4011f 100644
--- a/internal/ceres/parameter_block.h
+++ b/internal/ceres/parameter_block.h
@@ -39,13 +39,14 @@
 #include <string>
 #include <unordered_set>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/array_utils.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/manifold.h"
 #include "ceres/stringprintf.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/parameter_block_ordering.cc b/internal/ceres/parameter_block_ordering.cc
index 2b8bf6e..5bac2fd 100644
--- a/internal/ceres/parameter_block_ordering.cc
+++ b/internal/ceres/parameter_block_ordering.cc
@@ -36,6 +36,7 @@
 #include <unordered_set>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/graph.h"
 #include "ceres/graph_algorithms.h"
 #include "ceres/map_util.h"
@@ -43,7 +44,6 @@
 #include "ceres/program.h"
 #include "ceres/residual_block.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/parameter_dims_test.cc b/internal/ceres/parameter_dims_test.cc
index 58d2500..54dd073 100644
--- a/internal/ceres/parameter_dims_test.cc
+++ b/internal/ceres/parameter_dims_test.cc
@@ -24,11 +24,11 @@
 
 #include "ceres/internal/parameter_dims.h"
 
-#include <gtest/gtest.h>
-
 #include <type_traits>
 #include <utility>
 
+#include "gtest/gtest.h"
+
 namespace ceres {
 namespace internal {
 
diff --git a/internal/ceres/partitioned_matrix_view.cc b/internal/ceres/partitioned_matrix_view.cc
index cffdbc5..5257e22 100644
--- a/internal/ceres/partitioned_matrix_view.cc
+++ b/internal/ceres/partitioned_matrix_view.cc
@@ -39,10 +39,12 @@
 //
 // This file is generated using generate_template_specializations.py.
 
+#include "ceres/partitioned_matrix_view.h"
+
 #include <memory>
 
+#include "absl/log/log.h"
 #include "ceres/linear_solver.h"
-#include "ceres/partitioned_matrix_view.h"
 
 namespace ceres::internal {
 
@@ -51,134 +53,98 @@
 std::unique_ptr<PartitionedMatrixViewBase> PartitionedMatrixViewBase::Create(
     const LinearSolver::Options& options, const BlockSparseMatrix& matrix) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 2)) {
-    return std::make_unique<PartitionedMatrixView<2,2, 2>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 2)) {
+    return std::make_unique<PartitionedMatrixView<2, 2, 2>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 3)) {
-    return std::make_unique<PartitionedMatrixView<2,2, 3>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 3)) {
+    return std::make_unique<PartitionedMatrixView<2, 2, 3>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 4)) {
-    return std::make_unique<PartitionedMatrixView<2,2, 4>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 4)) {
+    return std::make_unique<PartitionedMatrixView<2, 2, 4>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2)) {
-    return std::make_unique<PartitionedMatrixView<2,2, Eigen::Dynamic>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 2)) {
+    return std::make_unique<PartitionedMatrixView<2, 2, Eigen::Dynamic>>(
+        options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 3)) {
-    return std::make_unique<PartitionedMatrixView<2,3, 3>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 3)) {
+    return std::make_unique<PartitionedMatrixView<2, 3, 3>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 4)) {
-    return std::make_unique<PartitionedMatrixView<2,3, 4>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 4)) {
+    return std::make_unique<PartitionedMatrixView<2, 3, 4>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 6)) {
-    return std::make_unique<PartitionedMatrixView<2,3, 6>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 6)) {
+    return std::make_unique<PartitionedMatrixView<2, 3, 6>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 9)) {
-    return std::make_unique<PartitionedMatrixView<2,3, 9>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 9)) {
+    return std::make_unique<PartitionedMatrixView<2, 3, 9>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3)) {
-    return std::make_unique<PartitionedMatrixView<2,3, Eigen::Dynamic>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 3)) {
+    return std::make_unique<PartitionedMatrixView<2, 3, Eigen::Dynamic>>(
+        options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 3)) {
-    return std::make_unique<PartitionedMatrixView<2,4, 3>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 3)) {
+    return std::make_unique<PartitionedMatrixView<2, 4, 3>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 4)) {
-    return std::make_unique<PartitionedMatrixView<2,4, 4>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 4)) {
+    return std::make_unique<PartitionedMatrixView<2, 4, 4>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 6)) {
-    return std::make_unique<PartitionedMatrixView<2,4, 6>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 6)) {
+    return std::make_unique<PartitionedMatrixView<2, 4, 6>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 8)) {
-    return std::make_unique<PartitionedMatrixView<2,4, 8>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 8)) {
+    return std::make_unique<PartitionedMatrixView<2, 4, 8>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 9)) {
-    return std::make_unique<PartitionedMatrixView<2,4, 9>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 9)) {
+    return std::make_unique<PartitionedMatrixView<2, 4, 9>>(options, matrix);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4)) {
-    return std::make_unique<PartitionedMatrixView<2,4, Eigen::Dynamic>>(
-                   options, matrix);
+  if ((options.row_block_size == 2) && (options.e_block_size == 4)) {
+    return std::make_unique<PartitionedMatrixView<2, 4, Eigen::Dynamic>>(
+        options, matrix);
   }
   if (options.row_block_size == 2) {
-    return std::make_unique<PartitionedMatrixView<2,Eigen::Dynamic, Eigen::Dynamic>>(
-                   options, matrix);
+    return std::make_unique<
+        PartitionedMatrixView<2, Eigen::Dynamic, Eigen::Dynamic>>(options,
+                                                                  matrix);
   }
-  if ((options.row_block_size == 3) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 3)) {
-    return std::make_unique<PartitionedMatrixView<3,3, 3>>(
-                   options, matrix);
+  if ((options.row_block_size == 3) && (options.e_block_size == 3) &&
+      (options.f_block_size == 3)) {
+    return std::make_unique<PartitionedMatrixView<3, 3, 3>>(options, matrix);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 2)) {
-    return std::make_unique<PartitionedMatrixView<4,4, 2>>(
-                   options, matrix);
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 2)) {
+    return std::make_unique<PartitionedMatrixView<4, 4, 2>>(options, matrix);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 3)) {
-    return std::make_unique<PartitionedMatrixView<4,4, 3>>(
-                   options, matrix);
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 3)) {
+    return std::make_unique<PartitionedMatrixView<4, 4, 3>>(options, matrix);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 4)) {
-    return std::make_unique<PartitionedMatrixView<4,4, 4>>(
-                   options, matrix);
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 4)) {
+    return std::make_unique<PartitionedMatrixView<4, 4, 4>>(options, matrix);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4)) {
-    return std::make_unique<PartitionedMatrixView<4,4, Eigen::Dynamic>>(
-                   options, matrix);
+  if ((options.row_block_size == 4) && (options.e_block_size == 4)) {
+    return std::make_unique<PartitionedMatrixView<4, 4, Eigen::Dynamic>>(
+        options, matrix);
   }
 
 #endif
   VLOG(1) << "Template specializations not found for <"
           << options.row_block_size << "," << options.e_block_size << ","
           << options.f_block_size << ">";
-  return std::make_unique<PartitionedMatrixView<Eigen::Dynamic,
-                                                Eigen::Dynamic,
-                                                Eigen::Dynamic>>(
+  return std::make_unique<
+      PartitionedMatrixView<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>>(
       options, matrix);
 };
 
diff --git a/internal/ceres/partitioned_matrix_view.h b/internal/ceres/partitioned_matrix_view.h
index 8589a3b..8fa8e5a 100644
--- a/internal/ceres/partitioned_matrix_view.h
+++ b/internal/ceres/partitioned_matrix_view.h
@@ -48,7 +48,6 @@
 #include "ceres/internal/export.h"
 #include "ceres/linear_solver.h"
 #include "ceres/small_blas.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/partitioned_matrix_view_impl.h b/internal/ceres/partitioned_matrix_view_impl.h
index bd02439..322d00f 100644
--- a/internal/ceres/partitioned_matrix_view_impl.h
+++ b/internal/ceres/partitioned_matrix_view_impl.h
@@ -33,6 +33,7 @@
 #include <memory>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
 #include "ceres/internal/eigen.h"
@@ -40,7 +41,6 @@
 #include "ceres/partition_range_for_parallel_for.h"
 #include "ceres/partitioned_matrix_view.h"
 #include "ceres/small_blas.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/partitioned_matrix_view_test.cc b/internal/ceres/partitioned_matrix_view_test.cc
index 3addba6..72ad1c4 100644
--- a/internal/ceres/partitioned_matrix_view_test.cc
+++ b/internal/ceres/partitioned_matrix_view_test.cc
@@ -36,12 +36,12 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/block_structure.h"
 #include "ceres/casts.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
 #include "ceres/sparse_matrix.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -65,7 +65,7 @@
     const int problem_id = ::testing::get<0>(GetParam());
     const int num_threads = ::testing::get<1>(GetParam());
     auto problem = CreateLinearLeastSquaresProblemFromId(problem_id);
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     A_ = std::move(problem->A);
     auto block_sparse = down_cast<BlockSparseMatrix*>(A_.get());
 
@@ -173,8 +173,8 @@
   const int num_col_blocks_f = pmv_->num_col_blocks_f();
   const int num_col_blocks_e = pmv_->num_col_blocks_e();
 
-  CHECK_EQ(block_diagonal_ff->num_rows(), num_cols_f);
-  CHECK_EQ(block_diagonal_ff->num_cols(), num_cols_f);
+  ASSERT_EQ(block_diagonal_ff->num_rows(), num_cols_f);
+  ASSERT_EQ(block_diagonal_ff->num_cols(), num_cols_f);
 
   EXPECT_EQ(bs_diagonal->cols.size(), num_col_blocks_f);
   EXPECT_EQ(bs_diagonal->rows.size(), num_col_blocks_f);
@@ -212,8 +212,8 @@
   const int num_cols_e = pmv_->num_cols_e();
   const int num_col_blocks_e = pmv_->num_col_blocks_e();
 
-  CHECK_EQ(block_diagonal_ee->num_rows(), num_cols_e);
-  CHECK_EQ(block_diagonal_ee->num_cols(), num_cols_e);
+  ASSERT_EQ(block_diagonal_ee->num_rows(), num_cols_e);
+  ASSERT_EQ(block_diagonal_ee->num_cols(), num_cols_e);
 
   EXPECT_EQ(bs->cols.size(), num_col_blocks_e);
   EXPECT_EQ(bs->rows.size(), num_col_blocks_e);
diff --git a/internal/ceres/polynomial.cc b/internal/ceres/polynomial.cc
index 8e99e34..db3a404 100644
--- a/internal/ceres/polynomial.cc
+++ b/internal/ceres/polynomial.cc
@@ -36,9 +36,10 @@
 #include <vector>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/function_sample.h"
 #include "ceres/internal/export.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/preconditioner.cc b/internal/ceres/preconditioner.cc
index 0b9ce96..7c51976 100644
--- a/internal/ceres/preconditioner.cc
+++ b/internal/ceres/preconditioner.cc
@@ -30,7 +30,7 @@
 
 #include "ceres/preconditioner.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/preprocessor.cc b/internal/ceres/preprocessor.cc
index 83c05d4..33fb7fb 100644
--- a/internal/ceres/preprocessor.cc
+++ b/internal/ceres/preprocessor.cc
@@ -32,6 +32,7 @@
 
 #include <memory>
 
+#include "absl/log/log.h"
 #include "ceres/callbacks.h"
 #include "ceres/gradient_checking_cost_function.h"
 #include "ceres/line_search_preprocessor.h"
diff --git a/internal/ceres/problem_impl.cc b/internal/ceres/problem_impl.cc
index 52575ee..eafbb20 100644
--- a/internal/ceres/problem_impl.cc
+++ b/internal/ceres/problem_impl.cc
@@ -41,6 +41,8 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/casts.h"
 #include "ceres/compressed_row_jacobian_writer.h"
 #include "ceres/compressed_row_sparse_matrix.h"
@@ -61,7 +63,6 @@
 #include "ceres/scratch_evaluate_preparer.h"
 #include "ceres/stl_util.h"
 #include "ceres/stringprintf.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 namespace {
diff --git a/internal/ceres/problem_test.cc b/internal/ceres/problem_test.cc
index ebf15cd..29524d1 100644
--- a/internal/ceres/problem_test.cc
+++ b/internal/ceres/problem_test.cc
@@ -35,6 +35,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/autodiff_cost_function.h"
 #include "ceres/casts.h"
 #include "ceres/cost_function.h"
@@ -324,7 +325,7 @@
   }
 
   // Check that the destructor was called only once.
-  CHECK_EQ(num_destructions, 1);
+  ASSERT_EQ(num_destructions, 1);
 }
 
 TEST(Problem, GetCostFunctionForResidualBlock) {
@@ -369,13 +370,13 @@
     EXPECT_EQ(2, problem.NumResidualBlocks());
 
     problem.RemoveResidualBlock(r_yz);
-    CHECK_EQ(num_destructions, 1);
+    ASSERT_EQ(num_destructions, 1);
     problem.RemoveResidualBlock(r_wz);
-    CHECK_EQ(num_destructions, 2);
+    ASSERT_EQ(num_destructions, 2);
 
     EXPECT_EQ(0, problem.NumResidualBlocks());
   }
-  CHECK_EQ(num_destructions, 2);
+  ASSERT_EQ(num_destructions, 2);
 }
 
 // Make the dynamic problem tests (e.g. for removing residual blocks)
@@ -1162,7 +1163,7 @@
 
 // Convert a CRSMatrix to a dense Eigen matrix.
 static void CRSToDenseMatrix(const CRSMatrix& input, Matrix* output) {
-  CHECK(output != nullptr);
+  ASSERT_TRUE(output != nullptr);
   Matrix& m = *output;
   m.resize(input.num_rows, input.num_cols);
   m.setZero();
diff --git a/internal/ceres/reorder_program.cc b/internal/ceres/reorder_program.cc
index 268c477..6753df9 100644
--- a/internal/ceres/reorder_program.cc
+++ b/internal/ceres/reorder_program.cc
@@ -63,7 +63,8 @@
 #include "Eigen/OrderingMethods"
 #endif
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/residual_block_utils.cc b/internal/ceres/residual_block_utils.cc
index 91370d8..54c41fb 100644
--- a/internal/ceres/residual_block_utils.cc
+++ b/internal/ceres/residual_block_utils.cc
@@ -35,13 +35,13 @@
 #include <limits>
 #include <string>
 
+#include "absl/log/check.h"
 #include "ceres/array_utils.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/parameter_block.h"
 #include "ceres/residual_block.h"
 #include "ceres/stringprintf.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/rotation_test.cc b/internal/ceres/rotation_test.cc
index f1ea071..ffa5ff3 100644
--- a/internal/ceres/rotation_test.cc
+++ b/internal/ceres/rotation_test.cc
@@ -38,6 +38,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/log/log.h"
 #include "ceres/constants.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/euler_angles.h"
@@ -46,7 +47,6 @@
 #include "ceres/jet.h"
 #include "ceres/stringprintf.h"
 #include "ceres/test_util.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -648,7 +648,7 @@
       }
     }
   }
-  CHECK_EQ(7, n_tests);
+  ASSERT_EQ(7, n_tests);
 }
 
 // Test that a random rotation produces an orthonormal rotation
diff --git a/internal/ceres/schur_complement_solver_test.cc b/internal/ceres/schur_complement_solver_test.cc
index 7c5ce28..de00508 100644
--- a/internal/ceres/schur_complement_solver_test.cc
+++ b/internal/ceres/schur_complement_solver_test.cc
@@ -42,7 +42,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -53,7 +52,7 @@
     std::unique_ptr<LinearLeastSquaresProblem> problem =
         CreateLinearLeastSquaresProblemFromId(problem_id);
 
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     A.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
     b = std::move(problem->b);
     D = std::move(problem->D);
diff --git a/internal/ceres/schur_eliminator.cc b/internal/ceres/schur_eliminator.cc
index cb079b5..86d6a2c 100644
--- a/internal/ceres/schur_eliminator.cc
+++ b/internal/ceres/schur_eliminator.cc
@@ -39,10 +39,12 @@
 //
 // This file is generated using generate_template_specializations.py.
 
+#include "ceres/schur_eliminator.h"
+
 #include <memory>
 
+#include "absl/log/log.h"
 #include "ceres/linear_solver.h"
-#include "ceres/schur_eliminator.h"
 
 namespace ceres::internal {
 
@@ -51,103 +53,84 @@
 std::unique_ptr<SchurEliminatorBase> SchurEliminatorBase::Create(
     const LinearSolver::Options& options) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 2)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 2)) {
     return std::make_unique<SchurEliminator<2, 2, 2>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 3)) {
     return std::make_unique<SchurEliminator<2, 2, 3>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 4)) {
     return std::make_unique<SchurEliminator<2, 2, 4>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2)) {
     return std::make_unique<SchurEliminator<2, 2, Eigen::Dynamic>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 3)) {
     return std::make_unique<SchurEliminator<2, 3, 3>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 4)) {
     return std::make_unique<SchurEliminator<2, 3, 4>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 6)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 6)) {
     return std::make_unique<SchurEliminator<2, 3, 6>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 9)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 9)) {
     return std::make_unique<SchurEliminator<2, 3, 9>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3)) {
     return std::make_unique<SchurEliminator<2, 3, Eigen::Dynamic>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 3)) {
     return std::make_unique<SchurEliminator<2, 4, 3>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 4)) {
     return std::make_unique<SchurEliminator<2, 4, 4>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 6)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 6)) {
     return std::make_unique<SchurEliminator<2, 4, 6>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 8)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 8)) {
     return std::make_unique<SchurEliminator<2, 4, 8>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 9)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 9)) {
     return std::make_unique<SchurEliminator<2, 4, 9>>(options);
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4)) {
     return std::make_unique<SchurEliminator<2, 4, Eigen::Dynamic>>(options);
   }
   if (options.row_block_size == 2) {
-    return std::make_unique<SchurEliminator<2, Eigen::Dynamic, Eigen::Dynamic>>(options);
+    return std::make_unique<SchurEliminator<2, Eigen::Dynamic, Eigen::Dynamic>>(
+        options);
   }
-  if ((options.row_block_size == 3) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 3) && (options.e_block_size == 3) &&
+      (options.f_block_size == 3)) {
     return std::make_unique<SchurEliminator<3, 3, 3>>(options);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 2)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 2)) {
     return std::make_unique<SchurEliminator<4, 4, 2>>(options);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 3)) {
     return std::make_unique<SchurEliminator<4, 4, 3>>(options);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 4)) {
     return std::make_unique<SchurEliminator<4, 4, 4>>(options);
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4)) {
     return std::make_unique<SchurEliminator<4, 4, Eigen::Dynamic>>(options);
   }
 
@@ -155,9 +138,8 @@
   VLOG(1) << "Template specializations not found for <"
           << options.row_block_size << "," << options.e_block_size << ","
           << options.f_block_size << ">";
-  return std::make_unique<SchurEliminator<Eigen::Dynamic,
-                                          Eigen::Dynamic,
-                                          Eigen::Dynamic>>(options);
+  return std::make_unique<
+      SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>>(options);
 }
 
 }  // namespace ceres::internal
diff --git a/internal/ceres/schur_eliminator_impl.h b/internal/ceres/schur_eliminator_impl.h
index ef5ce66..f018b42 100644
--- a/internal/ceres/schur_eliminator_impl.h
+++ b/internal/ceres/schur_eliminator_impl.h
@@ -54,6 +54,7 @@
 #include <map>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
 #include "ceres/block_random_access_matrix.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
@@ -67,7 +68,6 @@
 #include "ceres/small_blas.h"
 #include "ceres/stl_util.h"
 #include "ceres/thread_token_provider.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/schur_eliminator_test.cc b/internal/ceres/schur_eliminator_test.cc
index bdf8b8c..7821289 100644
--- a/internal/ceres/schur_eliminator_test.cc
+++ b/internal/ceres/schur_eliminator_test.cc
@@ -47,7 +47,6 @@
 #include "ceres/test_util.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 // TODO(sameeragarwal): Reduce the size of these tests and redo the
@@ -59,7 +58,7 @@
  protected:
   void SetUpFromId(int id) {
     auto problem = CreateLinearLeastSquaresProblemFromId(id);
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     SetupHelper(problem.get());
   }
 
diff --git a/internal/ceres/schur_jacobi_preconditioner.cc b/internal/ceres/schur_jacobi_preconditioner.cc
index fbe258d..83505dd 100644
--- a/internal/ceres/schur_jacobi_preconditioner.cc
+++ b/internal/ceres/schur_jacobi_preconditioner.cc
@@ -34,11 +34,11 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
 #include "ceres/block_random_access_diagonal_matrix.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/linear_solver.h"
 #include "ceres/schur_eliminator.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/schur_templates.cc b/internal/ceres/schur_templates.cc
index 95df671..56b0055 100644
--- a/internal/ceres/schur_templates.cc
+++ b/internal/ceres/schur_templates.cc
@@ -39,9 +39,10 @@
 //
 // This file is generated using generate_template_specializations.py.
 
-#include "ceres/internal/eigen.h"
 #include "ceres/schur_templates.h"
 
+#include "ceres/internal/eigen.h"
+
 namespace ceres {
 namespace internal {
 
@@ -56,118 +57,103 @@
   *e_block_size = Eigen::Dynamic;
   *f_block_size = Eigen::Dynamic;
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 2)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 2)) {
     *row_block_size = 2;
     *e_block_size = 2;
     *f_block_size = 2;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 3)) {
     *row_block_size = 2;
     *e_block_size = 2;
     *f_block_size = 3;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2) &&
+      (options.f_block_size == 4)) {
     *row_block_size = 2;
     *e_block_size = 2;
     *f_block_size = 4;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 2)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 2)) {
     *row_block_size = 2;
     *e_block_size = 2;
     *f_block_size = Eigen::Dynamic;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 3)) {
     *row_block_size = 2;
     *e_block_size = 3;
     *f_block_size = 3;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 4)) {
     *row_block_size = 2;
     *e_block_size = 3;
     *f_block_size = 4;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 6)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 6)) {
     *row_block_size = 2;
     *e_block_size = 3;
     *f_block_size = 6;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 9)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3) &&
+      (options.f_block_size == 9)) {
     *row_block_size = 2;
     *e_block_size = 3;
     *f_block_size = 9;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 3)) {
     *row_block_size = 2;
     *e_block_size = 3;
     *f_block_size = Eigen::Dynamic;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 3)) {
     *row_block_size = 2;
     *e_block_size = 4;
     *f_block_size = 3;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 4)) {
     *row_block_size = 2;
     *e_block_size = 4;
     *f_block_size = 4;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 6)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 6)) {
     *row_block_size = 2;
     *e_block_size = 4;
     *f_block_size = 6;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 8)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 8)) {
     *row_block_size = 2;
     *e_block_size = 4;
     *f_block_size = 8;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 9)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4) &&
+      (options.f_block_size == 9)) {
     *row_block_size = 2;
     *e_block_size = 4;
     *f_block_size = 9;
     return;
   }
-  if ((options.row_block_size == 2) &&
-     (options.e_block_size == 4)) {
+  if ((options.row_block_size == 2) && (options.e_block_size == 4)) {
     *row_block_size = 2;
     *e_block_size = 4;
     *f_block_size = Eigen::Dynamic;
@@ -179,40 +165,35 @@
     *f_block_size = Eigen::Dynamic;
     return;
   }
-  if ((options.row_block_size == 3) &&
-     (options.e_block_size == 3) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 3) && (options.e_block_size == 3) &&
+      (options.f_block_size == 3)) {
     *row_block_size = 3;
     *e_block_size = 3;
     *f_block_size = 3;
     return;
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 2)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 2)) {
     *row_block_size = 4;
     *e_block_size = 4;
     *f_block_size = 2;
     return;
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 3)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 3)) {
     *row_block_size = 4;
     *e_block_size = 4;
     *f_block_size = 3;
     return;
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4) &&
-     (options.f_block_size == 4)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4) &&
+      (options.f_block_size == 4)) {
     *row_block_size = 4;
     *e_block_size = 4;
     *f_block_size = 4;
     return;
   }
-  if ((options.row_block_size == 4) &&
-     (options.e_block_size == 4)) {
+  if ((options.row_block_size == 4) && (options.e_block_size == 4)) {
     *row_block_size = 4;
     *e_block_size = 4;
     *f_block_size = Eigen::Dynamic;
diff --git a/internal/ceres/small_blas.h b/internal/ceres/small_blas.h
index fb8d7fa..20fedf6 100644
--- a/internal/ceres/small_blas.h
+++ b/internal/ceres/small_blas.h
@@ -35,9 +35,9 @@
 #ifndef CERES_INTERNAL_SMALL_BLAS_H_
 #define CERES_INTERNAL_SMALL_BLAS_H_
 
+#include "absl/log/check.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
-#include "glog/logging.h"
 #include "small_blas_generic.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index fadb17b..a8de046 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -38,6 +38,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/casts.h"
 #include "ceres/context.h"
 #include "ceres/context_impl.h"
diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc
index 52bd594..0a83a34 100644
--- a/internal/ceres/solver_test.cc
+++ b/internal/ceres/solver_test.cc
@@ -36,6 +36,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/autodiff_cost_function.h"
 #include "ceres/evaluation_callback.h"
 #include "ceres/manifold.h"
diff --git a/internal/ceres/sparse_cholesky.cc b/internal/ceres/sparse_cholesky.cc
index ecfeb29..f20aa99 100644
--- a/internal/ceres/sparse_cholesky.cc
+++ b/internal/ceres/sparse_cholesky.cc
@@ -33,6 +33,7 @@
 #include <memory>
 #include <utility>
 
+#include "absl/log/log.h"
 #include "ceres/accelerate_sparse.h"
 #include "ceres/cuda_sparse_cholesky.h"
 #include "ceres/eigensparse.h"
diff --git a/internal/ceres/sparse_cholesky.h b/internal/ceres/sparse_cholesky.h
index 53f475a..0b2a3a4 100644
--- a/internal/ceres/sparse_cholesky.h
+++ b/internal/ceres/sparse_cholesky.h
@@ -41,7 +41,6 @@
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
 #include "ceres/linear_solver.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/sparse_cholesky_test.cc b/internal/ceres/sparse_cholesky_test.cc
index bb5c7c8..10efd28 100644
--- a/internal/ceres/sparse_cholesky_test.cc
+++ b/internal/ceres/sparse_cholesky_test.cc
@@ -44,7 +44,6 @@
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/iterative_refiner.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/internal/ceres/sparse_normal_cholesky_solver_test.cc b/internal/ceres/sparse_normal_cholesky_solver_test.cc
index 2ff3f6e..987272e 100644
--- a/internal/ceres/sparse_normal_cholesky_solver_test.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver_test.cc
@@ -38,7 +38,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -56,7 +55,7 @@
     std::unique_ptr<LinearLeastSquaresProblem> problem =
         CreateLinearLeastSquaresProblemFromId(2);
 
-    CHECK(problem != nullptr);
+    ASSERT_TRUE(problem != nullptr);
     A_.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
     b_ = std::move(problem->b);
     D_ = std::move(problem->D);
diff --git a/internal/ceres/subset_preconditioner.cc b/internal/ceres/subset_preconditioner.cc
index 068f6ce..52b79f7 100644
--- a/internal/ceres/subset_preconditioner.cc
+++ b/internal/ceres/subset_preconditioner.cc
@@ -34,6 +34,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/log/log.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/inner_product_computer.h"
 #include "ceres/linear_solver.h"
diff --git a/internal/ceres/subset_preconditioner_test.cc b/internal/ceres/subset_preconditioner_test.cc
index b73274c..4849264 100644
--- a/internal/ceres/subset_preconditioner_test.cc
+++ b/internal/ceres/subset_preconditioner_test.cc
@@ -40,7 +40,6 @@
 #include "ceres/inner_product_computer.h"
 #include "ceres/internal/config.h"
 #include "ceres/internal/eigen.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/suitesparse.cc b/internal/ceres/suitesparse.cc
index d93dd8d..3595b29 100644
--- a/internal/ceres/suitesparse.cc
+++ b/internal/ceres/suitesparse.cc
@@ -37,9 +37,11 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/log.h"
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/linear_solver.h"
+#include "ceres/stringprintf.h"
 #include "ceres/suitesparse.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "cholmod.h"
diff --git a/internal/ceres/suitesparse.h b/internal/ceres/suitesparse.h
index 703ee87..57d1d78 100644
--- a/internal/ceres/suitesparse.h
+++ b/internal/ceres/suitesparse.h
@@ -49,7 +49,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/sparse_cholesky.h"
 #include "cholmod.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/system_test.cc b/internal/ceres/system_test.cc
index 6134995..53c4451 100644
--- a/internal/ceres/system_test.cc
+++ b/internal/ceres/system_test.cc
@@ -40,7 +40,6 @@
 #include "ceres/solver.h"
 #include "ceres/test_util.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/test_util.cc b/internal/ceres/test_util.cc
index 05d24c3..a9d4335 100644
--- a/internal/ceres/test_util.cc
+++ b/internal/ceres/test_util.cc
@@ -35,11 +35,12 @@
 #include <algorithm>
 #include <cmath>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/file.h"
 #include "ceres/internal/port.h"
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 // This macro is used to inject additional path information specific
diff --git a/internal/ceres/thread_pool_test.cc b/internal/ceres/thread_pool_test.cc
index fa321b0..b794c3e 100644
--- a/internal/ceres/thread_pool_test.cc
+++ b/internal/ceres/thread_pool_test.cc
@@ -35,8 +35,8 @@
 #include <mutex>
 #include <thread>
 
+#include "absl/log/log.h"
 #include "ceres/internal/config.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/internal/ceres/triplet_sparse_matrix.cc b/internal/ceres/triplet_sparse_matrix.cc
index 4bb6685..554ece9 100644
--- a/internal/ceres/triplet_sparse_matrix.cc
+++ b/internal/ceres/triplet_sparse_matrix.cc
@@ -34,12 +34,13 @@
 #include <memory>
 #include <random>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/crs_matrix.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/export.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc
index d76f677..9d9b8e8 100644
--- a/internal/ceres/trust_region_minimizer.cc
+++ b/internal/ceres/trust_region_minimizer.cc
@@ -40,6 +40,8 @@
 #include <vector>
 
 #include "Eigen/Core"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/array_utils.h"
 #include "ceres/coordinate_descent_minimizer.h"
 #include "ceres/eigen_vector_ops.h"
@@ -50,7 +52,6 @@
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
 #include "ceres/wall_time.h"
-#include "glog/logging.h"
 
 // Helper macro to simplify some of the control flow.
 #define RETURN_IF_ERROR_AND_LOG(expr)                            \
diff --git a/internal/ceres/trust_region_minimizer_test.cc b/internal/ceres/trust_region_minimizer_test.cc
index 94c7162..ca28675 100644
--- a/internal/ceres/trust_region_minimizer_test.cc
+++ b/internal/ceres/trust_region_minimizer_test.cc
@@ -38,6 +38,8 @@
 #include <cmath>
 #include <memory>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/autodiff_cost_function.h"
 #include "ceres/cost_function.h"
 #include "ceres/dense_qr_solver.h"
diff --git a/internal/ceres/trust_region_step_evaluator.cc b/internal/ceres/trust_region_step_evaluator.cc
index a2333a0..5c10c05 100644
--- a/internal/ceres/trust_region_step_evaluator.cc
+++ b/internal/ceres/trust_region_step_evaluator.cc
@@ -33,8 +33,6 @@
 #include <algorithm>
 #include <limits>
 
-#include "glog/logging.h"
-
 namespace ceres::internal {
 
 TrustRegionStepEvaluator::TrustRegionStepEvaluator(
diff --git a/internal/ceres/trust_region_strategy.cc b/internal/ceres/trust_region_strategy.cc
index da5a337..530fc30 100644
--- a/internal/ceres/trust_region_strategy.cc
+++ b/internal/ceres/trust_region_strategy.cc
@@ -34,6 +34,7 @@
 
 #include <memory>
 
+#include "absl/log/log.h"
 #include "ceres/dogleg_strategy.h"
 #include "ceres/levenberg_marquardt_strategy.h"
 
diff --git a/internal/ceres/types.cc b/internal/ceres/types.cc
index e000560..4bbd602 100644
--- a/internal/ceres/types.cc
+++ b/internal/ceres/types.cc
@@ -34,8 +34,8 @@
 #include <cctype>
 #include <string>
 
+#include "absl/log/log.h"
 #include "ceres/internal/config.h"
-#include "glog/logging.h"
 
 namespace ceres {
 
diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
index 6c10fb2..05ac8b0 100644
--- a/internal/ceres/visibility.cc
+++ b/internal/ceres/visibility.cc
@@ -39,10 +39,11 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_structure.h"
 #include "ceres/graph.h"
 #include "ceres/pair_hash.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc
index 34d6e0c..0f46a87 100644
--- a/internal/ceres/visibility_based_preconditioner.cc
+++ b/internal/ceres/visibility_based_preconditioner.cc
@@ -41,6 +41,8 @@
 #include <vector>
 
 #include "Eigen/Dense"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ceres/block_random_access_sparse_matrix.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/canonical_views_clustering.h"
@@ -50,7 +52,6 @@
 #include "ceres/schur_eliminator.h"
 #include "ceres/single_linkage_clustering.h"
 #include "ceres/visibility.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/internal/ceres/visibility_based_preconditioner_test.cc b/internal/ceres/visibility_based_preconditioner_test.cc
index 4d52753..1cbad17 100644
--- a/internal/ceres/visibility_based_preconditioner_test.cc
+++ b/internal/ceres/visibility_based_preconditioner_test.cc
@@ -44,7 +44,6 @@
 #include "ceres/stringprintf.h"
 #include "ceres/test_util.h"
 #include "ceres/types.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
@@ -73,7 +72,7 @@
 //     D_.reset(problem->D.release());
 
 //     const CompressedRowBlockStructure* bs =
-//         CHECK_NOTNULL(A_->block_structure());
+//         ASSERT_TRUE(A_->block_structure()!=nullptr);
 //     const int num_col_blocks = bs->cols.size();
 
 //     num_cols_ = A_->num_cols();
diff --git a/internal/ceres/visibility_test.cc b/internal/ceres/visibility_test.cc
index 3efc77c..871ab56 100644
--- a/internal/ceres/visibility_test.cc
+++ b/internal/ceres/visibility_test.cc
@@ -37,7 +37,6 @@
 
 #include "ceres/block_structure.h"
 #include "ceres/graph.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres::internal {
diff --git a/internal/ceres/wall_time.cc b/internal/ceres/wall_time.cc
index 2f4cf28..f42f1ea 100644
--- a/internal/ceres/wall_time.cc
+++ b/internal/ceres/wall_time.cc
@@ -32,6 +32,7 @@
 
 #include <ctime>
 
+#include "absl/log/log.h"
 #include "ceres/internal/config.h"
 
 #ifdef _WIN32
@@ -40,6 +41,8 @@
 #include <sys/time.h>
 #endif
 
+#include "ceres/stringprintf.h"
+
 namespace ceres::internal {
 
 double WallTimeInSeconds() {
diff --git a/internal/ceres/wall_time.h b/internal/ceres/wall_time.h
index f99052b..8878f9b 100644
--- a/internal/ceres/wall_time.h
+++ b/internal/ceres/wall_time.h
@@ -36,8 +36,6 @@
 
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/export.h"
-#include "ceres/stringprintf.h"
-#include "glog/logging.h"
 
 namespace ceres::internal {
 
diff --git a/package.xml b/package.xml
index 9d43e43..a6abe4c 100644
--- a/package.xml
+++ b/package.xml
@@ -44,8 +44,6 @@
   <build_depend>gfortran</build_depend>
   <build_depend>suitesparse</build_depend>
   <depend>eigen</depend>
-  <depend>libgflags-dev</depend>
-  <depend>libgoogle-glog-dev</depend>
 
   <export>
     <build_type>cmake</build_type>
diff --git a/third_party/abseil-cpp b/third_party/abseil-cpp
new file mode 160000
index 0000000..d7aaad8
--- /dev/null
+++ b/third_party/abseil-cpp
@@ -0,0 +1 @@
+Subproject commit d7aaad83b488fd62bd51c81ecf16cd938532cc0a