Search code examples
gccprotocol-buffersldlinker-flagsabseil

How do I properly link the Google Protocol Buffers library with my application at compilation?


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!


Solution

  • 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.