关于macOS:OpenSSL装箱机无法在Mac OS X 10.11上编译

OpenSSL crate fails compilation on Mac OS X 10.11

我试图在Mac OS X 10.11.2上安装用于Rust的Iron框架,但是在编译openssl的内容时运行cargo buildcargo run时,它失败了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
failed to run custom build command for `openssl-sys-extras v0.7.4`
Process didn't exit successfully: `/xxx/rust/hello/target/debug/build/openssl-sys-extras-413d6c73b37a590d/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-apple-darwin")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-apple-darwin")
debug=true opt-level=0
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CC_x86_64-apple-darwin = None
CC_x86_64_apple_darwin = None
HOST_CC = None
CC = None
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CFLAGS_x86_64-apple-darwin = None
CFLAGS_x86_64_apple_darwin = None
HOST_CFLAGS = None
CFLAGS = None
running:"cc""-O0""-ffunction-sections""-fdata-sections""-g""-m64""-fPIC""-o""/xxx/rust/hello/target/debug/build/openssl-sys-extras-413d6c73b37a590d/out/src/openssl_shim.o""-c""src/openssl_shim.c"
ExitStatus(Code(1))


command did not execute successfully, got: exit code: 1



--- stderr
src/openssl_shim.c:1:10: fatal error: 'openssl/hmac.h' file not found
#include <openssl/hmac.h>
     ^
1 error generated.
thread '<main>' panicked at 'explicit panic', /xxx/.cargo/registry/src/github.com-0a35038f75765ae4/gcc-0.3.21/src/lib.rs:772

openssl版本似乎可以:

1
2
$ openssl version
OpenSSL 0.9.8zg 14 July 2015

我不知道该怎么做才能使此安装工作并尝试Iron。


从rust-openssl 0.8版开始,板条箱将自动检测安装了Homebrew的OpenSSL库,无需设置额外的环境变量。

如果您需要支持该版本之前的版本,或者选择不使用Homebrew,请继续阅读。

这是一个已知问题(也是this和this),但不是箱子可以解决的问题。

快速解决方案是使用Homebrew安装OpenSSL,然后通过设置OPENSSL_INCLUDE_DIROPENSSL_LIB_DIR环境变量来明确指向找到OpenSSL的目录:

1
2
3
OPENSSL_INCLUDE_DIR=/usr/local/Cellar/openssl/1.0.2e/include \\
OPENSSL_LIB_DIR=/usr/local/Cellar/openssl/1.0.2e/lib \\
cargo build

如果您已经完成一个cargo build,则需要先运行cargo clean,以清除一些过时的缓存信息。

如果不想为每个打开的外壳设置此设置,请将其添加到外壳初始化文件(如~/.bash_profile)。通过不对版本号进行硬编码,可以使它变脆一些:

1
2
export OPENSSL_INCLUDE_DIR=$(brew --prefix openssl)/include
export OPENSSL_LIB_DIR=$(brew --prefix openssl)/lib

如果您不想使用Homebrew,请遵循相同的过程,但是使用适当的路径访问OpenSSL副本。

较长的原因由andrewtj很好地描述了:

OpenSSL doesn't have a stable ABI so for compatibility purposes Apple have maintained a fork that's compatible with one of the earlier ABIs. They deprecated OpenSSL in 10.7 and finally dropped the headers in 10.11 to push OS X app developers toward bundling their own OpenSSL or using their frameworks. The dylibs have been left around so apps that haven't been updated don't break. You can still link against them but you're opening yourself up to odd compatibility issues by doing so (unless you grab the headers from an earlier OS X release).


使用Brew时,如下所示:

1
2
3
4
5
brew install openssl
export OPENSSL_INCLUDE_DIR=`brew --prefix openssl`/include
export OPENSSL_LIB_DIR=`brew --prefix openssl`/lib
cargo clean
cargo build


对于MacPorts,https://stackoverflow.com/a/39380733/1317564的答案:

1
2
3
4
5
sudo port install openssl
export OPENSSL_INCLUDE_DIR=/opt/local/include
export OPENSSL_LIB_DIR=/opt/local/lib
cargo clean
cargo build


如果您安装了自制软件的openssl,只需将以下内容添加到Cargo.toml中:

1
2
3
4
[target.x86_64-apple-darwin.openssl-sys]
rustc-link-search = ["/usr/local/opt/openssl/lib" ]
rustc-link-lib = ["ssl","crypto" ]
include = ["/usr/local/opt/openssl/include" ]

然后cargo clean && cargo build。不会通过在库的加载路径中引入不兼容的openssl来破坏OS X,也不要忘记在要构建时设置/取消设置环境变量(或者在不使用Rust东西时污染外壳环境)。总而言之,这是一种更快乐,更省心的方法。

我无法将此答案添加到我自己的问题所属的问题中(因为它取决于自制程序),因为Shepmaster决定应将其关闭,但我将在此处回答并链接到该问题。