Here is a minimal reproduction of my issue:

###############################################
# Compiler Version
##############################################
g++ --version
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

################################################
#source listing:
###############################################
./base.proto
./extension.proto
./glue.proto
./main.cpp


#############################################
# File Contentes
############################################

#############  base.proto  #################
message base
{
    extensions 100 to 105;
}

############  extension.proto  #############
message extension
{
}

############  glue.proto  ################
import "base.proto";
import "extension.proto";

extend base
{
    optional extension ext = 102;
}

########  main.cpp  ###################
#include <iostream>
#include <google/protobuf/descriptor.h>
#include "generated/base.pb.h"
//#include "generated/glue.pb.h"

int main(int, char**)
{
//    ext.number();
    base message;
    const google::protobuf::DescriptorPool* p
        = google::protobuf::DescriptorPool::generated_pool();
    std::vector<const google::protobuf::FieldDescriptor*> fields;
    p->FindAllExtensions(message.GetDescriptor(), &fields);
    for (size_t i = 0; i < fields.size(); i++)
    {
       std::cout << "Initializing extension type: "
                 << fields[i]->message_type()->name() << std::endl;;
    }
}

#########################################
# Build instructions
########################################
> mkdir generated
> protoc --cpp_out=./generated *.proto
> g++ -c generated/base.pb.cc -o generated/base.pb.cc.o
> g++ -c generated/extension.pb.cc -o generated/extension.pb.cc.o
> g++ -c generated/glue.pb.cc -o generated/glue.pb.cc.o
> ar cr protocollection.a generated/*.cc.o
> g++ main.cpp protocollection.a -o app -lprotobuf -lpthread


#########################################
# Results
########################################
> ./app
> # Nothing was printed expected to see "Initializing extension type: extension"


########################################
# Working instructions
#######################################
> g++ generated/base.pb.cc generated/extension.pb.cc generated/glue.pb.cc 
> main.cpp -o app -lprotobuf -lpthread
> ./app
Initializing extension type: extension

#######################################
# Question
#######################################
Note that this also works when linking the .o files together into a
shared object file libprotocollection.so or by just simply
uncommenting the lines in main.cpp

It appears that archiving the compiled object files of the
generated .pb.cc files before linking them into the application causes
the compiler or linker to ignore the static initialization of
unreferenced definitions, some sort of optimization.  Referencing a
symbol in glue.pb.cc (ie: uncommenting the lines in main.cpp)
causes the static initializer for glue.pb.cc to get called (see
snippet from glue.pb.cc):

    // Force AddDescriptors() to be called at static initialization
time.
    struct StaticDescriptorInitializer_glue_2eproto {
      StaticDescriptorInitializer_glue_2eproto() {
        protobuf_AddDesc_glue_2eproto();
      }
    } static_descriptor_initializer_glue_2eproto_;

We would like to provide clients with the option of linking the
generated protobuf code into their application either dynamically or
statically and still be able to use reflection and the generated pool
to discover the extension number(s) of base for messages of a generic
template type T.

Is there anything the protobuf library or protoc can do differently to
ensure that static_descriptor_initializer_glue_2eproto_ gets
initialized in this case?  Is there a g++ compiler flag that I could
use to resolve this issue?


-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To post to this group, send email to proto...@googlegroups.com.
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en.

Reply via email to