protobuf新版本(21+)安装记录

安装过protobuf不下10次,每次安装都会踩坑。而这次,踩的坑更深,原因是protobuf21+版本引用了第三方库。

一开始,我用的macos系统搭建环境,使用brew包管理器安装 protobuf:

evenoyan@MacBook-Pro ~ % brew install protobuf

安装完成后,开始编写cmakelist文件:

 1 cmake_minimum_required(VERSION 3.10.0)
 2 
 3 set(TARGET_NAME demo_server)
 4 project(${TARGET_NAME} VERSION 0.1.0 LANGUAGES C CXX)
 5 
 6 #set(CMAKE_VERBOSE_MAKEFILE ON)
 7 
 8 # C++17
 9 set(CMAKE_CXX_STANDARD 17)
10 
11 # 定义C++宏,当前工作目录
12 add_definitions(-DWORKSPACE_PATH="${CMAKE_SOURCE_DIR}")
13 
14 # 公共代码位置
15 set(PUBLIC_DIR ${CMAKE_SOURCE_DIR}/../public)
16 
17 # protobuf 文件位置
18 set(PROTO_DIR ${PUBLIC_DIR}/proto)
19 file(GLOB_RECURSE PROTO_FILES ${PROTO_DIR}/*.proto)
20 
21 # protubuf 生成文件输出位置
22 set(PROTO_PB_DIR ${PUBLIC_DIR}/proto_gen)
23 
24 file(GLOB_RECURSE PROTO_GEN_INCLUDE ${PROTO_PB_DIR}/*.h)
25 file(GLOB_RECURSE PROTO_GEN_SOURCES ${PROTO_PB_DIR}/*.cc)
26 
27 # include 头文件目录
28 include_directories(
29     ${PROTO_GEN_INCLUDE}
30     ${PUBLIC_DIR}
31     ${PUBLIC_DIR}/include
32     ${CMAKE_SOURCE_DIR}/include
33 )
34 
35 # source .cpp文件目录,要编译它们
36 file(GLOB CPP_SOURCE_FILES 
37     ${PROTO_GEN_SOURCES}
38     ${PUBLIC_DIR}/*.cpp 
39     ${PUBLIC_DIR}/source/*.cpp
40     ${CMAKE_SOURCE_DIR}/source/*.cpp
41     ${CMAKE_SOURCE_DIR}/*.cpp 
42 )
43 
44 add_executable(${TARGET_NAME} ${CPP_SOURCE_FILES})
45 
46 # 支持c++11 thread
47 target_link_libraries(${TARGET_NAME} pthread)
48 
49 # 寻找 protobuf
50 find_package(Protobuf REQUIRED)
51 include_directories(${Protobuf_INCLUDE_DIRS})
52 
53 # 链接 protobuf 库
54 target_link_libraries(${TARGET_NAME} ${Protobuf_LIBRARIES})

然后,新建 .proto 文件,并使用 protoc 命令来生成 .h .cc文件

(这里不叙述了,重点不是这里)

但工程编译时,在最后的链接阶段发生了错误:未定义符号,就是找不到类型或函数的实现:

Undefined symbols for architecture x86_64:
  "void absl::lts_20240722::log_internal::LogMessage::CopyToEncodedBuffer<(absl::lts_20240722::log_internal::LogMessage::StringType)0>(std::__1::basic_string_view<char, std::__1::char_traits<char>>)", referenced from:
      absl::lts_20240722::log_internal::LogMessage& absl::lts_20240722::log_internal::LogMessage::operator<<<19>(char const (&) [19]) in login.pb.cc.o
  "absl::lts_20240722::log_internal::LogMessage& absl::lts_20240722::log_internal::LogMessage::operator<<<unsigned long, 0>(unsigned long const&)", referenced from:
      absl::lts_20240722::log_internal::LogMessage::operator<<(unsigned long) in login.pb.cc.o
  "absl::lts_20240722::log_internal::LogMessageFatal::LogMessageFatal(char const*, int, std::__1::basic_string_view<char, std::__1::char_traits<char>>)", referenced from:
      DATA_Account::SharedDtor(google::protobuf::MessageLite&) in account_info.pb.cc.o
      DATA_Account::MergeImpl(google::protobuf::MessageLite&, google::protobuf::MessageLite const&) in account_info.pb.cc.o
      DATA_Account::InternalSwap(DATA_Account*) in account_info.pb.cc.o
      google::protobuf::internal::ClassData::full() const in account_info.pb.cc.o
      MSG_W2D_DATASAVE::SharedDtor(google::protobuf::MessageLite&) in data_save.pb.cc.o
      MSG_W2D_DATASAVE::MergeImpl(google::protobuf::MessageLite&, google::protobuf::MessageLite const&) in data_save.pb.cc.o
      MSG_W2D_DATASAVE::InternalSwap(MSG_W2D_DATASAVE*) in data_save.pb.cc.o
      ...
  "absl::lts_20240722::log_internal::LogMessageFatal::~LogMessageFatal()", referenced from:
      DATA_Account::SharedDtor(google::protobuf::MessageLite&) in account_info.pb.cc.o
......(还有好多)

查了一下,需要链接absl库,于是在cmakelist文件中增加absl库的链接:

 1 # 寻找abseil库,protobuf需要
 2 find_package(absl REQUIRED)
 3 
 4 # 链接 abseil 库
 5 #   protobuf@25+ 依赖 abseil,如果不这样写,protobuf就会找不到absl的实现代码,
 6 #   这似乎是 protobuf 的 bug
 7 #   建议使用 protobuf 21及之前的版本
 8 #   这里的坑巨大,可能导致protobuf运行时的崩溃,具体请查看:
 9 #       https://blog.gitcode.com/763172bc3b68275eea57297078deeb90.html
10 #   在安装时,推荐使用源码编译安装 protobuf 与 abseil,虽然这极其复杂
11 target_link_libraries(${TARGET_NAME} 
12     absl::absl_check
13     absl::absl_log
14     absl::algorithm
15     absl::base
16     absl::bind_front
17     absl::bits
18     absl::btree
19     absl::cleanup
20     absl::cord
21     absl::core_headers
22     absl::debugging
23     absl::die_if_null
24     absl::dynamic_annotations
25     absl::flags
26     absl::flat_hash_map
27     absl::flat_hash_set
28     absl::function_ref
29     absl::hash
30     absl::layout
31     absl::log_initialize
32     absl::log_severity
33     absl::memory
34     absl::node_hash_map
35     absl::node_hash_set
36     absl::optional
37     absl::span
38     absl::status
39     absl::statusor
40     absl::strings
41     absl::synchronization
42     absl::time
43     absl::type_traits
44     absl::utility
45     absl::variant
46 )

不要怀疑为什么要链接这么多的库,因为坑爹的absl就是这样干的:

列出名字包含absl的库:

evenoyan@MacBook-Pro ~ % pkg-config --list-package-names | grep absl
absl_strerror
absl_cord
absl_log
absl_bad_any_cast
absl_hashtable_debug
absl_random_internal_mock_helpers
absl_malloc_internal
absl_bind_front
absl_log_internal_structured
absl_absl_check
absl_fixed_array
absl_status_matchers
absl_string_view
absl_log_structured
absl_has_ostream_operator
absl_flat_hash_map
absl_scoped_mock_log
absl_random_internal_randen_hwaes_impl
absl_statusor
absl_strings
absl_random_internal_distribution_caller
absl_low_level_hash
absl_variant
absl_compare
absl_node_hash_map
absl_log_internal_conditions
absl_container_common
absl_core_headers
absl_random_random
absl_flags_program_name
absl_memory
absl_bad_any_cast_impl
absl_cordz_update_scope
absl_cordz_info
absl_flags_path_util
absl_log_internal_check_impl
absl_flags_commandlineflag_internal
absl_cleanup_internal
absl_flags_reflection
absl_log_flags
absl_crc_internal
absl_cordz_statistics
absl_fast_type_id
absl_config
absl_random_internal_pool_urbg
absl_flags_private_handle_accessor
absl_common_policy_traits
absl_vlog_config_internal
absl_utf8_for_code_point
absl_raw_hash_set
absl_bounded_utf8_length_sequence
absl_scoped_set_env
absl_log_internal_message
absl_absl_log
absl_die_if_null
absl_log_internal_flags
absl_graphcycles_internal
absl_random_seed_sequences
absl_flat_hash_set
absl_exponential_biased
absl_bits
absl_decode_rust_punycode
absl_cord_test_helpers
absl_time
absl_log_internal_log_impl
absl_base_internal
absl_throw_delegate
absl_endian
absl_charset
absl_random_internal_randen
absl_crc32c
absl_random_internal_randen_engine
absl_layout
absl_flags_usage_internal
absl_random_internal_generate_real
absl_flags_parse
absl_numeric
absl_hashtablez_sampler
absl_numeric_representation
absl_no_destructor
absl_city
absl_errno_saver
absl_crc_cord_state
absl_raw_hash_map
absl_log_internal_fnmatch
absl_if_constexpr
absl_node_slot_policy
absl_poison
absl_symbolize
absl_flags_commandlineflag
absl_atomic_hook
absl_compressed_tuple
absl_bad_variant_access
absl_log_sink
absl_periodic_sampler
absl_vlog_is_on
absl_spy_hash_state
absl_any_invocable
absl_crc_cpu_detect
absl_random_internal_salted_seed_seq
absl_log_internal_globals
absl_log_globals
absl_demangle_internal
absl_optional
absl_hash_container_defaults
absl_hash_policy_traits
absl_node_hash_set
absl_flags_usage
absl_random_internal_nonsecure_base
absl_hashtable_debug_hooks
absl_container_memory
absl_flags_internal
absl_log_initialize
absl_cord_internal
absl_str_format_internal
absl_log_internal_log_sink_set
absl_algorithm_container
absl_inlined_vector_internal
absl_raw_logging_internal
absl_cleanup
absl_random_internal_randen_slow
absl_random_distributions
absl_dynamic_annotations
absl_log_internal_check_op
absl_bad_optional_access
absl_random_bit_gen_ref
absl_overload
absl_flags
absl_log_internal_append_truncated
absl_time_zone
absl_random_seed_gen_exception
absl_type_traits
absl_hash_function_defaults
absl_random_internal_distribution_test_util
absl_meta
absl_utility
absl_non_temporal_memcpy
absl_btree
absl_civil_time
absl_examine_stack
absl_spinlock_wait
absl_random_internal_traits
absl_strings_internal
absl_cordz_functions
absl_algorithm
absl_cordz_update_tracker
absl_random_internal_fast_uniform_bits
absl_synchronization
absl_pretty_function
absl_log_internal_config
absl_log_internal_voidify
absl_base
absl_span
absl_log_internal_nullguard
absl_random_internal_fastmath
absl_hash_testing
absl_random_internal_platform
absl_log_internal_strip
absl_log_streamer
absl_kernel_timeout_internal
absl_inlined_vector
absl_demangle_rust
absl_int128
absl_failure_signal_handler
absl_random_internal_iostream_state_saver
absl_cordz_sample_token
absl_cordz_handle
absl_random_mocking_bit_gen
absl_log_entry
absl_debugging
absl_random_internal_wide_multiply
absl_random_internal_pcg_engine
absl_str_format
absl_hash
absl_log_sink_registry
absl_log_internal_nullstream
absl_prefetch
absl_flags_marshalling
absl_stacktrace
absl_log_internal_proto
absl_random_internal_seed_material
absl_leak_check
absl_status
absl_nullability
absl_any
absl_function_ref
absl_debugging_internal
absl_log_internal_format
absl_random_internal_uniform_helper
absl_check
absl_sample_recorder
absl_random_internal_randen_hwaes
absl_flags_config
absl_log_severity
absl_non_temporal_arm_intrinsics
absl_absl_vlog_is_on

ok,这次链接不失败了,但是遇到了新的问题。

现在,在一个proto文件中定义一个message,而这个message中,存在另一个类型的message成员:

 1 syntax = "proto3";
 2 
 3 message DATA_Account
 4 {
 5     optional string nick = 1;           //昵称
 6     optional int64 last_login = 2;      //最后登陆时间
 7     optional int64 total_online = 3;    //总计在线时间
 8 }
 9 
10 message DATA_PlayerInfo
11 {
12     optional int64 player_id = 1;           //玩家id
13     optional DATA_Account account_info = 2; //玩家账号相关数据
14 
15 }
1 message MSG_D2W_Login
2 {
3     optional EMessageErrorCode err = 1;     //错误码
4     optional int32 fd = 2;      //world server 需要的玩家 fd
5     optional DATA_PlayerInfo player_info = 3;   //玩家数据
6 }

于是,它就在  ParseFromString 函数中水灵灵地炸了。

1 MSG_D2W_Login from;
2 from.ParseFromString(data);

(崩溃的图没截,就是 DATA_PlayerInfo 中的 account_info 成员是一个空指针)

SerializeToString函数是成功的,反过来解析就炸了,这非常奇怪。
后来,同样在网上找到了原因(https://blog.gitcode.com/763172bc3b68275eea57297078deeb90.html):

 

这非常坑,坑得我不得不采用另一种方式来安装protobuf.

现在,我不想在macos中搭建环境了,我一直用的clang,因为它安装的gcc压根儿用不了!找不到某些头文件!除非使用xcode。(这个坑我实在是不想爬了)

 

以下是ubuntu中安装过程:

下载 protobuf 源码:

  https://codeload.github.com/protocolbuffers/protobuf/zip/refs/heads/main

下载 abseil 源码:

  https://codeload.github.com/abseil/abseil-cpp/zip/refs/heads/master

even@evenubuntu:~$ ls
abseil-cpp-master  protobuf-main  

 

首先安装abseil:

在 abseil-cpp-master 文件夹的 CMakeList.txt 中增加c++版本约定为c++17

set(CMAKE_CXX_STANDARD 17)

然后开始编译安装

even@evenubuntu:~$ cd abseil-cpp-master/
even@evenubuntu:~/abseil-cpp-master$ mkdir build
even@evenubuntu:~/abseil-cpp-master$ cd build/
even@evenubuntu:~/abseil-cpp-master/build$ cmake ..
CMake Warning at CMakeLists.txt:183 (message):
    The default and system-level install directories are unsupported except in LTS   releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your   source or build tree directly.    


-- Configuring done (0.5s)
-- Generating done (0.7s)
-- Build files have been written to: /home/even/abseil-cpp-master/build
even@evenubuntu:~/abseil-cpp-master/build$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
CMake Warning at CMakeLists.txt:183 (message):
    The default and system-level install directories are unsupported except in LTS   releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your   source or build tree directly.    


-- Configuring done (0.2s)
-- Generating done (0.3s)
-- Build files have been written to: /home/even/abseil-cpp-master/build
even@evenubuntu:~/abseil-cpp-master/build$ sudo make & make install 

 

然后安装 protobuf:

在 protobuf-main 文件夹的 CMakeList.txt 中增加c++版本约定为c++17

set(CMAKE_CXX_STANDARD 17)

然后编译安装

even@evenubuntu:~/protobuf-main/build$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
-- The C compiler identification is GNU 13.3.0
-- The CXX compiler identification is GNU 13.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- protobuf version: 32.0.0
-- Performing Test protobuf_HAVE_LD_VERSION_SCRIPT
-- Performing Test protobuf_HAVE_LD_VERSION_SCRIPT - Success
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.3")  
-- Performing Test protobuf_HAVE_BUILTIN_ATOMICS
-- Performing Test protobuf_HAVE_BUILTIN_ATOMICS - Success
-- Configuring done (1.0s)
-- Generating done (0.1s)
-- Build files have been written to: /home/even/protobuf-main/build
even@evenubuntu:
~/protobuf-main/build$ cmake --build . --config Release
even@evenubuntu:~/protobuf-main/build$ cmake --install . --config Release

安装完成后,编译测试代码,又出现链接错误:

/usr/bin/ld: /usr/local/lib/libprotobuf.a(generated_message_tctable_lite.cc.o): in function `utf8_range::IsStructurallyValid(std::basic_string_view<char, std::char_traits<char> >)':
generated_message_tctable_lite.cc:(.text._ZN10utf8_range19IsStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE[_ZN10utf8_range19IsStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE]+0x40): undefined reference to `utf8_range_IsValid'
/usr/bin/ld: /usr/local/lib/libprotobuf.a(parse_context.cc.o): in function `utf8_range::SpanStructurallyValid(std::basic_string_view<char, std::char_traits<char> >)':
parse_context.cc:(.text._ZN10utf8_range21SpanStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE[_ZN10utf8_range21SpanStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE]+0x40): undefined reference to `utf8_range_ValidPrefix'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test_repo.dir/build.make:202: test_repo] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/test_repo.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

这次又发现 utf8_range 找不到...

这又是怎么回事?直到我安装protobuf时( cmake --install . --config Release 命令),有一段输出引起了我的注意:

 1 even@evenubuntu:~/protobuf-main$ sudo cmake --install ./build --config Release
 2 [sudo] password for even: 
 3 -- Installing: /usr/local/lib/cmake/utf8_range/utf8_range-targets.cmake
 4 -- Installing: /usr/local/lib/libutf8_validity.a
 5 -- Installing: /usr/local/lib/libutf8_range.a
 6 -- Installing: /usr/local/lib/cmake/utf8_range/utf8_range-config.cmake
 7 -- Installing: /usr/local/lib/pkgconfig/utf8_range.pc
 8 -- Up-to-date: /usr/local/include/utf8_range.h
 9 -- Up-to-date: /usr/local/include/utf8_validity.h
10 -- Installing: /usr/local/lib/libprotobuf-lite.a
......

看见 utf8_range.pc 了没?

也就是说,utf8_range不是什么函数,它是一个库,protobuf32版本不仅依赖absl,还依赖 utf8_range

去pkg-config里碰碰运气看看有没有:

even@evenubuntu:/usr/bin$ pkg-config --list-all | grep utf8
absl_bounded_utf8_length_sequence absl_bounded_utf8_length_sequence - Abseil bounded_utf8_length_sequence library
absl_utf8_for_code_point       absl_utf8_for_code_point - Abseil utf8_for_code_point library
utf8_range                     UTF8 Range - Google's UTF8 Library

 有!那就在cmakelist文件中链接上:

1 find_package(utf8_range REQUIRED)
2 target_link_libraries(${TARGET_NAME} utf8_range)

 

这次终于编译成功了......

 

另外,如何得知protobuf需要absl中的哪些库?毕竟有那么多,少一个可能都编译不过。

在protobuf的源码文件夹中,有一个cmake文件夹:

even@evenubuntu:~$ cd protobuf-main/
even@evenubuntu:~/protobuf-main$ ls
appveyor.bat      CMakeLists.txt                examples                           maven_dev_install.json      Protobuf.podspec           toolchain
appveyor.yml      CODE_OF_CONDUCT.md            fix_permissions.sh                 maven_install.json          protobuf_release.bzl       upb
bazel             compatibility                 generate_descriptor_proto.sh       MODULE.bazel                protobuf_version.bzl       upb_generator
benchmarks        conformance                   global.json                        Neverlink_jruby_jars.patch  python                     version.json
build             CONTRIBUTING.md               go                                 objectivec                  README.md                  WORKSPACE
BUILD.bazel       CONTRIBUTORS.txt              google3_export_generated_files.sh  patches                     regenerate_stale_files.sh  WORKSPACE.bzlmod
build_defs        csharp                        hpb                                php                         ruby
Cargo.bazel.lock  Disable_bundle_install.patch  hpb_generator                      pkg                         rust
Cargo.lock        docs                          java                               PrivacyInfo.xcprivacy       SECURITY.md
ci                editions                      LICENSE                            protobuf.bzl                src
cmake             editors                       lua                                protobuf_deps.bzl           third_party

 

打开其中的 abseil-cpp.cmake 文件,里面有:

even@evenubuntu:~/protobuf-main$ cd cmake
even@evenubuntu:~/protobuf-main/cmake$ ls
abseil-cpp.cmake           gtest.cmake                      libprotobuf.cmake                protobuf-config-version.cmake.in  protoc.cmake          version.rc.in
BUILD.bazel                install.cmake                    libprotobuf-lite.cmake           protobuf-generate.cmake           README.md
conformance.cmake          installed_bin_golden.txt         libprotoc.cmake                  protobuf-lite.pc.cmake            tests.cmake
dependencies.cmake         installed_include_golden.txt     libupb.cmake                     protobuf-module.cmake.in          upb_generators.cmake
dependencies_generator.py  installed_lib_shared_golden.txt  protobuf-config.cmake.in         protobuf-options.cmake            upb.pc.cmake
examples.cmake             installed_lib_static_golden.txt  protobuf-configure-target.cmake  protobuf.pc.cmake                 utf8_range.cmake
even@evenubuntu:~/protobuf-main/cmake$ cat abseil-cpp.cmake 
# Setup our dependency on Abseil.

if(protobuf_BUILD_TESTS)
  # Tell Abseil to build test-only helpers.
  set(ABSL_BUILD_TEST_HELPERS ON)

  # We depend on googletest too, so just tell Abseil to use the same one we've
  # already setup.
  set(ABSL_USE_EXTERNAL_GOOGLETEST ON)
  set(ABSL_FIND_GOOGLETEST OFF)
endif()

if (NOT TARGET absl::strings)
  if (NOT protobuf_FORCE_FETCH_DEPENDENCIES)
    # Use "CONFIG" as there is no built-in cmake module for absl.
    find_package(absl CONFIG)
  endif()

  # Fallback to fetching Abseil from github if it's not found locally.
  if (NOT absl_FOUND AND NOT protobuf_LOCAL_DEPENDENCIES_ONLY)
    include(${protobuf_SOURCE_DIR}/cmake/dependencies.cmake)
    message(STATUS "Fallback to downloading Abseil ${abseil-cpp-version} from GitHub")

    include(FetchContent)
    FetchContent_Declare(
      absl
      GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git"
      GIT_TAG "${abseil-cpp-version}"
    )
    if (protobuf_INSTALL)
      # When protobuf_INSTALL is enabled and Abseil will be built as a module,
      # Abseil will be installed along with protobuf for convenience.
      set(ABSL_ENABLE_INSTALL ON)
    endif()
    FetchContent_MakeAvailable(absl)
  endif()
endif()

if (NOT TARGET absl::strings)
  message(FATAL_ERROR "Cannot find abseil-cpp dependency that's needed to build protobuf.\n")
endif()

set(_protobuf_FIND_ABSL "if(NOT TARGET absl::strings)\n  find_package(absl CONFIG)\nendif()")

if (BUILD_SHARED_LIBS AND MSVC)
  # On MSVC Abseil is bundled into a single DLL.
  # This condition is necessary as of abseil 20230125.3 when abseil is consumed
  # via add_subdirectory, the abseil_dll target is named abseil_dll, while if
  # abseil is consumed via find_package, the target is called absl::abseil_dll
  # Once https://github.com/abseil/abseil-cpp/pull/1466 is merged and released
  # in the minimum version of abseil required by protobuf, it is possible to
  # always link absl::abseil_dll and absl::abseil_test_dll and remove the if
  set(protobuf_ABSL_USED_TARGETS absl::abseil_dll)
  set(protobuf_ABSL_USED_TEST_TARGETS absl::abseil_test_dll)
else()
  set(protobuf_ABSL_USED_TARGETS
    absl::absl_check
    absl::absl_log
    absl::algorithm
    absl::base
    absl::bind_front
    absl::bits
    absl::btree
    absl::cleanup
    absl::cord
    absl::core_headers
    absl::debugging
    absl::die_if_null
    absl::dynamic_annotations
    absl::flags
    absl::flat_hash_map
    absl::flat_hash_set
    absl::function_ref
    absl::hash
    absl::layout
    absl::log_initialize
    absl::log_globals
    absl::log_severity
    absl::memory
    absl::node_hash_map
    absl::node_hash_set
    absl::optional
    absl::random_distributions
    absl::random_random
    absl::span
    absl::status
    absl::statusor
    absl::strings
    absl::synchronization
    absl::time
    absl::type_traits
    absl::utility
  )
  set(protobuf_ABSL_USED_TEST_TARGETS
    absl::scoped_mock_log
  )
endif ()

 

什么破玩意,搞得这么恶心,我都想自己造轮子了。

 

posted on 2025-05-01 23:02  __Even  阅读(842)  评论(0)    收藏  举报

导航