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
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 subdirectorythird_party/abseil-cpp
. Don’t forget togit 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: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:
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.
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: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
then applications successfully link on windows and linux, and when protobuf has been compiled as shared or static library.