I'm trying to build a C++ project with a later version of the protobuf libraries than my OS package manager provides.
To do this, I have chosen to use vcpkg
to configure the project dependencies. (In this case, just protobuf and nothing else.)
I have followed the Microsoft tutorial for vcpkg
+ cmake
, but I am encountering linker errors.
It may just be that I have missed something.
I am familiar with most of these tools, with the exception of vcpkg
which I have not used before.
The following files are all contained within a single directory.
Here is my main.cpp
.
#include "message.pb.h"
int main() {
std::cout << "hello world" << std::endl;
PersonMessage person_message;
person_message.set_name("henry");
std::cout << person_message.name() << std::endl;
std::cout << person_message.DebugString() << std::endl;
return 0;
}
Here is the message.proto
definition.
syntax = "proto3";
message PersonMessage {
string name = 1;
}
CMakeLists.txt
. I think this is sensible, but although I have used cmake
a bit, I'm not really an expert. I know how to do some things with the build system, but this CMakeLists.txt
might not be optimal.
cmake_minimum_required(VERSION 3.5)
project(vcpkg-project-test CXX)
find_package(Protobuf REQUIRED)
set(CMAKE_CXX_STANDARD 23)
set(PROTO_FILES message.proto)
set(PROTO_GENERATE_DIR ${CMAKE_BINARY_DIR}/generated)
file(MAKE_DIRECTORY ${PROTO_GENERATE_DIR})
protobuf_generate_cpp(
PROTO_SRCS PROTO_HDRS ${PROTO_FILES}
)
add_library(
lib_proto
STATIC
${PROTO_SRCS}
)
target_include_directories(
lib_proto
PUBLIC
${Protobuf_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR}
)
target_link_libraries(
lib_proto
PUBLIC
${Protobuf_LIBRARIES}
)
add_executable(
a.out
main.cpp
)
target_link_libraries(
a.out
PRIVATE
lib_proto
${Protobuf_LIBRARIES}
)
I have configured vcpkg.json
to define the dependencies. This file contains the following contents.
{
"dependencies": [
"protobuf"
]
}
Finally, these are the commands I am running to attempt to build this project.
cmake -B build -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build
I am using the g++
compiler, version g++ (Ubuntu 14.2.0-4ubuntu2) 14.2.0
.
When I try to build this project I encounter a very large list of linker errors. This is the first such error.
[build] /usr/bin/ld: liblib_proto.a(message.pb.cc.o): warning: relocation against `_ZN4absl12lts_2025012712log_internal9kCharNullE' in read-only section `.text._ZN4absl12lts_2025012712log_internal9NullGuardIPKcE5GuardES4_[_ZN4absl12lts_2025012712log_internal9NullGuardIPKcE5GuardES4_]'
[build] /usr/bin/ld: vcpkg_installed/x64-linux/lib/libprotobuf.a(arena.cc.o): in function `google::protobuf::internal::(anonymous namespace)::AllocateBlock(google::protobuf::internal::AllocationPolicy const*, unsigned long, unsigned long)':
The problem is that ${Protobuf_LIBRARIES}
contains only the local libraries built by protoc
.
It contains the following string:
/home/username/vcpkg-project-test/build/vcpkg_installed/x64-linux/lib/libprotobuf.a
What it does not contain are the general libraries which are also required.
We need to add them:
target_link_libraries(
a.out
PRIVATE
lib_proto
protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite
)
Also note that ${Protobuf_LIBRARIES}
is not required here, as the dependency is brought in via lib_proto
.
There is actually a helpful message printed by vcpkg
about this.
protobuf provides CMake targets:
# this is heuristically generated, and may not be correct
find_package(protobuf CONFIG REQUIRED)
target_link_libraries(main PRIVATE protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite)
It now works.