-
Notifications
You must be signed in to change notification settings - Fork 380
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
Problems with generated protos and DLLs on Windows #5849
Comments
Well, I just realized this does not matter, gRPC does not seem to support DLLs, so we are blocked: grpc/grpc#937 |
I'm seeing this issue when trying to use protobuf libraries. Importing a proto definition from a shared library into another proto definition contained in shared library fails. |
I wish I could... I think I tested the ideas in https://groups.google.com/g/protobuf/c/PDR1bqRazts in a branch, and then discarded the branch during a spring cleaning, sorry. I am going to edit the comment because it is widly inaccurate now. |
gRPC does not support this and has no plans to support this at the moment. Closing. |
Status
Blocked by gRPC support. I (@coryan) prototyped this solution for the files generated by protoc. But there is no answer for gRPC.
Background
DLLs on Windows use a Windows specific extension to declare which symbols are exported from the library and which remain private to the library. The default is "private", and there is no way to change this default (well, more on this later). In contrast, Unix (and Linux) shared objects (aka dynamic libraries, aka shared libraries) export all symbols, though it is possible to hide specific symbols.
More often than not, these extensions are used through a pre-processor "export macro", which is defined to be
__declspec(dllimport)
when the library is used, and__declspec(dllexport)
when the library is compiled.CMake supports
CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
which exports (almost) all symbols. As the documentation statesProtobuf generates a number of these global data symbols that are used by proto libraries that depend on each other. For example,
google/api/label.proto
generates:and this is used in the code generated for
google/api/metric.proto
:If these two protos are in different DLLs, we have a problem, as the DLLs would then reference data symbols from each other.
Problem
We cannot generate DLLs with protos that reference each other.
Proposed Solution: Group the protos into a small number of DLLs
We would need to use the
dllexport_decl
option in the protoc compiler to generate protos with the right export macros:https://github.com/protocolbuffers/protobuf/blob/a1f96fffc7d062037c52bcb83e9e841d325eeaf8/src/google/protobuf/compiler/cpp/cpp_options.h#L54
Then we would use
-include
(for GCC and Clang) and/FI
(for MSVC) to force include headers that define these export macros. Note that these would be included by our libraries and by any users of our libraries.https://groups.google.com/g/protobuf/c/PDR1bqRazts
The headers would need to be maintained by hand, we can have CMake generate them:
https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html
Alternatives considered
Use a single DLL with all the protos
Would not help if the protos are not usable by application developers outside the DLL. Which they would be, as we exposed protos for the admin APIs (and will expose them even more for generated libraries).
Keep the current target -> library mapping.
We have a lot of single-proto libraries, it seems wasteful to force include a header for each one, and pollute the command-line with dozens of flags.
Appendix: sample error messages from linking DLLs with protos
The text was updated successfully, but these errors were encountered: