This is an automated email from the ASF dual-hosted git repository.

chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new 82a68192 build(cmake): Modernize target-scoped CMake configuration 
(#3377)
82a68192 is described below

commit 82a681929738fabc036980d0432017b20b2ae06b
Author: darion-yaphet <[email protected]>
AuthorDate: Sun Jul 12 00:02:52 2026 +0800

    build(cmake): Modernize target-scoped CMake configuration (#3377)
    
    * build(cmake): keep modern CMake policy compatibility
    
    Raise the minimum CMake version range to 3.16...3.28 so CMake 4.x no longer 
treats the project as relying on removed pre-3.5 policy compatibility. The 
range preserves a conservative 3.16 runtime floor while documenting policy 
validation through 3.28.
    
    * build(cmake): modernize target-scoped CMake configuration
    
    Move shared compile definitions, include paths, options, and link 
dependencies onto interface targets so top-level, src, tools, tests, and 
standalone examples consume consistent build settings without relying on global 
directory state.
    
    Examples now share a small CMake helper, and the gtest download path is 
updated to configure with modern CMake while keeping downloaded gtest headers 
ahead of Homebrew's C++17-only installation.
---
 CMakeLists.txt                                     | 164 +++++++++++++--------
 cmake/CMakeLists.download_gtest.in                 |   2 +-
 example/asynchronous_echo_c++/CMakeLists.txt       |  52 ++-----
 example/auto_concurrency_limiter/CMakeLists.txt    |  52 ++-----
 example/backup_request_c++/CMakeLists.txt          |  52 ++-----
 .../baidu_proxy_and_generic_call/CMakeLists.txt    |  55 +++----
 example/bthread_tag_echo_c++/CMakeLists.txt        |  55 ++-----
 example/cancel_c++/CMakeLists.txt                  |  52 ++-----
 example/cascade_echo_c++/CMakeLists.txt            |  52 ++-----
 example/cmake/BrpcExample.cmake                    |  75 ++++++++++
 example/dynamic_partition_echo_c++/CMakeLists.txt  |  55 ++-----
 example/echo_c++/CMakeLists.txt                    |  52 ++-----
 example/grpc_c++/CMakeLists.txt                    |  54 ++-----
 example/http_c++/CMakeLists.txt                    |  58 +++-----
 example/memcache_c++/CMakeLists.txt                |  49 ++----
 example/multi_threaded_echo_c++/CMakeLists.txt     |  55 ++-----
 example/multi_threaded_echo_fns_c++/CMakeLists.txt |  55 ++-----
 example/nshead_extension_c++/CMakeLists.txt        |  52 ++-----
 example/nshead_pb_extension_c++/CMakeLists.txt     |  52 ++-----
 example/parallel_echo_c++/CMakeLists.txt           |  55 ++-----
 example/partition_echo_c++/CMakeLists.txt          |  55 ++-----
 example/rdma_performance/CMakeLists.txt            |  53 ++-----
 example/redis_c++/CMakeLists.txt                   |  57 +++----
 example/rpcz_echo_c++/CMakeLists.txt               |  52 ++-----
 example/selective_echo_c++/CMakeLists.txt          |  55 ++-----
 .../session_data_and_thread_local/CMakeLists.txt   |  54 ++-----
 example/streaming_batch_echo_c++/CMakeLists.txt    |  56 +++----
 example/streaming_echo_c++/CMakeLists.txt          |  52 ++-----
 src/CMakeLists.txt                                 |  27 ++--
 test/CMakeLists.txt                                |  82 ++++++-----
 tools/parallel_http/CMakeLists.txt                 |   2 +-
 tools/rpc_press/CMakeLists.txt                     |   4 +-
 tools/rpc_replay/CMakeLists.txt                    |   4 +-
 tools/rpc_view/CMakeLists.txt                      |   4 +-
 tools/trackme_server/CMakeLists.txt                |   2 +-
 35 files changed, 636 insertions(+), 1071 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f30859dd..130860ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.12)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(brpc C CXX)
 
 option(WITH_GLOG "With glog" OFF)
@@ -51,7 +51,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
         message(FATAL_ERROR "GCC is too old, please install a newer version 
supporting C++11")
     endif()
-elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
     # require at least clang 3.3
     if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.3)
         message(FATAL_ERROR "Clang is too old, please install a newer version 
supporting C++11")
@@ -60,6 +60,15 @@ else()
     message(WARNING "You are using an unsupported compiler! Compilation has 
only been tested with Clang and GCC.")
 endif()
 
+set(BRPC_COMMON_COMPILE_OPTIONS)
+set(BRPC_COMMON_DEFINITIONS)
+set(BRPC_COMMON_INCLUDE_DIRS
+    ${PROJECT_SOURCE_DIR}/src
+    ${CMAKE_CURRENT_BINARY_DIR}
+)
+set(BRPC_COMMON_LINK_OPTIONS)
+set(BRPC_CXX_STANDARD 11)
+
 set(WITH_GLOG_VAL "0")
 if(WITH_GLOG)
     set(WITH_GLOG_VAL "1")
@@ -67,7 +76,7 @@ if(WITH_GLOG)
 endif()
 
 if(WITH_DEBUG_SYMBOLS)
-    set(DEBUG_SYMBOL "-g")
+    list(APPEND BRPC_COMMON_COMPILE_OPTIONS -g)
 endif()
 
 set(WITH_DEBUG_LOCK_VAL "0")
@@ -76,7 +85,7 @@ if(WITH_DEBUG_LOCK)
 endif()
 
 if(WITH_THRIFT)
-    set(THRIFT_CPP_FLAG "-DENABLE_THRIFT_FRAMED_PROTOCOL")
+    list(APPEND BRPC_COMMON_DEFINITIONS ENABLE_THRIFT_FRAMED_PROTOCOL)
     find_library(THRIFT_LIB NAMES thrift)
     if (NOT THRIFT_LIB)
         message(FATAL_ERROR "Fail to find Thrift")
@@ -95,8 +104,8 @@ if (WITH_BTHREAD_TRACER)
     endif()
     find_package(absl REQUIRED CONFIG)
     set(bthread_tracer_ABSL_USED_TARGETS absl::base absl::stacktrace 
absl::symbolize)
-    add_definitions(-DBRPC_BTHREAD_TRACER)
-    include_directories(${LIBUNWIND_INCLUDE_PATH})
+    list(APPEND BRPC_COMMON_DEFINITIONS BRPC_BTHREAD_TRACER)
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_PATH})
 endif ()
 
 set(WITH_RDMA_VAL "0")
@@ -117,80 +126,94 @@ list(APPEND CMAKE_MODULE_PATH 
"${PROJECT_SOURCE_DIR}/cmake")
 
 find_package(GFLAGS REQUIRED)
 
-include_directories(
-    ${PROJECT_SOURCE_DIR}/src
-    ${CMAKE_CURRENT_BINARY_DIR}
-)
-
 execute_process(
     COMMAND bash -c "${PROJECT_SOURCE_DIR}/tools/get_brpc_revision.sh 
${PROJECT_SOURCE_DIR} | tr -d '\n'"
     OUTPUT_VARIABLE BRPC_REVISION
 )
+string(REPLACE "\\|" "|" BRPC_REVISION "${BRPC_REVISION}")
 
 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
     include(CheckFunctionExists)
     CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
     if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
+        list(APPEND BRPC_COMMON_DEFINITIONS NO_CLOCK_GETTIME_IN_MAC)
     endif()
-    set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wno-deprecated-declarations 
-Wno-inconsistent-missing-override")
+    list(APPEND BRPC_COMMON_COMPILE_OPTIONS
+        -Wno-deprecated-declarations
+        -Wno-inconsistent-missing-override
+    )
 endif()
 
-set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} ${DEFINE_CLOCK_GETTIME} 
-DBRPC_WITH_GLOG=${WITH_GLOG_VAL} -DBRPC_WITH_RDMA=${WITH_RDMA_VAL} 
-DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=${WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL} 
-DBRPC_DEBUG_LOCK=${WITH_DEBUG_LOCK_VAL}")
-if (WITH_ASAN)
-    set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -fsanitize=address")
-    set(CMAKE_C_FLAGS "${CMAKE_CPP_FLAGS} -fsanitize=address")
+list(APPEND BRPC_COMMON_DEFINITIONS
+    BRPC_WITH_GLOG=${WITH_GLOG_VAL}
+    BRPC_WITH_RDMA=${WITH_RDMA_VAL}
+    BRPC_DEBUG_BTHREAD_SCHE_SAFETY=${WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL}
+    BRPC_DEBUG_LOCK=${WITH_DEBUG_LOCK_VAL}
+    BTHREAD_USE_FAST_PTHREAD_MUTEX
+    __const__=__unused__
+    _GNU_SOURCE
+    USE_SYMBOLIZE
+    NO_TCMALLOC
+    __STDC_FORMAT_MACROS
+    __STDC_LIMIT_MACROS
+    __STDC_CONSTANT_MACROS
+    __STRICT_ANSI__
+)
+if(NOT DEBUG)
+    list(APPEND BRPC_COMMON_DEFINITIONS NDEBUG)
 endif()
-if(WITH_MESALINK)
-    set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -DUSE_MESALINK")
+if(WITH_ASAN)
+    list(APPEND BRPC_COMMON_COMPILE_OPTIONS -fsanitize=address)
+    list(APPEND BRPC_COMMON_LINK_OPTIONS -fsanitize=address)
 endif()
-set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -DBTHREAD_USE_FAST_PTHREAD_MUTEX 
-D__const__=__unused__ -D_GNU_SOURCE -DUSE_SYMBOLIZE -DNO_TCMALLOC 
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS 
-DBRPC_REVISION=\\\"${BRPC_REVISION}\\\" -D__STRICT_ANSI__")
-set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} ${DEBUG_SYMBOL} ${THRIFT_CPP_FLAG}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CPP_FLAGS} ${CMAKE_CXX_FLAGS} -O2 -pipe -Wall -W 
-fPIC -fstrict-aliasing -Wno-invalid-offsetof -Wno-unused-parameter 
-fno-omit-frame-pointer")
-set(CMAKE_C_FLAGS "${CMAKE_CPP_FLAGS} -O2 -pipe -Wall -W -fPIC 
-fstrict-aliasing -Wno-unused-parameter -fno-omit-frame-pointer")
-
-macro(use_cxx11)
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
-endmacro(use_cxx11)
+if(WITH_MESALINK)
+    list(APPEND BRPC_COMMON_DEFINITIONS USE_MESALINK)
+endif()
+
+list(APPEND BRPC_COMMON_COMPILE_OPTIONS
+    -O2
+    -pipe
+    -Wall
+    -W
+    -fPIC
+    -fstrict-aliasing
+    -Wno-unused-parameter
+    -fno-omit-frame-pointer
+    "-DBRPC_REVISION=\"${BRPC_REVISION}\""
+    $<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>
+)
 
 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     #required by butil/crc32.cc to boost performance for 10x
     if((CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") AND NOT 
(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4))
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -msse4.2")
+        list(APPEND BRPC_COMMON_COMPILE_OPTIONS
+            $<$<COMPILE_LANGUAGE:CXX>:-msse4>
+            $<$<COMPILE_LANGUAGE:CXX>:-msse4.2>
+        )
     elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64"))
         # segmentation fault in libcontext
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-gcse")
+        list(APPEND BRPC_COMMON_COMPILE_OPTIONS 
$<$<COMPILE_LANGUAGE:CXX>:-fno-gcse>)
     elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64"))
         # RISC-V specific optimizations
         option(WITH_RISCV_ZBC "Enable RISC-V Zbc carry-less multiplication for 
CRC32C acceleration" OFF)
         option(WITH_RISCV_ZVBC "Enable RISC-V Zvbc vector carry-less 
multiplication for CRC32C acceleration" OFF)
         if(WITH_RISCV_ZVBC)
-            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gcv_zbc_zvbc")
+            list(APPEND BRPC_COMMON_COMPILE_OPTIONS 
$<$<COMPILE_LANGUAGE:CXX>:-march=rv64gcv_zbc_zvbc>)
         elseif(WITH_RISCV_ZBC)
-            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gc_zbc")
+            list(APPEND BRPC_COMMON_COMPILE_OPTIONS 
$<$<COMPILE_LANGUAGE:CXX>:-march=rv64gc_zbc>)
         else()
-            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gc")
+            list(APPEND BRPC_COMMON_COMPILE_OPTIONS 
$<$<COMPILE_LANGUAGE:CXX>:-march=rv64gc>)
         endif()
     endif()
     if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new")
+        list(APPEND BRPC_COMMON_COMPILE_OPTIONS 
$<$<COMPILE_LANGUAGE:CXX>:-Wno-aligned-new>)
     endif()
 endif()
 
 find_package(Protobuf REQUIRED)
-if(Protobuf_VERSION GREATER 4.21)
+if(Protobuf_VERSION VERSION_GREATER 4.21)
     # required by absl
-    set(CMAKE_CXX_STANDARD 17)
+    set(BRPC_CXX_STANDARD 17)
 
     find_package(absl REQUIRED CONFIG)
     set(protobuf_ABSL_USED_TARGETS
@@ -231,8 +254,6 @@ if(Protobuf_VERSION GREATER 4.21)
         absl::utility
         absl::variant
     )
-else()
-    use_cxx11()
 endif()
 find_package(Threads REQUIRED)
 
@@ -248,7 +269,7 @@ if(WITH_SNAPPY)
     if ((NOT SNAPPY_INCLUDE_PATH) OR (NOT SNAPPY_LIB))
         message(FATAL_ERROR "Fail to find snappy")
     endif()
-    include_directories(${SNAPPY_INCLUDE_PATH})
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${SNAPPY_INCLUDE_PATH})
 endif()
 
 if(WITH_GLOG)
@@ -257,7 +278,7 @@ if(WITH_GLOG)
     if((NOT GLOG_INCLUDE_PATH) OR (NOT GLOG_LIB))
         message(FATAL_ERROR "Fail to find glog")
     endif()
-    include_directories(${GLOG_INCLUDE_PATH})
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${GLOG_INCLUDE_PATH})
 endif()
 
 if(WITH_MESALINK)
@@ -268,7 +289,7 @@ if(WITH_MESALINK)
     else()
         message(STATUS "Found MesaLink: ${MESALINK_LIB}")
     endif()
-    include_directories(${MESALINK_INCLUDE_PATH})
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${MESALINK_INCLUDE_PATH})
 endif()
 
 if(WITH_RDMA)
@@ -278,6 +299,7 @@ if(WITH_RDMA)
     if((NOT RDMA_INCLUDE_PATH) OR (NOT RDMA_LIB))
         message(FATAL_ERROR "Fail to find ibverbs")
     endif()
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${RDMA_INCLUDE_PATH})
 endif()
 
 find_library(PROTOC_LIB NAMES protoc)
@@ -287,7 +309,7 @@ endif()
 
 if(WITH_BORINGSSL)
     find_package(BoringSSL)
-    include_directories(${BORINGSSL_INCLUDE_DIR})
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${BORINGSSL_INCLUDE_DIR})
 else()
     if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
         set(OPENSSL_ROOT_DIR
@@ -295,15 +317,15 @@ else()
         )
     endif()
 
-    find_package(OpenSSL)
-    include_directories(${OPENSSL_INCLUDE_DIR})
+    find_package(OpenSSL REQUIRED)
+    list(APPEND BRPC_COMMON_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
 endif()
 
-include_directories(
-        ${GFLAGS_INCLUDE_PATH}
-        ${PROTOBUF_INCLUDE_DIRS}
-        ${LEVELDB_INCLUDE_PATH}
-        )
+list(APPEND BRPC_COMMON_INCLUDE_DIRS
+    ${GFLAGS_INCLUDE_PATH}
+    ${PROTOBUF_INCLUDE_DIRS}
+    ${LEVELDB_INCLUDE_PATH}
+)
 
 set(DYNAMIC_LIB
     ${GFLAGS_LIBRARY}
@@ -370,6 +392,17 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
     )
 endif()
 
+list(REMOVE_DUPLICATES BRPC_COMMON_INCLUDE_DIRS)
+
+add_library(brpc_common_config INTERFACE)
+target_include_directories(brpc_common_config INTERFACE 
${BRPC_COMMON_INCLUDE_DIRS})
+target_compile_definitions(brpc_common_config INTERFACE 
${BRPC_COMMON_DEFINITIONS})
+target_compile_options(brpc_common_config INTERFACE 
${BRPC_COMMON_COMPILE_OPTIONS})
+target_compile_features(brpc_common_config INTERFACE 
cxx_std_${BRPC_CXX_STANDARD})
+if(BRPC_COMMON_LINK_OPTIONS)
+    target_link_options(brpc_common_config INTERFACE 
${BRPC_COMMON_LINK_OPTIONS})
+endif()
+
 # for *.so
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/output/lib)
 # for *.a
@@ -512,12 +545,12 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
         ${PROJECT_SOURCE_DIR}/src/butil/mac/scoped_mach_port.cc)
 endif()
 
-file(GLOB_RECURSE BVAR_SOURCES "${PROJECT_SOURCE_DIR}/src/bvar/*.cpp")
-file(GLOB_RECURSE BTHREAD_SOURCES "${PROJECT_SOURCE_DIR}/src/bthread/*.cpp")
-file(GLOB_RECURSE JSON2PB_SOURCES "${PROJECT_SOURCE_DIR}/src/json2pb/*.cpp")
-file(GLOB_RECURSE BRPC_SOURCES "${PROJECT_SOURCE_DIR}/src/brpc/*.cpp")
-file(GLOB_RECURSE THRIFT_SOURCES "${PROJECT_SOURCE_DIR}/src/brpc/thrift*.cpp")
-file(GLOB_RECURSE EXCLUDE_SOURCES 
"${PROJECT_SOURCE_DIR}/src/brpc/event_dispatcher_*.cpp")
+file(GLOB_RECURSE BVAR_SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/src/bvar/*.cpp")
+file(GLOB_RECURSE BTHREAD_SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/src/bthread/*.cpp")
+file(GLOB_RECURSE JSON2PB_SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/src/json2pb/*.cpp")
+file(GLOB_RECURSE BRPC_SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/src/brpc/*.cpp")
+file(GLOB_RECURSE THRIFT_SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/src/brpc/thrift*.cpp")
+file(GLOB_RECURSE EXCLUDE_SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/src/brpc/event_dispatcher_*.cpp")
 
 if(WITH_THRIFT)
     message("brpc compile with thrift protocol")
@@ -567,6 +600,7 @@ compile_proto(PROTO_HDRS PROTO_SRCS ${PROJECT_BINARY_DIR}
                                     ${PROJECT_SOURCE_DIR}/src
                                     "${PROTO_FILES}")
 add_library(PROTO_LIB OBJECT ${PROTO_SRCS} ${PROTO_HDRS})
+target_link_libraries(PROTO_LIB PRIVATE brpc_common_config)
 
 set(SOURCES
     ${BVAR_SOURCES}
@@ -617,4 +651,4 @@ install(DIRECTORY 
${CMAKE_CURRENT_BINARY_DIR}/output/include/
 
 # Install pkgconfig
 configure_file(cmake/brpc.pc.in ${PROJECT_BINARY_DIR}/brpc.pc @ONLY)
-install(FILES ${PROJECT_BINARY_DIR}/brpc.pc DESTINATION 
${CMAKE_INSTALL_LIBDIR}/pkgconfig)
\ No newline at end of file
+install(FILES ${PROJECT_BINARY_DIR}/brpc.pc DESTINATION 
${CMAKE_INSTALL_LIBDIR}/pkgconfig)
diff --git a/cmake/CMakeLists.download_gtest.in 
b/cmake/CMakeLists.download_gtest.in
index 78d99baf..03ad5c8b 100644
--- a/cmake/CMakeLists.download_gtest.in
+++ b/cmake/CMakeLists.download_gtest.in
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 2.8.12)
+cmake_minimum_required(VERSION 3.16...3.28)
 
 project(googletest-download NONE)
 
diff --git a/example/asynchronous_echo_c++/CMakeLists.txt 
b/example/asynchronous_echo_c++/CMakeLists.txt
index 37cb5f38..e2d8f1e9 100644
--- a/example/asynchronous_echo_c++/CMakeLists.txt
+++ b/example/asynchronous_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(asynchronous_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(asynchronous_echo_client client.cpp ${PROTO_SRC})
+brpc_example_configure_target(asynchronous_echo_client)
 add_executable(asynchronous_echo_server server.cpp ${PROTO_SRC})
+brpc_example_configure_target(asynchronous_echo_server)
 
-target_link_libraries(asynchronous_echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(asynchronous_echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(asynchronous_echo_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
+target_link_libraries(asynchronous_echo_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
diff --git a/example/auto_concurrency_limiter/CMakeLists.txt 
b/example/auto_concurrency_limiter/CMakeLists.txt
index a496dd57..45636126 100644
--- a/example/auto_concurrency_limiter/CMakeLists.txt
+++ b/example/auto_concurrency_limiter/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(asynchronous_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER cl_test.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -42,55 +44,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -120,7 +96,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(asynchronous_echo_client client.cpp ${PROTO_SRC})
+brpc_example_configure_target(asynchronous_echo_client)
 add_executable(asynchronous_echo_server server.cpp ${PROTO_SRC})
+brpc_example_configure_target(asynchronous_echo_server)
 
-target_link_libraries(asynchronous_echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(asynchronous_echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(asynchronous_echo_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
+target_link_libraries(asynchronous_echo_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
diff --git a/example/backup_request_c++/CMakeLists.txt 
b/example/backup_request_c++/CMakeLists.txt
index 3c8d34a0..5de9b583 100644
--- a/example/backup_request_c++/CMakeLists.txt
+++ b/example/backup_request_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(backup_request_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(backup_request_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(backup_request_client)
 add_executable(backup_request_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(backup_request_server)
 
-target_link_libraries(backup_request_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(backup_request_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(backup_request_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(backup_request_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/baidu_proxy_and_generic_call/CMakeLists.txt 
b/example/baidu_proxy_and_generic_call/CMakeLists.txt
index 7e34d0a8..bd3da92e 100644
--- a/example/baidu_proxy_and_generic_call/CMakeLists.txt
+++ b/example/baidu_proxy_and_generic_call/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(baidu_proxy_and_generic_call C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -42,55 +44,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -118,9 +94,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_client)
 add_executable(proxy proxy.cpp)
+brpc_example_configure_target(proxy)
 add_executable(echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_server)
 
-target_link_libraries(echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(proxy ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(proxy PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/bthread_tag_echo_c++/CMakeLists.txt 
b/example/bthread_tag_echo_c++/CMakeLists.txt
index d91aa6ca..7543a6a6 100644
--- a/example/bthread_tag_echo_c++/CMakeLists.txt
+++ b/example/bthread_tag_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(bthread_tag_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,7 +107,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_client)
 add_executable(echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_server)
 
-target_link_libraries(echo_client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(echo_server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
diff --git a/example/cancel_c++/CMakeLists.txt 
b/example/cancel_c++/CMakeLists.txt
index b8d64dda..3dc198f0 100644
--- a/example/cancel_c++/CMakeLists.txt
+++ b/example/cancel_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(cancel_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(cancel_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(cancel_client)
 add_executable(cancel_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(cancel_server)
 
-target_link_libraries(cancel_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(cancel_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(cancel_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(cancel_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/cascade_echo_c++/CMakeLists.txt 
b/example/cascade_echo_c++/CMakeLists.txt
index 453067b1..4e9a0d60 100644
--- a/example/cascade_echo_c++/CMakeLists.txt
+++ b/example/cascade_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(cascade_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,12 +27,12 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
-include(FindThreads)
-include(FindProtobuf)
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -48,55 +50,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -125,7 +101,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(cascade_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(cascade_echo_client)
 add_executable(cascade_echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(cascade_echo_server)
 
-target_link_libraries(cascade_echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(cascade_echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(cascade_echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(cascade_echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/cmake/BrpcExample.cmake b/example/cmake/BrpcExample.cmake
new file mode 100644
index 00000000..a0af0ed5
--- /dev/null
+++ b/example/cmake/BrpcExample.cmake
@@ -0,0 +1,75 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+include_guard(GLOBAL)
+
+function(brpc_example_append_existing_dirs out_var)
+    set(_dirs)
+    foreach(_dir IN LISTS ARGN)
+        if(_dir AND NOT _dir MATCHES "-NOTFOUND$")
+            list(APPEND _dirs ${_dir})
+        endif()
+    endforeach()
+    set(${out_var} ${_dirs} PARENT_SCOPE)
+endfunction()
+
+function(brpc_example_configure_target target_name)
+    brpc_example_append_existing_dirs(_include_dirs
+        ${CMAKE_CURRENT_BINARY_DIR}
+        ${BRPC_INCLUDE_PATH}
+        ${GFLAGS_INCLUDE_PATH}
+        ${LEVELDB_INCLUDE_PATH}
+        ${OPENSSL_INCLUDE_DIR}
+        ${GPERFTOOLS_INCLUDE_DIR}
+        ${RDMA_INCLUDE_PATH}
+    )
+
+    if(_include_dirs)
+        target_include_directories(${target_name} PRIVATE ${_include_dirs})
+    endif()
+
+    target_compile_features(${target_name} PRIVATE cxx_std_11)
+    target_compile_definitions(${target_name} PRIVATE
+        NDEBUG
+        __const__=__unused__
+    )
+    target_compile_options(${target_name} PRIVATE
+        -O2
+        -pipe
+        -W
+        -Wall
+        -Wno-unused-parameter
+        -fPIC
+        -fno-omit-frame-pointer
+    )
+
+    if(BRPC_EXAMPLE_ENABLE_CPU_PROFILER)
+        target_compile_definitions(${target_name} PRIVATE 
BRPC_ENABLE_CPU_PROFILER)
+    endif()
+
+    if(BRPC_EXAMPLE_WITH_RDMA)
+        target_compile_definitions(${target_name} PRIVATE BRPC_WITH_RDMA=1)
+    endif()
+
+    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+        include(CheckFunctionExists)
+        check_function_exists(clock_gettime BRPC_EXAMPLE_HAVE_CLOCK_GETTIME)
+        if(NOT BRPC_EXAMPLE_HAVE_CLOCK_GETTIME)
+            target_compile_definitions(${target_name} PRIVATE 
NO_CLOCK_GETTIME_IN_MAC)
+        endif()
+    endif()
+endfunction()
diff --git a/example/dynamic_partition_echo_c++/CMakeLists.txt 
b/example/dynamic_partition_echo_c++/CMakeLists.txt
index cf79c8cb..df370a83 100644
--- a/example/dynamic_partition_echo_c++/CMakeLists.txt
+++ b/example/dynamic_partition_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(dynamic_partition_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,17 +27,16 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,10 +107,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(dynamic_partition_echo_client client.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(dynamic_partition_echo_client)
 add_executable(dynamic_partition_echo_server server.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(dynamic_partition_echo_server)
 
-target_link_libraries(dynamic_partition_echo_client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(dynamic_partition_echo_server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(dynamic_partition_echo_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
+target_link_libraries(dynamic_partition_echo_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
 
 file(COPY ${PROJECT_SOURCE_DIR}/server_list
      DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/example/echo_c++/CMakeLists.txt b/example/echo_c++/CMakeLists.txt
index 02d24779..5250959b 100644
--- a/example/echo_c++/CMakeLists.txt
+++ b/example/echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_client)
 add_executable(echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_server)
 
-target_link_libraries(echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/grpc_c++/CMakeLists.txt b/example/grpc_c++/CMakeLists.txt
index 3d947688..9d3340db 100644
--- a/example/grpc_c++/CMakeLists.txt
+++ b/example/grpc_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(grpc_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,17 +27,16 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER helloworld.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -46,56 +47,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -125,7 +101,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(server server.cpp ${PROTO_SRC} ${PROTO_HEADER} )
+brpc_example_configure_target(server)
 add_executable(client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(client)
 
-target_link_libraries(server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
diff --git a/example/http_c++/CMakeLists.txt b/example/http_c++/CMakeLists.txt
index 66c4deec..ee20fe6e 100644
--- a/example/http_c++/CMakeLists.txt
+++ b/example/http_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(http_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER http.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,12 +107,15 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(http_client http_client.cpp)
+brpc_example_configure_target(http_client)
 add_executable(http_server http_server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(http_server)
 add_executable(benchmark_http benchmark_http.cpp)
+brpc_example_configure_target(benchmark_http)
 
-target_link_libraries(http_server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(http_client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(benchmark_http ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(http_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(http_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(benchmark_http PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
 
 file(COPY ${PROJECT_SOURCE_DIR}/key.pem
      DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/example/memcache_c++/CMakeLists.txt 
b/example/memcache_c++/CMakeLists.txt
index e3e70f96..658e6028 100644
--- a/example/memcache_c++/CMakeLists.txt
+++ b/example/memcache_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(memcache_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,5 +102,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(memcache_client client.cpp)
+brpc_example_configure_target(memcache_client)
 
-target_link_libraries(memcache_client ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(memcache_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/multi_threaded_echo_c++/CMakeLists.txt 
b/example/multi_threaded_echo_c++/CMakeLists.txt
index d57886b6..1c17fa9c 100644
--- a/example/multi_threaded_echo_c++/CMakeLists.txt
+++ b/example/multi_threaded_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(multi_threaded_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,10 +107,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_client)
 add_executable(echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(echo_server)
 
-target_link_libraries(echo_client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(echo_server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
 
 file(COPY ${PROJECT_SOURCE_DIR}/key.pem
      DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/example/multi_threaded_echo_fns_c++/CMakeLists.txt 
b/example/multi_threaded_echo_fns_c++/CMakeLists.txt
index 0805485d..e184148f 100644
--- a/example/multi_threaded_echo_fns_c++/CMakeLists.txt
+++ b/example/multi_threaded_echo_fns_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(multi_threaded_echo_fns_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,7 +107,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(multi_threaded_echo_fns_client client.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(multi_threaded_echo_fns_client)
 add_executable(multi_threaded_echo_fns_server server.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(multi_threaded_echo_fns_server)
 
-target_link_libraries(multi_threaded_echo_fns_client ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
-target_link_libraries(multi_threaded_echo_fns_server ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
+target_link_libraries(multi_threaded_echo_fns_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
+target_link_libraries(multi_threaded_echo_fns_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
diff --git a/example/nshead_extension_c++/CMakeLists.txt 
b/example/nshead_extension_c++/CMakeLists.txt
index 244bca68..780e909e 100644
--- a/example/nshead_extension_c++/CMakeLists.txt
+++ b/example/nshead_extension_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(nshead_extension_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(nshead_extension_client client.cpp)
+brpc_example_configure_target(nshead_extension_client)
 add_executable(nshead_extension_server server.cpp)
+brpc_example_configure_target(nshead_extension_server)
 
-target_link_libraries(nshead_extension_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(nshead_extension_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(nshead_extension_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
+target_link_libraries(nshead_extension_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
diff --git a/example/nshead_pb_extension_c++/CMakeLists.txt 
b/example/nshead_pb_extension_c++/CMakeLists.txt
index b6302949..203dfa7e 100644
--- a/example/nshead_pb_extension_c++/CMakeLists.txt
+++ b/example/nshead_pb_extension_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(nshead_pb_extension_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(nshead_pb_extension_client client.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(nshead_pb_extension_client)
 add_executable(nshead_pb_extension_server server.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(nshead_pb_extension_server)
 
-target_link_libraries(nshead_pb_extension_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(nshead_pb_extension_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(nshead_pb_extension_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
+target_link_libraries(nshead_pb_extension_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
diff --git a/example/parallel_echo_c++/CMakeLists.txt 
b/example/parallel_echo_c++/CMakeLists.txt
index 7cdb412a..9fe5e661 100644
--- a/example/parallel_echo_c++/CMakeLists.txt
+++ b/example/parallel_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(parallel_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,7 +107,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(parallel_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(parallel_echo_client)
 add_executable(parallel_echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(parallel_echo_server)
 
-target_link_libraries(parallel_echo_client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(parallel_echo_server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(parallel_echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(parallel_echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
diff --git a/example/partition_echo_c++/CMakeLists.txt 
b/example/partition_echo_c++/CMakeLists.txt
index 4d845c72..0501f5c8 100644
--- a/example/partition_echo_c++/CMakeLists.txt
+++ b/example/partition_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(partition_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,10 +107,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(client)
 add_executable(server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(server)
 
-target_link_libraries(client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
 
 file(COPY ${PROJECT_SOURCE_DIR}/server_list
      DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/example/rdma_performance/CMakeLists.txt 
b/example/rdma_performance/CMakeLists.txt
index 2812b0b0..02b20a5d 100644
--- a/example/rdma_performance/CMakeLists.txt
+++ b/example/rdma_performance/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(rdma_performance C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER test.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,53 +51,28 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CPP_FLAGS "${DEFINE_CLOCK_GETTIME} -DBRPC_WITH_RDMA=1")
-set(CMAKE_CXX_FLAGS "${CMAKE_CPP_FLAGS} -DNDEBUG -O2 -D__const__=__unused__ 
-pipe -W -Wall -Wno-unused-parameter -fPIC -fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_WITH_RDMA ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 find_path(RDMA_INCLUDE_PATH NAMES infiniband/verbs.h)
 find_library(RDMA_LIB NAMES ibverbs)
@@ -104,7 +81,7 @@ if ((NOT RDMA_INCLUDE_PATH) OR (NOT RDMA_LIB))
 endif()
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -133,7 +110,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(client)
 add_executable(server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(server)
 
-target_link_libraries(client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/redis_c++/CMakeLists.txt b/example/redis_c++/CMakeLists.txt
index af3bd591..93a9cce7 100644
--- a/example/redis_c++/CMakeLists.txt
+++ b/example/redis_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(redis_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 # Install dependencies:
 # With apt:
 # sudo apt-get install libreadline-dev 
@@ -33,14 +35,15 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -58,55 +61,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -136,13 +113,17 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(redis_cli redis_cli.cpp)
+brpc_example_configure_target(redis_cli)
 add_executable(redis_press redis_press.cpp)
+brpc_example_configure_target(redis_press)
 add_executable(redis_server redis_server.cpp)
+brpc_example_configure_target(redis_server)
 add_executable(redis_cluster_client redis_cluster_client.cpp)
+brpc_example_configure_target(redis_cluster_client)
 
 set(AUX_LIB readline ncurses)
 
-target_link_libraries(redis_cli ${BRPC_LIB} ${DYNAMIC_LIB} ${AUX_LIB})
-target_link_libraries(redis_press ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(redis_server ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(redis_cluster_client ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(redis_cli PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} ${AUX_LIB})
+target_link_libraries(redis_press PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(redis_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(redis_cluster_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/example/rpcz_echo_c++/CMakeLists.txt 
b/example/rpcz_echo_c++/CMakeLists.txt
index d1f1d924..9ca90dc8 100644
--- a/example/rpcz_echo_c++/CMakeLists.txt
+++ b/example/rpcz_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(rpcz_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,8 +102,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(rpcz_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(rpcz_echo_client)
 add_executable(rpcz_echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(rpcz_echo_server)
 
-target_link_libraries(rpcz_echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(rpcz_echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(rpcz_echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(rpcz_echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
 
diff --git a/example/selective_echo_c++/CMakeLists.txt 
b/example/selective_echo_c++/CMakeLists.txt
index 809bd22a..22990028 100644
--- a/example/selective_echo_c++/CMakeLists.txt
+++ b/example/selective_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(selective_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,57 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
-
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -132,7 +107,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(selective_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(selective_echo_client)
 add_executable(selective_echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(selective_echo_server)
 
-target_link_libraries(selective_echo_client ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
-target_link_libraries(selective_echo_server ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(selective_echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
+target_link_libraries(selective_echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB} 
${GPERFTOOLS_LIBRARIES})
diff --git a/example/session_data_and_thread_local/CMakeLists.txt 
b/example/session_data_and_thread_local/CMakeLists.txt
index 27f60e58..de2302ae 100644
--- a/example/session_data_and_thread_local/CMakeLists.txt
+++ b/example/session_data_and_thread_local/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(session_data_and_thread_local C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -42,7 +44,6 @@ endif()
 
 find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
 find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
 
 find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
 if(LINK_SO)
@@ -53,58 +54,31 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
 
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBRPC_ENABLE_CPU_PROFILER")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
+set(BRPC_EXAMPLE_ENABLE_CPU_PROFILER ON)
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
-
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
 
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -133,7 +107,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(session_data_and_thread_local_client client.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(session_data_and_thread_local_client)
 add_executable(session_data_and_thread_local_server server.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(session_data_and_thread_local_server)
 
-target_link_libraries(session_data_and_thread_local_client ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
-target_link_libraries(session_data_and_thread_local_server ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
+target_link_libraries(session_data_and_thread_local_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
+target_link_libraries(session_data_and_thread_local_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB} ${GPERFTOOLS_LIBRARIES})
diff --git a/example/streaming_batch_echo_c++/CMakeLists.txt 
b/example/streaming_batch_echo_c++/CMakeLists.txt
index c4340672..f0093356 100644
--- a/example/streaming_batch_echo_c++/CMakeLists.txt
+++ b/example/streaming_batch_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(streaming_batch_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
         OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
-            "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
-    )
+        "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
+        )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-        ${CMAKE_THREAD_LIBS_INIT}
+        Threads::Threads
         ${GFLAGS_LIBRARY}
         ${PROTOBUF_LIBRARIES}
         ${LEVELDB_LIB}
@@ -123,7 +99,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(streaming_batch_echo_client client.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(streaming_batch_echo_client)
 add_executable(streaming_batch_echo_server server.cpp ${PROTO_SRC} 
${PROTO_HEADER})
+brpc_example_configure_target(streaming_batch_echo_server)
 
-target_link_libraries(streaming_batch_echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(streaming_batch_echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(streaming_batch_echo_client PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
+target_link_libraries(streaming_batch_echo_server PRIVATE ${BRPC_LIB} 
${DYNAMIC_LIB})
diff --git a/example/streaming_echo_c++/CMakeLists.txt 
b/example/streaming_echo_c++/CMakeLists.txt
index 571991e0..47f9373f 100644
--- a/example/streaming_echo_c++/CMakeLists.txt
+++ b/example/streaming_echo_c++/CMakeLists.txt
@@ -15,9 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.16...3.28)
 project(streaming_echo_c++ C CXX)
 
+include(${CMAKE_CURRENT_LIST_DIR}/../cmake/BrpcExample.cmake)
+
 option(LINK_SO "Whether examples are linked dynamically" OFF)
 
 execute_process(
@@ -25,13 +27,13 @@ execute_process(
     OUTPUT_VARIABLE OUTPUT_PATH
 )
 
-set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+if(OUTPUT_PATH)
+    list(PREPEND CMAKE_PREFIX_PATH ${OUTPUT_PATH})
+endif()
 
-include(FindThreads)
-include(FindProtobuf)
+find_package(Threads REQUIRED)
+find_package(Protobuf REQUIRED)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
-# include PROTO_HEADER
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Search for libthrift* by best effort. If it is not found and brpc is
 # compiled with thrift protocol enabled, a link error would be reported.
@@ -49,55 +51,29 @@ endif()
 if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
     message(FATAL_ERROR "Fail to find brpc")
 endif()
-include_directories(${BRPC_INCLUDE_PATH})
 
 find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h)
 find_library(GFLAGS_LIBRARY NAMES gflags libgflags)
 if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY))
     message(FATAL_ERROR "Fail to find gflags")
 endif()
-include_directories(${GFLAGS_INCLUDE_PATH})
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    include(CheckFunctionExists)
-    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
-    if(NOT HAVE_CLOCK_GETTIME)
-        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
-    endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${DEFINE_CLOCK_GETTIME} -DNDEBUG -O2 
-D__const__=__unused__ -pipe -W -Wall -Wno-unused-parameter -fPIC 
-fno-omit-frame-pointer")
-
-if(CMAKE_VERSION VERSION_LESS "3.1.3")
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-    endif()
-else()
-    set(CMAKE_CXX_STANDARD 11)
-    set(CMAKE_CXX_STANDARD_REQUIRED ON)
-endif()
 
 find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
 find_library(LEVELDB_LIB NAMES leveldb)
 if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
     message(FATAL_ERROR "Fail to find leveldb")
 endif()
-include_directories(${LEVELDB_INCLUDE_PATH})
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
     set(OPENSSL_ROOT_DIR
         "/usr/local/opt/openssl"    # Homebrew installed OpenSSL
         )
 endif()
 
-find_package(OpenSSL)
-include_directories(${OPENSSL_INCLUDE_DIR})
+find_package(OpenSSL REQUIRED)
 
 set(DYNAMIC_LIB
-    ${CMAKE_THREAD_LIBS_INIT}
+    Threads::Threads
     ${GFLAGS_LIBRARY}
     ${PROTOBUF_LIBRARIES}
     ${LEVELDB_LIB}
@@ -126,7 +102,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 endif()
 
 add_executable(streaming_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(streaming_echo_client)
 add_executable(streaming_echo_server server.cpp ${PROTO_SRC} ${PROTO_HEADER})
+brpc_example_configure_target(streaming_echo_server)
 
-target_link_libraries(streaming_echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
-target_link_libraries(streaming_echo_server ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(streaming_echo_client PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
+target_link_libraries(streaming_echo_server PRIVATE ${BRPC_LIB} ${DYNAMIC_LIB})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1b4b2332..a9a4d11f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,17 +15,11 @@
 # specific language governing permissions and limitations
 # under the License.
 
-if(NOT DEBUG)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNDEBUG")
-endif()
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-include_directories(${PROJECT_SOURCE_DIR}/src)
-
 add_library(BUTIL_LIB OBJECT ${BUTIL_SOURCES})
 add_library(SOURCES_LIB OBJECT ${SOURCES})
 add_dependencies(SOURCES_LIB PROTO_LIB)
+target_link_libraries(BUTIL_LIB PRIVATE brpc_common_config)
+target_link_libraries(SOURCES_LIB PRIVATE brpc_common_config)
 
 # shared library needs POSITION_INDEPENDENT_CODE
 set_property(TARGET ${SOURCES_LIB} PROPERTY POSITION_INDEPENDENT_CODE 1)
@@ -34,6 +28,7 @@ set_property(TARGET ${BUTIL_LIB} PROPERTY 
POSITION_INDEPENDENT_CODE 1)
 add_library(brpc-static STATIC $<TARGET_OBJECTS:BUTIL_LIB>
                                $<TARGET_OBJECTS:SOURCES_LIB>
                                $<TARGET_OBJECTS:PROTO_LIB>)
+target_link_libraries(brpc-static PUBLIC brpc_common_config)
 
 function(check_thrift_version target_arg)
     #use thrift command to get version
@@ -52,7 +47,7 @@ function(check_thrift_version target_arg)
 
     if (THRIFT_MAJOR_VERSION EQUAL 0 AND THRIFT_MINOR_VERSION LESS 11)
         message(STATUS "Thrift version is less than 0.11.0")
-        target_compile_definitions($(target_arg) PRIVATE 
_THRIFT_VERSION_LOWER_THAN_0_11_0_)
+        target_compile_definitions(${target_arg} PRIVATE 
_THRIFT_VERSION_LOWER_THAN_0_11_0_)
     else()
         message(STATUS "Thrift version is equal to or greater than 0.11.0")
     endif()
@@ -60,7 +55,7 @@ endfunction()
 
 
 if(WITH_THRIFT)
-   target_link_libraries(brpc-static ${THRIFT_LIB})
+   target_link_libraries(brpc-static PRIVATE ${THRIFT_LIB})
    check_thrift_version(brpc-static)
 endif()
 
@@ -74,22 +69,24 @@ set(protoc_gen_mcpack_SOURCES
  )
     
 add_executable(protoc-gen-mcpack ${protoc_gen_mcpack_SOURCES})
+target_link_libraries(protoc-gen-mcpack PRIVATE brpc_common_config)
 
 if(BUILD_SHARED_LIBS)
     add_library(brpc-shared SHARED $<TARGET_OBJECTS:BUTIL_LIB> 
                                    $<TARGET_OBJECTS:SOURCES_LIB>
                                    $<TARGET_OBJECTS:PROTO_LIB>)
-    target_link_libraries(brpc-shared ${DYNAMIC_LIB})
+    target_link_libraries(brpc-shared PUBLIC brpc_common_config)
+    target_link_libraries(brpc-shared PRIVATE ${DYNAMIC_LIB})
     if(WITH_GLOG)
-        target_link_libraries(brpc-shared ${GLOG_LIB})
+        target_link_libraries(brpc-shared PRIVATE ${GLOG_LIB})
     endif()
     if(WITH_THRIFT)
-        target_link_libraries(brpc-shared ${THRIFT_LIB})
+        target_link_libraries(brpc-shared PRIVATE ${THRIFT_LIB})
         check_thrift_version(brpc-shared)
     endif()
     SET_TARGET_PROPERTIES(brpc-shared PROPERTIES OUTPUT_NAME brpc 
CLEAN_DIRECT_OUTPUT 1)
 
-    target_link_libraries(protoc-gen-mcpack brpc-shared ${DYNAMIC_LIB} pthread)
+    target_link_libraries(protoc-gen-mcpack PRIVATE brpc-shared ${DYNAMIC_LIB} 
pthread)
 
     install(TARGETS brpc-shared
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -97,7 +94,7 @@ if(BUILD_SHARED_LIBS)
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             )
 else()
-    target_link_libraries(protoc-gen-mcpack brpc-static ${DYNAMIC_LIB} pthread)
+    target_link_libraries(protoc-gen-mcpack PRIVATE brpc-static ${DYNAMIC_LIB} 
pthread)
 endif()
 
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index cd149408..6aebe271 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -16,8 +16,18 @@
 # under the License.
 
 find_package(Gperftools)
-include_directories(${GPERFTOOLS_INCLUDE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_library(brpc_test_config INTERFACE)
+target_link_libraries(brpc_test_config INTERFACE brpc_common_config)
+target_include_directories(brpc_test_config INTERFACE 
${CMAKE_CURRENT_BINARY_DIR})
+target_compile_definitions(brpc_test_config INTERFACE
+    UNIT_TEST
+    BVAR_NOT_LINK_DEFAULT_VARIABLES
+)
+target_compile_options(brpc_test_config INTERFACE -fno-access-control)
+if(GPERFTOOLS_INCLUDE_DIR)
+    target_include_directories(brpc_test_config INTERFACE 
${GPERFTOOLS_INCLUDE_DIR})
+endif()
 
 include(CompileProto)
 set(TEST_PROTO_FILES addressbook1.proto
@@ -41,32 +51,27 @@ compile_proto(PROTO_HDRS PROTO_SRCS ${CMAKE_BINARY_DIR}/test
                                     ${CMAKE_SOURCE_DIR}/test
                                     "${TEST_PROTO_FILES}")
 add_library(TEST_PROTO_LIB OBJECT ${PROTO_SRCS} ${PROTO_HDRS})
+target_link_libraries(TEST_PROTO_LIB PRIVATE brpc_test_config)
 
 set(BRPC_SYSTEM_GTEST_SOURCE_DIR "" CACHE PATH "System googletest source 
directory.")
 
 if(DOWNLOAD_GTEST)
     include(SetupGtest)
+    set(BRPC_DOWNLOADED_GTEST_INCLUDE_DIR 
${CMAKE_CURRENT_BINARY_DIR}/downloaded-googletest-include)
+    file(REMOVE_RECURSE ${BRPC_DOWNLOADED_GTEST_INCLUDE_DIR})
+    file(MAKE_DIRECTORY ${BRPC_DOWNLOADED_GTEST_INCLUDE_DIR})
+    file(COPY
+        ${PROJECT_BINARY_DIR}/googletest-src/googletest/include/
+        ${PROJECT_BINARY_DIR}/googletest-src/googlemock/include/
+        DESTINATION ${BRPC_DOWNLOADED_GTEST_INCLUDE_DIR})
+    target_include_directories(brpc_test_config BEFORE INTERFACE
+        ${BRPC_DOWNLOADED_GTEST_INCLUDE_DIR})
 elseif(BRPC_SYSTEM_GTEST_SOURCE_DIR)
     add_subdirectory("${BRPC_SYSTEM_GTEST_SOURCE_DIR}" 
"${PROJECT_BINARY_DIR}/system-googletest-build")
 else()
     message(FATAL_ERROR "Googletest is not available")
 endif()
 
-set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} ${DEFINE_CLOCK_GETTIME} 
-DBRPC_WITH_GLOG=${WITH_GLOG_VAL} -DBRPC_WITH_RDMA=${WITH_RDMA_VAL}")
-set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -DBTHREAD_USE_FAST_PTHREAD_MUTEX 
-D__const__=__unused__ -D_GNU_SOURCE -DUSE_SYMBOLIZE -DNO_TCMALLOC 
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS 
-DUNIT_TEST -DBVAR_NOT_LINK_DEFAULT_VARIABLES -D__STRICT_ANSI__")
-set(CMAKE_CXX_FLAGS "${CMAKE_CPP_FLAGS} -g -O2 -pipe -Wall -W -fPIC 
-fstrict-aliasing -Wno-invalid-offsetof -Wno-unused-parameter 
-fno-omit-frame-pointer -fno-access-control")
-use_cxx11()
-
-if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-    #required by butil/crc32.cc to boost performance for 10x
-    if((CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") AND NOT 
(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4))
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -msse4.2")
-    endif()
-    if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new")
-    endif()
-endif()
-
 file(COPY ${PROJECT_SOURCE_DIR}/test/cert1.key DESTINATION 
${CMAKE_CURRENT_BINARY_DIR})
 file(COPY ${PROJECT_SOURCE_DIR}/test/cert2.key DESTINATION 
${CMAKE_CURRENT_BINARY_DIR})
 file(COPY ${PROJECT_SOURCE_DIR}/test/cert1.crt DESTINATION 
${CMAKE_CURRENT_BINARY_DIR})
@@ -199,6 +204,8 @@ endif()
 add_library(BUTIL_DEBUG_LIB OBJECT ${BUTIL_SOURCES})
 add_library(SOURCES_DEBUG_LIB OBJECT ${SOURCES})
 add_dependencies(SOURCES_DEBUG_LIB PROTO_LIB)
+target_link_libraries(BUTIL_DEBUG_LIB PRIVATE brpc_test_config)
+target_link_libraries(SOURCES_DEBUG_LIB PRIVATE brpc_test_config)
 
 # shared library needs POSITION_INDEPENDENT_CODE
 set_property(TARGET ${BUTIL_DEBUG_LIB} PROPERTY POSITION_INDEPENDENT_CODE 1)
@@ -211,9 +218,9 @@ add_library(brpc-shared-debug SHARED 
$<TARGET_OBJECTS:BUTIL_DEBUG_LIB>
 set_target_properties(brpc-shared-debug PROPERTIES
          LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/test)
 
-target_link_libraries(brpc-shared-debug ${DYNAMIC_LIB})
+target_link_libraries(brpc-shared-debug PUBLIC brpc_test_config ${DYNAMIC_LIB})
 if(BRPC_WITH_GLOG)
-    target_link_libraries(brpc-shared-debug ${GLOG_LIB})
+    target_link_libraries(brpc-shared-debug PUBLIC ${GLOG_LIB})
 endif()
 
 # AddressSanitizer is incompatible with tcmalloc/gperftools, do not link it 
when WITH_ASAN is on
@@ -224,9 +231,10 @@ endif()
 # test_butil
 add_executable(test_butil ${TEST_BUTIL_SOURCES}
                           ${CMAKE_CURRENT_BINARY_DIR}/iobuf.pb.cc)
-target_link_libraries(test_butil brpc-shared-debug
-                                 gtest
-                                 ${GPERFTOOLS_LIBRARIES})
+target_link_libraries(test_butil PRIVATE
+    brpc-shared-debug
+    gtest
+    ${GPERFTOOLS_LIBRARIES})
 
 add_test(NAME test_butil COMMAND test_butil)
 
@@ -235,13 +243,16 @@ add_test(NAME test_butil COMMAND test_butil)
 list(REMOVE_ITEM BVAR_SOURCES 
${PROJECT_SOURCE_DIR}/src/bvar/default_variables.cpp)
 
 add_library(BVAR_DEBUG_LIB OBJECT ${BVAR_SOURCES})
+target_link_libraries(BVAR_DEBUG_LIB PRIVATE brpc_test_config)
 file(GLOB TEST_BVAR_SRCS "bvar_*_unittest.cpp")
 add_executable(test_bvar ${TEST_BVAR_SRCS}
                          $<TARGET_OBJECTS:BVAR_DEBUG_LIB>
                          $<TARGET_OBJECTS:BUTIL_DEBUG_LIB>)
-target_link_libraries(test_bvar gtest
-                                ${GPERFTOOLS_LIBRARIES}
-                                ${DYNAMIC_LIB})
+target_link_libraries(test_bvar PRIVATE
+    gtest
+    brpc_test_config
+    ${GPERFTOOLS_LIBRARIES}
+    ${DYNAMIC_LIB})
 add_test(NAME test_bvar COMMAND test_bvar)
 
 # bthread tests
@@ -249,9 +260,10 @@ file(GLOB BTHREAD_UNITTESTS "bthread*unittest.cpp")
 foreach(BTHREAD_UT ${BTHREAD_UNITTESTS})
     get_filename_component(BTHREAD_UT_WE ${BTHREAD_UT} NAME_WE)
     add_executable(${BTHREAD_UT_WE} ${BTHREAD_UT})
-    target_link_libraries(${BTHREAD_UT_WE} gtest_main
-                                           brpc-shared-debug
-                                           ${GPERFTOOLS_LIBRARIES})
+    target_link_libraries(${BTHREAD_UT_WE} PRIVATE
+        gtest_main
+        brpc-shared-debug
+        ${GPERFTOOLS_LIBRARIES})
     add_test(NAME ${BTHREAD_UT_WE} COMMAND ${BTHREAD_UT_WE})
 endforeach()
 
@@ -260,9 +272,11 @@ file(GLOB BRPC_UNITTESTS "brpc_*_unittest.cpp")
 foreach(BRPC_UT ${BRPC_UNITTESTS})
     get_filename_component(BRPC_UT_WE ${BRPC_UT} NAME_WE)
     add_executable(${BRPC_UT_WE} ${BRPC_UT} $<TARGET_OBJECTS:TEST_PROTO_LIB>)
-    target_link_libraries(${BRPC_UT_WE} brpc-shared-debug
-                                        gtest_main
-                                        ${GPERFTOOLS_LIBRARIES})
+    target_link_libraries(${BRPC_UT_WE} PRIVATE
+        brpc-shared-debug
+        gtest_main
+        brpc_test_config
+        ${GPERFTOOLS_LIBRARIES})
     add_test(NAME ${BRPC_UT_WE} COMMAND ${BRPC_UT_WE})
 endforeach()
 
@@ -274,9 +288,9 @@ if(BUILD_FUZZ_TESTS)
     set_target_properties(brpc-static-debug PROPERTIES
             LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/test)
 
-    target_link_libraries(brpc-static-debug ${DYNAMIC_LIB})
+    target_link_libraries(brpc-static-debug PUBLIC brpc_test_config 
${DYNAMIC_LIB})
     if(BRPC_WITH_GLOG)
-        target_link_libraries(brpc-static-debug ${GLOG_LIB})
+        target_link_libraries(brpc-static-debug PUBLIC ${GLOG_LIB})
     endif()
 
     set(FUZZ_TARGETS fuzz_butil fuzz_esp fuzz_hpack fuzz_http
@@ -287,7 +301,7 @@ if(BUILD_FUZZ_TESTS)
 
     foreach(target ${FUZZ_TARGETS})
         add_executable(${target} fuzzing/${target}.cpp 
$<TARGET_OBJECTS:TEST_PROTO_LIB>)
-        target_link_libraries(${target} brpc-static-debug 
${LIB_FUZZING_ENGINE})
+        target_link_libraries(${target} PRIVATE brpc-static-debug 
${LIB_FUZZING_ENGINE})
         set_target_properties(${target} PROPERTIES
             BUILD_WITH_INSTALL_RPATH TRUE
             INSTALL_RPATH "$ORIGIN/lib")
diff --git a/tools/parallel_http/CMakeLists.txt 
b/tools/parallel_http/CMakeLists.txt
index 7099f3e4..69676444 100644
--- a/tools/parallel_http/CMakeLists.txt
+++ b/tools/parallel_http/CMakeLists.txt
@@ -16,5 +16,5 @@
 # under the License.
 
 add_executable(parallel_http parallel_http.cpp)
-target_link_libraries(parallel_http brpc-static ${DYNAMIC_LIB})
+target_link_libraries(parallel_http PRIVATE brpc-static ${DYNAMIC_LIB})
 install(TARGETS parallel_http RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/tools/rpc_press/CMakeLists.txt b/tools/rpc_press/CMakeLists.txt
index bdcba5d5..762d3466 100644
--- a/tools/rpc_press/CMakeLists.txt
+++ b/tools/rpc_press/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/tools/rpc_press/*.cpp")
+file(GLOB SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/tools/rpc_press/*.cpp")
 add_executable(rpc_press ${SOURCES})
-target_link_libraries(rpc_press brpc-static ${DYNAMIC_LIB})
+target_link_libraries(rpc_press PRIVATE brpc-static ${DYNAMIC_LIB})
 install(TARGETS rpc_press RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/tools/rpc_replay/CMakeLists.txt b/tools/rpc_replay/CMakeLists.txt
index 8278da28..f1a55abd 100644
--- a/tools/rpc_replay/CMakeLists.txt
+++ b/tools/rpc_replay/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/tools/rpc_replay/*.cpp")
+file(GLOB SOURCES CONFIGURE_DEPENDS 
"${PROJECT_SOURCE_DIR}/tools/rpc_replay/*.cpp")
 add_executable(rpc_replay ${SOURCES})
-target_link_libraries(rpc_replay brpc-static ${DYNAMIC_LIB})
+target_link_libraries(rpc_replay PRIVATE brpc-static ${DYNAMIC_LIB})
 install(TARGETS rpc_replay RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/tools/rpc_view/CMakeLists.txt b/tools/rpc_view/CMakeLists.txt
index 55a3bc5e..1fe67014 100644
--- a/tools/rpc_view/CMakeLists.txt
+++ b/tools/rpc_view/CMakeLists.txt
@@ -17,8 +17,8 @@
 
 include(FindProtobuf)
 protobuf_generate_cpp(PROTO_SRC PROTO_HEADER view.proto)
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 add_executable(rpc_view rpc_view.cpp ${PROTO_SRC})
-target_link_libraries(rpc_view brpc-static ${DYNAMIC_LIB})
+target_include_directories(rpc_view PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(rpc_view PRIVATE brpc-static ${DYNAMIC_LIB})
 install(TARGETS rpc_view RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/tools/trackme_server/CMakeLists.txt 
b/tools/trackme_server/CMakeLists.txt
index 35d797e9..ca40e419 100644
--- a/tools/trackme_server/CMakeLists.txt
+++ b/tools/trackme_server/CMakeLists.txt
@@ -16,5 +16,5 @@
 # under the License.
 
 add_executable(trackme_server trackme_server.cpp)
-target_link_libraries(trackme_server brpc-static ${DYNAMIC_LIB})
+target_link_libraries(trackme_server PRIVATE brpc-static ${DYNAMIC_LIB})
 install(TARGETS trackme_server RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to