4

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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Naftuli Kay
  • 87,710
  • 93
  • 269
  • 411
  • 1
    Have you done a clean build and rebuilt? Your output indicates that no compilation actually occurred, otherwise we'd see "Compiling" in the output. See also [OpenSSL crate fails compilation on Mac OS X 10.11](https://stackoverflow.com/q/34612395/155423), which includes the same advice. – Shepmaster Mar 13 '18 at 18:49
  • @Shepmaster I have done a clean build. – Naftuli Kay Mar 13 '18 at 19:07
  • It is not clear, where you get precompiled `libssl.a` and where you put it? Not sure that something like `openssl-dev` package contains staticaly linked openssl. – fghj Mar 14 '18 at 00:32
  • I am installing openssl-static which contains the static code. – Naftuli Kay Mar 14 '18 at 00:58

1 Answers1

8

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
harmic
  • 28,606
  • 5
  • 67
  • 91
  • [THANK YOU SO MUCH](https://github.com/naftulikay/rust-openssl-static-example/pull/3)! I should have gone to source. – Naftuli Kay Mar 14 '18 at 03:38
  • I raised [a bug](https://github.com/sfackler/rust-openssl/issues/878) on rust-openssl about this. – harmic Mar 14 '18 at 03:49