When using cmake to use protobufs, there's no way to have protoc create the 
output files in the cmake build directory unless the build directory is a 
direct subdirectory from the source directory. 

For example, I have source code that resides in directory ${SRCDIR} with 
the protobuf files in ${SRCDIR}/protobuf. The cmake file (for a variety of 
reasons) is not located in ${SRCDIR} but in ${SRCDIR}/cmake_server/DMSO. 
I'm building in ${SRCDIR}/cmake_server/DMSO/cmake_build_vs2017 using Visual 
Studio 2017.

${SRC_DIR}/
  - protobuf/
    pb_hla_utilities.proto
    pb_messages.proto
  - cmake_server/
    - DMSO/
      CMakeLists.txt
      - cmake_build_vs2017/
        - protobuf_build/       <== What I want

Here's the relevent code in my CMakeLists.txt file:

set(PROTBUF_FILES
    ${SRCDIR}/protobuf/pb_messages.proto
    ${SRCDIR}/protobuf/pb_hla_utilities.proto
  )

set(protobuf_DIR <path_to_protobuf_install>/cmake)
find_package(protobuf REQUIRED CONFIG)

protobuf_generate(
  APPEND_PATH
  TARGET ${LOCAL_EXE_NAME}
  LANGUAGE cpp
  OUT_VAR PROTO_SRCS
  PROTOS ${PROTBUF_FILES}
  IMPORT_DIRS ${SRC_DIR}/protobuf
  PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf_build
  )

# Group protobuf output files in their own subfolder within visual studio.
source_group("protobuf" FILES ${PROTO_SRCS})

However, the generated visual studio solution files assume that the output 
is relative to the CMAKE_CURRENT_SOURCE_DIR which appears to mess things up 
when the build directory is more than one level down from the actual source 
code. In the above example here's what is generated from 
protobuf-config.cmake:

CMAKE_CURRENT_SOURCE_DIR: ${SRCDIR}/cmake_server/DMSO 

_rel_dir: ../../protobuf

_abs_dir: ${SRCDIR}/protobuf

_generated_srcs: 
${SRCDIR}/cmake_server/DMSO/cmake_build_vs2017/protobuf_build/../../protobuf/pb_hla_utilities.pb.h
 


                          
${SRCDIR}/cmake_server/DMSO/cmake_build_vs2017/protobuf_build/../../protobuf/pb_hla_utilities.pb.cc


This causes visual studio to create the output directory "protobuf" in 
  ${SRCDIR}/cmake_server/DMSO
and then protoc is directed to write the output into 
  ${SRCDIR}/cmake_server/DMSO/cmake_build_vs2017/protobuf_build/
which then fails the build. 

What I think should be happening is the output files should always be 
created in PROTOC_OUT_DIR.

I'm not sure what the reason is to not do it this way, but a way to make 
this work is to add a new option to maintain backward compatability to the 
protobuf-config.cmake script.

Here's a patch to do that based off of current master:

----------------------------------------------------------------------
diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in
index 29e39d88..33b1b33f 100644
--- a/cmake/protobuf-config.cmake.in
+++ b/cmake/protobuf-config.cmake.in
@@ -10,7 +10,13 @@ 
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake")
 function(protobuf_generate)
   include(CMakeParseArguments)
 
-  set(_options APPEND_PATH)
+  # USE_ABSOLUTE_OUTPUT_DIR: If set, create the protobuf output files in 
the directory pointed to by PROTOC_OUT_DIR.
+  #   If not set, the protobuf output files are created in the directory 
pointed to by
+  #   PROTOC_OUT_DIR but assumed to be created relative to 
CMAKE_CURRENT_SOURCE_DIR.
+  # APPEND_PATH: If set, add the path for each file created by protoc as 
arguments to -I.
+  #   If not set, use CMAKE_CURRENT_SOURCE_DIR as the include path.
+  set(_options APPEND_PATH USE_ABSOLUTE_OUTPUT_DIR)
+  
   set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR)
   if(COMMAND target_sources)
     list(APPEND _singleargs TARGET)
@@ -98,7 +104,11 @@ function(protobuf_generate)
 
     set(_generated_srcs)
     foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS})
-      list(APPEND _generated_srcs 
"${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}")
+      if (${protobuf_generate_USE_ABSOLUTE_OUTPUT_DIR})
+        list(APPEND _generated_srcs 
"${protobuf_generate_PROTOC_OUT_DIR}/${_basename}${_ext}")
+      else()
+        list(APPEND _generated_srcs 
"${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}")
+      endif()
     endforeach()
     list(APPEND _generated_srcs_all ${_generated_srcs})
 

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.

Reply via email to