Series
- Part 1: compile protobuf-cpp on ubuntu 16.04
- Part 2: compile protobuf-cpp on windows 10
- Part 3: protobuf usage
Guide
- protobuf 2.6.1
- protobuf 3.6.1 latest
old version
install
sudo apt-get install libprotobuf-dev
which protoc
/usr/bin/protoc
protoc --version
2.6.1
remove
#remove exist `protobuf 2.6.1`
sudo apt-get remove libprotobuf-dev
compile
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.tar.gz
tar -xvf protobuf-cpp-3.6.1.tar.gz
cd protobuf-3.6.1
./configure --disable-shared CXXFLAGS="-fPIC"
make -j8
tips: we compile static library with
--disable-shared CXXFLAGS="-fPIC"
. 编译动态库dll/so的时候,如果依赖static library(比如profobuf),那么static library编译的时候需要加上-fPIC
,否则动态库编译出错。
对于CMake,使用cmake CMAKE_CXX_FLGAS="-fPIC" ..
otherwise, error occurs
Linking CXX shared library ../../../../bin/libcommon.so
/usr/bin/ld: /usr/local/lib/libprotobuf.a(common.o): relocation R_X86_64_32S against `.rodata' can not be used when makinga shared object; recompile with -fPIC
/usr/local/lib/libprotobuf.a: error adding symbols: Bad value
install
sudo make install
sudo ldconfig
sudo make uninstall
install path:
- header:
/usr/local/include/google/protobuf
- lib:
/usr/local/lib
- executable:
/usr/local/bin
static libs
ll /usr/local/lib/libproto
libprotobuf.a libprotobuf-lite.a libprotoc.a
libprotobuf.la libprotobuf-lite.la libprotoc.la
By default,
make install' will install all the files in
/usr/local/bin’,/usr/local/lib' etc. You can specify an installation prefix other than
/usr/local’ using--prefix', for instance
–prefix=$HOME’.
./configure -h
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
Static Linking vs DLL
Static linking
is now the default for the Protocol Buffer libraries. Due to issues with Win32’s use of a separate heap for each DLL, as well as binary compatibility issues between different versions of MSVC’s STL library, it is recommended that you use static linkage only.
However, it is possible to build libprotobuf and libprotoc as DLLs if you really want. To do this, do the following:
- Add an additional flag
-Dprotobuf_BUILD_SHARED_LIBS=ON
when invoking cmake - Follow the same steps as described in the above section.
- When compiling your project, make sure to
#define PROTOBUF_USE_DLLS
.
test
which protoc
/usr/local/bin/protoc
protoc --version
libprotoc 3.6.1
tips install openmpi
sudo apt-get install -y libiomp-dev libopenmpi-dev
multiple protoc
whereis protoc
protoc: /usr/bin/protoc # 2.6.0
/usr/local/bin/protoc # 3.6.1
/usr/share/man/man1/protoc.1.gz
Example
usage
protoc --cpp_out=. ./point_cloud.proto
protoc --java_out=./java/ ./proto/helloworld.proto
protoc --go_out=./go/ ./proto/helloworld.proto
CMakeLists.txt
find_package(Protobuf REQUIRED)
#add_definitions( -DPROTOBUF_USE_DLLS ) # KEY STEPS
MESSAGE( [Main] " PROTOBUF_INCLUDE_DIRS = ${PROTOBUF_INCLUDE_DIRS}")
MESSAGE( [Main] " PROTOBUF_LIBRARIES = ${PROTOBUF_LIBRARIES}")
error
./node_perception
[libprotobuf ERROR google/protobuf/descriptor_database.cc:58] File already exists in database: adapter_config.proto
[libprotobuf FATAL google/protobuf/descriptor.cc:1315] CHECK failed: generated_database_->Add(encoded_file_descriptor, size):
terminate called after throwing an instance of 'google::protobuf::FatalException'
what(): CHECK failed: generated_database_->Add(encoded_file_descriptor, size):
Aborted (core dumped)
reasons
The problem happens when you have multiple compiled copies of the same .pb.cc file sharing a single copy of libprotobuf.so.
`common`模块编译了`adapter_config.pb.cc`,`node_perception`依赖于`common`,同时也要编译`adapter_config.pb.cc`。运行`node_perception`就会报错。
solutions
同一份`adapter_config.pb.cc`只编译到`node_perception`等executable,不要编译到所依赖的`common`模块。
common和node_perception使用static或者dynamic的protobuf,都会遇到同样的问题。
Reference
History
- 20181219: created.