title: undefined reference to google protobuf
body: <p>Well, I'm having some problems trying to understand how to compile libraries that include the code generated by Google's protobuf. Here's my    CMakeLists.txt:</p>
  
  <pre><code>cmake_minimum_required(VERSION 3.4.1)
  
  set (CMAKE_CXX_STANDARD 11)
  
  include_directories(
      ${CMAKE_CURRENT_SOURCE_DIR}/sandbox
      /usr
  )
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libraries)
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/executables)
  SET(COMPILE_FLAGS "-I/usr/local/include -pthread ")
  SET(LINK_FLAGS "-L/usr/local/lib -lprotobuf -pthread -lpthread")
  SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}" )
  SET( CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${LINK_FLAGS}" )
  
  add_library(
      protoAddress
      SHARED
      ${CMAKE_CURRENT_SOURCE_DIR}/sandbox/addressbook.pb.cc
  )
  
  
  add_executable(prueba sandbox/testProto.cpp)
  target_link_libraries(prueba protoAddress)
  </code></pre>
  
  <p>addressbook.pb.cc is the source code generated when you use protoc command with --cpp_out on Google's example:</p>
  
  <pre><code>syntax = "proto2";
  
  package tutorial;
  
  message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;
  
    enum PhoneType {
      MOBILE = 0;
      HOME = 1;
      WORK = 2;
    }
  
    message PhoneNumber {
      required string number = 1;
      optional PhoneType type = 2 [default = HOME];
    }
  
    repeated PhoneNumber phones = 4;
  }
  
  message AddressBook {
    repeated Person people = 1;
  }
  </code></pre>
  
  <p>The test I'm trying to make executable is the same of the example that uses google to explain how does it work with c++:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;fstream&gt;
  #include &lt;string&gt;
  #include "addressbook.pb.h"
  using namespace std;
  
  // This function fills in a Person message based on user input.
  void PromptForAddress(tutorial::Person* person) {
    cout &lt;&lt; "Enter person ID number: ";
    int id;
    cin &gt;&gt; id;
    person-&gt;set_id(id);
    cin.ignore(256, '\n');
  
    cout &lt;&lt; "Enter name: ";
    getline(cin, *person-&gt;mutable_name());
  
    cout &lt;&lt; "Enter email address (blank for none): ";
    string email;
    getline(cin, email);
    if (!email.empty()) {
      person-&gt;set_email(email);
    }
  
    while (true) {
      cout &lt;&lt; "Enter a phone number (or leave blank to finish): ";
      string number;
      getline(cin, number);
      if (number.empty()) {
        break;
      }
  
      tutorial::Person::PhoneNumber* phone_number = person-&gt;add_phones();
      phone_number-&gt;set_number(number);
  
      cout &lt;&lt; "Is this a mobile, home, or work phone? ";
      string type;
      getline(cin, type);
      if (type == "mobile") {
        phone_number-&gt;set_type(tutorial::Person::MOBILE);
      } else if (type == "home") {
        phone_number-&gt;set_type(tutorial::Person::HOME);
      } else if (type == "work") {
        phone_number-&gt;set_type(tutorial::Person::WORK);
      } else {
        cout &lt;&lt; "Unknown phone type.  Using default." &lt;&lt; endl;
      }
    }
  }
  
  // Main function:  Reads the entire address book from a file,
  //   adds one person based on user input, then writes it back out to the same
  //   file.
  int main(int argc, char* argv[]) {
    // Verify that the version of the library that we linked against is
    // compatible with the version of the headers we compiled against.
    GOOGLE_PROTOBUF_VERIFY_VERSION;
  
    if (argc != 2) {
      cerr &lt;&lt; "Usage:  " &lt;&lt; argv[0] &lt;&lt; " ADDRESS_BOOK_FILE" &lt;&lt; endl;
      return -1;
    }
  
    tutorial::AddressBook address_book;
  
    {
      // Read the existing address book.
      fstream input(argv[1], ios::in | ios::binary);
      if (!input) {
        cout &lt;&lt; argv[1] &lt;&lt; ": File not found.  Creating a new file." &lt;&lt; endl;
      } else if (!address_book.ParseFromIstream(&amp;input)) {
        cerr &lt;&lt; "Failed to parse address book." &lt;&lt; endl;
        return -1;
      }
    }
  
    // Add an address.
    PromptForAddress(address_book.add_people());
  
    {
      // Write the new address book back to disk.
      fstream output(argv[1], ios::out | ios::trunc | ios::binary);
      if (!address_book.SerializeToOstream(&amp;output)) {
        cerr &lt;&lt; "Failed to write address book." &lt;&lt; endl;
        return -1;
      }
    }
  
    // Optional:  Delete all global objects allocated by libprotobuf.
    google::protobuf::ShutdownProtobufLibrary();
  
    return 0;
  }
  </code></pre>
  
  <p>After trying to make this CMakeLists, I get a lot of errors, mostly from undefined reference:</p>
  
  <pre><code>    -- Configuring done
  -- Generating done
  -- Build files have been written to: /home/jverdeguer/Documents/workspace/protobuf/build
  [ 25%] Building CXX object CMakeFiles/protoAddress.dir/sandbox/addressbook.pb.cc.o
  [ 50%] Linking CXX shared library ../libraries/libprotoAddress.so
  [ 50%] Built target protoAddress
  [ 75%] Building CXX object CMakeFiles/prueba.dir/sandbox/testProto.cpp.o
  [100%] Linking CXX executable ../executables/prueba
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `main':
  testProto.cpp:(.text+0x2f6): undefined reference to `google::protobuf::internal::VerifyVersion(int, int, char const*)'
  testProto.cpp:(.text+0x3f0): undefined reference to `google::protobuf::Message::ParseFromIstream(std::istream*)'
  testProto.cpp:(.text+0x4b1): undefined reference to `google::protobuf::Message::SerializeToOstream(std::ostream*) const'
  testProto.cpp:(.text+0x502): undefined reference to `google::protobuf::ShutdownProtobufLibrary()'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::Arena::AllocHook(std::type_info const*, unsigned long) const':
  testProto.cpp:(.text._ZNK6google8protobuf5Arena9AllocHookEPKSt9type_infom[_ZNK6google8protobuf5Arena9AllocHookEPKSt9type_infom]+0x3d): undefined reference to `google::protobuf::Arena::OnArenaAllocation(std::type_info const*, unsigned long)const'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::internal::ArenaStringPtr::CreateInstanceNoArena(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const*)':
  testProto.cpp:(.text._ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x4b): undefined reference to `google::protobuf::internal::LogMessage::LogMessage(google::protobuf::LogLevel, char const*, int)'
  testProto.cpp:(.text._ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x61): undefined reference to `google::protobuf::internal::LogMessage::operator&lt;&lt;(char const*)'
  testProto.cpp:(.text._ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x79): undefined reference to `google::protobuf::internal::LogFinisher::operator=(google::protobuf::internal::LogMessage&amp;)'
  testProto.cpp:(.text._ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x8d): undefined reference to `google::protobuf::internal::LogMessage::~LogMessage()'
  testProto.cpp:(.text._ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr21CreateInstanceNoArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0xdc): undefined reference to `google::protobuf::internal::LogMessage::~LogMessage()'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11]()':
  testProto.cpp:(.text._ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev[_ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev]+0x5): undefined reference to `google::protobuf::internal::fixed_address_empty_string[abi:cxx11]'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::RepeatedPtrField&lt;tutorial::Person_PhoneNumber&gt;::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add&lt;google::protobuf::RepeatedPtrField&lt;tutorial::Person_PhoneNumber&gt;::TypeHandler&gt;(google::protobuf::RepeatedPtrField&lt;tutorial::Person_PhoneNumber&gt;::TypeHandler::Type*)':
  testProto.cpp:(.text._ZN6google8protobuf8internal20RepeatedPtrFieldBase3AddINS0_16RepeatedPtrFieldIN8tutorial18Person_PhoneNumberEE11TypeHandlerEEEPNT_4TypeESB_[_ZN6google8protobuf8internal20RepeatedPtrFieldBase3AddINS0_16RepeatedPtrFieldIN8tutorial18Person_PhoneNumberEE11TypeHandlerEEEPNT_4TypeESB_]+0x95): undefined reference to `google::protobuf::internal::RepeatedPtrFieldBase::Reserve(int)'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::RepeatedPtrField&lt;tutorial::Person&gt;::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add&lt;google::protobuf::RepeatedPtrField&lt;tutorial::Person&gt;::TypeHandler&gt;(google::protobuf::RepeatedPtrField&lt;tutorial::Person&gt;::TypeHandler::Type*)':
  testProto.cpp:(.text._ZN6google8protobuf8internal20RepeatedPtrFieldBase3AddINS0_16RepeatedPtrFieldIN8tutorial6PersonEE11TypeHandlerEEEPNT_4TypeESB_[_ZN6google8protobuf8internal20RepeatedPtrFieldBase3AddINS0_16RepeatedPtrFieldIN8tutorial6PersonEE11TypeHandlerEEEPNT_4TypeESB_]+0x95): undefined reference to `google::protobuf::internal::RepeatedPtrFieldBase::Reserve(int)'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::internal::GenericTypeHandler&lt;tutorial::Person_PhoneNumber&gt;::New(google::protobuf::Arena*)':
  testProto.cpp:(.text._ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial18Person_PhoneNumberEE3NewEPNS0_5ArenaE[_ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial18Person_PhoneNumberEE3NewEPNS0_5ArenaE]+0xb6): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
  testProto.cpp:(.text._ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial18Person_PhoneNumberEE3NewEPNS0_5ArenaE[_ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial18Person_PhoneNumberEE3NewEPNS0_5ArenaE]+0xd3): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
  CMakeFiles/prueba.dir/sandbox/testProto.cpp.o: In function `google::protobuf::internal::GenericTypeHandler&lt;tutorial::Person&gt;::New(google::protobuf::Arena*)':
  testProto.cpp:(.text._ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial6PersonEE3NewEPNS0_5ArenaE[_ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial6PersonEE3NewEPNS0_5ArenaE]+0xb6): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
  testProto.cpp:(.text._ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial6PersonEE3NewEPNS0_5ArenaE[_ZN6google8protobuf8internal18GenericTypeHandlerIN8tutorial6PersonEE3NewEPNS0_5ArenaE]+0xd3): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::RegisterAllTypes(google::protobuf::Metadata const*, int)'
  ../libraries/libprotoAddress.so: undefined reference to `vtable for google::protobuf::Closure'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::io::CodedOutputStream::WriteStringWithSizeToArray(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned char*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormatLite::WriteEnum(int, int, google::protobuf::io::CodedOutputStream*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(int, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, google::protobuf::io::CodedOutputStream*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::io::CodedInputStream::ReadVarintSizeAsIntFallback()'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::InitProtobufDefaults()'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormatLite::WriteInt32(int, int, google::protobuf::io::CodedOutputStream*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::Message::CheckTypeAndMergeFrom(google::protobuf::MessageLite const&amp;)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::GoogleOnceInitImpl(long*, google::protobuf::Closure*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::io::CodedInputStream::ReadTagFallback(unsigned int)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormatLite::ReadBytes(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::Message::GetTypeName[abi:cxx11]() const'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::Message::InitializationErrorString[abi:cxx11]() const'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormat::SerializeUnknownFields(google::protobuf::UnknownFieldSet const&amp;, google::protobuf::io::CodedOutputStream*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::Message::DiscardUnknownFields()'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::UnknownFieldSet::AddVarint(int, unsigned long)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::MessageLite::SerializeWithCachedSizesToArray(unsigned char*) const'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(int, google::protobuf::MessageLite const&amp;, google::protobuf::io::CodedOutputStream*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::OnShutdownDestroyMessage(void const*)'
  ../libraries/libprotoAddress.so: undefined reference to `vtable for google::protobuf::internal::FunctionClosure0'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::DescriptorPool::InternalAddGeneratedFile(void const*, int)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::ReflectionOps::Merge(google::protobuf::Message const&amp;, google::protobuf::Message*)'
  ../libraries/libprotoAddress.so: undefined reference to `vtable for google::protobuf::MessageLite'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::FunctionClosure0::~FunctionClosure0()'
  ../libraries/libprotoAddress.so: undefined reference to `typeinfo for google::protobuf::Message'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::UnknownFieldSet::default_instance()'
  ../libraries/libprotoAddress.so: undefined reference to `vtable for google::protobuf::Message'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::UnknownFieldSet::MergeFrom(google::protobuf::UnknownFieldSet const&amp;)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::UnknownFieldSet::ClearFallback()'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::io::CodedInputStream::IncrementRecursionDepthAndPushLimit(int)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(google::protobuf::UnknownFieldSet const&amp;, unsigned char*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(google::protobuf::UnknownFieldSet const&amp;)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::Message::SpaceUsedLong() const'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::io::CodedInputStream::ReadVarint32Fallback(unsigned int)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::RepeatedPtrFieldBase::InternalExtend(int)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::WireFormat::SkipField(google::protobuf::io::CodedInputStream*, unsigned int, google::protobuf::UnknownFieldSet*)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;))'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::internal::AssignDescriptors(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, google::protobuf::internal::MigrationSchema const*, google::protobuf::Message const* const*, unsigned int const*, google::protobuf::MessageFactory*, google::protobuf::Metadata*, google::protobuf::EnumDescriptor const**, google::protobuf::ServiceDescriptor const**)'
  ../libraries/libprotoAddress.so: undefined reference to `google::protobuf::io::CodedInputStream::DecrementRecursionDepthAndPopLimit(int)'
  collect2: error: ld returned 1 exit status
  CMakeFiles/prueba.dir/build.make:95: recipe for target '../executables/prueba' failed
  make[2]: *** [../executables/prueba] Error 1
  CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/prueba.dir/all' failed
  make[1]: *** [CMakeFiles/prueba.dir/all] Error 2
  Makefile:83: recipe for target 'all' failed
  make: *** [all] Error 2
  </code></pre>
  
  <p>It seems pretty clear that something is wrong when linking with the google library, but I can't see what is wrong or how to solve it</p>
  
  <p>FYI: I run this is Linux Mint 18 'Sonya' and installed the protoc package from the github with the default options.</p>
  
  <p>Can anyone help me solve this errors and explain what is happening? If you feel like you need more information feel free to ask. Thanks in advance.</p>
  
  <p>EDIT: 
  I updated my cmakelists and now it works, but I dont understand why. I list next the new CMakeLists.txt</p>
  
  <pre><code>cmake_minimum_required(VERSION 3.4.1)
  
  set (CMAKE_CXX_STANDARD 11)
  
  include(FindProtobuf)
  find_package(Protobuf REQUIRED)
  include_directories(${PROTOBUF_INCLUDE_DIR})
  include_directories(
      ${CMAKE_CURRENT_SOURCE_DIR}/sandbox
      /usr
  )
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libraries)
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/executables)
  SET(COMPILE_FLAGS "-I/usr/local/include -pthread ")
  SET(LINK_FLAGS "-L/usr/local/lib -lprotobuf -pthread -lpthread")
  SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}" )
  SET( CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${LINK_FLAGS}" )
  
  add_library(
      protoAddress
      SHARED
      ${CMAKE_CURRENT_SOURCE_DIR}/sandbox/addressbook.pb.cc
  )
  
  
  add_executable(prueba sandbox/testProto.cpp)
  target_link_libraries(prueba protoAddress ${PROTOBUF_LIBRARY})
  </code></pre>
  
  <p>I understand the fact of why I need the library, but not how Cmake does locate that and give me a link for linking both libraries.</p>