Search code examples
c++cmakeprotocol-buffers

How to convert protobuffer files to c++ using cmake with the output files in same directory as the proto files


I'm generating c++ files from protobuf files using cmake with the following

find_package(Protobuf REQUIRED)

file(GLOB PROTO_FILES *.proto)

protobuf_generate_cpp(CPP_SOURCE_FILES PROTO_HEADERS ${PROTO_FILES})
add_custom_target(PROTO_TO_CPP ALL DEPENDS ${CPP_SOURCE_FILES})

This works as expected. The problem is the output c++ files are generated in the build directory, and I want them in the same directory as the protobuf files. I've tried the following which, based on the documentation, should work

set_target_properties(PROTO_TO_CPP
    RUNTIME_OUTPUT_DIRECTORY
    ${CMAKE_CURRENT_SOURCE_DIR})

But the c++ files are still generated in the build directory. Q: Is there a way to set the output directory for a custom target?


Solution

  • Just to understand what is the purpose of generating them within the source directory?

    I think it is bad practice since cmake allows out-of-source build and that generated files should not be considered as "sources of your project".

    Your custom target will never move files as it does not "run" anything. It just depends on some files generated by protobuf_generate_cpp.

    I think, if you actually need them alongside your .proto files you could use protobuf_generate this way:

    protobuf_generate(
        TARGET 
            protobuf-generate-cpp
        PROTOS
            ${PROTO_FILES}
        LANGUAGE
            cpp
        OUT_VAR
            PROTOBUF_GENERATED_FILES
        PROTOC_OUT_DIR
            <path/to/proto/dir>
     )
    
    

    In the end I think you will have to have another target depend on protobuf-generate-cpp

    I haven't tested this code but from the documentation this should work.

    Edit: I think it is also bad practice to use file(GLOB ...) as you do not have full control of what files are being taken. This might be OK in your project but if you ever use it in a project that has different targets with different proto files you will not want "all proto files" to be taken each time. From my point of view, it is always better to explicitly list files that you want to include (even if it forces you editing the cmake file each time you add a .proto file