skip to Main Content

I am following the tutorial listed here on Protobuf’s website. I copied the sample addressbook.proto and compiled it using the line

protoc --cpp_out=. addressbook.proto

Which produced addressbook.pb.cc and addressbook.pb.h. Here is my program, which doesn’t do anything right now (I am just trying to get it to compile).

#include "addressbook.pb.h"

int main(int argc, char *argv[]) {
    return 0;
}

My problem arises at compilation. I thought this would suffice:

g++ -std=c++14 main.cpp addressbook.pb.cc -o main -L/usr/local/lib64 -lprotobuf -lprotoc -lprotobuf-lite -lpthread

However, I get enough linker errors to fill my terminal’s history, pretty much all of them start with

undefined reference to `absl::lts_20230125:: ...

I tried manually installing Abseil from source by following the directions here, which put the *.a files in /usr/local/lib64.

I tried using -L to specify the original build directory to the linker (before installation).

I found a list of 60-70 Abseil-related linker flags which I tried to incorporate into my compilation command.

I tried various assortments of compiler/linker flags, enivronment variables, and recompiling Protobuf and Abseil, all resulting in the same thing.

For the record, I installed Protocol Buffers from source by following the CMake directions specified here. My GCC version is 8.3.1 (via devtoolset-8 on CentOS 7.9). I made sure to include the -DCMAKE_CXX_STANDARD=14 flag when building. For me, it is installed at /usr/local/lib64.

I imagine I’m making a simple mistake somewhere or I’m missing something basic since protobuf is a well-known library, but I’m really stumped here. Any help is appreciated!

2

Answers


  1. I just stumbled into this problem after building from source. In a nutshell, as you already discovered, protobuf must be linked with some Abseil libraries for the build to work. Using protobuf v4.25.3 from github I found the Abseil git submodule within the protobuf repo in subdirectory third_party/abseil-cpp. Don’t forget to git submodule update --init --recursive or it won’t populate the submodules. It was quick and simple to build and install Abseil using standard cmake syntax:

    cmake <rel path to Abseil CMakeLists.txt>
    make
    sudo make install
    

    I was then able to eventually build my executable without error by manually searching through the Abseil static libs for each undefined reference that popped up when trying to build. I arrived at this:

    g++ main.cpp test.pb.cc -fPIC  -lpthread -lprotobuf -labsl_raw_logging_internal -labsl_log_internal_check_op -labsl_log_internal_message
    

    I can’t help thinking this isn’t the best way to build it, but I wasn’t able to find any official documentation from google on the correct way to build. I might update this if I make any further progress.

    Login or Signup to reply.
  2. In response to an issue I created on the protobuf GitHub page 19494 one of the contributors indicated that — when using cmake — the correct way to link all of the appropriate abseil (and other) libraries is to include this line in the CMakeLists.txt file:

    find_package(protobuf REQUIRED CONFIG)
    

    Before that point, I was omitting the CONFIG word, so I attribute my grief to a lack of cmake proficiency I guess.
    It wouldn’t hurt for them to explicitly indicate this in their documentation though.

    I don’t understand the machinery that enables it, but with a later line like

    target_link_libraries(my_app PRIVATE protobuf::libprotobuf)
    

    then applications successfully link on windows and linux, and when protobuf has been compiled as shared or static library.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search