Building gRPC support in libprocess with Autotools.

This patch enables autotools to build gRPC support in libprocess along
with tests under Linux.

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


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

Branch: refs/heads/master
Commit: e08593ae97c98f6b78405549a5cc7ad39233781d
Parents: 90f7a7e
Author: Chun-Hung Hsiao <chhs...@mesosphere.io>
Authored: Mon Aug 7 17:24:06 2017 -0700
Committer: Jie Yu <yujie....@gmail.com>
Committed: Thu Aug 10 16:55:06 2017 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/3rdparty/Makefile.am |  50 ++++++++++
 3rdparty/libprocess/Makefile.am          | 101 ++++++++++++++++++---
 3rdparty/libprocess/configure.ac         | 126 +++++++++++++++++++++++++-
 3rdparty/libprocess/include/Makefile.am  |   1 +
 4 files changed, 259 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/e08593ae/3rdparty/libprocess/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/Makefile.am 
b/3rdparty/libprocess/3rdparty/Makefile.am
index 103a7cf..1070f6a 100644
--- a/3rdparty/libprocess/3rdparty/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/Makefile.am
@@ -25,6 +25,8 @@ BUILT_SOURCES = # Initialized to enable using +=.
 CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
 
 # Set up building flags for non-bundled libraries.
+SSL_INCLUDE_FLAGS = @SSL_CPPFLAGS@
+SSL_LINKER_FLAGS = @SSL_LINKERFLAGS@
 ZLIB_INCLUDE_FLAGS = @ZLIB_CPPFLAGS@
 ZLIB_LINKER_FLAGS = @ZLIB_LINKERFLAGS@
 
@@ -39,6 +41,7 @@ GLOG = glog-$(GLOG_VERSION)
 GOOGLETEST = googletest-release-$(GOOGLETEST_VERSION)
 GMOCK = $(GOOGLETEST)/googlemock
 GPERFTOOLS = gperftools-$(GPERFTOOLS_VERSION)
+GRPC = grpc-$(GRPC_VERSION)
 GTEST = $(GOOGLETEST)/googletest
 HTTP_PARSER = http-parser-$(HTTP_PARSER_VERSION)
 LIBEV = libev-$(LIBEV_VERSION)
@@ -51,6 +54,7 @@ EXTRA_DIST =                  \
   $(GLOG).tar.gz               \
   $(GOOGLETEST).tar.gz         \
   $(GPERFTOOLS).tar.gz         \
+  $(GRPC).tar.gz               \
   $(HTTP_PARSER).tar.gz                \
   $(LIBEV).tar.gz              \
   $(PROTOBUF).tar.gz           \
@@ -61,6 +65,10 @@ EXTRA_DIST =                 \
 EXTRA_DIST +=          \
   $(GLOG).patch
 
+# We patch grpc for CMake compilation issues.
+EXTRA_DIST +=          \
+  $(GRPC).patch
+
 # We patch http-parser to avoid a name collision with our `flags` namespace.
 EXTRA_DIST +=          \
   $(HTTP_PARSER).patch
@@ -78,6 +86,7 @@ CLEAN_EXTRACTED =             \
   $(BOOST)                     \
   $(CONCURRENTQUEUE)           \
   $(GLOG)                      \
+  $(GRPC)                      \
   $(GOOGLETEST)                        \
   $(GPERFTOOLS)                        \
   $(HTTP_PARSER)               \
@@ -185,6 +194,47 @@ $(PROTOBUF)-build-stamp: $(PROTOBUF)-stamp
        touch $@
 ALL_LOCAL += $(PROTOBUF)/src/libprotobuf.la
 ALL_LOCAL += $(PROTOBUF)/src/protoc
+
+PROTOBUF_INCLUDE_FLAGS = -I$(abs_builddir)/$(PROTOBUF)/src
+PROTOBUF_LINKER_FLAGS = -L$(abs_builddir)/$(PROTOBUF)/src/.libs
+PROTOC = $(abs_builddir)/$(PROTOBUF)/src/protoc
+else
+$(PROTOBUF)-build-stamp:
+       touch $@
+
+PROTOBUF_INCLUDE_FLAGS = @PROTOBUF_CPPFLAGS@
+PROTOBUF_LINKER_FLAGS = @PROTOBUF_LINKERFLAGS@
+PROTOC = @PROTOCOMPILER@
+endif
+
+if ENABLE_GRPC
+if WITH_BUNDLED_GRPC
+LIB_GRPC = $(GRPC)/libs/opt/libgrpc++.a                \
+           $(GRPC)/libs/opt/libgrpc.a          \
+           $(GRPC)/libs/opt/libgpr.a
+
+$(LIB_GRPC): $(GRPC)-build-stamp
+
+$(GRPC)-build-stamp: $(GRPC)-stamp             \
+                     $(PROTOBUF)-build-stamp
+       cd $(GRPC) &&                           \
+         CPPFLAGS="$(PROTOBUF_INCLUDE_FLAGS)   \
+                   $(SSL_INCLUDE_FLAGS)        \
+                   $(ZLIB_INCLUDE_FLAGS)"      \
+         LDFLAGS="$(PROTOBUF_LINKER_FLAGS)     \
+                  $(SSL_LINKER_FLAGS)          \
+                  $(ZLIB_LINKERFLAGS)"         \
+         $(MAKE) $(AM_MAKEFLAGS)               \
+                 HAS_PKG_CONFIG=false          \
+                 NO_PROTOC=false               \
+                 PROTOC=$(PROTOC)
+       touch $@
+
+ALL_LOCAL += $(LIB_GRPC)
+else
+$(GRPC)-build-stamp:
+       touch $@
+endif
 endif
 
 # Convenience library for gmock/gtest.

http://git-wip-us.apache.org/repos/asf/mesos/blob/e08593ae/3rdparty/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/Makefile.am b/3rdparty/libprocess/Makefile.am
index 90b7295..c2fa3f9 100644
--- a/3rdparty/libprocess/Makefile.am
+++ b/3rdparty/libprocess/Makefile.am
@@ -58,6 +58,7 @@ GLOG = $(BUNDLED_DIR)/glog-$(GLOG_VERSION)
 GOOGLETEST = $(BUNDLED_DIR)/googletest-release-$(GOOGLETEST_VERSION)
 GMOCK = $(GOOGLETEST)/googlemock
 GPERFTOOLS = $(BUNDLED_DIR)/gperftools-$(GPERFTOOLS_VERSION)
+GRPC = $(BUNDLED_DIR)/grpc-$(GRPC_VERSION)
 GTEST = $(GOOGLETEST)/googletest
 HTTP_PARSER = $(BUNDLED_DIR)/http-parser-$(HTTP_PARSER_VERSION)
 LIBEV = $(BUNDLED_DIR)/libev-$(LIBEV_VERSION)
@@ -111,6 +112,28 @@ $(LIB_GPERFTOOLS): $(GPERFTOOLS)-build-stamp
 BUNDLED_DEPS += $(GPERFTOOLS)-build-stamp
 endif
 
+if ENABLE_GRPC
+if WITH_BUNDLED_GRPC
+GRPC_INCLUDE_FLAGS = -I$(GRPC)/include
+LIB_GRPC = $(GRPC)/libs/opt/libgrpc++.a        \
+           $(GRPC)/libs/opt/libgrpc.a  \
+           $(GRPC)/libs/opt/libgpr.a   \
+           -lssl -lcrypto
+GRPC_CPP_PLUGIN = $(GRPC)/bins/opt/grpc_cpp_plugin
+
+# NOTE: We need to specify the dependency between Protobuf and gRPC
+# here, otherwise `make` might launch concurrent gRPC and Protobuf
+# builds, which in turn trigger two racy Protobuf builds.
+$(GRPC)-build-stamp: $(PROTOBUF)-build-stamp
+
+$(LIB_GRPC): $(GRPC)-build-stamp
+BUNDLED_DEPS += $(GRPC)-build-stamp
+else
+LIB_GRPC = -lgrpc++ -lgrpc -lgpr -lssl -lcrypto
+GRPC_CPP_PLUGIN = @GRPC_CXX_PLUGIN@
+endif
+endif
+
 if WITH_BUNDLED_HTTP_PARSER
 HTTP_PARSER_INCLUDE_FLAGS = -I$(HTTP_PARSER)
 LIB_HTTP_PARSER = $(BUNDLED_DIR)/libry_http_parser.la
@@ -140,7 +163,14 @@ BUNDLED_DEPS += $(PICOJSON)-stamp
 endif
 
 if WITH_BUNDLED_PROTOBUF
+PROTOBUF_INCLUDE_FLAGS = -I$(PROTOBUF)/src
+LIB_PROTOBUF = $(PROTOBUF)/src/libprotobuf.la
+PROTOC = $(PROTOBUF)/src/protoc
+$(LIB_PROTOBUF): $(PROTOBUF)-build-stamp
 BUNDLED_DEPS += $(PROTOBUF)-build-stamp
+else
+LIB_PROTOBUF = -lprotobuf
+PROTOC = @PROTOCOMPILER@
 endif
 
 if WITH_BUNDLED_STOUT
@@ -192,13 +222,13 @@ libprocess_la_SOURCES =           \
 
 if ENABLE_SSL
 libprocess_la_SOURCES +=       \
-    src/jwt.cpp                        \
-    src/jwt_authenticator.cpp  \
-    src/libevent_ssl_socket.cpp        \
-    src/libevent_ssl_socket.hpp        \
-    src/openssl.cpp            \
-    src/openssl.hpp            \
-    src/ssl/utilities.cpp
+  src/jwt.cpp                  \
+  src/jwt_authenticator.cpp    \
+  src/libevent_ssl_socket.cpp  \
+  src/libevent_ssl_socket.hpp  \
+  src/openssl.cpp              \
+  src/openssl.hpp              \
+  src/ssl/utilities.cpp
 endif
 
 
@@ -213,22 +243,29 @@ libprocess_la_CPPFLAGS =                  \
   $(ELFIO_INCLUDE_FLAGS)                       \
   $(GLOG_INCLUDE_FLAGS)                                \
   $(GPERFTOOLS_INCLUDE_FLAGS)                  \
+  $(GRPC_INCLUDE_FLAGS)                                \
   $(HTTP_PARSER_INCLUDE_FLAGS)                 \
   $(LIB_EV_INCLUDE_FLAGS)                      \
   $(PICOJSON_INCLUDE_FLAGS)                    \
+  $(PROTOBUF_INCLUDE_FLAGS)                    \
   $(STOUT_INCLUDE_FLAGS)                       \
   $(AM_CPPFLAGS)
 
+if ENABLE_GRPC
+libprocess_la_SOURCES +=       \
+  src/grpc.cpp
+endif
+
 if ENABLE_LIBEVENT
 libprocess_la_SOURCES +=       \
-    src/libevent.hpp           \
-    src/libevent.cpp           \
-    src/libevent_poll.cpp
+  src/libevent.hpp             \
+  src/libevent.cpp             \
+  src/libevent_poll.cpp
 else
-  libprocess_la_SOURCES +=     \
-    src/libev.hpp              \
-    src/libev.cpp              \
-    src/libev_poll.cpp
+libprocess_la_SOURCES +=       \
+  src/libev.hpp                        \
+  src/libev.cpp                        \
+  src/libev_poll.cpp
 endif
 
 if ENABLE_STATIC_LIBPROCESS
@@ -282,9 +319,35 @@ libprocess_tests_CPPFLAGS =                \
   $(libprocess_la_CPPFLAGS)
 
 libprocess_tests_LDADD =               \
+  $(LIB_GRPC)                          \
   $(LIB_GMOCK)                         \
+  $(LIB_PROTOBUF)                      \
   libprocess.la
 
+if ENABLE_GRPC
+libprocess_tests_SOURCES +=                            \
+  src/tests/grpc_tests.cpp                             \
+  src/tests/grpc_tests.proto
+
+GRPC_TESTS_GENERATED_SOURCES =                         \
+  grpc_tests.pb.h                                      \
+  grpc_tests.pb.cc                                     \
+  grpc_tests.grpc.pb.h                                 \
+  grpc_tests.grpc.pb.cc
+
+# Use a pseudo-target here to avoid multiple protoc invocations.
+$(GRPC_TESTS_GENERATED_SOURCES): grpc_tests_proto
+
+grpc_tests_proto: src/tests/grpc_tests.proto           \
+                  $(PROTOBUF)-build-stamp              \
+                  $(GRPC)-build-stamp
+       $(PROTOC) $<                                    \
+         -I$(srcdir)/src/tests                         \
+         --cpp_out=$(builddir)                         \
+         --grpc_out=$(builddir)                        \
+         --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN)
+endif
+
 if ENABLE_SSL
 check_PROGRAMS += ssl-client
 ssl_client_SOURCES = src/tests/ssl_client.cpp
@@ -333,7 +396,15 @@ libprocess_tests_LDADD +=          \
   $(LIB_EV)
 endif
 
-BUILT_SOURCES = $(BUNDLED_DEPS)
+BUILT_SOURCES =                                                        \
+  $(BUNDLED_DEPS)                                              \
+  $(GRPC_TESTS_GENERATED_SOURCES)
+
+nodist_libprocess_tests_SOURCES =                              \
+  $(GRPC_TESTS_GENERATED_SOURCES)
+
+CLEANFILES =                                                   \
+  $(GRPC_TESTS_GENERATED_SOURCES)
 
 # We use a check-local target for now to avoid the parallel test
 # runner that ships with newer versions of autotools.

http://git-wip-us.apache.org/repos/asf/mesos/blob/e08593ae/3rdparty/libprocess/configure.ac
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/configure.ac b/3rdparty/libprocess/configure.ac
index 31556f7..1069d57 100644
--- a/3rdparty/libprocess/configure.ac
+++ b/3rdparty/libprocess/configure.ac
@@ -105,6 +105,11 @@ AC_ARG_ENABLE([debug],
                               option won't change them default: no]),
               [], [enable_debug=no])
 
+AC_ARG_ENABLE([grpc],
+              AS_HELP_STRING([--enable-grpc],
+                             [enable grpc support]),
+              [], [enable_grpc=no])
+
 AC_ARG_ENABLE([install],
               AS_HELP_STRING([--enable-install],
                              [install libprocess]),
@@ -188,6 +193,13 @@ AC_ARG_WITH([gmock],
                             location prefixed by the given path]),
             [without_bundled_gmock=yes], [])
 
+AC_ARG_WITH([grpc],
+            AS_HELP_STRING([--with-grpc@<:@=DIR@:>@],
+                           [excludes building and using the bundled grpc
+                            package in lieu of an installed version at a
+                            location prefixed by the given path]),
+            [without_bundled_grpc=yes], [])
+
 AC_ARG_WITH([http-parser],
             AS_HELP_STRING([--with-http-parser@<:@=DIR@:>@],
                            [excludes building and using the bundled http-parser
@@ -877,8 +889,11 @@ AM_CONDITIONAL([WITH_BUNDLED_PICOJSON], [test 
"x$with_bundled_picojson" = "xyes"
 
 
 if test -n "`echo $with_protobuf`"; then
-  CPPFLAGS="$CPPFLAGS -I${with_protobuf}/include"
-  LDFLAGS="$LDFLAGS -L${with_protobuf}/lib"
+  PROTOBUF_CPPFLAGS="-isystem ${with_protobuf}/include"
+  PROTOBUF_LINKERFLAGS="-L${with_protobuf}/lib"
+
+  CPPFLAGS="$PROTOBUF_CPPFLAGS $CPPFLAGS"
+  LDFLAGS="$PROTOBUF_LINKERFLAGS $LDFLAGS"
 fi
 
 # Check if user has asked us to use a preinstalled protobuf, or if
@@ -917,6 +932,8 @@ if test "x$without_bundled_protobuf" = "xyes" || \
       AC_MSG_ERROR([protoc not found in PATH])
     fi
 
+    PROTOCOMPILER="$PROTOBUFPREFIX/bin/protoc"
+
   else
     AC_MSG_ERROR([cannot find protobuf
 -------------------------------------------------------------------
@@ -936,6 +953,10 @@ fi
 AM_CONDITIONAL([WITH_BUNDLED_PROTOBUF],
                [test "x$with_bundled_protobuf" = "xyes"])
 
+AC_SUBST([PROTOBUF_CPPFLAGS])
+AC_SUBST([PROTOBUF_LINKERFLAGS])
+AC_SUBST([PROTOCOMPILER])
+
 
 # Check if libssl prefix path was provided, and if so, add it to
 # the CPPFLAGS and LDFLAGS with respective /include and /lib path
@@ -948,8 +969,11 @@ if test -z "`echo $with_ssl`" &&
 fi
 
 if test -n "`echo $with_ssl`"; then
-  CPPFLAGS="-I${with_ssl}/include $CPPFLAGS"
-  LDFLAGS="-L${with_ssl}/lib $LDFLAGS"
+  SSL_CPPFLAGS="-isystem ${with_ssl}/include"
+  SSL_LINKERFLAGS="-L${with_ssl}/lib"
+
+  CPPFLAGS="$SSL_CPPFLAGS $CPPFLAGS"
+  LDFLAGS="$SSL_LINKERFLAGS $LDFLAGS"
 fi
 
 AC_CHECK_LIB([crypto], [RAND_poll], [found_crypto=yes])
@@ -1003,6 +1027,9 @@ fi
 
 AM_CONDITIONAL([ENABLE_SSL], [test x"$enable_ssl" = "xyes"])
 
+AC_SUBST([SSL_CPPFLAGS])
+AC_SUBST([SSL_LINKERFLAGS])
+
 
 if test -n "`echo $with_stout`"; then
   CPPFLAGS="$CPPFLAGS -I${with_stout}/include"
@@ -1108,6 +1135,97 @@ AC_SUBST([ZLIB_CPPFLAGS])
 AC_SUBST([ZLIB_LINKERFLAGS])
 
 
+# Check if grpc prefix path was supplied and if so, add it to the
+# CPPFLAGS and LDFLAGS with respective /include and /lib path suffixes.
+if test -n "`echo $with_grpc`"; then
+  if test "x$without_bundled_protobuf" != "xyes"; then
+    AC_MSG_ERROR([protobuf not specified
+-------------------------------------------------------------------
+You have requested the use of a non-bundled grpc without specifying
+the protobuf library it uses. This is prohibited to avoid using
+conflicting versions of protobuf libraries. Please specify the
+location of protobuf used by grpc by providing a prefix path via
+--with-protobuf=DIR.
+-------------------------------------------------------------------
+    ])
+  fi
+
+  CPPFLAGS="$CPPFLAGS -isystem ${with_grpc}/include"
+  LDFLAGS="$LDFLAGS -L${with_grpc}/lib"
+fi
+
+if test "x$enable_grpc" = "xyes"; then
+  # Check if user has asked us to use a preinstalled grpc, or if they
+  # asked us to ignore all bundled libraries while compiling and linking.
+  if test "x$without_bundled_grpc" = "xyes" || \
+     test "x$enable_bundled" != "xyes"; then
+    # Use the system default prefix if not specified.
+    if test -n "`echo $with_grpc`"; then
+      GRPCPREFIX="${with_grpc}"
+    elif test "x$enable_bundled" != "xyes"; then
+      GRPCPREFIX="/usr"
+    fi
+
+    # Check if headers and library were located.
+    saved_LIBS="$LIBS"
+    LIBS="-lgrpc++ -lgrpc -lgpr $LIBS"
+    AC_LANG_PUSH([C++])
+    AC_CHECK_HEADERS([grpc++/grpc++.h],
+                     [AC_LINK_IFELSE(
+                         [AC_LANG_PROGRAM([#include <grpc++/grpc++.h>],
+                                          [grpc::Version();])],
+                         [found_grpc=yes],
+                         [found_grpc=no])],
+                     [found_grpc=no])
+    AC_LANG_POP()
+    LIBS="$saved_LIBS"
+
+    if test "x$found_grpc" = "xyes"; then
+      with_bundled_grpc=no
+
+      AC_CHECK_TOOL([GRPC_CXX_PLUGIN_TEST],
+                    [grpc_cpp_plugin],
+                    [],
+                    [$GRPCPREFIX/bin])
+
+      if test -z "`echo $GRPC_CXX_PLUGIN_TEST`"; then
+        AC_MSG_ERROR([grpc_cpp_plugin not found in PATH])
+      fi
+
+      GRPC_CXX_PLUGIN="$GRPCPREFIX/bin/grpc_cpp_plugin"
+
+    else
+      AC_MSG_ERROR([cannot find grpc
+-------------------------------------------------------------------
+You have requested the use of a non-bundled grpc but no suitable
+grpc could be found.
+
+You may want specify the location of grpc by providing a prefix
+path via --with-grpc=DIR, or check that the path you provided is
+correct if you are already doing this.
+-------------------------------------------------------------------
+      ])
+    fi
+  else
+    if test "x$found_ssl" != "xyes"; then
+      AC_MSG_ERROR([cannot find libssl
+-------------------------------------------------------------------
+libssl is required for gRPC to build.
+-------------------------------------------------------------------
+      ])
+    fi
+
+    with_bundled_grpc=yes
+  fi
+fi
+
+AM_CONDITIONAL([ENABLE_GRPC], [test "x$enable_grpc" = "xyes"])
+AM_CONDITIONAL([WITH_BUNDLED_GRPC],
+               [test "x$with_bundled_grpc" = "xyes"])
+
+AC_SUBST([GRPC_CXX_PLUGIN])
+
+
 # Once all CXXFLAGS are completely assembled, make sure the we are not
 # affected by libcxx undefined behavior,
 # https://llvm.org/bugs/show_bug.cgi?id=28469.

http://git-wip-us.apache.org/repos/asf/mesos/blob/e08593ae/3rdparty/libprocess/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/Makefile.am 
b/3rdparty/libprocess/include/Makefile.am
index 637654e..c5dc0bb 100644
--- a/3rdparty/libprocess/include/Makefile.am
+++ b/3rdparty/libprocess/include/Makefile.am
@@ -31,6 +31,7 @@ nobase_include_HEADERS =              \
   process/future.hpp                   \
   process/gc.hpp                       \
   process/gmock.hpp                    \
+  process/grpc.hpp                     \
   process/gtest.hpp                    \
   process/help.hpp                     \
   process/http.hpp                     \

Reply via email to