https://bugs.gentoo.org/912775 https://github.com/protobuf-c/protobuf-c/issues/679 https://github.com/protobuf-c/protobuf-c/issues/544 https://github.com/protobuf-c/protobuf-c/pull/673 From ad48868dfe77592c4bacf936ade208f384a26b09 Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Sun, 2 Jul 2023 17:48:18 -0400 Subject: [PATCH 1/7] protoc-c: Remove GOOGLE_DISALLOW_EVIL_CONSTRUCTORS macro invocations protobuf has removed the definition of this macro as of commit 1595417dd3859bbff7d3d61ad0b6e39044d47489, so the invocation of this macro in protobuf-c breaks the build when building agaist the protobuf 22.x or 23.x series. Simply removing the macro invocations seems to be safe and doesn't break the build on Debian's protobuf 3.21.12 nor Debian's protobuf 3.6.1.3. --- protoc-c/c_bytes_field.h | 2 -- protoc-c/c_enum.h | 2 -- protoc-c/c_enum_field.h | 2 -- protoc-c/c_extension.h | 2 -- protoc-c/c_field.h | 5 ----- protoc-c/c_file.h | 2 -- protoc-c/c_generator.h | 3 --- protoc-c/c_message.h | 2 -- protoc-c/c_message_field.h | 4 ---- protoc-c/c_primitive_field.h | 4 ---- protoc-c/c_service.h | 2 -- protoc-c/c_string_field.h | 2 -- 12 files changed, 32 deletions(-) diff --git a/protoc-c/c_bytes_field.h b/protoc-c/c_bytes_field.h index bf873f0f..df91ef73 100644 --- a/protoc-c/c_bytes_field.h +++ b/protoc-c/c_bytes_field.h @@ -87,8 +87,6 @@ class BytesFieldGenerator : public FieldGenerator { private: std::map variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BytesFieldGenerator); }; diff --git a/protoc-c/c_enum.h b/protoc-c/c_enum.h index 9c34b697..089c3366 100644 --- a/protoc-c/c_enum.h +++ b/protoc-c/c_enum.h @@ -106,8 +106,6 @@ class EnumGenerator { private: const EnumDescriptor* descriptor_; std::string dllexport_decl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); }; } // namespace c diff --git a/protoc-c/c_enum_field.h b/protoc-c/c_enum_field.h index 3f8c005d..e0c96adf 100644 --- a/protoc-c/c_enum_field.h +++ b/protoc-c/c_enum_field.h @@ -85,8 +85,6 @@ class EnumFieldGenerator : public FieldGenerator { private: std::map variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); }; diff --git a/protoc-c/c_extension.h b/protoc-c/c_extension.h index 95413885..bda0bc55 100644 --- a/protoc-c/c_extension.h +++ b/protoc-c/c_extension.h @@ -98,8 +98,6 @@ class ExtensionGenerator { const FieldDescriptor* descriptor_; std::string type_traits_; std::string dllexport_decl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); }; } // namespace c diff --git a/protoc-c/c_field.h b/protoc-c/c_field.h index 3cad35d3..623a872e 100644 --- a/protoc-c/c_field.h +++ b/protoc-c/c_field.h @@ -103,9 +103,6 @@ class FieldGenerator { const std::string &type_macro, const std::string &descriptor_addr) const; const FieldDescriptor *descriptor_; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); }; // Convenience class which constructs FieldGenerators for a Descriptor. @@ -121,8 +118,6 @@ class FieldGeneratorMap { std::unique_ptr[]> field_generators_; static FieldGenerator* MakeGenerator(const FieldDescriptor* field); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; } // namespace c diff --git a/protoc-c/c_file.h b/protoc-c/c_file.h index 8dfd8ba0..db1866cd 100644 --- a/protoc-c/c_file.h +++ b/protoc-c/c_file.h @@ -103,8 +103,6 @@ class FileGenerator { std::unique_ptr[]> enum_generators_; std::unique_ptr[]> service_generators_; std::unique_ptr[]> extension_generators_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); }; } // namespace c diff --git a/protoc-c/c_generator.h b/protoc-c/c_generator.h index ac1ffafe..b8b44aaa 100644 --- a/protoc-c/c_generator.h +++ b/protoc-c/c_generator.h @@ -93,9 +93,6 @@ class PROTOC_C_EXPORT CGenerator : public CodeGenerator { const std::string& parameter, OutputDirectory* output_directory, std::string* error) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CGenerator); }; } // namespace c diff --git a/protoc-c/c_message.h b/protoc-c/c_message.h index ea1c3ab3..0d8c6440 100644 --- a/protoc-c/c_message.h +++ b/protoc-c/c_message.h @@ -136,8 +136,6 @@ class MessageGenerator { std::unique_ptr[]> nested_generators_; std::unique_ptr[]> enum_generators_; std::unique_ptr[]> extension_generators_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); }; } // namespace c diff --git a/protoc-c/c_message_field.h b/protoc-c/c_message_field.h index 39b8d999..e485921a 100644 --- a/protoc-c/c_message_field.h +++ b/protoc-c/c_message_field.h @@ -82,10 +82,6 @@ class MessageFieldGenerator : public FieldGenerator { void GenerateDescriptorInitializer(io::Printer* printer) const; std::string GetDefaultValue(void) const; void GenerateStaticInit(io::Printer* printer) const; - - private: - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); }; diff --git a/protoc-c/c_primitive_field.h b/protoc-c/c_primitive_field.h index a9eb893b..aa7079f9 100644 --- a/protoc-c/c_primitive_field.h +++ b/protoc-c/c_primitive_field.h @@ -82,10 +82,6 @@ class PrimitiveFieldGenerator : public FieldGenerator { void GenerateDescriptorInitializer(io::Printer* printer) const; std::string GetDefaultValue(void) const; void GenerateStaticInit(io::Printer* printer) const; - - private: - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); }; } // namespace c diff --git a/protoc-c/c_service.h b/protoc-c/c_service.h index 27125a60..b51472f9 100644 --- a/protoc-c/c_service.h +++ b/protoc-c/c_service.h @@ -100,8 +100,6 @@ class ServiceGenerator { const ServiceDescriptor* descriptor_; std::map vars_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); }; } // namespace c diff --git a/protoc-c/c_string_field.h b/protoc-c/c_string_field.h index 513cea75..b3a1a7ff 100644 --- a/protoc-c/c_string_field.h +++ b/protoc-c/c_string_field.h @@ -87,8 +87,6 @@ class StringFieldGenerator : public FieldGenerator { private: std::map variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); }; From 7b90330bff40ab555bb3f0c5ee43ae208a275104 Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Sun, 2 Jul 2023 19:35:43 -0400 Subject: [PATCH 2/7] Use GOOGLE_LOG(FATAL) instead of GOOGLE_LOG(DFATAL) Looking at where these identifiers are ultimately defined [0], it looks like "DFATAL" means either "ERROR" or "FATAL" depending on whether NDEBUG is defined. However, looking at the actual code sites in protoc-c where DFATAL is used, it's not clear why we couldn't just use FATAL unconditionally. This is aimed at supporting newer versions of protobuf where the DFATAL identifier apparently no longer exists. [0] https://github.com/protocolbuffers/protobuf/blob/v21.12/src/google/protobuf/stubs/logging.h#L61-L65 --- protoc-c/c_message.cc | 4 ++-- protoc-c/c_primitive_field.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protoc-c/c_message.cc b/protoc-c/c_message.cc index 37e8bf8b..af2974ca 100755 --- a/protoc-c/c_message.cc +++ b/protoc-c/c_message.cc @@ -499,7 +499,7 @@ GenerateMessageDescriptor(io::Printer* printer, bool gen_init) { // NOTE: not supported by protobuf vars["maybe_static"] = ""; vars["field_dv_ctype"] = "{ ... }"; - GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; + GOOGLE_LOG(FATAL) << "Messages can't have default values!"; break; case FieldDescriptor::CPPTYPE_STRING: if (fd->type() == FieldDescriptor::TYPE_BYTES || opt.string_as_bytes()) @@ -521,7 +521,7 @@ GenerateMessageDescriptor(io::Printer* printer, bool gen_init) { break; } default: - GOOGLE_LOG(DFATAL) << "Unknown CPPTYPE"; + GOOGLE_LOG(FATAL) << "Unknown CPPTYPE"; break; } if (!already_defined) diff --git a/protoc-c/c_primitive_field.cc b/protoc-c/c_primitive_field.cc index 6990893f..1727af38 100644 --- a/protoc-c/c_primitive_field.cc +++ b/protoc-c/c_primitive_field.cc @@ -143,7 +143,7 @@ std::string PrimitiveFieldGenerator::GetDefaultValue() const case FieldDescriptor::CPPTYPE_BOOL: return descriptor_->default_value_bool() ? "1" : "0"; default: - GOOGLE_LOG(DFATAL) << "unexpected CPPTYPE in c_primitive_field"; + GOOGLE_LOG(FATAL) << "unexpected CPPTYPE in c_primitive_field"; return "UNEXPECTED_CPPTYPE"; } } From 8d334a7204d98874cbf970cb96ab0c7b52e06695 Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Sun, 2 Jul 2023 19:42:19 -0400 Subject: [PATCH 3/7] Work around GOOGLE_* changes in protobuf >= 22.0 According to the protobuf migration guide as of June 2023 [0], protobuf 22.0 (aka 4.22.0) took a dependency on something called "abseil" and as a result the "stubs" have been removed. This apparently caused all the uses of GOOGLE_* identifiers in protoc-c to fail when building against newer versions of protobuf. This commit introduces compatibility definitions when building against protobuf >= 4.22.0 so that protobuf-c can build against older and newer versions of protobuf. [0] https://web.archive.org/web/20230611151200/https://protobuf.dev/support/migration/#abseil --- protoc-c/c_helpers.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/protoc-c/c_helpers.h b/protoc-c/c_helpers.h index 7598a4e1..adc7ee21 100644 --- a/protoc-c/c_helpers.h +++ b/protoc-c/c_helpers.h @@ -178,6 +178,16 @@ inline int FieldSyntax(const FieldDescriptor* field) { #endif } +// Work around changes in protobuf >= 22.x without breaking compilation against +// older protobuf versions. +#if GOOGLE_PROTOBUF_VERSION >= 4022000 +# define GOOGLE_ARRAYSIZE ABSL_ARRAYSIZE +# define GOOGLE_CHECK_EQ ABSL_CHECK_EQ +# define GOOGLE_CHECK_EQ ABSL_CHECK_EQ +# define GOOGLE_DCHECK_GE ABSL_DCHECK_GE +# define GOOGLE_LOG ABSL_LOG +#endif + } // namespace c } // namespace compiler } // namespace protobuf From 23d2246e0f6ebfc69232ab29b6c6325d8009d1f7 Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Sun, 2 Jul 2023 19:48:17 -0400 Subject: [PATCH 4/7] configure.ac: Require C++17 when building against protobuf >= 4.22.0 It's unclear from looking at the online protobuf documentation whether C++14 or C++17 is now required when building against newer versions of protobuf (or perhaps I'm looking in the wrong place), but experimentally it did not work for me with C++14. This commit rewrites the versioned PKG_CHECK_MODULES checks in configure.ac to enforce the following policies: * Require protobuf >= 2.6.0. * On protobuf >= 3.0.0, require C++11. * On protobuf >= 4.22.0, require C++17. --- configure.ac | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 94d01dca..fa024b6a 100644 --- a/configure.ac +++ b/configure.ac @@ -76,12 +76,26 @@ AC_ARG_ENABLE([protoc], if test "x$enable_protoc" != "xno"; then AC_LANG_PUSH([C++]) - AX_CXX_COMPILE_STDCXX(11, noext, mandatory) - - PKG_CHECK_MODULES([protobuf], [protobuf >= 3.0.0], - [proto3_supported=yes], - [PKG_CHECK_MODULES([protobuf], [protobuf >= 2.6.0])] - ) + # PKG_CHECK_MODULES(prefix, list-of-modules, action-if-found, action-if-not-found) + PKG_CHECK_MODULES( + [protobuf], + [protobuf >= 4.22.0], + [ + proto3_supported=yes + AX_CXX_COMPILE_STDCXX(17, noext, mandatory) + ], + [ + PKG_CHECK_MODULES( + [protobuf], + [protobuf >= 3.0.0], + [ + proto3_supported=yes + AX_CXX_COMPILE_STDCXX(11, noext, mandatory) + ], + [ + PKG_CHECK_MODULES([protobuf], [protobuf >= 2.6.0]) + ]) + ]) save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$save_CPPFLAGS $protobuf_CFLAGS" From 1937ba946b0a7a62c0f534e60f4d4799d7e0daed Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Sun, 2 Jul 2023 22:57:57 -0400 Subject: [PATCH 5/7] protoc-c: Use FileDescriptorLegacy to obtain proto syntax version on protobuf >= 23.0 Use the newer "legacy" way of determining whether a file descriptor is using proto2 or proto3 syntax on protobuf >= 23.0. Based on https://github.com/protobuf-c/protobuf-c/pull/556/commits/66574f3fd85a205eb7c90b790477d5415364209e but continues to support older versions of protobuf. Unfortunately, since this is a "deprecated", "legacy" API it'll probably disappear in about five seconds. --- protoc-c/c_file.cc | 4 ++++ protoc-c/c_helpers.h | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/protoc-c/c_file.cc b/protoc-c/c_file.cc index 59c1824e..d211a3da 100644 --- a/protoc-c/c_file.cc +++ b/protoc-c/c_file.cc @@ -119,7 +119,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { int min_header_version = 1000000; #if defined(HAVE_PROTO3) +# if GOOGLE_PROTOBUF_VERSION >= 4023000 + if (FileDescriptorLegacy(file_).syntax() == FileDescriptorLegacy::SYNTAX_PROTO3) { +# else if (file_->syntax() == FileDescriptor::SYNTAX_PROTO3) { +#endif min_header_version = 1003000; } #endif diff --git a/protoc-c/c_helpers.h b/protoc-c/c_helpers.h index adc7ee21..055528bf 100644 --- a/protoc-c/c_helpers.h +++ b/protoc-c/c_helpers.h @@ -70,6 +70,10 @@ #include #include +#if GOOGLE_PROTOBUF_VERSION >= 4023000 +# include +#endif + namespace google { namespace protobuf { namespace compiler { @@ -172,7 +176,11 @@ int compare_name_indices_by_name(const void*, const void*); // This wrapper is needed to be able to compile against protobuf2. inline int FieldSyntax(const FieldDescriptor* field) { #ifdef HAVE_PROTO3 +# if GOOGLE_PROTOBUF_VERSION >= 4023000 + return FileDescriptorLegacy(field->file()).syntax() == FileDescriptorLegacy::SYNTAX_PROTO3 ? 3 : 2; +# else return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? 3 : 2; +# endif #else return 2; #endif From 7582b6e7d640636bf24c0f9dd2b386ed6fd41919 Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Sun, 2 Jul 2023 22:58:48 -0400 Subject: [PATCH 6/7] cmake: Require C++17 Newer versions of protobuf apparently don't build with older versions of the C++ standard. --- build-cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-cmake/CMakeLists.txt b/build-cmake/CMakeLists.txt index 95f561c0..c71dd899 100644 --- a/build-cmake/CMakeLists.txt +++ b/build-cmake/CMakeLists.txt @@ -96,7 +96,7 @@ if (MSVC AND NOT BUILD_SHARED_LIBS) endif (MSVC AND NOT BUILD_SHARED_LIBS) IF(BUILD_PROTOC) -SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_EXTENSIONS OFF) ADD_CUSTOM_COMMAND(OUTPUT protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h From 5b0661f1e8a0e03f75cc6f53b8d42507e95403c9 Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Mon, 3 Jul 2023 01:10:28 -0400 Subject: [PATCH 7/7] configure.ac: Require C++17 There are some recent reports of strange build failures that might have been fixed by compiling in C++17 mode, so it might be a good idea to use C++17 in general, and not just when building against very recent protobuf versions. Since it looks like we've lost protobuf < 3.0.0 support, configure.ac can be simplified a bit if we just use C++17 by default. --- configure.ac | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/configure.ac b/configure.ac index fa024b6a..586ac3c0 100644 --- a/configure.ac +++ b/configure.ac @@ -75,27 +75,8 @@ AC_ARG_ENABLE([protoc], AS_HELP_STRING([--disable-protoc], [Disable building protoc_c (also disables tests)])) if test "x$enable_protoc" != "xno"; then AC_LANG_PUSH([C++]) - - # PKG_CHECK_MODULES(prefix, list-of-modules, action-if-found, action-if-not-found) - PKG_CHECK_MODULES( - [protobuf], - [protobuf >= 4.22.0], - [ - proto3_supported=yes - AX_CXX_COMPILE_STDCXX(17, noext, mandatory) - ], - [ - PKG_CHECK_MODULES( - [protobuf], - [protobuf >= 3.0.0], - [ - proto3_supported=yes - AX_CXX_COMPILE_STDCXX(11, noext, mandatory) - ], - [ - PKG_CHECK_MODULES([protobuf], [protobuf >= 2.6.0]) - ]) - ]) + AX_CXX_COMPILE_STDCXX(17, noext, mandatory) + PKG_CHECK_MODULES([protobuf], [protobuf >= 3.0.0], [proto3_supported=yes]) save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$save_CPPFLAGS $protobuf_CFLAGS"