Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pb_cc_library in generic.cmake #2653

Merged
merged 11 commits into from
Jun 29, 2017

Conversation

reyoung
Copy link
Collaborator

@reyoung reyoung commented Jun 28, 2017

Fix #2567

pb_cc_library pb_py_library
Description generate a C++ protobuf sources and headers, create a cc_library, add to include dirs generate Python protobuf sources to target directory(default is CMAKE_CURRENT_BINARY_DIR)
Example pb_cc_library(paddle_proto SRCS ${proto_filenames}) pb_py_library(gen_proto_py SRCS ${proto_filenames} TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR})

@reyoung reyoung force-pushed the feature/protobuf_lib branch 3 times, most recently from bfa57a0 to 6991da8 Compare June 28, 2017 15:02
Copy link
Collaborator

@wangkuiyi wangkuiyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!

@@ -331,3 +331,52 @@ function(go_test TARGET_NAME)
add_custom_target(${TARGET_NAME} ALL DEPENDS ${TARGET_NAME}_timestamp ${go_test_DEPS})
add_test(${TARGET_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME})
endfunction(go_test)

function(pb_cc_library TARGET_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR! I do NOT think we need rules that compile .proto files into a specific programming language; instead, we need just a proto_library, similar to Bazel's https://bazel.build/blog/2017/02/27/protocol-buffers.html, to

  1. convert .proto into .h and .cc using the standard function protobuf_generate_cpp, and
  2. build a static library from the generated C++ source files by calling cc_library.

I have a draft of proto_library at
https://github.com/PaddlePaddle/Paddle/pull/2569/files#diff-7a3600c73304487a6d5f6bd3fa3fd662R175:

 +function(proto_library TARGET_NAME)
 +  if (NOT ${PROTOBUF_FOUND})
 +    error("Using proto_library but CMake cannot find installed protobuf.")
 +  endif()
 +  
 +  set(options STATIC static SHARED shared)
 +  set(oneValueArgs "")
 +  set(multiValueArgs SRCS DEPS)
 +  cmake_parse_arguments(proto_library "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 +
 +  protobuf_generate_cpp(${TARGET_NAME}_PROTO_SRCS ${TARGET_NAME}_PROTO_HDRS ${proto_library_SRCS})
 +  cc_library(${TARGET_NAME} SRCS ${${TARGET_NAME}_PROTO_SRCS} DEPS ${${proto_library}_DEPS} protobuf)
 +endfunction(proto_library)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we cannot use protobuf_generate_cpp directly because we are manually compiling Protobuf instead of using Find(Protobuf) in our system. If we do not use Find(Protobuf), the protobuf_generate_cpp is not defined.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can. We just need to set the corresponding variable so that protobuf_generate_cpp knows where protoc is. In my PR I tried this technique; it works.

Copy link
Contributor

@Xreki Xreki Jun 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested the use of protobuf_generate_cpp in #2582 and found out the standard function prptobuf_generate_cpp is not good enough to use because of two reasons:

  1. Function protobuf_generate_cpp is defined in cmake's Protobuf.cmake. In the case that find_package(Protobuf) is not called, the build process will be aborted because of Unknown CMake command "protobuf_generate_cpp" error.
  2. In protobuf_generate_cpp, we cannot set the dependency of others, and the function may be called before the protoc executable in third_party generated. The error information is:
No rule to make target `../third_party/install/protobuf/bin/protoc', needed by `paddle/framework/example.pb.cc'.  Stop.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Xreki

  1. We could use Find_PACKAGE(Protobuf QUIET) to import function protobuf_generate_cpp.
  2. We could define ${Protobuf_PROTC_EXECUTABLE}, let protobuf_generate_cpp handle the dependencies.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Xreki See here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reyoung I decided not to call find_package(Protobuf), because when we do cross-compiling, it may find the protobuf library of the host. That must be avoided.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see you set PROTOBUF_FOUND to OFF after calling find_package(Protobuf QUIET). It can avoid the problem I listed.

list(APPEND proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")

add_custom_command(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are to generate source files from .proto files, we can call protobuf_generate_cpp, which is much more convenient than calling protoc from a customized command.

cc_library(${TARGET_NAME} SRCS ${proto_srcs})
endfunction()

function(pb_py_library TARGET_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think our Python code will call C++ code via the C-API, and only C++ code fills in and serializes protobuf messages. Given that Python code doesn't work with protobuf messages directly, we don't need a pb_py_library, at least at the current time.

If we need it in the future, we can add it, by please keep naming consistent with Bazel, as we have always been doing in generic.cmake.

FYR: Bazel has the following rules in https://github.com/pubref/rules_protobuf#rules

Language Compile 1 Build 2 gRPC 3
C++ cc_proto_compile cc_proto_library v1.0.1
C# csharp_proto_compile csharp_proto_library 1.0.0
Closure closure_proto_compile closure_proto_library
Go go_proto_compile go_proto_library v1.0.5
Go (gogo) gogo_proto_compile gogo_proto_library fb8a35
gRPC gateway grpc_gateway_proto_compile
grpc_gateway_swagger_compile
grpc_gateway_proto_library
grpc_gateway_binary
v1.0.4
Java java_proto_compile java_proto_library v1.0.1
Node node_proto_compile node_proto_library 1.0.0
Objective-C objc_proto_compile objc_proto_library 4 v1.0.0673f
Python py_proto_compile v1.0.0673f
Ruby ruby_proto_compile v1.0.0673f
Custom proto_language proto_compile

Copy link
Collaborator

@wangkuiyi wangkuiyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the proto_library we need!

set(proto_srcs)
set(proto_hdrs)
protobuf_generate_cpp(proto_srcs proto_hdrs ${proto_library_SRCS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought that we should moved include_directories(${CMAKE_CURRENT_BINARY_DIR}) out from this function to the top of generic.cmake?

set(proto_hdrs)
protobuf_generate_cpp(proto_srcs proto_hdrs ${proto_library_SRCS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
cc_library(${TARGET_NAME} SRCS ${proto_srcs})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think cc_library needs to depend on the external target protobuf?

@wangkuiyi
Copy link
Collaborator

TeamCity complains that

[22:40:05]	In file included from /paddle/paddle/cuda/include/hl_gpu.h:28:0,
[22:40:05]	from /paddle/paddle/utils/Util.h:34,
[22:40:05]	from /paddle/paddle/testing/TestMain.cpp:16:
[22:40:05]	/paddle/paddle/cuda/include/hl_warpctc_wrap.h:18:17: fatal error: ctc.h: No such file or directory
[22:40:05]	compilation terminated.
[22:40:05]	In file included from /paddle/paddle/cuda/include/hl_gpu.h:28:0,
[22:40:05]	from /paddle/paddle/utils/Util.h:34,
[22:40:05]	from /paddle/paddle/utils/ThreadLocal.h:25,
[22:40:05]	from /paddle/paddle/math/Matrix.h:22,
[22:40:05]	from /paddle/paddle/testing/TestUtil.h:18,
[22:40:05]	from /paddle/paddle/testing/TestUtil.cpp:15:
[22:40:05]	/paddle/paddle/cuda/include/hl_warpctc_wrap.h:18:17: fatal error: ctc.h: No such file or directory
[22:40:05]	compilation terminated.

set(proto_srcs)
set(proto_hdrs)
protobuf_generate_cpp(proto_srcs proto_hdrs ${proto_library_SRCS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested this PR, and it works fine to build the example_proto through a simple command:

proto_library(example_proto SRCS example.proto)

No undefined problem and no dependency problem! Great work!
Just remind here that what kind of including path we want. If we want to use #include "paddle/framework/example.pb.h", we may need to change CMAKE_CURRENT_BINARY_DIR to CMAKE_BINARY_DIR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!

@reyoung reyoung merged commit c8e56d3 into PaddlePaddle:develop Jun 29, 2017
@reyoung reyoung deleted the feature/protobuf_lib branch July 13, 2017 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants