15

My project is written in Rust (Ubuntu 16.04, CMake 3.5.1).

Previously it used grpcio = "0.4.0" as a dependency in Cargo.toml and I could successfully cross-compile (i.e., create a static binary) it (using cross). However, after I changed my dependency to grpcio = { version = "0.4.2", features = ["openssl"] } I can't cross-compile it anymore: it says that it couldn't compile grpcio-sys = "0.4.2" and displays a few CMake errors (and I can't continue to use 0.4.0 because it doesn't support features=["openssl"]):

  1. Couldn't find some enviroments flags for OpenSSL (even though I installed sudo apt-get install libssl-dev) for Ubuntu 16.04.
  2. gRPC_PROTOBUF_PROVIDER is "module" but PROTOBUF_ROOT_DIR is wrong.

How can I fix it? This post says I should avoid OpenSSL completely. And here's another post about cross compiling with OpenSSL.

James Larkin
  • 541
  • 5
  • 18

4 Answers4

1

It took me a while to find, but I believe nowadays there's an easy option for OpenSSL cross-compilation - enabling the vendored feature.

This causes OpenSSL to be compiled from source as part of your project's build (and therefore against the same target architecture as the rest of the project) instead of expecting it to already be installed on your system.

You can propagate the feature into your own project to optionally depend on vendored by adding something like this to your Cargo.toml:

[features]
...

# If compiling on a system without OpenSSL installed, or cross-compiling for a different
# architecture, enable this feature to compile OpenSSL as part of the build.
# See https://docs.rs/openssl/#vendored for more.
static_ssl = ['openssl/vendored']

[dependencies]
...

[dependencies.openssl]
optional = true
version = ...

Enabling the static_ssl feature when building your project will then compile OpenSSL at the same time.

For grpcio in particular see their documentation, which indicates they provide an openssl-vendored feature for this purpose. So you can add grpcio = { version = "0.7", features = ["openssl-vendored"] } to your Cargo.toml to unconditionally compile OpenSSL, or use the same pattern as above (just don't mark the grpcio package as optional).

This post goes into some more details about different ways of compiling with OpenSSL.

dimo414
  • 47,227
  • 18
  • 148
  • 244
1

I was searching for a similar problem when trying to compile to Turris Omnia router (armv71). I found a great docker image that solved my problem.

Take a look at: https://github.com/messense/rust-musl-cross.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Michal Borek
  • 4,584
  • 2
  • 30
  • 40
0

You can't cross-compile your rust program with every feature of Openssl, because some version of OpenSSL doesn't support (feature as Vendored) which helps for cross-compilation. So you can use that version of OpenSSL which supports this feature. like openssl = { version = "0.10", features = ["vendored"] }

Pawan Bisht
  • 215
  • 2
  • 9
0

The posts that you shared are correct: you have to avoid OpenSSL in Rust. Not because OpenSSL is bad per se, but because the current port in Rust is actually relying on your system's OpenSSL installation. Therefore it is not suitable for cross-compilation.

Instead, you need a more portable solution, such as rustls, which is supported by reqwest and several other web-oriented crates.

In your case grpcio, it seems that the default feature set makes you use boringssl instead of your system's OpenSSL, which should be good for you.

Victor Paléologue
  • 2,025
  • 1
  • 17
  • 27