CMake protobuf_generate_cpp uses absolute paths instead of relative paths.
TLDR; Invoking protoc through protobuf_generate_cpp uses absolute paths and thus produces invalid code.
When manually invoking proto:
/usr/bin/protoc --cpp_out /home/pp/Projects/SmartHomeManagement/shm-iw/build shmiw/metadata/metadata.proto
The (part of) content of metadata.pb.h is:
::DescriptorTable descriptor_table_shmiw_2fmetadata_2fmetadata_2eproto;
Whereas when invoking through protobuf_generate_cpp:
/usr/bin/protoc --cpp_out /home/pp/Projects/SmartHomeManagement/shm-iw/build -I /home/pp/Projects/SmartHomeManagement/shm-iw/shmiw/metadata /home/pp/Projects/SmartHomeManagement/shm-iw/shmiw/metadata/metadata.proto
the content of metadata.pb.h is:
::DescriptorTable descriptor_table_metadata_2eproto;
which breaks the compilation of bci.pb.cc which uses declarations from metadata.pb.h
Error being raised during compilation is:
shm-iw/build/shm-iw/bci/bci.pb.cc:183:6: error: ‘::descriptor_table_shm_2diw_2fmetadata_2fmetadata_2eproto’ has not been declared 183 | &::descriptor_table_shmiw_2fmetadata_2fmetadata_2eproto, |
As you can see when compiling bci, it wants to find the declaration similar to the one produced by manual invocation of protoc, not the one generated by cmake's protobuf_generate_cpp
I've found a few more topics referring to this issue but none of them was solved, thus I created a new one.
My cmake version is: 3.22.1 protoc version is: 3.12.4
Below you can find a broader description.
Here is a directory structure: -CMakeLists.txt (1) -shm-iw/
- CMakeLists.txt (2)
- bci
- CMakeLists.txt (3)
- bci.proto
- metadata
- CMakeLists.txt (4)
- metadata.proto
Root CMakeLists.txt(1)
cmake_minimum_required(VERSION 3.12)
project(shm-iw CXX)
set(SHM-IW_VERSION 0.1)
find_package(Protobuf REQUIRED)
include_directories(${CMAKE_BINARY_DIR})
set (Protobuf_IMPORT_DIRS ${CMAKE_SOURCE_DIR} )
add_subdirectory(shm-iw)
shm-iw/CMakeLists.txt(2)
cmake_minimum_required(VERSION 3.12)
add_subdirectory(metadata)
add_subdirectory(bci)
shm-iw/bci/CMakeLists.txt (3)
cmake_minimum_required(VERSION 3.12)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS
bci.proto
)
add_library(bci_objlib OBJECT
${PROTO_SRCS}
${PROTO_HDRS}
)
target_link_libraries(bci_objlib metadata_objlib)
add_dependencies(bci_objlib metadata_objlib)
shm-iw/bci/bci.proto
syntax = "proto3";
/* Board Control Interface */
import "shmiw/metadata/metadata.proto"; //Note the path to metadata.proto
package shm.iw.bci;
enum IndicatorType {
Status = 0;
Warning = 1;
Maintenance = 2;
Fault = 3;
}
enum IndicatorState {
SteadyOff = 0;
SteadyOn = 1;
Blink = 2;
};
message GetVisualIndicationReq
{
option (shm.iw.metadata.MESSAGE_NUMBER) = 0x1000101;
IndicatorType indicator = 1;
}
message GetVisualIndicationCfm
{
option (shm.iw.metadata.MESSAGE_NUMBER) = 0x1000102;
IndicatorType indicator = 1;
IndicatorState state = 2;
}
shm-iw/metadata/CMakeLists.txt (4)
cmake_minimum_required(VERSION 3.12)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS
metadata.proto
)
add_library(metadata_objlib OBJECT
${PROTO_SRCS}
${PROTO_HDRS}
)
shm-iw/metadta/metadata.proto
syntax = "proto3";
import "google/protobuf/descriptor.proto";
package shm.iw.metadata;
extend google.protobuf.MessageOptions {
uint32 MESSAGE_NUMBER = 50001;
}