diff --git a/CMakeLists.txt b/CMakeLists.txt index ec4fc25443..d717ef717a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,8 @@ else () endif () option (jemalloc "Enables jemalloc for heap profiling" OFF) option (werr "treat warnings as errors" OFF) +option (local_protobuf + "Force use of a local build of protobuf instead of system version." OFF) # this one is a string and therefore can't be an option set (san "" CACHE STRING "On gcc & clang, add sanitizer instrumentation") @@ -612,10 +614,11 @@ set_target_properties(OpenSSL::SSL PROPERTIES build option #]=========================================================] find_package (ZLIB) +set (has_zlib FALSE) if (TARGET ZLIB::ZLIB) - #target_link_libraries (OpenSSL::Crypto INTERFACE ZLIB::ZLIB) set_target_properties(OpenSSL::Crypto PROPERTIES INTERFACE_LINK_LIBRARIES ZLIB::ZLIB) + set (has_zlib TRUE) endif () #[===================================================================[ @@ -924,13 +927,13 @@ set(sqlite_BINARY_DIR ${BINARY_DIR}) NIH dep: soci #]===================================================================] -set (lib_pre ${ep_lib_prefix}) -set (lib_post "") +set (soci_lib_pre ${ep_lib_prefix}) +set (soci_lib_post "") if (WIN32) # for some reason soci on windows still prepends lib (non-standard) - set (lib_pre lib) + set (soci_lib_pre lib) # this version in the name might change if/when we change versions of soci - set (lib_post "_4_0") + set (soci_lib_post "_4_0") endif () ExternalProject_Add (soci PREFIX ${nih_cache_path} @@ -993,21 +996,21 @@ ExternalProject_Add (soci $<$: COMMAND ${CMAKE_COMMAND} -E copy - /lib/$/${lib_pre}soci_core${lib_post}$<$:_d>${ep_lib_suffix} - /lib/$/${lib_pre}soci_empty${lib_post}$<$:_d>${ep_lib_suffix} - /lib/$/${lib_pre}soci_sqlite3${lib_post}$<$:_d>${ep_lib_suffix} + /lib/$/${soci_lib_pre}soci_core${soci_lib_post}$<$:_d>${ep_lib_suffix} + /lib/$/${soci_lib_pre}soci_empty${soci_lib_post}$<$:_d>${ep_lib_suffix} + /lib/$/${soci_lib_pre}soci_sqlite3${soci_lib_post}$<$:_d>${ep_lib_suffix} /lib > TEST_COMMAND "" INSTALL_COMMAND "" DEPENDS sqlite3 BUILD_BYPRODUCTS - /lib/${lib_pre}soci_core${lib_post}${ep_lib_suffix} - /lib/${lib_pre}soci_core${lib_post}_d${ep_lib_suffix} - /lib/${lib_pre}soci_empty${lib_post}${ep_lib_suffix} - /lib/${lib_pre}soci_empty${lib_post}_d${ep_lib_suffix} - /lib/${lib_pre}soci_sqlite3${lib_post}${ep_lib_suffix} - /lib/${lib_pre}soci_sqlite3${lib_post}_d${ep_lib_suffix} + /lib/${soci_lib_pre}soci_core${soci_lib_post}${ep_lib_suffix} + /lib/${soci_lib_pre}soci_core${soci_lib_post}_d${ep_lib_suffix} + /lib/${soci_lib_pre}soci_empty${soci_lib_post}${ep_lib_suffix} + /lib/${soci_lib_pre}soci_empty${soci_lib_post}_d${ep_lib_suffix} + /lib/${soci_lib_pre}soci_sqlite3${soci_lib_post}${ep_lib_suffix} + /lib/${soci_lib_pre}soci_sqlite3${soci_lib_post}_d${ep_lib_suffix} ) ExternalProject_Get_Property (soci BINARY_DIR) ExternalProject_Get_Property (soci SOURCE_DIR) @@ -1020,9 +1023,9 @@ foreach (_comp core empty sqlite3) add_library ("soci_${_comp}" STATIC IMPORTED GLOBAL) set_target_properties ("soci_${_comp}" PROPERTIES IMPORTED_LOCATION_DEBUG - ${BINARY_DIR}/lib/${lib_pre}soci_${_comp}${lib_post}_d${ep_lib_suffix} + ${BINARY_DIR}/lib/${soci_lib_pre}soci_${_comp}${soci_lib_post}_d${ep_lib_suffix} IMPORTED_LOCATION_RELEASE - ${BINARY_DIR}/lib/${lib_pre}soci_${_comp}${lib_post}${ep_lib_suffix} + ${BINARY_DIR}/lib/${soci_lib_pre}soci_${_comp}${soci_lib_post}${ep_lib_suffix} INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include;${BINARY_DIR}/include") add_dependencies ("soci_${_comp}" soci) # something has to depend on the ExternalProject to trigger it @@ -1189,35 +1192,103 @@ target_link_libraries (ripple_libs INTERFACE NIH::nudb) #[===================================================================[ import protobuf (lib and compiler) and create a lib - from our proto message definitions. There is fallback - logic for windows that builds some version of the protobuf - core library from source and downloads the protoc compiler - if needed + from our proto message definitions. If the system protobuf + is not found, fallback on EP to download and build a version + from official source. #]===================================================================] if (static) set (Protobuf_USE_STATIC_LIBS ON) endif () find_package (Protobuf) -if (MSVC AND NOT TARGET protobuf::protoc) - find_program (my_protoc NAMES protoc) - if (NOT my_protoc) - message (WARNING "No protoc found -- downloading now") - file (DOWNLOAD - "https://ripple.github.io/Downloads/protoc/2.5.1/protoc.exe" - ${CMAKE_BINARY_DIR}/tools/protoc.exe - STATUS status - TIMEOUT 30) - list (GET status 0 status_code) - list (GET status 1 status_string) - if (NOT status_code EQUAL 0) - message (FATAL_ERROR "Failed to download protoc: ${status_string}") - endif () - set (my_protoc ${CMAKE_BINARY_DIR}/tools/protoc.exe) +if (local_protobuf OR NOT TARGET protobuf::libprotobuf) + message (STATUS "using local protobuf build.") + if (WIN32) + # protobuf prepends lib even on windows + set (pbuf_lib_pre "lib") + else () + set (pbuf_lib_pre ${ep_lib_prefix}) + endif () + # for the external project build of protobuf, we currently ignore the + # static option and always build static libs here. This is consistent + # with our other EP builds. Dynamic libs in an EP would add complexity + # because we'd need to get them into the runtime path, and probably + # install them. + ExternalProject_Add (protobuf_src + PREFIX ${nih_cache_path} + GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git + GIT_TAG v3.6.1 + SOURCE_SUBDIR cmake + CMAKE_ARGS + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -Dprotobuf_BUILD_TESTS=OFF + -Dprotobuf_BUILD_EXAMPLES=OFF + -Dprotobuf_BUILD_PROTOC_BINARIES=ON + -Dprotobuf_MSVC_STATIC_RUNTIME=ON + -DBUILD_SHARED_LIBS=OFF + -Dprotobuf_BUILD_SHARED_LIBS=OFF + -DCMAKE_DEBUG_POSTFIX=_d + -Dprotobuf_DEBUG_POSTFIX=_d + -Dprotobuf_WITH_ZLIB=$,ON,OFF> + $<$:-DCMAKE_VERBOSE_MAKEFILE=ON> + $<$>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}> + $<$: + "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP" + > + LOG_BUILD ON + LOG_CONFIGURE ON + BUILD_COMMAND + ${CMAKE_COMMAND} + --build . + --config $ + $<$:--parallel$<$: ${num_procs}>> + $<$: + COMMAND + ${CMAKE_COMMAND} -E copy + /$/${pbuf_lib_pre}protobuf$<$:_d>${ep_lib_suffix} + + COMMAND + ${CMAKE_COMMAND} -E copy + /$/protoc${CMAKE_EXECUTABLE_SUFFIX} + + > + TEST_COMMAND "" + INSTALL_COMMAND "" + BUILD_BYPRODUCTS + /${pbuf_lib_pre}protobuf${ep_lib_suffix} + /${pbuf_lib_pre}protobuf_d${ep_lib_suffix} + /protoc${CMAKE_EXECUTABLE_SUFFIX} + ) + ExternalProject_Get_Property (protobuf_src BINARY_DIR) + ExternalProject_Get_Property (protobuf_src SOURCE_DIR) + ExternalProject_Get_Property (protobuf_src STAMP_DIR) + if (CMAKE_VERBOSE_MAKEFILE) + print_ep_logs (protobuf_src) + endif () + + if (NOT TARGET protobuf::libprotobuf) + add_library (protobuf::libprotobuf STATIC IMPORTED GLOBAL) + endif () + file (MAKE_DIRECTORY ${SOURCE_DIR}/src) + set_target_properties (protobuf::libprotobuf PROPERTIES + IMPORTED_LOCATION_DEBUG + ${BINARY_DIR}/${pbuf_lib_pre}protobuf_d${ep_lib_suffix} + IMPORTED_LOCATION_RELEASE + ${BINARY_DIR}/${pbuf_lib_pre}protobuf${ep_lib_suffix} + INTERFACE_INCLUDE_DIRECTORIES + ${SOURCE_DIR}/src) + add_dependencies (protobuf::libprotobuf protobuf_src) + exclude_if_included (protobuf_src) + exclude_if_included (protobuf::libprotobuf) + + if (NOT TARGET protobuf::protoc) + add_executable (protobuf::protoc IMPORTED) + exclude_if_included (protobuf::protoc) endif () - add_executable (protobuf::protoc IMPORTED) set_target_properties (protobuf::protoc PROPERTIES - IMPORTED_LOCATION "${my_protoc}") + IMPORTED_LOCATION "${BINARY_DIR}/protoc${CMAKE_EXECUTABLE_SUFFIX}") + add_dependencies (protobuf::protoc protobuf_src) endif () file (MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen) @@ -1230,46 +1301,16 @@ protobuf_generate_cpp ( set (CMAKE_CURRENT_BINARY_DIR ${save_CBD}) add_library (pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS}) -if ((NOT TARGET protobuf::libprotobuf) AND (NOT Protobuf_LIBRARIES)) - message (STATUS "protobuf lib not found - adding unity source for lib") - target_sources (pbufs PRIVATE src/ripple/unity/protobuf.cpp) - target_include_directories (pbufs - PUBLIC - src/protobuf/src - src/protobuf/vsprojects - src/ripple/proto) - target_compile_definitions (pbufs - PRIVATE - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS) -endif () + target_include_directories (pbufs PRIVATE src) target_include_directories (pbufs - SYSTEM PUBLIC - ${CMAKE_BINARY_DIR}/proto_gen) -if (NOT MSVC) - if (TARGET protobuf::libprotobuf) - target_link_libraries (pbufs protobuf::libprotobuf) - else () - target_link_libraries (pbufs ${Protobuf_LIBRARIES}) - target_include_directories (pbufs PUBLIC ${Protobuf_INCLUDE_DIR}) - endif () -endif () + SYSTEM PUBLIC ${CMAKE_BINARY_DIR}/proto_gen) +target_link_libraries (pbufs protobuf::libprotobuf) target_compile_options (pbufs PUBLIC $<$: --system-header-prefix="google/protobuf" -Wno-deprecated-dynamic-exception-spec - > - $<$: - -wd4251 - -wd4146 - > - PRIVATE - $<$: - -wd4018 - -wd4244 - -wd4800 - -wd4996 >) add_library (Ripple::pbufs ALIAS pbufs) target_link_libraries (ripple_libs INTERFACE Ripple::pbufs)