diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 41e9a330dd..7083396235 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -1137,12 +1137,18 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { } )cc"); - p->Emit({{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}}, - R"cc( - // Force running AddDescriptors() at dynamic initialization time. - PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 - static ::_pbi::AddDescriptorsRunner $dummy$(&$desc_table$); - )cc"); + // For descriptor.proto we want to avoid doing any dynamic initialization, + // because in some situations that would otherwise pull in a lot of + // unnecessary code that can't be stripped by --gc-sections. Descriptor + // initialization will still be performed lazily when it's needed. + if (file_->name() != "net/proto2/proto/descriptor.proto") { + p->Emit({{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}}, + R"cc( + // Force running AddDescriptors() at dynamic initialization time. + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 + static ::_pbi::AddDescriptorsRunner $dummy$(&$desc_table$); + )cc"); + } // However, we must provide a way to force initialize the default instances // of FileDescriptorProto which will be used during registration of other diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index b7e79c331e..6716eda0c6 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -1963,7 +1963,13 @@ DescriptorPool* DescriptorPool::internal_generated_pool() { } const DescriptorPool* DescriptorPool::generated_pool() { - return internal_generated_pool(); + const DescriptorPool* pool = internal_generated_pool(); + // Ensure that descriptor.proto gets registered in the generated pool. It is a + // special case because it is included in the full runtime. We have to avoid + // registering it pre-main, because we need to ensure that the linker + // --gc-sections step can strip out the full runtime if it is unused. + DescriptorProto::descriptor(); + return pool; }