From edf77cf270e3ff7c4a08cd85fcaf537b254f6273 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 9 Mar 2012 19:46:21 +0400 Subject: [PATCH 1/2] Link protobuf to dfhack core as a shared library. - Change protobuf libraries to build as DLLs. - Move some stream features to the lite library. - Install the lite library and use it from dfhack. Note that: - A couple of protobuf headers had to be tweaked. - The lite library is used because the full one is absolutely incompatible with reloading plugins. - Shutting down protobuf also can't be allowed. --- CMakeLists.txt | 4 ++ library/CMakeLists.txt | 2 +- library/depends/protobuf/CMakeLists.txt | 43 +++++++++++++++---- .../google/protobuf/generated_message_util.h | 2 +- .../protobuf/google/protobuf/stubs/common.h | 3 ++ plugins/mapexport/CMakeLists.txt | 14 +----- plugins/mapexport/mapexport.cpp | 1 - 7 files changed, 46 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a5ceb74a..0bf68dc11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,10 @@ ENDIF() #add depends to include path INCLUDE_DIRECTORIES ( library/depends ) +INCLUDE_DIRECTORIES ( library/depends/protobuf/ ) + +# use shared libraries for protobuf +ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS) # build the static lua for dfusion INCLUDE_DIRECTORIES ( lua/include ) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 94704beba..ca4c9d47f 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -196,7 +196,7 @@ endif() #effectively disables debug builds... SET_TARGET_PROPERTIES(dfhack PROPERTIES DEBUG_POSTFIX "-debug" ) -TARGET_LINK_LIBRARIES(dfhack ${PROJECT_LIBS}) +TARGET_LINK_LIBRARIES(dfhack protobuf-lite ${PROJECT_LIBS}) IF(UNIX) # On linux, copy our version of the df launch script which sets LD_PRELOAD diff --git a/library/depends/protobuf/CMakeLists.txt b/library/depends/protobuf/CMakeLists.txt index 46711b418..cdd85014f 100644 --- a/library/depends/protobuf/CMakeLists.txt +++ b/library/depends/protobuf/CMakeLists.txt @@ -91,6 +91,8 @@ google/protobuf/wire_format_lite.h google/protobuf/wire_format_lite_inl.h google/protobuf/io/zero_copy_stream.h google/protobuf/io/zero_copy_stream_impl_lite.h +google/protobuf/io/gzip_stream.h +google/protobuf/io/zero_copy_stream_impl.h ) SET(LIBPROTOBUF_FULL_HDRS @@ -99,7 +101,6 @@ google/protobuf/descriptor.pb.h google/protobuf/descriptor_database.h google/protobuf/dynamic_message.h google/protobuf/generated_message_reflection.h -google/protobuf/io/gzip_stream.h google/protobuf/compiler/importer.h google/protobuf/message.h google/protobuf/compiler/parser.h @@ -112,7 +113,6 @@ google/protobuf/text_format.h google/protobuf/io/tokenizer.h google/protobuf/unknown_field_set.h google/protobuf/wire_format.h -google/protobuf/io/zero_copy_stream_impl.h ) LIST(APPEND LIBPROTOBUF_FULL_HDRS ${LIBPROTOBUF_LITE_HDRS}) @@ -128,6 +128,8 @@ google/protobuf/repeated_field.cc google/protobuf/wire_format_lite.cc google/protobuf/io/zero_copy_stream.cc google/protobuf/io/zero_copy_stream_impl_lite.cc +google/protobuf/io/gzip_stream.cc +google/protobuf/io/zero_copy_stream_impl.cc ) SET(LIBPROTOBUF_FULL_SRCS @@ -137,7 +139,6 @@ google/protobuf/descriptor_database.cc google/protobuf/dynamic_message.cc google/protobuf/extension_set_heavy.cc google/protobuf/generated_message_reflection.cc -google/protobuf/io/gzip_stream.cc google/protobuf/compiler/importer.cc google/protobuf/message.cc google/protobuf/compiler/parser.cc @@ -151,7 +152,6 @@ google/protobuf/text_format.cc google/protobuf/io/tokenizer.cc google/protobuf/unknown_field_set.cc google/protobuf/wire_format.cc -google/protobuf/io/zero_copy_stream_impl.cc ) SET(LIBPROTOC_HDRS @@ -201,9 +201,36 @@ LIST(APPEND LIBPROTOBUF_FULL_SRCS ${LIBPROTOBUF_LITE_SRCS}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${dfhack_SOURCE_DIR}/library/depends/zlib) -ADD_LIBRARY(protobuf-lite ${LIBPROTOBUF_LITE_SRCS} ${LIBPROTOBUF_LITE_HDRS}) -ADD_LIBRARY(protobuf ${LIBPROTOBUF_FULL_SRCS} ${LIBPROTOBUF_FULL_HDRS}) -ADD_LIBRARY(protoc ${LIBPROTOC_SRCS} ${LIBPROTOC_HDRS}) +# Protobuf shared libraries + +ADD_LIBRARY(protobuf SHARED ${LIBPROTOBUF_FULL_SRCS} ${LIBPROTOBUF_FULL_HDRS}) +ADD_LIBRARY(protobuf-lite SHARED ${LIBPROTOBUF_LITE_SRCS} ${LIBPROTOBUF_LITE_HDRS}) + +SET_TARGET_PROPERTIES(protobuf PROPERTIES COMPILE_DEFINITIONS LIBPROTOBUF_EXPORTS) +SET_TARGET_PROPERTIES(protobuf-lite PROPERTIES COMPILE_DEFINITIONS LIBPROTOBUF_EXPORTS) + +IF(WIN32) + TARGET_LINK_LIBRARIES(protobuf ${CMAKE_THREAD_LIBS_INIT} zlib) + TARGET_LINK_LIBRARIES(protobuf-lite ${CMAKE_THREAD_LIBS_INIT} zlib) +ELSE() + TARGET_LINK_LIBRARIES(protobuf ${CMAKE_THREAD_LIBS_INIT} z) + TARGET_LINK_LIBRARIES(protobuf-lite ${CMAKE_THREAD_LIBS_INIT} z) +ENDIF() + +install(TARGETS protobuf-lite + LIBRARY DESTINATION ${DFHACK_LIBRARY_DESTINATION}/deplibs + RUNTIME DESTINATION ${DFHACK_LIBRARY_DESTINATION}/deplibs) + +# Protobuf compiler shared library + +ADD_LIBRARY(protoc SHARED ${LIBPROTOC_SRCS} ${LIBPROTOC_HDRS}) + +SET_TARGET_PROPERTIES(protoc PROPERTIES COMPILE_DEFINITIONS LIBPROTOC_EXPORTS) +TARGET_LINK_LIBRARIES(protoc protobuf) + +# Protobuf compiler executable + ADD_EXECUTABLE(protoc-bin google/protobuf/compiler/main.cc google/protobuf/compiler/command_line_interface.h google/protobuf/compiler/cpp/cpp_generator.h) + SET_TARGET_PROPERTIES(protoc-bin PROPERTIES OUTPUT_NAME protoc) -TARGET_LINK_LIBRARIES(protoc-bin protoc protobuf ${CMAKE_THREAD_LIBS_INIT}) +TARGET_LINK_LIBRARIES(protoc-bin protoc) diff --git a/library/depends/protobuf/google/protobuf/generated_message_util.h b/library/depends/protobuf/google/protobuf/generated_message_util.h index 1a2343d44..239daea59 100644 --- a/library/depends/protobuf/google/protobuf/generated_message_util.h +++ b/library/depends/protobuf/google/protobuf/generated_message_util.h @@ -72,7 +72,7 @@ double Infinity(); double NaN(); // Constant used for empty default strings. -extern const ::std::string kEmptyString; +extern LIBPROTOBUF_EXPORT const ::std::string kEmptyString; } // namespace internal diff --git a/library/depends/protobuf/google/protobuf/stubs/common.h b/library/depends/protobuf/google/protobuf/stubs/common.h index 7173a84d1..832973574 100644 --- a/library/depends/protobuf/google/protobuf/stubs/common.h +++ b/library/depends/protobuf/google/protobuf/stubs/common.h @@ -96,6 +96,9 @@ namespace protobuf { #else #define LIBPROTOC_EXPORT __declspec(dllimport) #endif +#elif defined(PROTOBUF_USE_DLLS) + #define LIBPROTOBUF_EXPORT __attribute__ ((visibility("default"))) + #define LIBPROTOC_EXPORT __attribute__ ((visibility("default"))) #else #define LIBPROTOBUF_EXPORT #define LIBPROTOC_EXPORT diff --git a/plugins/mapexport/CMakeLists.txt b/plugins/mapexport/CMakeLists.txt index d3ff25857..bebdd08ee 100644 --- a/plugins/mapexport/CMakeLists.txt +++ b/plugins/mapexport/CMakeLists.txt @@ -1,15 +1,5 @@ PROJECT(mapexport) -INCLUDE_DIRECTORIES ( - ${CMAKE_CURRENT_SOURCE_DIR} - ${dfhack_SOURCE_DIR}/library/depends/protobuf/ - ${dfhack_SOURCE_DIR}/library/depends/zlib/ -) - -LINK_DIRECTORIES( - ${dfhack_SOURCE_DIR}/library/depends/zlib/ -) - #The protobuf sources we generate will require these headers SET(PROJECT_HDRS ${dfhack_SOURCE_DIR}/library/depends/protobuf/google/protobuf/stubs/once.h @@ -51,7 +41,7 @@ DEPENDS protoc-bin ${PROJECT_PROTOS} ) IF(WIN32) - DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf zlib) + DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf-lite) ELSE() - DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf z) + DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf-lite) ENDIF() diff --git a/plugins/mapexport/mapexport.cpp b/plugins/mapexport/mapexport.cpp index 2e5197718..ea7b8894c 100644 --- a/plugins/mapexport/mapexport.cpp +++ b/plugins/mapexport/mapexport.cpp @@ -37,7 +37,6 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector DFhackCExport command_result plugin_shutdown ( Core * c ) { - google::protobuf::ShutdownProtobufLibrary(); return CR_OK; } From 75c569b09773c0d7644d54fd77350e6ff1073475 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 9 Mar 2012 21:42:22 +0400 Subject: [PATCH 2/2] Add some experimental message definitions to the main library. --- library/CMakeLists.txt | 26 ++++++++++++++ library/proto/.gitignore | 2 ++ library/proto/CoreProtocol.proto | 59 ++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 library/proto/.gitignore create mode 100644 library/proto/CoreProtocol.proto diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index ca4c9d47f..e310268a7 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -141,6 +141,26 @@ ELSE() LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS}) ENDIF() +# Protobuf + +FILE(GLOB PROJECT_PROTOS ${CMAKE_CURRENT_SOURCE_DIR}/proto/*.proto) + +STRING(REPLACE ".proto" ".pb.cc" PROJECT_PROTO_SRCS ${PROJECT_PROTOS}) +STRING(REPLACE ".proto" ".pb.h" PROJECT_PROTO_HDRS ${PROJECT_PROTOS}) + +LIST(APPEND PROJECT_HDRS ${PROJECT_PROTO_HDRS}) +LIST(APPEND PROJECT_SRCS ${PROJECT_PROTO_SRCS}) + +ADD_CUSTOM_COMMAND( + OUTPUT ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS} + COMMAND protoc-bin -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ + --cpp_out=dllexport_decl=DFHACK_EXPORT:${CMAKE_CURRENT_SOURCE_DIR}/proto/ + ${PROJECT_PROTOS} + DEPENDS protoc-bin ${PROJECT_PROTOS} +) + +# + SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE ) LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) @@ -193,6 +213,12 @@ else() ENDIF() endif() +IF(WIN32) + SET_TARGET_PROPERTIES(dfhack PROPERTIES COMPILE_FLAGS "/FI\"Export.h\"" ) +ELSE() + SET_TARGET_PROPERTIES(dfhack PROPERTIES COMPILE_FLAGS "-include Export.h" ) +ENDIF() + #effectively disables debug builds... SET_TARGET_PROPERTIES(dfhack PROPERTIES DEBUG_POSTFIX "-debug" ) diff --git a/library/proto/.gitignore b/library/proto/.gitignore new file mode 100644 index 000000000..a1fb10cce --- /dev/null +++ b/library/proto/.gitignore @@ -0,0 +1,2 @@ +*.pb.cc +*.pb.h diff --git a/library/proto/CoreProtocol.proto b/library/proto/CoreProtocol.proto new file mode 100644 index 000000000..33ec0f4a0 --- /dev/null +++ b/library/proto/CoreProtocol.proto @@ -0,0 +1,59 @@ +package dfproto; + +option optimize_for = LITE_RUNTIME; + +message CoreTextFragment { + required string text = 1; + + enum Color { + COLOR_BLACK = 0; + COLOR_BLUE = 1; + COLOR_GREEN = 2; + COLOR_CYAN = 3; + COLOR_RED = 4; + COLOR_MAGENTA = 5; + COLOR_BROWN = 6; + COLOR_GREY = 7; + COLOR_DARKGREY = 8; + COLOR_LIGHTBLUE = 9; + COLOR_LIGHTGREEN = 10; + COLOR_LIGHTCYAN = 11; + COLOR_LIGHTRED = 12; + COLOR_LIGHTMAGENTA = 13; + COLOR_YELLOW = 14; + COLOR_WHITE = 15; + }; + optional Color color = 2; +} + +message CoreTextNotification { + repeated CoreTextFragment fragments = 1; +} + +message CoreErrorNotification { + enum ErrorCode { + CR_WOULD_BREAK = -2; + CR_NOT_IMPLEMENTED = -1; + CR_FAILURE = 0; + CR_OK = 1; + CR_WRONG_USAGE = 2; + }; + + required ErrorCode code = 1; +} + +message CoreBindRequest { + required string method = 1; + optional string plugin = 2; + optional int32 min_version = 3; +} + +message CoreBindReply { + required int32 assigned_id = 1; + required int32 version = 2; +} + +message CoreRunStringRequest { + required string command = 1; + repeated string arguments = 2; +}