Patch-Source: https://github.com/open-telemetry/opentelemetry-cpp/pull/2163
--
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 997c944..3209653 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,9 @@ project(opentelemetry-cpp)
 # Mark variables as used so cmake doesn't complain about them
 mark_as_advanced(CMAKE_TOOLCHAIN_FILE)
 
+# Prefer cmake CONFIG to auto resolve dependencies.
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
+
 # Don't use customized cmake modules if vcpkg is used to resolve dependence.
 if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
   list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")
@@ -125,6 +128,8 @@ endif()
 option(OPENTELEMETRY_INSTALL "Whether to install opentelemetry targets"
        ${OPENTELEMETRY_INSTALL_default})
 
+include("${PROJECT_SOURCE_DIR}/cmake/tools.cmake")
+
 if(NOT DEFINED CMAKE_CXX_STANDARD)
   if(WITH_STL)
     # Require at least C++17. C++20 is needed to avoid gsl::span
@@ -343,9 +348,22 @@ if(WITH_PROMETHEUS)
   endif()
 endif()
 
+if(WITH_ABSEIL)
+  find_package(absl CONFIG REQUIRED)
+endif()
+
 if(WITH_OTLP_GRPC OR WITH_OTLP_HTTP)
   set(protobuf_MODULE_COMPATIBLE ON)
   find_package(Protobuf)
+  if(Protobuf_VERSION AND Protobuf_VERSION VERSION_GREATER_EQUAL "3.22.0")
+    if(NOT WITH_ABSEIL)
+      message(
+        FATAL_ERROR
+          "Protobuf 3.22 or upper require abseil-cpp(Recommended version: 20230125.3 or upper)"
+      )
+    endif()
+  endif()
+
   if(WITH_OTLP_GRPC)
     find_package(gRPC)
   endif()
@@ -375,10 +393,14 @@ if(WITH_OTLP_GRPC OR WITH_OTLP_HTTP)
         )
       endif()
     endif()
-    # Latest Protobuf uses mixed case instead of uppercase
-    if(Protobuf_PROTOC_EXECUTABLE)
-      set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
-    endif()
+  endif()
+  # Latest Protobuf imported targets and without legacy module support
+  if(TARGET protobuf::protoc)
+    project_build_tools_get_imported_location(PROTOBUF_PROTOC_EXECUTABLE
+                                              protobuf::protoc)
+  elseif(Protobuf_PROTOC_EXECUTABLE)
+    # Some versions of FindProtobuf.cmake uses mixed case instead of uppercase
+    set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
   endif()
   include(CMakeDependentOption)
 
@@ -543,7 +565,17 @@ if(BUILD_TESTING)
     # Prefer GTest installed by OS distro, brew or vcpkg package manager
     find_package(GTest REQUIRED)
   endif()
-  include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
+  if(NOT GTEST_BOTH_LIBRARIES)
+    # New GTest package names
+    if(TARGET GTest::gtest)
+      set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main GTest::gmock)
+    elseif(TARGET GTest::GTest)
+      set(GTEST_BOTH_LIBRARIES GTest::GTest GTest::Main)
+    endif()
+  endif()
+  if(GTEST_INCLUDE_DIRS)
+    include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
+  endif()
   message("GTEST_INCLUDE_DIRS   = ${GTEST_INCLUDE_DIRS}")
   message("GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}")
   enable_testing()
@@ -616,6 +648,8 @@ endif()
 
 include(cmake/opentelemetry-build-external-component.cmake)
 
+include("${PROJECT_SOURCE_DIR}/cmake/patch-imported-config.cmake")
+
 if(OPENTELEMETRY_INSTALL)
   # Export cmake config and support find_packages(opentelemetry-cpp CONFIG)
   # Write config file for find_packages(opentelemetry-cpp CONFIG)
diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt
index d1a6a77..594d9c9 100644
--- a/api/CMakeLists.txt
+++ b/api/CMakeLists.txt
@@ -48,8 +48,6 @@ endif()
 
 if(WITH_ABSEIL)
 
-  find_package(absl CONFIG REQUIRED)
-
   target_compile_definitions(opentelemetry_api INTERFACE HAVE_ABSEIL)
   target_link_libraries(
     opentelemetry_api INTERFACE absl::bad_variant_access absl::any absl::base
diff --git a/ci/do_ci.sh b/ci/do_ci.sh
index 69a6eef..62e47b5 100755
--- a/ci/do_ci.sh
+++ b/ci/do_ci.sh
@@ -83,12 +83,17 @@ BAZEL_MACOS_TEST_OPTIONS="$BAZEL_MACOS_OPTIONS --test_output=errors"
 
 BAZEL_STARTUP_OPTIONS="--output_user_root=$HOME/.cache/bazel"
 
+CMAKE_OPTIONS=(-DCMAKE_BUILD_TYPE=Debug)
+if [ ! -z "${CXX_STANDARD}" ]; then
+  CMAKE_OPTIONS=(${CMAKE_OPTIONS[@]} "-DCMAKE_CXX_STANDARD=${CXX_STANDARD}")
+fi
+
 export CTEST_OUTPUT_ON_FAILURE=1
 
 if [[ "$1" == "cmake.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_PROMETHEUS=ON \
         -DWITH_ZIPKIN=ON \
         -DWITH_ELASTICSEARCH=ON \
@@ -102,7 +107,7 @@ if [[ "$1" == "cmake.test" ]]; then
 elif [[ "$1" == "cmake.maintainer.sync.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_OTLP_HTTP=ON \
         -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \
         -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \
@@ -150,7 +155,7 @@ elif [[ "$1" == "cmake.maintainer.async.test" ]]; then
 elif [[ "$1" == "cmake.maintainer.cpp11.async.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_STANDARD=11 \
         -DWITH_OTLP_HTTP=ON \
         -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \
@@ -174,7 +179,7 @@ elif [[ "$1" == "cmake.maintainer.cpp11.async.test" ]]; then
 elif [[ "$1" == "cmake.with_async_export.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_PROMETHEUS=ON \
         -DWITH_ZIPKIN=ON \
         -DWITH_ELASTICSEARCH=ON \
@@ -189,7 +194,7 @@ elif [[ "$1" == "cmake.with_async_export.test" ]]; then
 elif [[ "$1" == "cmake.abseil.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \
         -DWITH_LOGS_PREVIEW=ON \
         -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \
@@ -202,7 +207,7 @@ elif [[ "$1" == "cmake.abseil.test" ]]; then
 elif [[ "$1" == "cmake.opentracing_shim.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug \
+  cmake ${CMAKE_OPTIONS[@]} \
         -DCMAKE_CXX_FLAGS="-Werror -Wno-error=redundant-move $CXXFLAGS" \
         -DWITH_OPENTRACING=ON \
         "${SRC_DIR}"
@@ -212,7 +217,7 @@ elif [[ "$1" == "cmake.opentracing_shim.test" ]]; then
 elif [[ "$1" == "cmake.c++20.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \
         -DWITH_ASYNC_EXPORT_PREVIEW=ON \
         -DCMAKE_CXX_STANDARD=20 \
@@ -224,7 +229,7 @@ elif [[ "$1" == "cmake.c++20.test" ]]; then
 elif [[ "$1" == "cmake.c++20.stl.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \
         -DWITH_LOGS_PREVIEW=ON \
         -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \
@@ -240,7 +245,7 @@ elif [[ "$1" == "cmake.legacy.test" ]]; then
   rm -rf *
   export BUILD_ROOT="${BUILD_DIR}"
   ${SRC_DIR}/tools/build-benchmark.sh
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \
         -DCMAKE_CXX_STANDARD=11 \
         "${SRC_DIR}"
@@ -252,7 +257,7 @@ elif [[ "$1" == "cmake.legacy.exporter.otprotocol.test" ]]; then
   rm -rf *
   export BUILD_ROOT="${BUILD_DIR}"
   ${SRC_DIR}/tools/build-benchmark.sh
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_STANDARD=11 \
         -DWITH_OTLP_GRPC=ON \
         -DWITH_OTLP_HTTP=ON \
@@ -267,7 +272,10 @@ elif [[ "$1" == "cmake.legacy.exporter.otprotocol.test" ]]; then
 elif [[ "$1" == "cmake.exporter.otprotocol.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  if [[ ! -z "${WITH_ABSEIL}" ]]; then
+    CMAKE_OPTIONS=(${CMAKE_OPTIONS[@]} "-DWITH_ABSEIL=${WITH_ABSEIL}")
+  fi
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_OTLP_GRPC=ON \
         -DWITH_OTLP_HTTP=ON \
         -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \
@@ -295,7 +303,7 @@ elif [[ "$1" == "cmake.exporter.otprotocol.shared_libs.with_static_grpc.test" ]]
 elif [[ "$1" == "cmake.exporter.otprotocol.with_async_export.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_OTLP_GRPC=ON \
         -DWITH_OTLP_HTTP=ON \
         -DWITH_ASYNC_EXPORT_PREVIEW=ON \
@@ -309,7 +317,7 @@ elif [[ "$1" == "cmake.exporter.otprotocol.with_async_export.test" ]]; then
 elif [[ "$1" == "cmake.do_not_install.test" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DWITH_OTLP_GRPC=ON \
         -DWITH_OTLP_HTTP=ON \
         -DWITH_ASYNC_EXPORT_PREVIEW=ON \
@@ -342,7 +350,7 @@ EOF
     -static-libgcc \
     -Wl,--version-script=${PWD}/export.map \
   "
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \
         -DCMAKE_EXE_LINKER_FLAGS="$LINKER_FLAGS" \
         -DCMAKE_SHARED_LINKER_FLAGS="$LINKER_FLAGS" \
@@ -353,7 +361,7 @@ EOF
   # Verify we can load the plugin
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS" \
         "${SRC_DIR}"
   make load_plugin_example
@@ -435,7 +443,7 @@ elif [[ "$1" == "format" ]]; then
 elif [[ "$1" == "code.coverage" ]]; then
   cd "${BUILD_DIR}"
   rm -rf *
-  cmake -DCMAKE_BUILD_TYPE=Debug  \
+  cmake ${CMAKE_OPTIONS[@]}  \
         -DCMAKE_CXX_FLAGS="-Werror --coverage $CXXFLAGS" \
         "${SRC_DIR}"
   make
diff --git a/ci/install_abseil.sh b/ci/install_abseil.sh
index 7764b4d..3bc69df 100755
--- a/ci/install_abseil.sh
+++ b/ci/install_abseil.sh
@@ -3,19 +3,27 @@
 # Copyright The OpenTelemetry Authors
 # SPDX-License-Identifier: Apache-2.0
 
-set -e
+set -ex
 export DEBIAN_FRONTEND=noninteractive
+[ -z "${ABSEIL_CPP_VERSION}" ] && export ABSEIL_CPP_VERSION="20220623.1"
 
 BUILD_DIR=/tmp/
 INSTALL_DIR=/usr/local/
-TAG=20220623.1
 pushd $BUILD_DIR
-git clone --depth=1 -b ${TAG} https://github.com/abseil/abseil-cpp.git
+git clone --depth=1 -b ${ABSEIL_CPP_VERSION} https://github.com/abseil/abseil-cpp.git
 cd abseil-cpp
+ABSEIL_CPP_BUILD_OPTIONS=(
+    "-DBUILD_TESTING=OFF"
+    "-DCMAKE_POSITION_INDEPENDENT_CODE=ON"
+    "-DCMAKE_INSTALL_PREFIX=$INSTALL_DIR"
+)
+
+if [ ! -z "${CXX_STANDARD}" ]; then
+    ABSEIL_CPP_BUILD_OPTIONS=(${ABSEIL_CPP_BUILD_OPTIONS[@]} "-DCMAKE_CXX_STANDARD=${CXX_STANDARD}")
+fi
+
 mkdir build && pushd build
-cmake -DBUILD_TESTING=OFF -DCMAKE_CXX_STANDARD=11 \
-    -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
-    ..
+cmake ${ABSEIL_CPP_BUILD_OPTIONS[@]} ..
 make -j $(nproc)
 make install
 popd
diff --git a/ci/install_protobuf.sh b/ci/install_protobuf.sh
index dde9411..3fb18e7 100755
--- a/ci/install_protobuf.sh
+++ b/ci/install_protobuf.sh
@@ -31,12 +31,41 @@ set -e
 # when calling this script
 #
 
-export CPP_PROTOBUF_VERSION="3.${PROTOBUF_VERSION}"
+CPP_PROTOBUF_BUILD_OPTIONS=(
+  "-DCMAKE_POSITION_INDEPENDENT_CODE=ON"
+  "-Dprotobuf_BUILD_TESTS=OFF"
+  "-Dprotobuf_BUILD_EXAMPLES=OFF"
+)
 
-cd /
-wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-cpp-${CPP_PROTOBUF_VERSION}.tar.gz
-tar zxf protobuf-cpp-${CPP_PROTOBUF_VERSION}.tar.gz --no-same-owner
-cd protobuf-${CPP_PROTOBUF_VERSION}
-./configure
-make -j $(nproc) && make install
+if [ ! -z "${CXX_STANDARD}" ]; then
+    CPP_PROTOBUF_BUILD_OPTIONS=(${CPP_PROTOBUF_BUILD_OPTIONS[@]} "-DCMAKE_CXX_STANDARD=${CXX_STANDARD}")
+fi
+
+# After protobuf 22/4.22, protobuf depends on absl and we can use
+# "-Dprotobuf_ABSL_PROVIDER=package" to tell protobuf to find absl from the
+# system. Otherwise, it will build absl from source.
+# 4.XX.YY and 3.XX.YY are alias of XX.YY, and source pacakges are moved into the
+# tag of XX.YY and without -cpp suffix from protobuf v22.
+if [[ ${PROTOBUF_VERSION/.*/} -ge 22 ]]; then
+  export CPP_PROTOBUF_VERSION="${PROTOBUF_VERSION}"
+  CPP_PROTOBUF_PACKAGE_NAME="protobuf-${CPP_PROTOBUF_VERSION}"
+  CPP_PROTOBUF_BUILD_OPTIONS=(${CPP_PROTOBUF_BUILD_OPTIONS[@]} "-Dprotobuf_ABSL_PROVIDER=package")
+else
+  export CPP_PROTOBUF_VERSION="3.${PROTOBUF_VERSION}"
+  CPP_PROTOBUF_PACKAGE_NAME="protobuf-cpp-${CPP_PROTOBUF_VERSION}"
+fi
+
+cd /tmp
+wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${CPP_PROTOBUF_PACKAGE_NAME}.tar.gz
+tar zxf ${CPP_PROTOBUF_PACKAGE_NAME}.tar.gz --no-same-owner
+
+mkdir protobuf-${CPP_PROTOBUF_VERSION}/build && pushd protobuf-${CPP_PROTOBUF_VERSION}/build
+if [ -e "../CMakeLists.txt" ]; then
+  cmake .. ${CPP_PROTOBUF_BUILD_OPTIONS[@]}
+else
+  cmake ../cmake ${CPP_PROTOBUF_BUILD_OPTIONS[@]}
+fi
+cmake --build . -j $(nproc)
+cmake --install .
+popd
 ldconfig
diff --git a/ci/setup_grpc.sh b/ci/setup_grpc.sh
index e1002b6..81876b4 100755
--- a/ci/setup_grpc.sh
+++ b/ci/setup_grpc.sh
@@ -22,9 +22,20 @@ while getopts ":v:i:r:s:TH" o; do
         i)
             install_dir=${OPTARG}
             ;;
+        p)
+            if [ "${OPTARG}" == "protobuf" ]; then
+                GRPC_BUILD_OPTIONS=(${GRPC_BUILD_OPTIONS[@]} "-DgRPC_PROTOBUF_PROVIDER=package")
+            elif [ "${OPTARG}" == "abseil-cpp" ]; then
+                GRPC_BUILD_OPTIONS=(${GRPC_BUILD_OPTIONS[@]} "-DgRPC_ABSL_PROVIDER=package")
+                build_internal_abseil_cpp=0
+            fi
+            ;;
         r)
             install_grpc_version=${OPTARG}
             ;;
+        m)
+            install_grpc_version=${modern_grpc_version}
+            ;;
         s)
             std_version=${OPTARG}
             ;;
@@ -36,14 +47,16 @@ while getopts ":v:i:r:s:TH" o; do
             ;;
         *)
             usage
+            exit 1;
             ;;
     esac
 done
+
 if [ -z "${gcc_version}" ]; then
     gcc_version=`gcc --version | awk '/gcc/  {print $NF}'`
 fi
-if [[ "${gcc_version}" < "${gcc_version_for_new_grpc}" ]]; then
-    echo "less"
+if [[ "${gcc_version}" < "${gcc_version_for_new_grpc}" ]] && [[ "${gcc_version:1:1}" == "." ]]; then
+    echo "${gcc_version} less than ${gcc_version_for_new_grpc}"
     std_version='11'
     install_grpc_version=${old_grpc_version}
 fi
diff --git a/cmake/opentelemetry-proto.cmake b/cmake/opentelemetry-proto.cmake
index 07238ba..15eefe3 100644
--- a/cmake/opentelemetry-proto.cmake
+++ b/cmake/opentelemetry-proto.cmake
@@ -65,8 +65,6 @@ else()
   endif()
 endif()
 
-include(${PROJECT_SOURCE_DIR}/cmake/proto-options-patch.cmake)
-
 set(COMMON_PROTO "${PROTO_PATH}/opentelemetry/proto/common/v1/common.proto")
 set(RESOURCE_PROTO
     "${PROTO_PATH}/opentelemetry/proto/resource/v1/resource.proto")
diff --git a/cmake/patch-imported-config.cmake b/cmake/patch-imported-config.cmake
new file mode 100644
index 0000000..6d76014
--- /dev/null
+++ b/cmake/patch-imported-config.cmake
@@ -0,0 +1,142 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+# Some prebuilt or installed targets may have different CONFIG settings than
+# what we use to configure otel-cpp. This file applies patches to the imported
+# targets in order to use compatible CONFIG settings for fallback.
+
+# Common dependencies
+include(cmake/proto-options-patch.cmake)
+project_build_tools_patch_default_imported_config(ZLIB::ZLIB)
+
+# protobuf targets
+if(Protobuf_FOUND OR PROTOBUF_FOUND)
+  project_build_tools_patch_default_imported_config(
+    utf8_range::utf8_range utf8_range::utf8_validity protobuf::libprotobuf-lite
+    protobuf::libprotobuf protobuf::libprotoc)
+endif()
+
+# cares targets
+if(TARGET c-ares::cares)
+  project_build_tools_patch_default_imported_config(c-ares::cares)
+endif()
+
+# curl targets
+if(TARGET CURL::libcurl)
+  project_build_tools_patch_default_imported_config(CURL::libcurl)
+endif()
+
+# abseil targets
+if(WITH_ABSEIL)
+  project_build_tools_patch_default_imported_config(
+    absl::bad_variant_access
+    absl::raw_logging_internal
+    absl::log_severity
+    absl::log_internal_check_op
+    absl::log_internal_nullguard
+    absl::strings
+    absl::strings_internal
+    absl::base
+    absl::spinlock_wait
+    absl::int128
+    absl::throw_delegate
+    absl::log_internal_message
+    absl::examine_stack
+    absl::stacktrace
+    absl::debugging_internal
+    absl::symbolize
+    absl::demangle_internal
+    absl::malloc_internal
+    absl::log_internal_format
+    absl::log_internal_globals
+    absl::time
+    absl::civil_time
+    absl::time_zone
+    absl::str_format_internal
+    absl::log_internal_proto
+    absl::log_internal_log_sink_set
+    absl::log_globals
+    absl::hash
+    absl::city
+    absl::bad_optional_access
+    absl::low_level_hash
+    absl::log_entry
+    absl::log_sink
+    absl::synchronization
+    absl::graphcycles_internal
+    absl::strerror
+    absl::log_internal_conditions
+    absl::cord
+    absl::cord_internal
+    absl::crc_cord_state
+    absl::crc32c
+    absl::crc_cpu_detect
+    absl::crc_internal
+    absl::cordz_functions
+    absl::exponential_biased
+    absl::cordz_info
+    absl::cordz_handle
+    absl::leak_check
+    absl::die_if_null
+    absl::flags
+    absl::flags_commandlineflag
+    absl::flags_commandlineflag_internal
+    absl::flags_config
+    absl::flags_program_name
+    absl::flags_internal
+    absl::flags_marshalling
+    absl::flags_reflection
+    absl::flags_private_handle_accessor
+    absl::raw_hash_set
+    absl::hashtablez_sampler
+    absl::log_initialize
+    absl::status
+    absl::statusor)
+endif()
+
+# gRPC targets
+if(TARGET gRPC::grpc++)
+  project_build_tools_patch_default_imported_config(
+    gRPC::cares
+    gRPC::re2
+    gRPC::ssl
+    gRPC::crypto
+    gRPC::zlibstatic
+    gRPC::address_sorting
+    gRPC::gpr
+    gRPC::grpc
+    gRPC::grpc_unsecure
+    gRPC::grpc++
+    gRPC::grpc++_alts
+    gRPC::grpc++_error_details
+    gRPC::grpc++_reflection
+    gRPC::grpc++_unsecure
+    gRPC::grpc_authorization_provider
+    gRPC::grpc_plugin_support
+    gRPC::grpcpp_channelz
+    gRPC::upb)
+endif()
+
+# prometheus targets
+if(TARGET prometheus-cpp::core)
+  project_build_tools_patch_default_imported_config(
+    prometheus-cpp::core prometheus-cpp::pull prometheus-cpp::push)
+endif()
+
+# civetweb targets
+if(TARGET civetweb::civetweb)
+  project_build_tools_patch_default_imported_config(
+    civetweb::civetweb civetweb::server civetweb::civetweb-cpp)
+endif()
+
+if(BUILD_TESTING)
+  project_build_tools_patch_default_imported_config(
+    GTest::gtest
+    GTest::gtest_main
+    GTest::gmock
+    GTest::gmock_main
+    GTest::GTest
+    GTest::Main
+    benchmark::benchmark
+    benchmark::benchmark_main)
+endif()
diff --git a/cmake/proto-options-patch.cmake b/cmake/proto-options-patch.cmake
index 9787205..dee9a94 100644
--- a/cmake/proto-options-patch.cmake
+++ b/cmake/proto-options-patch.cmake
@@ -117,3 +117,71 @@ function(project_build_tools_get_imported_location OUTPUT_VAR_NAME TARGET_NAME)
         PARENT_SCOPE)
   endif()
 endfunction()
+
+function(project_build_tools_patch_default_imported_config)
+  set(PATCH_VARS
+      IMPORTED_IMPLIB
+      IMPORTED_LIBNAME
+      IMPORTED_LINK_DEPENDENT_LIBRARIES
+      IMPORTED_LINK_INTERFACE_LANGUAGES
+      IMPORTED_LINK_INTERFACE_LIBRARIES
+      IMPORTED_LINK_INTERFACE_MULTIPLICITY
+      IMPORTED_LOCATION
+      IMPORTED_NO_SONAME
+      IMPORTED_OBJECTS
+      IMPORTED_SONAME)
+  foreach(TARGET_NAME ${ARGN})
+    if(TARGET ${TARGET_NAME})
+      get_target_property(IS_IMPORTED_TARGET ${TARGET_NAME} IMPORTED)
+      if(NOT IS_IMPORTED_TARGET)
+        continue()
+      endif()
+
+      if(CMAKE_VERSION VERSION_LESS "3.19.0")
+        get_target_property(TARGET_TYPE_NAME ${TARGET_NAME} TYPE)
+        if(TARGET_TYPE_NAME STREQUAL "INTERFACE_LIBRARY")
+          continue()
+        endif()
+      endif()
+
+      get_target_property(DO_NOT_OVERWRITE ${TARGET_NAME} IMPORTED_LOCATION)
+      if(DO_NOT_OVERWRITE)
+        continue()
+      endif()
+
+      # MSVC's STL and debug level must match the target, so we can only move
+      # out IMPORTED_LOCATION_NOCONFIG
+      if(MSVC)
+        set(PATCH_IMPORTED_CONFIGURATION "NOCONFIG")
+      else()
+        get_target_property(PATCH_IMPORTED_CONFIGURATION ${TARGET_NAME}
+                            IMPORTED_CONFIGURATIONS)
+      endif()
+
+      if(NOT PATCH_IMPORTED_CONFIGURATION)
+        continue()
+      endif()
+
+      get_target_property(PATCH_TARGET_LOCATION ${TARGET_NAME}
+                          "IMPORTED_LOCATION_${PATCH_IMPORTED_CONFIGURATION}")
+      if(NOT PATCH_TARGET_LOCATION)
+        continue()
+      endif()
+
+      foreach(PATCH_IMPORTED_KEY IN LISTS PATCH_VARS)
+        get_target_property(
+          PATCH_IMPORTED_VALUE ${TARGET_NAME}
+          "${PATCH_IMPORTED_KEY}_${PATCH_IMPORTED_CONFIGURATION}")
+        if(PATCH_IMPORTED_VALUE)
+          set_target_properties(
+            ${TARGET_NAME} PROPERTIES "${PATCH_IMPORTED_KEY}"
+                                      "${PATCH_IMPORTED_VALUE}")
+          message(
+            STATUS
+              "Patch: ${TARGET_NAME} ${PATCH_IMPORTED_KEY} will use ${PATCH_IMPORTED_KEY}_${PATCH_IMPORTED_CONFIGURATION}(\"${PATCH_IMPORTED_VALUE}\") by default."
+          )
+        endif()
+      endforeach()
+    endif()
+  endforeach()
+endfunction()
diff --git a/cmake/tools.cmake b/cmake/tools.cmake
new file mode 100644
index 0000000..9787205
--- /dev/null
+++ b/cmake/tools.cmake
@@ -0,0 +1,119 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+macro(check_append_cxx_compiler_flag OUTPUT_VAR)
+  foreach(CHECK_FLAG ${ARGN})
+    check_cxx_compiler_flag(${CHECK_FLAG}
+                            "check_cxx_compiler_flag_${CHECK_FLAG}")
+    if(check_cxx_compiler_flag_${CHECK_FLAG})
+      list(APPEND ${OUTPUT_VAR} ${CHECK_FLAG})
+    endif()
+  endforeach()
+endmacro()
+
+if(NOT PATCH_PROTOBUF_SOURCES_OPTIONS_SET)
+  if(MSVC)
+    unset(PATCH_PROTOBUF_SOURCES_OPTIONS CACHE)
+    set(PATCH_PROTOBUF_SOURCES_OPTIONS /wd4244 /wd4251 /wd4267 /wd4309)
+
+    if(MSVC_VERSION GREATER_EQUAL 1922)
+      # see
+      # https://docs.microsoft.com/en-us/cpp/overview/cpp-conformance-improvements?view=vs-2019#improvements_162
+      # for detail
+      list(APPEND PATCH_PROTOBUF_SOURCES_OPTIONS /wd5054)
+    endif()
+
+    if(MSVC_VERSION GREATER_EQUAL 1925)
+      list(APPEND PATCH_PROTOBUF_SOURCES_OPTIONS /wd4996)
+    endif()
+
+    if(MSVC_VERSION LESS 1910)
+      list(APPEND PATCH_PROTOBUF_SOURCES_OPTIONS /wd4800)
+    endif()
+  else()
+    unset(PATCH_PROTOBUF_SOURCES_OPTIONS CACHE)
+    include(CheckCXXCompilerFlag)
+    check_append_cxx_compiler_flag(
+      PATCH_PROTOBUF_SOURCES_OPTIONS -Wno-type-limits
+      -Wno-deprecated-declarations -Wno-unused-parameter)
+  endif()
+  set(PATCH_PROTOBUF_SOURCES_OPTIONS_SET TRUE)
+  if(PATCH_PROTOBUF_SOURCES_OPTIONS)
+    set(PATCH_PROTOBUF_SOURCES_OPTIONS
+        ${PATCH_PROTOBUF_SOURCES_OPTIONS}
+        CACHE INTERNAL
+              "Options to disable warning of generated protobuf sources" FORCE)
+  endif()
+endif()
+
+function(patch_protobuf_sources)
+  if(PATCH_PROTOBUF_SOURCES_OPTIONS)
+    foreach(PROTO_SRC ${ARGN})
+      unset(PROTO_SRC_OPTIONS)
+      get_source_file_property(PROTO_SRC_OPTIONS ${PROTO_SRC} COMPILE_OPTIONS)
+      if(PROTO_SRC_OPTIONS)
+        list(APPEND PROTO_SRC_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS})
+      else()
+        set(PROTO_SRC_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS})
+      endif()
+
+      set_source_files_properties(
+        ${PROTO_SRC} PROPERTIES COMPILE_OPTIONS "${PROTO_SRC_OPTIONS}")
+    endforeach()
+    unset(PROTO_SRC)
+    unset(PROTO_SRC_OPTIONS)
+  endif()
+endfunction()
+
+function(patch_protobuf_targets)
+  if(PATCH_PROTOBUF_SOURCES_OPTIONS)
+    foreach(PROTO_TARGET ${ARGN})
+      unset(PROTO_TARGET_OPTIONS)
+      get_target_property(PROTO_TARGET_OPTIONS ${PROTO_TARGET} COMPILE_OPTIONS)
+      if(PROTO_TARGET_OPTIONS)
+        list(APPEND PROTO_TARGET_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS})
+      else()
+        set(PROTO_TARGET_OPTIONS ${PATCH_PROTOBUF_SOURCES_OPTIONS})
+      endif()
+
+      set_target_properties(
+        ${PROTO_TARGET} PROPERTIES COMPILE_OPTIONS "${PROTO_TARGET_OPTIONS}")
+    endforeach()
+    unset(PROTO_TARGET)
+    unset(PROTO_TARGET_OPTIONS)
+  endif()
+endfunction()
+
+function(project_build_tools_get_imported_location OUTPUT_VAR_NAME TARGET_NAME)
+  if(CMAKE_BUILD_TYPE)
+    string(TOUPPER "IMPORTED_LOCATION_${CMAKE_BUILD_TYPE}"
+                   TRY_SPECIFY_IMPORTED_LOCATION)
+    get_target_property(${OUTPUT_VAR_NAME} ${TARGET_NAME}
+                        ${TRY_SPECIFY_IMPORTED_LOCATION})
+  endif()
+  if(NOT ${OUTPUT_VAR_NAME})
+    get_target_property(${OUTPUT_VAR_NAME} ${TARGET_NAME} IMPORTED_LOCATION)
+  endif()
+  if(NOT ${OUTPUT_VAR_NAME})
+    get_target_property(
+      project_build_tools_get_imported_location_IMPORTED_CONFIGURATIONS
+      ${TARGET_NAME} IMPORTED_CONFIGURATIONS)
+    foreach(
+      project_build_tools_get_imported_location_IMPORTED_CONFIGURATION IN
+      LISTS project_build_tools_get_imported_location_IMPORTED_CONFIGURATIONS)
+      get_target_property(
+        ${OUTPUT_VAR_NAME}
+        ${TARGET_NAME}
+        "IMPORTED_LOCATION_${project_build_tools_get_imported_location_IMPORTED_CONFIGURATION}"
+      )
+      if(${OUTPUT_VAR_NAME})
+        break()
+      endif()
+    endforeach()
+  endif()
+  if(${OUTPUT_VAR_NAME})
+    set(${OUTPUT_VAR_NAME}
+        ${${OUTPUT_VAR_NAME}}
+        PARENT_SCOPE)
+  endif()
+endfunction()
diff --git a/examples/grpc/CMakeLists.txt b/examples/grpc/CMakeLists.txt
index 1ea1c9b..938a009 100644
--- a/examples/grpc/CMakeLists.txt
+++ b/examples/grpc/CMakeLists.txt
@@ -23,7 +23,6 @@ add_custom_command(
 add_library(example_grpc_proto ${example_grpc_srcs} ${example_grpc_hdrs}
                                ${example_proto_srcs} ${example_proto_hdrs})
 
-include(${PROJECT_SOURCE_DIR}/cmake/proto-options-patch.cmake)
 patch_protobuf_targets(example_grpc_proto)
 
 include_directories(
@@ -33,16 +32,20 @@ include_directories(
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 if(TARGET protobuf::libprotobuf)
-  target_link_libraries(example_grpc_proto gRPC::grpc++ protobuf::libprotobuf)
+  target_link_libraries(example_grpc_proto PUBLIC gRPC::grpc++
+                                                  protobuf::libprotobuf)
 else()
-  target_include_directories(example_grpc_proto ${Protobuf_INCLUDE_DIRS})
-  target_link_libraries(example_grpc_proto ${Protobuf_LIBRARIES})
+  target_include_directories(example_grpc_proto PUBLIC ${Protobuf_INCLUDE_DIRS})
+  target_link_libraries(example_grpc_proto PUBLIC gRPC::grpc++
+                                                  ${Protobuf_LIBRARIES})
+endif()
+if(WITH_ABSEIL)
+  target_link_libraries(example_grpc_proto PUBLIC absl::bad_variant_access)
 endif()
 
 foreach(_target client server)
   add_executable(${_target} "${_target}.cc")
-  target_link_libraries(
-    ${_target} example_grpc_proto protobuf::libprotobuf gRPC::grpc++
-    opentelemetry_trace opentelemetry_exporter_ostream_span)
+  target_link_libraries(${_target} example_grpc_proto opentelemetry_trace
+                        opentelemetry_exporter_ostream_span)
   patch_protobuf_targets(${_target})
 endforeach()
diff --git a/exporters/otlp/BUILD b/exporters/otlp/BUILD
index 01dc83f..7da4a18 100644
--- a/exporters/otlp/BUILD
+++ b/exporters/otlp/BUILD
@@ -131,6 +131,7 @@ cc_library(
         "//ext/src/http/client/curl:http_client_curl",
         "//sdk:headers",
         "@com_github_opentelemetry_proto//:common_proto_cc",
+        "@com_google_absl//absl/strings",
         "@github_nlohmann_json//:json",
     ],
 )
diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt
index e05b0e2..9e4b49f 100644
--- a/exporters/otlp/CMakeLists.txt
+++ b/exporters/otlp/CMakeLists.txt
@@ -116,6 +116,10 @@ if(WITH_OTLP_HTTP)
     PUBLIC opentelemetry_sdk opentelemetry_ext
     PRIVATE opentelemetry_proto opentelemetry_http_client_curl
             nlohmann_json::nlohmann_json)
+  if(TARGET absl::strings)
+    target_link_libraries(opentelemetry_exporter_otlp_http_client
+                          PUBLIC absl::strings)
+  endif()
   if(nlohmann_json_clone)
     add_dependencies(opentelemetry_exporter_otlp_http_client
                      nlohmann_json::nlohmann_json)
diff --git a/exporters/otlp/src/otlp_http_client.cc b/exporters/otlp/src/otlp_http_client.cc
index 44c154f..62515b8 100644
--- a/exporters/otlp/src/otlp_http_client.cc
+++ b/exporters/otlp/src/otlp_http_client.cc
@@ -17,13 +17,15 @@
 #include "google/protobuf/message.h"
 #include "google/protobuf/reflection.h"
 #include "google/protobuf/stubs/common.h"
-#include "google/protobuf/stubs/stringpiece.h"
 #include "nlohmann/json.hpp"
 
-#if defined(GOOGLE_PROTOBUF_VERSION) && GOOGLE_PROTOBUF_VERSION >= 3007000
+#if defined(HAVE_ABSEIL)
+#  include "absl/strings/escaping.h"
+#elif defined(GOOGLE_PROTOBUF_VERSION) && GOOGLE_PROTOBUF_VERSION >= 3007000
 #  include "google/protobuf/stubs/strutil.h"
 #else
 #  include "google/protobuf/stubs/port.h"
+#  include "google/protobuf/stubs/stringpiece.h"
 namespace google
 {
 namespace protobuf
@@ -414,14 +416,22 @@ static std::string BytesMapping(const std::string &bytes,
       else
       {
         std::string base64_value;
+#if defined(HAVE_ABSEIL)
+        absl::Base64Escape(bytes, &base64_value);
+#else
         google::protobuf::Base64Escape(bytes, &base64_value);
+#endif
         return base64_value;
       }
     }
     case JsonBytesMappingKind::kBase64: {
       // Base64 is the default bytes mapping of protobuf
       std::string base64_value;
+#if defined(HAVE_ABSEIL)
+      absl::Base64Escape(bytes, &base64_value);
+#else
       google::protobuf::Base64Escape(bytes, &base64_value);
+#endif
       return base64_value;
     }
     case JsonBytesMappingKind::kHex:
