diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eb1933add..48d5bfe3a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,7 @@ option(QUIC_USE_SYSTEM_LIBCRYPTO "Use system libcrypto if quictls TLS" OFF) option(QUIC_USE_EXTERNAL_OPENSSL "Use external OpenSSL instead of building from submodules" OFF) set(QUIC_OPENSSL_INCLUDE_DIR "" CACHE PATH "Path to OpenSSL include directory") set(QUIC_OPENSSL_LIB_DIR "" CACHE PATH "Path to OpenSSL library directory") +set(QUIC_OPENSSL_ROOT_DIR "" CACHE PATH "Path to OpenSSL Root directory") option(QUIC_HIGH_RES_TIMERS "Configure the system to use high resolution timers" OFF) option(QUIC_OFFICIAL_RELEASE "Configured the build for an official release" OFF) set(QUIC_FOLDER_PREFIX "" CACHE STRING "Optional prefix for source group folders when using an IDE generator") @@ -763,20 +764,28 @@ if(QUIC_TLS_LIB STREQUAL "quictls" OR QUIC_TLS_LIB STREQUAL "openssl") add_library(OpenSSL INTERFACE) # OpenSSL versions before 3.5.0 do not expose these APIs. - if(QUIC_TLS_LIB STREQUAL "quictls" AND (QUIC_USE_EXTERNAL_OPENSSL OR QUIC_OPENSSL_INCLUDE_DIR OR QUIC_OPENSSL_LIB_DIR)) + if(QUIC_TLS_LIB STREQUAL "quictls" AND (QUIC_USE_EXTERNAL_OPENSSL OR QUIC_OPENSSL_INCLUDE_DIR OR QUIC_OPENSSL_LIB_DIR OR QUIC_OPENSSL_ROOT_DIR)) message(FATAL_ERROR "Manual OpenSSL selection is not supported with the 'quictls'. 'quictls' must be built from submodules to ensure static linkage with required QUIC APIs. Use 'openssl' provider for external 3.5.0+ OpenSSL.") endif() # Only 'openssl' provider supports external selection for now - if(QUIC_TLS_LIB STREQUAL "openssl" AND (QUIC_USE_EXTERNAL_OPENSSL OR QUIC_OPENSSL_INCLUDE_DIR OR QUIC_OPENSSL_LIB_DIR)) + if(QUIC_TLS_LIB STREQUAL "openssl" AND (QUIC_USE_EXTERNAL_OPENSSL OR QUIC_OPENSSL_INCLUDE_DIR OR QUIC_OPENSSL_LIB_DIR OR QUIC_OPENSSL_ROOT_DIR)) add_library(OpenSSLQuic INTERFACE) if(QUIC_OPENSSL_INCLUDE_DIR AND QUIC_OPENSSL_LIB_DIR) target_include_directories(OpenSSLQuic INTERFACE ${QUIC_OPENSSL_INCLUDE_DIR}) - find_library(LIB_CRYPTO NAMES crypto libcrypto PATHS ${QUIC_OPENSSL_LIB_DIR} NO_DEFAULT_PATH) + if(BUILD_SHARED_LIBS) + find_library(LIB_CRYPTO NAMES crypto libcrypto PATHS ${QUIC_OPENSSL_LIB_DIR} NO_DEFAULT_PATH) + else() + find_library(LIB_CRYPTO NAMES "crypto${CMAKE_STATIC_LIBRARY_SUFFIX}" "libcrypto${CMAKE_STATIC_LIBRARY_SUFFIX}" PATHS ${QUIC_OPENSSL_LIB_DIR} NO_DEFAULT_PATH) + endif() if(NOT LIB_CRYPTO) message(FATAL_ERROR "libcrypto not found in ${QUIC_OPENSSL_LIB_DIR}") endif() - find_library(LIB_SSL NAMES ssl libssl PATHS ${QUIC_OPENSSL_LIB_DIR} NO_DEFAULT_PATH) + if(BUILD_SHARED_LIBS) + find_library(LIB_SSL NAMES ssl libssl PATHS ${QUIC_OPENSSL_LIB_DIR} NO_DEFAULT_PATH) + else() + find_library(LIB_SSL NAMES "ssl${CMAKE_STATIC_LIBRARY_SUFFIX}" "libssl${CMAKE_STATIC_LIBRARY_SUFFIX}" PATHS ${QUIC_OPENSSL_LIB_DIR} NO_DEFAULT_PATH) + endif() if(NOT LIB_SSL) message(FATAL_ERROR "libssl not found in ${QUIC_OPENSSL_LIB_DIR}") endif() @@ -784,8 +793,18 @@ if(QUIC_TLS_LIB STREQUAL "quictls" OR QUIC_TLS_LIB STREQUAL "openssl") elseif(QUIC_OPENSSL_INCLUDE_DIR OR QUIC_OPENSSL_LIB_DIR) message(FATAL_ERROR "Both QUIC_OPENSSL_INCLUDE_DIR and QUIC_OPENSSL_LIB_DIR must be set to select custom OpenSSL version.") else() + if(QUIC_OPENSSL_ROOT_DIR) + set(OPENSSL_ROOT_DIR "${QUIC_OPENSSL_ROOT_DIR}") + endif() + if(NOT BUILD_SHARED_LIBS) + set(OPENSSL_USE_STATIC_LIBS TRUE) + endif() find_package(OpenSSL 3.5.0 REQUIRED) - target_link_libraries(OpenSSLQuic INTERFACE OpenSSL::SSL OpenSSL::Crypto) + # OpenSSL::SSL and OpenSSL::Crypto imported targets include their dependencies such as zstd. + # However, these dependencies will be linked in src/platform/CMakeLists.txt, + # so link only the main OpenSSL targets here to avoid duplication. + target_include_directories(OpenSSLQuic INTERFACE ${OPENSSL_INCLUDE_DIR}) + target_link_libraries(OpenSSLQuic INTERFACE ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) endif() add_library(MsQuic::OpenSSL ALIAS OpenSSLQuic) else() diff --git a/Cargo.toml b/Cargo.toml index 70e5049b91..27a24b977d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,7 @@ find = [] # This feature enables quictls on windows, and has no effect on linux. # This feature enables openssl on windows, and has no effect on linux. openssl = [] +openssl_external = [] quictls = [] static = ["src"] preview-api = [] diff --git a/scripts/build.rs b/scripts/build.rs index 0cbb348619..7b7c8c573c 100644 --- a/scripts/build.rs +++ b/scripts/build.rs @@ -29,9 +29,11 @@ fn cmake_build() { let target = env::var("TARGET").unwrap().replace("\\", "/"); let out_dir = env::var("OUT_DIR").unwrap().replace("\\", "/"); // The output directory for the native MsQuic library. - let libdir = "/lib"; - let full_out_dir = [out_dir, libdir.to_string()].join(""); - let quic_output_dir = Path::new(&full_out_dir); + let quic_output_dir = if cfg!(windows) { + Path::new(&out_dir).join("lib") + } else { + Path::new(&out_dir).join("artifacts") + }; // Builds the native MsQuic and installs it into $OUT_DIR. let mut config = Config::new("."); @@ -50,6 +52,20 @@ fn cmake_build() { config.define("QUIC_TLS_LIB", "quictls"); } else if cfg!(feature = "openssl") { config.define("QUIC_TLS_LIB", "openssl"); + } else if cfg!(feature = "openssl_external") { + config + .define("QUIC_TLS_LIB", "openssl") + .define("QUIC_USE_EXTERNAL_OPENSSL", "on"); + if let Ok(openssl_dir) = std::env::var("OPENSSL_ROOT_DIR") { + config.define("QUIC_OPENSSL_ROOT_DIR", openssl_dir); + } else { + if let Ok(openssl_include_dir) = std::env::var("OPENSSL_INCLUDE_DIR") { + config.define("QUIC_OPENSSL_INCLUDE_DIR", openssl_include_dir); + } + if let Ok(openssl_lib_dir) = std::env::var("OPENSSL_LIB_DIR") { + config.define("QUIC_OPENSSL_LIB_DIR", openssl_lib_dir); + } + } } else if cfg!(windows) { config.define("QUIC_TLS_LIB", "schannel"); } else { diff --git a/src/rs/config.rs b/src/rs/config.rs index fb6e9fe463..9de830f4fc 100644 --- a/src/rs/config.rs +++ b/src/rs/config.rs @@ -476,7 +476,11 @@ mod tests { .unwrap_err() .try_as_status_code() .unwrap(); - if cfg!(windows) && !cfg!(feature = "openssl") && !cfg!(feature = "quictls") { + if cfg!(windows) + && !cfg!(feature = "openssl") + && !cfg!(feature = "openssl_external") + && !cfg!(feature = "quictls") + { // schannel does not support load from file. assert_eq!(load_err, StatusCode::QUIC_STATUS_NOT_SUPPORTED); } else {