I’m working on a larger project which currently performs in-tree out-of-build protobuf generation. I’m looking at converting to using in-build protobuf generation with CMake’s support. Unfortunately, I’m running into issues where protobuf_generate() seems to attempt to use incorrect paths. Hopefully this is a usage issue. If not, I can see about filing a ticket.
I’m currently using cmake 3.30.5
I’ve created a minimal testcase with the directory hierarchy:
- builds
- libs
-
- proto_build
-
-
- CMakeLists.txt
-
- protos
-
- proto-base
-
-
- proto_component
-
-
-
-
- test.proto
-
-
- CMakeLists.txt
The contents:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.22.1)
project(cmake_demo VERSION 0.0.1)
set(ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
add_subdirectory(libs/proto_build)
libs/proto_build/CMakeLists.txt:
project(ProtoBuildProject)
find_package(Qt6 COMPONENTS Core Network REQUIRED)
find_package(Protobuf)
file(GLOB_RECURSE PROTO_FILES "${ROOT_DIR}/protos/proto-base/proto_component/*.proto")
add_library(proto-build-proto-lib)
protobuf_generate(
TARGET proto-build-proto-lib
LANGUAGE cpp
OUT_VAR BUILD_PROTO_OUT_FILES
EXPORT_MACRO "EXPORT_MACRO"
\# PROTOC_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/proto/build/src"
PROTOC_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}"
PROTOS ${PROTO_FILES}
IMPORT_DIRS "${ROOT_DIR}/protos/"
)
protos/proto-base/proto_component/test.proto:
syntax = "proto3";
package proto_component;
message TestProto
{
string s = 1;
int32 i = 2;
}
I run cmake with:
/home/developer/Qt/Tools/CMake/bin/cmake -S /home/developer/cmake_demo -B /home/developer/cmake_demo/builds/Debug -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++ -DCMAKE_GENERATOR:STRING=Ninja
My expectation is that I would have the relevant .pb.cc and .pb.h files created, compiled and linked into a library. Instead, I end up with path mismatches.
First, the files are created. They can be found at:
- /home/developer/cmake_demo/builds/Debug/libs/proto_build/proto-base/proto_component/test.pb.cc
- /home/developer/cmake_demo/builds/Debug/libs/proto_build/proto-base/proto_component/test.pb.h
However, the attempt to build them fails. I get:
$ ninja
FAILED: libs/proto_build/CMakeFiles/proto-build-proto-lib.dir///protos/proto-base/proto_component/test.pb.cc.o
/usr/bin/g++ -O2 -pipe -g -feliminate-unused-debug-types -g -MD -MT libs/proto_build/CMakeFiles/proto-build-proto-lib.dir///protos/proto-base/proto_component/test.pb.cc.o -MF libs/proto_build/CMakeFiles/proto-build-proto-lib.dir///protos/proto-base/proto_component/test.pb.cc.o.d -o libs/proto_build/CMakeFiles/proto-build-proto-lib.dir///protos/proto-base/proto_component/test.pb.cc.o -c /home/developer/cmake_demo/builds/Debug/protos/proto-base/proto_component/test.pb.cc
cc1plus: fatal error: /home/developer/cmake_demo/builds/Debug/protos/proto-base/proto_component/test.pb.cc: No such file or directory
So it looks like it builds the .pb.cc/.pb.h files in the specified PROTOC_OUT_DIR directory, but then looks for them to be in the source directory.
As a related issue, I noticed that the PROTOC_OUT_DIR parameter doesn’t work if the specified directory doesn’t exist. If I swap out the commented-out version above to place the generated files in subdirectory of ${CMAKE_CURRENT_BINARY_DIR} which currently doesn’t exist, the build will fail due to the directory not existing.
Please let me know if I’ve done something obviously-wrong here which can be worked around.