View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0016077 | CMake | Modules | public | 2016-04-22 17:09 | 2016-06-10 14:31 | ||||
Reporter | skebanga | ||||||||
Assigned To | Kitware Robot | ||||||||
Priority | normal | Severity | minor | Reproducibility | always | ||||
Status | closed | Resolution | moved | ||||||
Platform | Linux | OS | Ubuntu | OS Version | 14.04 | ||||
Product Version | CMake 3.5 | ||||||||
Target Version | Fixed in Version | ||||||||
Summary | 0016077: FindProtobuf.cmake doesn't have required flexibility to configure protoc usage for all use cases | ||||||||
Description | I have here a very simple test project which has 2 protobuf files, one of which is included in the other. Using cmake, I will create a static library for each generated protobuf message. ##Protobuf files: **`src/foo/message.proto`:** package test.foo; message FooMsg { required string s = 1; } **`src/bar/message.proto`:** package test.bar; import "foo/message.proto"; message BarMsg { optional foo.FooMsg f = 1; } ##CMake files: I build `lib_foo` from generated `foo/message.proto` files. **`src/foo/CMakeLists.txt`:** protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS message.proto) add_library(lib_foo STATIC ${PROTO_SRCS}) I build `lib_bar` from the generated `bar/message.proto` files, and link in `lib_foo`: **`src/bar/CMakeLists.txt`:** protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS message.proto ) add_library(lib_bar STATIC ${PROTO_SRCS}) target_link_libraries(lib_bar lib_foo) **`src/CMakeLists.txt`:** cmake_minimum_required (VERSION 3.5) project (cmake_proto_test CXX) find_package(Protobuf REQUIRED) # proto files import from the source root directory, so add the required -I flag set(PROTOBUF_IMPORT_DIRS ${CMAKE_SOURCE_DIR}) # genererated proto files go into the CMake binary output dir include_directories("${CMAKE_BINARY_DIR}") add_subdirectory(foo) add_subdirectory(bar) ##Build error: When I try to build this, I get the following error: $ make .. VERBOSE=1 cd src/cmake_proto/build/bar && /usr/bin/c++ -I src/cmake_proto/build -o CMakeFiles/lib_bar.dir/message.pb.cc.o -c src/cmake_proto/build/bar/message.pb.cc In file included from src/cmake_proto/build/bar/message.pb.cc:5:0: src/cmake_proto/build/bar/message.pb.h:99:24: error: ‘foo’ in namespace ‘test’ does not name a type inline const ::test::foo::FooMsg& f() const; ^ ##Reason: The error is due to the header guard created by `protoc` being the same for the 2 generated files: #ifndef PROTOBUF_message_2eproto__INCLUDED #define PROTOBUF_message_2eproto__INCLUDED ... #endif The reason is that the header guard is derived from a combination of the output directory and the generated file's path. The current command issued by `FindProtobuf.cmake` results in the header guard only using the filename: cd src/cmake_proto/build/foo && /usr/local/bin/protoc --cpp_out src/cmake_proto/build/foo -I src/cmake_proto/foo -I src/cmake_proto src/cmake_proto/foo/message.proto cd src/cmake_proto/build/bar && /usr/local/bin/protoc --cpp_out src/cmake_proto/build/bar -I src/cmake_proto/bar -I src/cmake_proto src/cmake_proto/bar/message.proto This command, however, will result in the files being generated in the same location, but with a different header guard: cd src/cmake_proto/build && /usr/local/bin/protoc --cpp_out src/cmake_proto/build -I src/cmake_proto src/cmake_proto/foo/message.proto cd src/cmake_proto/build && /usr/local/bin/protoc --cpp_out src/cmake_proto/build -I src/cmake_proto src/cmake_proto/bar/message.proto Header guards: PROTOBUF_foo_2fmessage_2eproto__INCLUDED PROTOBUF_bar_2fmessage_2eproto__INCLUDED There are three key differences here: - The `WORKING_DIRECTORY` from which `protoc` is run from is `${CMAKE_BINARY_DIR}` - The `--cpp_out` directory passed to `protoc` is `${CMAKE_BINARY_DIR}` - The `-I` include path passed to `protoc` does **not** include the folder where the proto file is found Being able to control these 3 items would give the flexibility required to use this tool in the above setup. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | |||||||||
Relationships | |
Relationships |
Notes | |
(0040927) skebanga (reporter) 2016-04-25 11:11 |
Here is an implementation which I've come up with - may be of use? function(PROTOC SRCS HDRS) set(options) set(values CPP_OUT CWD) set(lists INCLUDE PROTO) cmake_parse_arguments(PROTOC "${options}" "${values}" "${lists}" "${ARGN}") if (NOT PROTOC_CPP_OUT) set(PROTOC_CPP_OUT ${CMAKE_CURRENT_BINARY_DIR}) endif() if (NOT PROTOC_CWD) set(PROTOC_CWD ${CMAKE_CURRENT_BINARY_DIR}) endif() if (NOT PROTOC_INCLUDE) set(PROTOC_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}) endif() foreach(PATH ${PROTOC_INCLUDE}) list(FIND _protobuf_include_path ${PATH} _contains_already) if(${_contains_already} EQUAL -1) list(APPEND _protobuf_include_path -I ${PATH}) endif() endforeach() set(${SRCS}) set(${HDRS}) foreach(FILE ${PROTOC_PROTO}) get_filename_component(ABS_FILE ${FILE} ABSOLUTE) # convert path of input file into path of output file string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} BIN_DEST ${ABS_FILE}) get_filename_component(FILE_DEST ${BIN_DEST} DIRECTORY) get_filename_component(FILE_WE ${BIN_DEST} NAME_WE) list(APPEND ${SRCS} "${FILE_DEST}/${FILE_WE}.pb.cc") list(APPEND ${HDRS} "${FILE_DEST}/${FILE_WE}.pb.h") add_custom_command( OUTPUT "${FILE_DEST}/${FILE_WE}.pb.cc" "${FILE_DEST}/${FILE_WE}.pb.h" COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ARGS --cpp_out ${PROTOC_CPP_OUT} ${_protobuf_include_path} ${ABS_FILE} WORKING_DIRECTORY ${PROTOC_CWD} DEPENDS ${ABS_FILE} ${PROTOBUF_PROTOC_EXECUTABLE} COMMENT "Running C++ protocol buffer compiler on ${FILE}" VERBATIM ) endforeach() set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) set(${SRCS} ${${SRCS}} PARENT_SCOPE) set(${HDRS} ${${HDRS}} PARENT_SCOPE) endfunction() |
(0040928) Brad King (manager) 2016-04-25 11:28 |
Re 0016077:0040927: Thanks. Rather than introducing a whole new function for this, please look at extending protobuf_generate_cpp to parse ARGN and look for options activating such behavior. The defaults can simply fall back to current behavior. |
(0042988) Kitware Robot (administrator) 2016-06-10 14:29 |
Resolving issue as `moved`. This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page. |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2016-04-22 17:09 | skebanga | New Issue | |
2016-04-25 11:11 | skebanga | Note Added: 0040927 | |
2016-04-25 11:28 | Brad King | Note Added: 0040928 | |
2016-06-10 14:29 | Kitware Robot | Note Added: 0042988 | |
2016-06-10 14:29 | Kitware Robot | Status | new => resolved |
2016-06-10 14:29 | Kitware Robot | Resolution | open => moved |
2016-06-10 14:29 | Kitware Robot | Assigned To | => Kitware Robot |
2016-06-10 14:31 | Kitware Robot | Status | resolved => closed |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |