Repository: mesos
Updated Branches:
  refs/heads/master 2cf3e6dd4 -> 1e3145f92


Made `PROTOC_GENERATE` compile proto files from 3rd-party libraries.

PROTOC_GENERATE now has the following new features:
  (1) With the `LIB` option, compile .proto files found in a third-party
      specification library.
  (2) Provides the `GRPC` option that, once we support gRPC in CMake,
      will generate the `.grpc.pb.h` and `.grpc.pb.cc` files.
  (3) With the `LIB` option, append to list variable `PUBLIC_PROTO_PATH`
      or `INTERNAL_PROTO_PATH` the fully qualified path to the library's
      include directory, and append to list variable
      `PUBLIC_PROTOBUF_INCLUDE_DIR` or `INTERNAL_PROTOBUF_INCLUDE_DIR`
      the fully qualified path to the directory where the generated
      `.pb.h` files are placed.

Review: https://reviews.apache.org/r/65997/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f0b33da2
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f0b33da2
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f0b33da2

Branch: refs/heads/master
Commit: f0b33da2a94c9281fb8509a8f134c4d333481e2e
Parents: 2cf3e6d
Author: Chun-Hung Hsiao <chhs...@mesosphere.io>
Authored: Thu Mar 15 10:08:06 2018 -0700
Committer: Chun-Hung Hsiao <chhs...@mesosphere.io>
Committed: Thu Mar 15 10:08:06 2018 -0700

----------------------------------------------------------------------
 src/CMakeLists.txt            |  33 ++++---
 src/cmake/MesosProtobuf.cmake | 178 +++++++++++++++++++++++++++++--------
 2 files changed, 163 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f0b33da2/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0c13503..6fc45db 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,12 +18,18 @@
 #########################################
 include(MesosProtobuf)
 
+set(PUBLIC_PROTO_PATH "")
+set(PUBLIC_PROTOBUF_INCLUDE_DIR "")
+set(PUBLIC_PROTOBUF_SRC "")
+set(INTERNAL_PROTO_PATH "")
+set(INTERNAL_PROTOBUF_INCLUDE_DIR "")
+set(INTERNAL_PROTOBUF_SRC "")
+set(JAVA_PROTOBUF_SRC "")
+
 # Build the protobuf structs.
 #
-# NOTE: `PROTOC_GENERATE` will list append to `PUBLIC_PROTOBUF_SRC`,
-# `INTERNAL_PROTOBUF_SRC`, and/or `JAVA_PROTOBUF_SRC` depending on the
-# `INTERNAL` and `JAVA` options.
-set(PUBLIC_PROTOBUF_SRC "")
+# NOTE: The following `PROTOC_GENERATE` calls will list append to
+# `PUBLIC_PROTOBUF_SRC`.
 PROTOC_GENERATE(TARGET mesos/agent/agent)
 PROTOC_GENERATE(TARGET mesos/allocator/allocator)
 PROTOC_GENERATE(TARGET mesos/appc/spec)
@@ -45,8 +51,9 @@ PROTOC_GENERATE(TARGET mesos/slave/oversubscription)
 PROTOC_GENERATE(TARGET mesos/state/state)
 PROTOC_GENERATE(TARGET mesos/uri/uri)
 
-# NOTE: The JAVA option is a noop if Java is disabled.
-set(JAVA_PROTOBUF_SRC "")
+# NOTE: The following `PROTOC_GENERATE` calls will list append to
+# `PUBLIC_PROTOBUF_SRC` and/or `JAVA_PROTOBUF_SRC`. The JAVA option is a noop 
if
+# Java is disabled.
 PROTOC_GENERATE(JAVA TARGET mesos/executor/executor)
 PROTOC_GENERATE(JAVA TARGET mesos/fetcher/fetcher)
 PROTOC_GENERATE(JAVA TARGET mesos/mesos)
@@ -61,7 +68,8 @@ PROTOC_GENERATE(JAVA TARGET mesos/v1/quota/quota)
 PROTOC_GENERATE(JAVA TARGET mesos/v1/resource_provider/resource_provider)
 PROTOC_GENERATE(JAVA TARGET mesos/v1/scheduler/scheduler)
 
-set(INTERNAL_PROTOBUF_SRC "")
+# NOTE: The following `PROTOC_GENERATE` calls will list append to
+# `INTERNAL_PROTOBUF_SRC`.
 PROTOC_GENERATE(INTERNAL TARGET messages/flags)
 PROTOC_GENERATE(INTERNAL TARGET messages/log)
 PROTOC_GENERATE(INTERNAL TARGET messages/messages)
@@ -94,7 +102,13 @@ add_library(
 
 target_link_libraries(mesos-protobufs PUBLIC protobuf)
 target_include_directories(
-  mesos-protobufs PUBLIC ${MESOS_PROTOBUF_HEADER_INCLUDE_DIRS})
+  mesos-protobufs
+  PUBLIC
+  ${MESOS_PROTOBUF_HEADER_INCLUDE_DIRS}
+  ${PUBLIC_PROTOBUF_INCLUDE_DIR}
+
+  PRIVATE
+  ${INTERNAL_PROTOBUF_INCLUDE_DIR})
 
 
 # BUILD JAVA ARTIFACTS.
@@ -483,10 +497,7 @@ target_compile_definitions(mesos PUBLIC 
USE_CMAKE_BUILD_CONFIG)
 target_include_directories(
   mesos PUBLIC
   ${MESOS_PUBLIC_INCLUDE_DIR}
-
-  # Contains (e.g.) compiled *.pb.h files.
   ${MESOS_BIN_INCLUDE_DIR}
-  ${MESOS_BIN_INCLUDE_DIR}/mesos
   ${MESOS_BIN_SRC_DIR}
   ${MESOS_SRC_DIR})
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/f0b33da2/src/cmake/MesosProtobuf.cmake
----------------------------------------------------------------------
diff --git a/src/cmake/MesosProtobuf.cmake b/src/cmake/MesosProtobuf.cmake
index ef90c15..dde034f 100644
--- a/src/cmake/MesosProtobuf.cmake
+++ b/src/cmake/MesosProtobuf.cmake
@@ -16,43 +16,102 @@
 
 # PROTOC_GENERATE is a convenience function that will:
 #   (1) Compile .proto files found in the Mesos public-facing `include/`
-#       directory, or with the option `INTERNAL` the Mesos `src/` directory.
-#       The `JAVA` option flag will generate the Java Protobuf files to
-#       `src/java/generated`.
-#   (2) Place the generated files in the build folder, but with an identical
-#       directory structure.
-#   (3) Append to list variables `PUBLIC_PROTOBUF_SRC`, 
`INTERNAL_PROTOBUF_SRC`,
+#       directory, or with the `INTERNAL` option the Mesos `src/` directory,
+#       or with the `LIB` option a third-party specification library.
+#   (2) Place the generated files in the build folder, under the `include/`
+#       directory, or with the `INTERNAL` option the `src/` directory. The
+#       `JAVA` option will generate the Java Protobuf files to
+#       `src/java/generated` (not supported with the `LIB` option). The `GRPC`
+#       option will generate the `.grpc.pb.h` and `.grpc.pb.cc` files.
+#   (3) With the `LIB` option, append to list variable `PUBLIC_PROTO_PATH` or
+#       `INTERNAL_PROTO_PATH` the fully qualified path to the library's include
+#       directory, and append to list variable `PUBLIC_PROTOBUF_INCLUDE_DIR` or
+#       `INTERNAL_PROTOBUF_INCLUDE_DIR` the fully qualified path to the
+#       directory where the generated `.pb.h` files are placed. This export is 
a
+#       *side effect* and modifies the variables in the parent scope.
+#   (4) Append to list variables `PUBLIC_PROTOBUF_SRC`, 
`INTERNAL_PROTOBUF_SRC`,
 #       and `JAVA_PROTOBUF_SRC` (depending on options passed in) the fully
 #       qualified path to the generated files. This export is a *side effect*
 #       and modifies the variables in the parent scope.
 #
-# For example, if suppose wish to compile `include/mesos/mesos.proto`,
-# we might pass in the following values for the parameters:
+# Example 1: Suppose we wish to compile `include/mesos/mesos.proto`, we might
+# pass in the following values for the parameters:
 #
 #   PROTOC_GENERATE(TARGET mesos/mesos)
 #
 # Where `mesos/mesos.proto` would be the relative path to the .proto file,
-# we'd use this "root name" to generate files like `mesos/mesos.pb.cc`
+# we'd use this "root name" to generate files like `mesos/mesos.pb.cc`. In this
+# case, this function would:
 #
-# In this case, this function would:
-#
-#   (1) Compile the `include/mesos/mesos.proto`, which would generate the files
+#   (1) Compile `include/mesos/mesos.proto`, which would generate the files
 #       `build/include/mesos/mesos.pb.h` and `build/include/mesos/mesos.pb.cc`.
 #   (2) Append the path `${MESOS_ROOT}/build/include/mesos/mesos.pb.cc` to
 #       the parent scope variable `PUBLIC_PROTOBUF_SRC`.
 #
+# Example 2: Suppose we wish to compile `csi.proto` in the `csi` specification
+# library (assuming version 0.1.0) with gRPC enabled, we might pass in the
+# following values for the parameters:
+#
+#   PROTOC_GENERATE(GRPC LIB csi TARGET csi)
+#
+# Where `csi.proto` would be the relative path to the .proto file in the `csi`
+# library's include directory. In this case, this function would:
+#
+#   (1) Compile `build/3rdparty/csi-0.1.0/src/csi-0.1.0/csi.proto`, which would
+#       generate the files `build/include/csi/csi.pb.h`,
+#       `build/include/csi/csi.pb.cc`, `build/include/csi/csi.grpc.pb.h`, and
+#       `build/include/csi/csi.grpc.pb.cc`.
+#   (2) Append the path `${MESOS_ROOT}/build/3rdparty/csi-0.1.0/src/csi-0.1.0/`
+#       to the parent scope variable `PUBLIC_PROTO_PATH`, and the path
+#       `${MESOS_ROOT}/build/include/csi/` to the parent scope variable
+#       `PUBLIC_PROTOBUF_INCLUDE_DIR`.
+#   (3) Append the paths `${MESOS_ROOT}/build/include/csi/csi.pb.cc` and
+#       `${MESOS_ROOT}/build/include/csi/csi.grpc.pb.cc` to the parent scope
+#       variable `PUBLIC_PROTOBUF_SRC`.
+#
 # NOTE: The `protoc` binary used here is an imported executable target from
 # `3rdparty/CMakeLists.txt`. However, this is not strictly necessary, and
 # `protoc` could be supplied in `PATH`.
 function(PROTOC_GENERATE)
-  set(options OPTIONAL INTERNAL JAVA)
-  set(oneValueArgs TARGET)
+  set(options OPTIONAL INTERNAL JAVA GRPC)
+  set(oneValueArgs LIB TARGET)
   cmake_parse_arguments(PROTOC "${options}" "${oneValueArgs}" "" ${ARGN})
 
-  if (PROTOC_INTERNAL)
-    set(CPP_OUT ${MESOS_BIN_SRC_DIR})
+  # Fully qualified paths for the input .proto file and the output directories.
+  if (PROTOC_LIB)
+    get_target_property(
+      PROTOC_LIB_INCLUDE_DIR
+      ${PROTOC_LIB}
+      INTERFACE_INCLUDE_DIRECTORIES)
+
+    set(PROTO ${PROTOC_LIB_INCLUDE_DIR}/${PROTOC_TARGET}.proto)
+
+    # TODO(chhsiao): `PUBLIC_PROTOBUF_INCLUDE_DIR` and
+    # `INTERNAL_PROTOBUF_INCLUDE_DIR` are temporary include directories which
+    # point to the generated header files. Derivative protocol buffers need the
+    # headers in order to build. These variables can be removed if all 
3rd-party
+    # specification libraries build their own generated code.
+    if (PROTOC_INTERNAL)
+      set(CPP_OUT ${MESOS_BIN_SRC_DIR}/${PROTOC_LIB})
+      list(APPEND INTERNAL_PROTO_PATH ${PROTOC_LIB_INCLUDE_DIR})
+      list(APPEND INTERNAL_PROTOBUF_INCLUDE_DIR ${CPP_OUT})
+    else ()
+      set(CPP_OUT ${MESOS_BIN_INCLUDE_DIR}/${PROTOC_LIB})
+      list(APPEND PUBLIC_PROTO_PATH ${PROTOC_LIB_INCLUDE_DIR})
+      list(APPEND PUBLIC_PROTOBUF_INCLUDE_DIR ${CPP_OUT})
+    endif ()
   else ()
-    set(CPP_OUT ${MESOS_BIN_INCLUDE_DIR})
+    if (PROTOC_INTERNAL)
+      set(PROTO ${MESOS_SRC_DIR}/${PROTOC_TARGET}.proto)
+      set(CPP_OUT ${MESOS_BIN_SRC_DIR})
+    else ()
+      set(PROTO ${MESOS_PUBLIC_INCLUDE_DIR}/${PROTOC_TARGET}.proto)
+      set(CPP_OUT ${MESOS_BIN_INCLUDE_DIR})
+    endif()
+
+    if (PROTOC_JAVA AND HAS_JAVA)
+      set(JAVA_OUT ${MESOS_BIN_SRC_DIR}/java/generated)
+    endif()
   endif ()
 
   set(PROTOC_OPTIONS
@@ -60,54 +119,99 @@ function(PROTOC_GENERATE)
     -I${MESOS_SRC_DIR}
     --cpp_out=${CPP_OUT})
 
-  if (PROTOC_JAVA AND HAS_JAVA)
-    list(APPEND PROTOC_OPTIONS
-      --java_out=${MESOS_BIN_SRC_DIR}/java/generated)
+  if (PUBLIC_PROTO_PATH)
+    list(APPEND PROTOC_OPTIONS -I${PUBLIC_PROTO_PATH})
+  endif ()
+
+  if (INTERNAL_PROTO_PATH)
+    list(APPEND PROTOC_OPTIONS -I${INTERNAL_PROTO_PATH})
   endif ()
 
-  # Fully qualified paths for the input .proto files and the output C file.
-  if (PROTOC_INTERNAL) # to src dir
-    set(PROTO ${MESOS_SRC_DIR}/${PROTOC_TARGET}.proto)
-  else () # to public include dir
-    set(PROTO ${MESOS_PUBLIC_INCLUDE_DIR}/${PROTOC_TARGET}.proto)
+  if (PROTOC_GRPC AND HAS_GRPC)
+    # TODO(chhsiao): Add the gRPC plugin.
+    list(APPEND PROTOC_OPTIONS --grpc_out=${CPP_OUT})
   endif ()
 
+  if (JAVA_OUT)
+    list(APPEND PROTOC_OPTIONS --java_out=${JAVA_OUT})
+  endif ()
+
+  # Fully qualified paths for the output .pb.h and .pb.cc files.
   set(CC ${CPP_OUT}/${PROTOC_TARGET}.pb.cc)
   set(H ${CPP_OUT}/${PROTOC_TARGET}.pb.h)
 
+  if (PROTOC_GRPC AND HAS_GRPC)
+    set(GRPC_CC ${CPP_OUT}/${PROTOC_TARGET}.grpc.pb.cc)
+    set(GRPC_H ${CPP_OUT}/${PROTOC_TARGET}.grpc.pb.h)
+  endif ()
+
   # Fully qualified path for the Java file.
-  if (PROTOC_JAVA AND HAS_JAVA)
+  if (JAVA_OUT)
     get_filename_component(PROTOC_JAVA_DIR ${PROTOC_TARGET} DIRECTORY)
-    set(JAVA 
${MESOS_BIN_SRC_DIR}/java/generated/org/apache/${PROTOC_JAVA_DIR}/Protos.java)
+    set(JAVA ${JAVA_OUT}/org/apache/${PROTOC_JAVA_DIR}/Protos.java)
   endif ()
 
   # Export variables holding the target filenames.
   if (PROTOC_INTERNAL)
-    list(APPEND INTERNAL_PROTOBUF_SRC ${CC})
+    set(INTERNAL_PROTO_PATH ${INTERNAL_PROTO_PATH} PARENT_SCOPE)
+
+    set(
+      INTERNAL_PROTOBUF_INCLUDE_DIR
+      ${INTERNAL_PROTOBUF_INCLUDE_DIR}
+      PARENT_SCOPE)
+
+    list(APPEND INTERNAL_PROTOBUF_SRC ${CC} ${GRPC_CC})
     set(INTERNAL_PROTOBUF_SRC ${INTERNAL_PROTOBUF_SRC} PARENT_SCOPE)
   else ()
-    list(APPEND PUBLIC_PROTOBUF_SRC ${CC})
+    set(PUBLIC_PROTO_PATH ${PUBLIC_PROTO_PATH} PARENT_SCOPE)
+
+    set(PUBLIC_PROTOBUF_INCLUDE_DIR ${PUBLIC_PROTOBUF_INCLUDE_DIR} 
PARENT_SCOPE)
+
+    list(APPEND PUBLIC_PROTOBUF_SRC ${CC} ${GRPC_CC})
     set(PUBLIC_PROTOBUF_SRC ${PUBLIC_PROTOBUF_SRC} PARENT_SCOPE)
   endif ()
 
-  if (PROTOC_JAVA AND HAS_JAVA)
+  if (JAVA)
     list(APPEND JAVA_PROTOBUF_SRC ${JAVA})
     set(JAVA_PROTOBUF_SRC ${JAVA_PROTOBUF_SRC} PARENT_SCOPE)
   endif ()
 
-  if (PROTOC_INTERNAL)
-    set(PROTOC_DEPENDS make_bin_src_dir)
+  # Make the directory that generated files go into.
+  # TODO(chhsiao): Put the following directory creation targets together with
+  # `make_bin_include_dir` and `make_bin_src_dir`, and find a better way to
+  # ensure that the output directories are created.
+  if (PROTOC_LIB)
+    if (PROTOC_INTERNAL)
+      set(MAKE_CPP_OUT_DIR make_bin_src_${PROTOC_LIB}_dir)
+      add_custom_target(
+        ${MAKE_CPP_OUT_DIR} ALL
+        COMMAND ${CMAKE_COMMAND} -E make_directory ${CPP_OUT}
+        DEPENDS make_bin_src_dir)
+    else ()
+      set(MAKE_CPP_OUT_DIR make_bin_include_${PROTOC_LIB}_dir)
+      add_custom_target(
+        ${MAKE_CPP_OUT_DIR} ALL
+        COMMAND ${CMAKE_COMMAND} -E make_directory ${CPP_OUT}
+        DEPENDS make_bin_include_dir)
+    endif()
+
+    set(PROTOC_DEPENDS ${MAKE_CPP_OUT_DIR} ${PROTOC_LIB})
   else ()
-    set(PROTOC_DEPENDS make_bin_include_dir)
-  endif ()
+    if (PROTOC_INTERNAL)
+      set(PROTOC_DEPENDS make_bin_src_dir)
+    else ()
+      set(PROTOC_DEPENDS make_bin_include_dir)
+    endif ()
 
-  if (PROTOC_JAVA AND HAS_JAVA)
-    list(APPEND PROTOC_DEPENDS make_bin_java_dir)
+    if (JAVA_OUT)
+      list(APPEND PROTOC_DEPENDS make_bin_java_dir)
+    endif ()
   endif ()
 
   # Compile the .proto file.
+  # TODO(chhsiao): Add a gRPC dependency.
   add_custom_command(
-    OUTPUT ${CC} ${H} ${JAVA}
+    OUTPUT ${CC} ${H} ${GRPC_CC} ${GRPC_H} ${JAVA}
     COMMAND protoc ${PROTOC_OPTIONS} ${PROTO}
     DEPENDS ${PROTOC_DEPENDS} ${PROTO}
     WORKING_DIRECTORY ${MESOS_BIN})

Reply via email to