How do I statically link the openssl-sys crate int

2019-07-20 06:33发布

问题:

I am using a library which depends on openssl-sys. According to the documentation, if I specify OPENSSL_STATIC=1 as an environment variable, OpenSSL will be statically linked into the shared library output.

Due to a host of complicated problems, I need to statically link OpenSSL into my shared library output.

Here is my 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"]

Here is my lib.rs:

#[link(name="openssl", kind="static")]
extern crate openssl_sys;

When I look at my liblambda.so produced, I still see it is linked against libssl:

[vagrant@api vagrant]$ OPENSSL_STATIC=1 cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.94 secs
[vagrant@api vagrant]$ ldd target/debug/liblambda.so | grep -i ssl
        libssl.so.10 => /lib64/libssl.so.10 (0x00007faa5f5bf000)

I seem to have told it in every way I know how to statically link libssl into the shared library output.

What am I missing?

回答1:

Inspecting the build.rs file supplied with openssl-sys, I noticed two things.

  1. If you do not set both OPENSSL_LIB_DIR and OPENSSL_INCLUDE_DIR, then it will try to detect the OpenSSL directories by calling pkg-config. If that succeeds (and it does in my system) then it will exit early, and never even considers the value of OPENSSL_STATIC.

    Arguably that's a bug, but I found that if I used this command line:

    OPENSSL_STATIC=1 OPENSSL_LIB_DIR=/usr/lib64 OPENSSL_INCLUDE_DIR=/usr/include/openssl cargo build
    

    then it would perform static linking.

  2. On my Centos 7 system, it was not enough to install openssl-devel. The static libraries are included in the openssl-static package.

Even after all this, it did not successfully build - there were a lot of undefined symbol references. Within the comments in build.rs it states that compilation options used when compiling OpenSSL may affect which API components are available - I assume this is the reason for the link failure. Apparently this is less of a problem from OpenSSL 1.1.0 (my system had 1.0.2).

My advice would be to compile OpenSSL 1.1.0 from source and link against that.