在Mac OS X 10.11上,OpenSSL包无法编译通过。

20

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

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 版本看起来没问题:

$ openssl version
OpenSSL 0.9.8zg 14 July 2015

我不知道我需要做什么才能使这个安装工作并尝试使用Iron。

4个回答

25
自rust-openssl 0.8版本起,该包将自动检测Homebrew安装的OpenSSL库,无需设置额外环境变量。
如果您需要支持早期版本或选择不使用Homebrew,请继续阅读。
这是一个已知问题(也包括thisthis),但这不是创建框架可以解决的问题。
快速解决方案是使用Homebrew安装OpenSSL,然后通过设置OPENSSL_INCLUDE_DIROPENSSL_LIB_DIR环境变量来明确指向OpenSSL所在目录。
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以清除一些旧的缓存信息。
如果您不想为每个打开的shell设置此项,请将其添加到您的shell初始化文件中(例如~/.bash_profile)。您可以通过不硬编码版本号来使其更加灵活。
export OPENSSL_INCLUDE_DIR=$(brew --prefix openssl)/include
export OPENSSL_LIB_DIR=$(brew --prefix openssl)/lib

如果您不想使用Homebrew,可以按照相同的流程,但使用适当的路径到您的OpenSSL副本。

更长的原因由andrewtj描述:

OpenSSL没有稳定的ABI,因此为了兼容性,苹果公司维护了一个与早期ABI兼容的分支。他们在10.7中弃用了OpenSSL,并在10.11中最终删除了头文件,以推动OS X应用程序开发人员打包自己的OpenSSL或使用它们的框架。dylibs仍然保留,以便未更新的应用程序不会崩溃。您仍然可以链接到它们,但这样做会导致奇怪的兼容性问题(除非您从早期的OS X版本中获取头文件)。


2
我非常确定运行 brew link --force openssl 并安装 pkg-config 将自动解决此问题。话虽如此,将 OpenSSL 库默认可用可能不是一个好主意,我不确定。 - Vladimir Matveev
@VladimirMatveev 是的,在一些问题中提到了这一点,但在我彻底理解之前,我也对像 --force 这样的东西持谨慎态度。我希望 Homebrew 的开发人员能够做出所有艰苦工作,并提出一个可靠的建议,我只需遵循即可。 :-) - Shepmaster
2
据我所知,在这种情况下,“--force”只会覆盖公式中默认不创建符号链接的设置。因此,这不应该造成任何危险,甚至可以通过“brew unlink”撤消。但是,是的,我不知道将openssl库放在“/usr/local/lib”中的后果。 - Vladimir Matveev
我也遇到了与hyper类似的问题,这也帮助了我解决它。 - pyj
我认为只需要一个变量 export OPENSSL_DIR="$(brew --prefix openssl)" 就足够了。 - BallpointBen

10

使用Brew,可以按照以下方式操作:

brew install openssl
export OPENSSL_INCLUDE_DIR=`brew --prefix openssl`/include
export OPENSSL_LIB_DIR=`brew --prefix openssl`/lib
cargo clean
cargo build

这个方法在2017年4月的El Capitan OSX上对我有效。谢谢。 - james-see
2020年10月,在Catalina 10.15.7上对我有效。 - Sean Pianka

2
如果你已经安装了Homebrew的openssl,只需将以下内容添加到Cargo.toml文件中:
[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相关内容时污染shell环境)。总的来说,这是一种更加愉快和少令人恼火的方法。
我无法将这个答案添加到我的问题中(因为它依赖于homebrew),因为Shepmaster决定关闭该问题,但我会在这里回答并链接到那个问题。

请注意,这个解决方案(看起来很合理)似乎并不依赖于Homebrew;无论您在哪里或如何安装openssl,您都应该能够添加这些配置变量。最大的缺点是,您将代码绑定到仅在您的计算机上运行(或具有类似布局的计算机)。并非所有的“x86_64-apple-darwin”目标都具有相同的安装路径。 - Shepmaster
没错,这不是一个难以安装的自制软件依赖项,但是自从 El Cap 以来,您需要自己安装 openssl,因为系统 openssl 的头文件已经不存在了(而且它太老了,几乎没有什么用处)。 - Camden Narzt
是的,这似乎符合其他答案底部的引用。Fink或MacPorts之类的东西还存在吗?我猜人们总是可以编译自己的OpenSSL版本... - Shepmaster
在我不那么谦虚的意见中,Homebrew 是一个明显更好的选择,原因与我不喜欢使用 brew link --force openssl 方法的想法相同,它们会污染系统并且难以清理。 - Camden Narzt

1

2
有趣的是,真正的答案在这里很早就存在了。 - Omar Abid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接