From 0248e2053140b5291cf6d67f825655b55e013215 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Mon, 26 Oct 2020 17:40:40 -0500 Subject: [PATCH] Add option to compile dynamic libraries Also, fix build: Clang 10.0.1 has incompatible rules with other compilers on whether you must/cannot put the `template` keyword in part of the reflection code. Add a special case to make it work all around. --- CMakeLists.txt | 38 +++++++++++++++++++++++++------ include/fc/network/tcp_socket.hpp | 2 +- include/fc/reflect/reflect.hpp | 12 ++++++++-- include/fc/reflect/typelist.hpp | 4 ++-- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b953d1..8f7f786 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ PROJECT( fc ) set( CMAKE_CXX_STANDARD 14 ) SET( CMAKE_CXX_STANDARD_REQUIRED ON ) +set( FC_BUILD_DYNAMIC_LIBRARIES OFF CACHE BOOL "Whether FC should build as a dynamic library rather than static" ) + if( "${CMAKE_CXX_COMPILER_ID}" MATCHES "^(Apple)?Clang|GNU$" ) set( CMAKE_CXX_EXTENSIONS ON ) # for __int128 support else( "${CMAKE_CXX_COMPILER_ID}" MATCHES "^(Apple)?Clang|GNU$" ) @@ -41,7 +43,11 @@ endif() SET(BOOST_COMPONENTS) LIST(APPEND BOOST_COMPONENTS coroutine thread date_time filesystem system program_options serialization chrono unit_test_framework context iostreams regex) # boost::endian is also required, but FindBoost can't handle header-only libs -SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) +if(${FC_BUILD_DYNAMIC_LIBRARIES}) + SET( Boost_USE_STATIC_LIBS OFF CACHE STRING "ON or OFF" ) +else() + SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) +endif() # Configure secp256k1-zkp if ( WIN32 ) @@ -63,10 +69,16 @@ if ( WIN32 ) else ( WIN32 ) include(ExternalProject) + if( CMAKE_POSITION_INDEPENDENT_CODE ) + set( SECP_USE_PIC --with-pic ) + else( CMAKE_POSITION_INDEPENDENT_CODE ) + set( SECP_USE_PIC "" ) + endif() + ExternalProject_Add( project_secp256k1 PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp --with-bignum=no + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp --with-bignum=no ${SECP_USE_PIC} BUILD_COMMAND make INSTALL_COMMAND true BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp/src/project_secp256k1-build/.libs/libsecp256k1.a @@ -84,7 +96,10 @@ else ( WIN32 ) set_property(TARGET secp256k1 PROPERTY IMPORTED_LOCATION ${binary_dir}/.libs/libsecp256k1${CMAKE_STATIC_LIBRARY_SUFFIX}) set_property(TARGET secp256k1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/include) add_dependencies(secp256k1 project_secp256k1) - install( FILES ${binary_dir}/.libs/libsecp256k1${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib/cryptonomex ) + if (${FC_BUILD_DYNAMIC_LIBRARIES}) + FILE(GLOB SECP_SHARED ${binary_dir}/.libs/libsecp256k1.so*) + endif() + install( FILES ${binary_dir}/.libs/libsecp256k1${CMAKE_STATIC_LIBRARY_SUFFIX} ${SECP_SHARED} DESTINATION lib/cryptonomex ) endif ( WIN32 ) # End configure secp256k1-zkp @@ -95,7 +110,7 @@ if ( NOT WIN32 ) ExternalProject_Add( project_editline PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline CFLAGS=-fPIC BUILD_COMMAND make INSTALL_COMMAND true BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/src/.libs/libeditline.a @@ -111,7 +126,10 @@ if ( NOT WIN32 ) set_property(TARGET editline PROPERTY IMPORTED_LOCATION ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX}) set_property(TARGET editline PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/include) add_dependencies(editline project_editline) - install( FILES ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib/cryptonomex ) + if (${FC_BUILD_DYNAMIC_LIBRARIES}) + FILE(GLOB EDITLINE_SHARED ${binary_dir}/src/.libs/libeditline.so*) + endif() + install( FILES ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX} ${EDITLINE_SHARED} DESTINATION lib/cryptonomex ) endif ( NOT WIN32 ) # End configure editline @@ -240,7 +258,13 @@ list(APPEND sources ${fc_headers}) add_subdirectory( vendor/websocketpp EXCLUDE_FROM_ALL ) -add_library( fc ${sources} ) +if (NOT ${FC_BUILD_DYNAMIC_LIBRARIES} ) + add_library( fc ${sources} ) +else() + add_library( fc SHARED ${sources} ) +endif() + +install( TARGETS fc LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION include ) # begin editline stuff @@ -351,7 +375,7 @@ elseif(WIN32 AND MINGW) endif() -IF(Boost_UNIT_TEST_FRAMEWORK_LIBRARY MATCHES "\\.(so|dll)$") +IF(Boost_UNIT_TEST_FRAMEWORK_LIBRARY MATCHES "\\.(so|dll)$" OR FC_BUILD_DYNAMIC_LIBRARIES) IF(MSVC) add_definitions(/DBOOST_TEST_DYN_LINK) ELSE(MSVC) diff --git a/include/fc/network/tcp_socket.hpp b/include/fc/network/tcp_socket.hpp index 6e69f80..db677a7 100644 --- a/include/fc/network/tcp_socket.hpp +++ b/include/fc/network/tcp_socket.hpp @@ -55,7 +55,7 @@ namespace fc { #ifdef _WIN64 fc::fwd my; #else - fc::fwd my; + fc::fwd my; #endif }; typedef std::shared_ptr tcp_socket_ptr; diff --git a/include/fc/reflect/reflect.hpp b/include/fc/reflect/reflect.hpp index bf68d17..e47d629 100644 --- a/include/fc/reflect/reflect.hpp +++ b/include/fc/reflect/reflect.hpp @@ -110,12 +110,20 @@ struct Derivation_reflection_transformer { }; } // namespace impl +// Workaround to inconsistent compiler rules on whether template must/cannot be specified here +#if defined(__clang__) && __clang_major__ < 11 +#define MAYBE_TEMPLATE template +#else +#define MAYBE_TEMPLATE +#endif + /// Macro to transform reflected fields of a base class to a derived class and concatenate them to a type list #define FC_CONCAT_BASE_MEMBER_REFLECTIONS(r, derived, base) \ - ::add_list::members, impl::Derivation_reflection_transformer>> + ::add_list::members, \ + impl::Derivation_reflection_transformer>> /// Macro to concatenate a new @ref field_reflection to a typelist #define FC_CONCAT_MEMBER_REFLECTION(r, container, idx, member) \ - ::add::template with_field_type \ + ::MAYBE_TEMPLATE add::template with_field_type \ ::template at_index \ ::template with_field_pointer<&container::member>::type> #define FC_REFLECT_MEMBER_NAME(r, container, idx, member) \ diff --git a/include/fc/reflect/typelist.hpp b/include/fc/reflect/typelist.hpp index d1d3e0d..6b0f4a2 100644 --- a/include/fc/reflect/typelist.hpp +++ b/include/fc/reflect/typelist.hpp @@ -240,7 +240,7 @@ template struct wrapper { using type = T; }; */ template::value != 0>, typename Return = decltype(std::declval()(wrapper, 0>>()))> -Return dispatch(list, std::size_t index, Callable c) { +Return dispatch(list, uint64_t index, Callable c) { static std::function call_table[] = { impl::dispatch_helper>... }; if (index < impl::length::value) return call_table[index](c); @@ -249,7 +249,7 @@ Return dispatch(list, std::size_t index, Callable c) { template auto dispatch(List l, int64_t index, Callable c) { if (index < 0) throw std::out_of_range("Negative index to fc::typelist::runtime::dispatch()"); - return dispatch(l, std::size_t(index), std::move(c)); + return dispatch(l, std::uint64_t(index), std::move(c)); } /// @brief Invoke the provided callable with an argument wrapper() for each type in the list