diff --git a/Makefile b/Makefile index 1e224265..f298e6cc 100644 --- a/Makefile +++ b/Makefile @@ -256,7 +256,7 @@ install-java8-if-missing: @sudo apt install -y openjdk-8-jre install-build-dependencies: update-apt-cache-if-needed - @sudo apt-get install -y libssl1.1 libuv1-dev libkrb5-dev libc6-dbg + @sudo apt-get install -y libssl1.1 libssl-dev libuv1-dev libkrb5-dev libc6-dbg # Alias for backward compatibility install-bin-dependencies: install-build-dependencies diff --git a/cmake/CMakeCargo.cmake b/cmake/CMakeCargo.cmake index 7278f25b..7d9f93e6 100644 --- a/cmake/CMakeCargo.cmake +++ b/cmake/CMakeCargo.cmake @@ -115,9 +115,10 @@ # __target — custom target driving the cargo build # # The caller controls Rust compiler flags via CMAKE_Rust_FLAGS (passed as -# RUSTFLAGS) and the build profile via CMAKE_BUILD_TYPE. +# RUSTFLAGS) and the build profile via CMAKE_BUILD_TYPE. Additional +# environment variables for the cargo process can be passed via ENV. function(cargo_build) - cmake_parse_arguments(CARGO "" "NAME;CRATE_TYPE" "FEATURES" ${ARGN}) + cmake_parse_arguments(CARGO "" "NAME;CRATE_TYPE" "FEATURES;ENV" ${ARGN}) string(REPLACE "-" "_" LIB_NAME ${CARGO_NAME}) if(NOT CARGO_CRATE_TYPE) @@ -236,7 +237,10 @@ function(cargo_build) ) # Set CARGO_TARGET_DIR and RUSTFLAGS in the cargo process environment. - set(CARGO_ENV_COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CARGO_TARGET_DIR}" "RUSTFLAGS=${CMAKE_Rust_FLAGS}") + set(CARGO_ENV_COMMAND ${CMAKE_COMMAND} -E env + "CARGO_TARGET_DIR=${CARGO_TARGET_DIR}" + "RUSTFLAGS=${CMAKE_Rust_FLAGS}" + ${CARGO_ENV}) add_custom_command( OUTPUT ${LIB_OUTPUTS} diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 903c68d0..36f36bdc 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -103,6 +103,9 @@ if(CASS_USE_OPENSSL) message(STATUS "${OPENSSL_NAME} version: v${OPENSSL_VERSION}") endif() + # Derive OPENSSL_LIB_DIR for passing to openssl-sys via environment. + get_filename_component(OPENSSL_LIB_DIR "${OPENSSL_SSL_LIBRARY}" DIRECTORY) + set(CASS_INCLUDES ${CASS_INCLUDES} ${OPENSSL_INCLUDE_DIR}) set(CASS_LIBS ${CASS_LIBS} ${OPENSSL_LIBRARIES}) endif() diff --git a/scylla-rust-wrapper/CMakeLists.txt b/scylla-rust-wrapper/CMakeLists.txt index 1385c798..58251a02 100644 --- a/scylla-rust-wrapper/CMakeLists.txt +++ b/scylla-rust-wrapper/CMakeLists.txt @@ -57,7 +57,9 @@ else() set(CMAKE_Rust_FLAGS "${CMAKE_Rust_FLAGS_SONAME}") endif() if(CASS_BUILD_SHARED) - cargo_build(NAME scylla_cpp_driver CRATE_TYPE cdylib) + cargo_build(NAME scylla_cpp_driver CRATE_TYPE cdylib + ENV "OPENSSL_LIB_DIR=${OPENSSL_LIB_DIR}" + "OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}") create_copy($ ${INSTALL_NAME_SHARED}) add_library(scylla-cpp-driver SHARED IMPORTED GLOBAL) add_dependencies(scylla-cpp-driver ${INSTALL_NAME_SHARED}_copy) @@ -75,12 +77,22 @@ if(CASS_BUILD_SHARED) endif() endif() if(CASS_BUILD_STATIC) - cargo_build(NAME scylla_cpp_driver CRATE_TYPE staticlib) + cargo_build(NAME scylla_cpp_driver CRATE_TYPE staticlib + ENV "OPENSSL_STATIC=1" + "OPENSSL_LIB_DIR=${OPENSSL_LIB_DIR}" + "OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}") create_copy($ ${INSTALL_NAME_STATIC}) add_library(scylla-cpp-driver_static STATIC IMPORTED GLOBAL) add_dependencies(scylla-cpp-driver_static ${INSTALL_NAME_STATIC}_copy) set_target_properties(scylla-cpp-driver_static PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/${INSTALL_NAME_STATIC}) endif() +# When both builds share CARGO_TARGET_DIR, they must not run concurrently: +# they pass different OPENSSL_STATIC values, which causes openssl-sys's build +# script to re-run (due to rerun-if-env-changed). Concurrent cargo invocations +# with different env fingerprints would thrash the shared build script cache. +if(CASS_BUILD_SHARED AND CASS_BUILD_STATIC) + add_dependencies(scylla_cpp_driver_staticlib_target scylla_cpp_driver_cdylib_target) +endif() #------------------------------------- # Installation @@ -188,6 +200,17 @@ if(CASS_BUILD_STATIC) # Static library pkg-config file goes to dev package if(CASS_INSTALL_PKG_CONFIG) if(PKG_CONFIG_FOUND) + # System libraries needed when linking the static Rust archive. + # Ideally these would come from `cargo rustc -- --print native-static-libs`, + # but that flag is nightly-only. These are hardcoded approximations that + # may need updating if dependencies or Rust versions change. + if(APPLE) + set(native_static_libs "-lm -lpthread -ldl -framework Security -framework CoreFoundation") + elseif(WIN32) + set(native_static_libs "-lws2_32 -lbcrypt -luserenv -lntdll") + else() + set(native_static_libs "-lm -lpthread -ldl -lrt") + endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scylla-cpp-driver_static.pc.in" "scylla-cpp-driver_static.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/scylla-cpp-driver_static.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" diff --git a/scylla-rust-wrapper/scylla-cpp-driver_static.pc.in b/scylla-rust-wrapper/scylla-cpp-driver_static.pc.in index 6c5b6f31..23dfc8e9 100644 --- a/scylla-rust-wrapper/scylla-cpp-driver_static.pc.in +++ b/scylla-rust-wrapper/scylla-cpp-driver_static.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: scylla-cpp-rs-driver Description: ScyllaDB CPP RS Driver Version: @version@ -Requires: openssl -Libs: -L${libdir} -lscylla-cpp-driver_static +Requires.private: openssl +Libs: -L${libdir} -lscylla-cpp-driver_static @native_static_libs@ Cflags: -I${includedir} URL: https://github.com/scylladb/cpp-rs-driver/