-1

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)':
2
  • @PepijnKramer You suggesting changing from one package manager (vcpkg) to another (conan2). Can you explain why? I would have assumed both would do the same job, and accomplish the same end objective? Commented Apr 13 at 9:29
  • Sorry me bad, I don't know why but I missed the vcpkg part. Commented Apr 14 at 3:46

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.