MantisBT - CMake
View Issue Details
0011148CMakeModulespublic2010-08-18 12:282011-11-11 10:45
Johannes Wienke 
Philip Lowman 
normalmajoralways
closedfixed 
CMake-2-8 
CMake 2.8.5CMake 2.8.5 
0011148: protobuf macro does not allow proto files out of source folder
Sometime it is desirable to install the proto-files somewhere on the system if they are used by different projects.
However the provided macro does not allow to specify an additional proto_path command line option for the protobuf compiler. So compilation of proto-files outside of the project root fails.
No tags attached.
Issue History
2010-08-18 12:28Johannes WienkeNew Issue
2010-08-18 23:28Philip LowmanStatusnew => assigned
2010-08-18 23:28Philip LowmanAssigned To => Philip Lowman
2010-08-18 23:35Philip LowmanNote Added: 0021819
2010-08-19 04:05Johannes WienkeNote Added: 0021824
2010-08-19 23:45Philip LowmanNote Added: 0021862
2011-05-26 00:14Philip LowmanNote Added: 0026607
2011-05-26 00:25Philip LowmanNote Added: 0026608
2011-05-26 00:25Philip LowmanTarget Version => CMake 2.8.5
2011-06-07 01:21Philip LowmanNote Added: 0026733
2011-06-07 01:21Philip LowmanStatusassigned => resolved
2011-06-07 01:21Philip LowmanResolutionopen => fixed
2011-06-07 01:21Philip LowmanFixed in Version => CMake 2.8.5
2011-11-11 10:45David ColeNote Added: 0027762
2011-11-11 10:45David ColeStatusresolved => closed

Notes
(0021819)
Philip Lowman   
2010-08-18 23:35   
Hi, thanks for filing the issue. Having proto files outside of the source tree wasn't a use-case that I considered when I wrote the module (surprisingly).

Could you include a small example of what you are trying to do in CMakeLists.txt and the error message that you get? Also, if you have a workaround, please post that as well. Is the problem worked around by simply adding a command line option?
(0021824)
Johannes Wienke   
2010-08-19 04:05   
We got several different language bindings for a middleware that uses protocol buffers to communicate. Therefore we created a separate project which contains the proto-files for the message types we have defined and installs them under $prefix/share/rsbprotocol. This is the path required as the proto_path argument to the protobuf compiler.

My workaround right now is this modified version of your original macro:

function(RSBPROTOBUF_GENERATE_CPP SRCS HDRS)
  if(NOT ARGN)
    message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
    return()
  endif(NOT ARGN)

  set(${SRCS})
  set(${HDRS})
  foreach(FIL ${ARGN})
    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
    get_filename_component(FIL_WE ${FIL} NAME_WE)
    get_filename_component(FIL_EXT ${FIL} NAME)
    
    STRING(REPLACE ${RSBPROTO_ROOT} "" WO_PREFIX ${FIL})
    STRING(REPLACE ${FIL_EXT} "" REL_PATH ${WO_PREFIX})

    # Attention: REL_PATH always begins and terminates with /, do not add extra slashes. This confuses the cmake dependency calculation
    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}${REL_PATH}${FIL_WE}.pb.cc")
    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}${REL_PATH}${FIL_WE}.pb.h")

    add_custom_command(
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}${REL_PATH}${FIL_WE}.pb.cc"
             "${CMAKE_CURRENT_BINARY_DIR}${REL_PATH}${FIL_WE}.pb.h"
      COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
      # TODO this is the bad hack... the root is hard-coded
      ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${RSBPROTO_ROOT} ${ABS_FIL}
      DEPENDS ${ABS_FIL}
      COMMENT "Running C++ protocol buffer compiler on ${FIL}"
      VERBATIM )
  endforeach()

  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()

RSBPROTO_ROOT is the path mentioned above. The files given as ARGN have a fully-specified path name, e.g. /vol/xyz/releases/cuttingedge/share/rsbprotocol/introspection/PortStateChange.proto where /vol/xyz/releases/cuttingedge is $prefix.

Please note that this modified version of the macro also fixes bug 10997 but requires the root. Right now this is a global variable in the project but I would expect some syntax like function(PROTOBUF_GENERATE_CPP [PROTOROOT path] [OUTPUT path] SRCS HDRS). Always building to CMAKE_CURRENT_BINARY_DIR might also be undesired sometime, hence specifying an output folder would also help.
(0021862)
Philip Lowman   
2010-08-19 23:45   
Thanks for posting the information. I will investigate your workaround/use-case and the patch included in 10997 soon. A second public macro that supports different output directories and proto_path locations doesn't seem like an unreasonable addition.
(0026607)
Philip Lowman   
2011-05-26 00:14   
I'm leaning towards what I've come up with in 0010997 (see attached file) as a way to fix this issue.

The proposal is to determine what directory each proto file is in and generate a list of '-I /path/to/dir' arguments to feed into protoc. I'm also proposing that this become the default behavior (seems unlikely to break anyone given the existing behavior of the macro).
(0026608)
Philip Lowman   
2011-05-26 00:25   
tentatively targeting this to 2.8.5...
(0026733)
Philip Lowman   
2011-06-07 01:21   
The fix in topic 10997 should resolve this bug.
Merge topic '10997_PROTOBDUF_GENERATE_CPP_returns_wrong_path' into next

Allow proto files outside of the current source directory to be compiled in the PROTOBUF_GENERATE_CPP module. This is accomplished by using the -I flag for each path where proto files are being compiled.
(0027762)
David Cole   
2011-11-11 10:45   
Closing resolved issues that have not been updated in more than 4 months.