如何将 openssl-sys crate 静态链接到共享库?

Naf*_*Kay 2 openssl rust rust-cargo

我正在使用一个依赖openssl-sys的库。根据文档,如果我指定OPENSSL_STATIC=1为环境变量,OpenSSL 将静态链接到共享库输出中。

由于一系列复杂的问题,我需要将 OpenSSL 静态链接到我的共享库输出中。

这是我的Cargo.toml

[package]
name = "api"
version = "0.1.0"
authors = ["Naftuli Kay <me@naftuli.wtf>"]
publish = false

[lib]
name = "lambda"
crate-type = ["cdylib"]

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
constant_time_eq = "0.1.3"
cpython = { version = "0.1", default-features = false }
crowbar = { version = "0.2", default-features = false }
libc = "0.2.29"
lazy_static = "1.0"
log = "0.4.1"
log4rs = "0.8.0"
openssl-sys = "0.9.27"
parking_lot ="0.5.4"
rand = "0.4.2"
rusoto_core = "0.32.0"
rusoto_kms = "0.32.0"
serde = "1.0.27"
serde-aux = "0.5.2"
serde_derive = "1.0.27"
serde_json = "1.0.9"
serde_qs = "0.3.0"
tokio = "0.1.3"
tokio-reactor = "0.1.0"

[features]
default = ["cpython/python3-sys"]
Run Code Online (Sandbox Code Playgroud)

这是我的lib.rs

#[link(name="openssl", kind="static")]
extern crate openssl_sys;
Run Code Online (Sandbox Code Playgroud)

当我查看我的liblambda.so作品时,我仍然看到它与以下内容相关联libssl

[package]
name = "api"
version = "0.1.0"
authors = ["Naftuli Kay <me@naftuli.wtf>"]
publish = false

[lib]
name = "lambda"
crate-type = ["cdylib"]

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
constant_time_eq = "0.1.3"
cpython = { version = "0.1", default-features = false }
crowbar = { version = "0.2", default-features = false }
libc = "0.2.29"
lazy_static = "1.0"
log = "0.4.1"
log4rs = "0.8.0"
openssl-sys = "0.9.27"
parking_lot ="0.5.4"
rand = "0.4.2"
rusoto_core = "0.32.0"
rusoto_kms = "0.32.0"
serde = "1.0.27"
serde-aux = "0.5.2"
serde_derive = "1.0.27"
serde_json = "1.0.9"
serde_qs = "0.3.0"
tokio = "0.1.3"
tokio-reactor = "0.1.0"

[features]
default = ["cpython/python3-sys"]
Run Code Online (Sandbox Code Playgroud)

我似乎以各种方式告诉它我知道如何静态链接libssl到共享库输出。

我错过了什么?

har*_*mic 6

检查build.rs随 openssl-sys 提供的文件,我注意到两件事。

  1. 如果您没有同时设置OPENSSL_LIB_DIROPENSSL_INCLUDE_DIR,那么它将尝试通过调用 pkg-config 来检测 OpenSSL 目录。如果成功(并且在我的系统中成功),那么它将提前退出,甚至从不考虑OPENSSL_STATIC.

    可以说这是一个错误,但我发现如果我使用这个命令行:

    OPENSSL_STATIC=1 OPENSSL_LIB_DIR=/usr/lib64 OPENSSL_INCLUDE_DIR=/usr/include/openssl cargo build
    
    Run Code Online (Sandbox Code Playgroud)

    然后它将执行静态链接。

  2. 在我的 Centos 7 系统上,安装openssl-devel. 静态库包含在openssl-static包中。

即使在这一切之后,它也没有成功构建 - 有很多未定义的符号引用。在其中的评论中build.rs指出,编译 OpenSSL 时使用的编译选项可能会影响可用的 API 组件 - 我认为这是链接失败的原因。显然,这不是 OpenSSL 1.1.0 的问题(我的系统有 1.0.2)。

我的建议是从源代码编译 OpenSSL 1.1.0 并与之链接。