简体   繁体   English

rust如何在Mac OS上交叉编译openssL库?

[英]How do I cross-compile openssL libraries on Mac OS by rust?

When I was compiling a Linux binary on MacOS, I encountered this problem: It looks like the rust library "openssl-sys v0.9.61" is bound to the C library of MacOS.当我在 MacOS 上编译 Linux 二进制文件时,我遇到了这个问题:它看起来像 rust 库“openssl-sys v0.9.61”绑定到 MacOS 的 C 库。 can't link to linux.无法链接到 linux。

cargo build --release --target=x86_64-unknown-linux-musl
   Compiling openssl-sys v0.9.61
error: failed to run custom build command for `openssl-sys v0.9.61`

Caused by:
  process didn't exit successfully: `~/test/../bin/release/build/openssl-sys-96148dcd52905249/build-script-main` (exit status: 101)
  --- stdout
  cargo:rustc-cfg=const_fn
  cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_LIB_DIR
  X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_LIB_DIR unset
  cargo:rerun-if-env-changed=OPENSSL_LIB_DIR
  OPENSSL_LIB_DIR unset
  cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_INCLUDE_DIR
  X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_INCLUDE_DIR unset
  cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR
  OPENSSL_INCLUDE_DIR unset
  cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR
  X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR unset
  cargo:rerun-if-env-changed=OPENSSL_DIR
  OPENSSL_DIR unset
  cargo:rerun-if-env-changed=OPENSSL_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  run pkg_config fail: "pkg-config has not been configured to support cross-compilation.\n\n                Install a sysroot for the target platform and configure it via\n                PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_PATH, or install a\n                cross-compiling wrapper for pkg-config and set it via\n                PKG_CONFIG environment variable."

  --- stderr
  thread 'main' panicked at '

  Could not find directory of OpenSSL installation, and this `-sys` crate cannot
  proceed without this knowledge. If OpenSSL is installed and this crate had
  trouble finding it,  you can set the `OPENSSL_DIR` environment variable for the
  compilation process.

  Make sure you also have the development packages of openssl installed.
  For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.

  If you're in a situation where you think the directory *should* be found
  automatically, please open a bug at https://github.com/sfackler/rust-openssl
  and include information about your system as well as this message.

  $HOST = x86_64-apple-darwin
  $TARGET = x86_64-unknown-linux-musl
  openssl-sys = 0.9.61

  ', ~/.cargo/registry/src/openssl-sys-0.9.61/build/find_normal.rs:174:5
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I found that some people also encountered this problem: https://www.andrew-thorburn.com/cross-compiling-a-simple-rust-web-app/我发现也有人遇到这个问题: https://www.andrew-thorburn.com/cross-compiling-a-simple-rust-web-app/

It's true that you need to determine which rust dependencies use openssl during the cross compile link phase.确实需要在交叉编译链接阶段判断哪些rust依赖使用了openssl。 In my project, reqwest and mysql dependencies apparently use them when cross-compiling.在我的项目中,reqwest 和 mysql 依赖项显然在交叉编译时使用它们。 I had a similar issue when cross-compiling from my mac to x86_64 or aarch64 (arm) linux targets on my mac m1.从我的 mac 交叉编译到我的 mac m1 上的 x86_64 或 aarch64 (arm) linux 目标时,我遇到了类似的问题。 The linker was failing when linking to openssl.. The trick is to add openssl crate to your project.链接到 openssl 时 linker 失败。诀窍是将 openssl 箱子添加到您的项目中。 There is good information here: https://docs.rs/openssl/latest/openssl/这里有很好的信息: https://docs.rs/openssl/latest/openssl/

here are the steps with other helpful links also:以下是带有其他有用链接的步骤:

1.rustup add target  (this is AMD64 linux)
rustup target add x86_64-unknown-linux-musl

for (arm7 linux)
rustup target add aarch64-unknown-linux-musl



1(a) add the xplatform linker
brew install FiloSottile/musl-cross/musl-cross

for x86 and arm7 support:
brew install FiloSottile/musl-cross/musl-cross --with-aarch64 --with-x86_64

1(b) add openssl crate
https://docs.rs/openssl/latest/openssl/

may need to install openssl (see directions)
brew install openssl@1.1

[dependencies]
openssl = { version = "0.10", features = ["vendored"] }

2. modify ~/.cargo/config.toml

add link targets
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"

[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc"

[target.x86_64-unknown-linux-gnu]  - notneeded
linker = "x86_64-unknown-linux-gnu-gcc"

3. export TARGET_CC

x86_64:
export TARGET_CC=x86_64-linux-musl-gcc

for arm7:
export TARGET_CC=aarch64-linux-musl-gcc

4. compiling openssl
include the openssl crate:
openssl = { version = "0.10", features = ["vendored"] }

5. build for target
cargo build --target x86_64-unknown-linux-musl

cargo build --target aarch64-unknown-linux-musl

The first step is to determine which dependency is using openssl, which you can do with crate tree :第一步是确定哪个依赖项正在使用 openssl,您可以使用crate tree执行此操作:

crate tree --target=x86_64-unknown-linux-musl -i openssl-sys

In my case this identified the rusoto_core crate as the one depending on it.就我而言,这将rusoto_core板条箱确定为依赖于它的板条箱。 Some crates can be compiled with feature flags to use alternate TLS libraries, making them easier to use than OpenSSL.一些 crate 可以使用功能标志编译以使用备用 TLS 库,使它们比 OpenSSL 更易于使用。

For example, Rusoto enables rustls like this in the Cargo.toml :例如,Rusoto 在rustls中启用了这样的Cargo.toml

rusoto_core = {version = "0.42.0", default_features = false, features=["rustls"]}
rusoto_s3 = {version = "0.42.0", default_features = false, features=["rustls"]}
rusoto_sqs = {version = "0.42.0", default_features = false, features=["rustls"]}

In the Rusoto case, there is documentation for cross-compiling for use with AWS Lambda: https://rusoto.org/lambdas.html在 Rusoto 案例中,有用于 AWS Lambda 的交叉编译文档: https://rusoto.org/lambdas.html

Alternately, you may be able to provide cross-compiled OpenSSL to the compiler, but from what I understand this is more difficult and poorly documented at this time.或者,您可以向编译器提供交叉编译的 OpenSSL,但据我了解,目前这更困难且文档记录不充分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM