Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
build: [x86_64, i686, x86_64-musl, mingw, system-curl, x86_64-beta, x86_64-nightly, macos, win64, win32]
build: [x86_64, i686, x86_64-musl, mingw, system-curl, x86_64-beta, x86_64-nightly, macos, win64-static-ssl, win64, win32]
include:
- build: x86_64
os: ubuntu-latest
Expand Down Expand Up @@ -67,6 +67,11 @@ jobs:
os: windows-latest
rust: stable
target: x86_64-pc-windows-msvc
- build: win64-static-ssl
os: windows-latest
rust: stable
target: x86_64-pc-windows-msvc
static_ssl: windows
steps:
- uses: actions/checkout@v1
with:
Expand All @@ -75,7 +80,29 @@ jobs:
run: rustup update ${{ matrix.rust }} --no-self-update && rustup default ${{ matrix.rust }}
shell: bash
- run: rustup target add ${{ matrix.target }}
- run: TARGET=${{ matrix.target }} ./ci/run.sh
- name: Compute vcpkg cache entries
if: matrix.static_ssl == 'windows'
id: vcpkg-cache
shell: bash
run: |
echo "path=${{ runner.temp }}/vcpkg-cache" >> "$GITHUB_OUTPUT"
echo "key=vcpkg-${{ matrix.target }}-${{ hashFiles('vcpkg.json') }}-$ImageVersion" >> "$GITHUB_OUTPUT"
- name: Restore vcpkg binary cache (files backend)
if: matrix.static_ssl == 'windows'
uses: actions/cache@v5
with:
path: ${{ steps.vcpkg-cache.outputs.path }}
key: ${{ steps.vcpkg-cache.outputs.key }}
- name: Install vcpkg dependencies (for windows-static-ssl)
if: matrix.static_ssl == 'windows'
shell: bash
env:
VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite"
run: |
vcpkg install --triplet=x64-windows-static-md \
--x-install-root="$VCPKG_INSTALLATION_ROOT/installed"
echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> "$GITHUB_ENV"
- run: TARGET=${{ matrix.target }} STATIC_SSL=${{ matrix.static_ssl }} ./ci/run.sh
if: matrix.os != 'ubuntu-latest'
name: Run non-docker tests
shell: bash
Expand Down
16 changes: 15 additions & 1 deletion ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ if [ "$TARGET" = "x86_64-unknown-linux-musl" ]; then
features="--features static-ssl"
fi

# `windows-static-ssl` (curl + OpenSSL on Windows) needs vcpkg-installed
# OpenSSL and `VCPKG_ROOT` set for vcpkg-rs's discovery.
if [ "$STATIC_SSL" = "windows" ]; then
features="--features windows-static-ssl --no-default-features"
# Enable the Windows native CA store for the test suite so doctests that
# make HTTPS requests can verify server certificates. Not baked into
# build.rs to avoid forcing the default on library consumers.
export CFLAGS="-DCURL_CA_NATIVE"
fi

cargo test --target $TARGET --no-run $features
# First test with no extra protocols enabled.
cargo test --target $TARGET --no-run --features static-curl $features
Expand All @@ -28,7 +38,11 @@ cargo test --target $TARGET --no-run --features static-curl $features
# Compiling on i686-windows requires nasm to be installed (other platforms
# have pre-compiled object files), which is just slightly too much
# inconvenience for me.
if [ "$TARGET" != "x86_64-pc-windows-gnu" ] && [ "$TARGET" != "i686-pc-windows-msvc" ]
#
# Note also that rustls silently wins over windows-static-ssl in curl-sys's
# build.rs else-if, so we skip this on the win64-static-ssl entry and keep
# actually exercising windows-static-ssl in the tests below.
if [ "$TARGET" != "x86_64-pc-windows-gnu" ] && [ "$TARGET" != "i686-pc-windows-msvc" ] && [ "$STATIC_SSL" != "windows" ]
then
cargo test --target $TARGET --no-run --features rustls,static-curl $features
fi
Expand Down
58 changes: 47 additions & 11 deletions curl-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,17 +360,39 @@ fn main() {
if windows {
cfg.define("USE_OPENSSL", None)
.file("curl/lib/vtls/openssl.c");
// We need both openssl and zlib
// Those can be installed with
// ```shell
// git clone https://github.com/microsoft/vcpkg
// cd vcpkg
// ./bootstrap-vcpkg.bat -disableMetrics
// ./vcpkg.exe integrate install
// ./vcpkg.exe install openssl:x64-windows-static-md
// ```
#[cfg(target_env = "msvc")]
vcpkg::Config::new().find_package("openssl").ok();
// Probe `<TARGET>_OPENSSL_DIR` / `OPENSSL_DIR` before falling
// back to vcpkg. Matches openssl-sys's env-lookup convention so
// a single env var can point both `openssl-sys` and `curl-sys`
// at the same OpenSSL install.
if let Some(dir) = openssl_dir_from_env(&target) {
cfg.include(dir.join("include"));
println!(
"cargo:rustc-link-search=native={}",
dir.join("lib").display()
);
println!("cargo:rustc-link-lib=libssl");
println!("cargo:rustc-link-lib=libcrypto");
} else {
// vcpkg openssl fallback. Install with:
// ```shell
// git clone https://github.com/microsoft/vcpkg
// cd vcpkg
// ./bootstrap-vcpkg.bat -disableMetrics
// ./vcpkg.exe integrate install
// ./vcpkg.exe install openssl:x64-windows-static-md
// ```
// `find_package` emits `rustc-link-search` + `rustc-link-lib`
// for the linker, but the returned `Library`'s `include_paths`
// still have to be threaded into `cc-rs` explicitly.
#[cfg(target_env = "msvc")]
if let Ok(lib) = vcpkg::Config::new().find_package("openssl") {
for path in &lib.include_paths {
cfg.include(path);
}
}
}
// OpenSSL static libs reference MessageBoxA (OPENSSL_showfatal).
println!("cargo:rustc-link-lib=user32");
#[cfg(target_env = "msvc")]
vcpkg::Config::new().find_package("zlib").ok();
} else {
Expand Down Expand Up @@ -529,6 +551,20 @@ fn main() {
}
}

/// Probe `<TARGET>_OPENSSL_DIR` first, then plain `OPENSSL_DIR`, matching
/// openssl-sys's env-lookup convention (`build/main.rs::env`). Always emits
/// `rerun-if-env-changed` for both names so the build is invalidated when
/// the env changes, even when neither is set at build time.
fn openssl_dir_from_env(target: &str) -> Option<PathBuf> {
let prefix = target.to_uppercase().replace('-', "_");
let prefixed = format!("{prefix}_OPENSSL_DIR");
println!("cargo:rerun-if-env-changed={prefixed}");
println!("cargo:rerun-if-env-changed=OPENSSL_DIR");
env::var_os(&prefixed)
.or_else(|| env::var_os("OPENSSL_DIR"))
.map(PathBuf::from)
}

#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() -> bool {
false
Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@
#![deny(missing_docs, missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/curl/0.4")]

// `ssl` (Schannel on Windows) and `windows-static-ssl` (OpenSSL) are mutually
// exclusive TLS backends for libcurl.
// Gated on `not(doc)` so that `cargo doc --all-features` still generates a
// union of feature-conditional items.
#[cfg(all(feature = "ssl", feature = "windows-static-ssl", not(doc)))]
compile_error!("`ssl` and `windows-static-ssl` are mutually exclusive TLS backends");

use std::ffi::CStr;
use std::str;
use std::sync::Once;
Expand Down
1 change: 1 addition & 0 deletions systest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ ctest2 = "0.4"

[features]
static-ssl = ['curl-sys/static-ssl']
windows-static-ssl = ['curl-sys/windows-static-ssl']
13 changes: 13 additions & 0 deletions vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"builtin-baseline": "960d40ee7351cca3fc648e9d38993b59f01dfd2b",
"dependencies": [
"openssl"
],
"overrides": [
{
"name": "openssl",
"version": "3.6.4",
"port-version": 1
}
]
}
Loading