在 OS X 上构建 Multiarch OpenSSL

问题描述 投票:0回答:2

我需要在 OS X 上为 32 位和 64 位架构构建 OpenSSL。我需要为

./Configure
提供哪些选项,以便将两种架构构建到同一个 .a 文件中?

macos openssl x86-64 i386
2个回答
27
投票

./配置以便我将两种架构构建到同一个 .a 文件中?

您必须小心使用 OpenSSL 和多架构库,因为该库不是多架构安全的。那是因为每个配置都有自己的

<openssl/opensslconf.h>
文件,并且每个平台的
BIGNUM
都不同。

由于 OpenSSL 的构建系统形成命令的方式,提供

-arch x86_64 -arch i386

 将导致构建失败。另请参阅 
为 Mac 编译 OpenSSL 时出现 libcrypto ar 错误

下面详述的相同过程也适用于 iOS。唯一改变的是

-arch

。对于 iOS,您可能会使用 
armv7
armv7s
arm64
i386
(用于 32 位模拟器调试)和 
x86_64
(用于 64 位模拟器调试)。

还需要另一个不那么明显的技巧。 OpenSSL根据

--prefix

--openssldir
硬编码了一些默认路径,所以你必须为安装目录构建32位,安装,然后移动它;然后建64位的安装目录,安装,然后移动;然后在安装目录中创建fat库。另请参阅
如何确定 openssl.cnf 的默认位置?

最后,

不要替换 OS X 提供的 OpenSSL。 OpenSSL 1.0.x 和 1.1.x 与 Apple 的 0.9.8 版本的 OpenSSL 二进制兼容。由于不兼容,以下过程使用 $HOME/ssl

。您可以使用 
/usr/local/ssl
 或任何其他适合您口味的位置。


开始之前,OpenSSL wiki 有一个关于“编译和安装”的页面。有很多选项可以提供给

config。选择适合您口味的。我总是用no-ssl2

,而且通常用
no-ssl3
no-comp
。在移动设备上,我使用 
no-srp
no-psk
no-hw
no-dso
no-engines

以下是构建库的说明。您将为多架构构建中支持的每个架构配置、构建、安装然后移动。


32 位

make clean && make dclean KERNEL_BITS=32 ./config no-ssl2 no-ssl3 --prefix=$HOME/ssl make depend make make install_sw mv $HOME/ssl/include/openssl/opensslconf.h $HOME/ssl/include/openssl/opensslconf-x86.h mv $HOME/ssl/include/openssl/bn.h $HOME/ssl/include/openssl/bn-x86.h mv $HOME/ssl/ $HOME/ssl-x86

64 位

make clean && make dclean KERNEL_BITS=64 ./config no-ssl2 no-ssl3 --prefix=$HOME/ssl make depend make make install_sw mv $HOME/ssl/include/openssl/opensslconf.h $HOME/ssl/include/openssl/opensslconf-x64.h mv $HOME/ssl/include/openssl/bn.h $HOME/ssl/include/openssl/bn-x64.h mv $HOME/ssl/ $HOME/ssl-x64

标题

你需要复制一组标题(哪个并不重要),复制opensslconf-x86.h

opensslconf-x64.h

 
bn-x86.h
bn-x64.h
,创建一个新的
<openssl/opensslconf.h>
,创建一个新的
<openssl/bn.h>
,最后创建多架构库。
rm -rf $HOME/ssl

mkdir -p $HOME/ssl/bin
mkdir -p $HOME/ssl/include/openssl
mkdir -p $HOME/ssl/lib

cp $HOME/ssl-x86/openssl.cnf $HOME/ssl/openssl.cnf
cp $HOME/ssl-x86/include/openssl/* $HOME/ssl/include/openssl
cp $HOME/ssl-x86/include/openssl/opensslconf-x86.h $HOME/ssl/include/openssl/opensslconf-x86.h
cp $HOME/ssl-x64/include/openssl/opensslconf-x64.h $HOME/ssl/include/openssl/opensslconf-x64.h
cp $HOME/ssl-x86/include/openssl/bn-x86.h $HOME/ssl/include/openssl/bn-x86.h
cp $HOME/ssl-x64/include/openssl/bn-x64.h $HOME/ssl/include/openssl/bn-x64.h

如果您还没有这样做,请创建 $HOME/ssl/include/openssl/opensslconf.h

。确保使用新的标头护罩 (

OPENSSL_MULTIARCH_CONF_HEADER

):
cat $HOME/ssl/include/openssl/opensslconf.h
#ifndef OPENSSL_MULTIARCH_CONF_HEADER
#define OPENSSL_MULTIARCH_CONF_HEADER

#if __i386 || __i386__
# include "opensslconf-x86.h"
#elif __x86_64 || __x86_64__ || __amd64 || __amd64__
# include "opensslconf-x64.h"
#else
# error Unknown architecture
#endif

#endif /* OPENSSL_MULTIARCH_CONF_HEADER */

创建$HOME/ssl/include/openssl/bn.h

。确保使用新的标头护罩 (

OPENSSL_MULTIARCH_BN_HEADER

):
cat $HOME/ssl/include/openssl/bn.h
#ifndef OPENSSL_MULTIARCH_BN_HEADER
#define OPENSSL_MULTIARCH_BN_HEADER

#if __i386 || __i386__
# include "bn-x86.h"
#elif __x86_64 || __x86_64__ || __amd64 || __amd64__
# include "bn-x64.h"
#else
# error Unknown architecture
#endif

#endif /* OPENSSL_MULTIARCH_BN_HEADER */

图书馆

此时,您拥有位于 $HOME/ssl-x86

的 x86 版本库和位于

$HOME/ssl-x64

 的 x64 版本库。您将它们与 
lipo
 处的 
$HOME/ssl
 组合起来。
lipo -create $HOME/ssl-x86/lib/libcrypto.a \
             $HOME/ssl-x64/lib/libcrypto.a \
             -output $HOME/ssl/lib/libcrypto.a

lipo -create $HOME/ssl-x86/lib/libssl.a \
             $HOME/ssl-x64/lib/libssl.a \
             -output $HOME/ssl/lib/libssl.a

lipo -create $HOME/ssl-x86/bin/openssl \
             $HOME/ssl-x64/bin/openssl \
             -output $HOME/ssl/bin/openssl

共享图书馆

如果

您配置了

shared,那么您需要执行:

lipo -create $HOME/ssl-x86/lib/libcrypto.1.0.0.dylib \
             $HOME/ssl-x64/lib/libcrypto.1.0.0.dylib \
             -output $HOME/ssl/lib/libcrypto.1.0.0.dylib

lipo -create $HOME/ssl-x86/lib/libssl.1.0.0.dylib \
             $HOME/ssl-x64/lib/libssl.1.0.0.dylib \
             -output $HOME/ssl/lib/libssl.1.0.0.dylib

然后,您需要重新创建软链接:

ln -s $HOME/ssl/lib/libcrypto.dylib $HOME/ssl/lib/libcrypto.1.0.0.dylib ln -s $HOME/ssl/lib/libssl.dylib $HOME/ssl/lib/libssl.1.0.0.dylib

最后,进行测试。验证库是多架构的:

ls $HOME/ssl/lib/ libcrypto.a libssl.a lipo -info $HOME/ssl/lib/libcrypto.a Architectures in the fat file: $HOME/ssl/lib/libcrypto.a are: i386 x86_64 lipo -info $HOME/ssl/lib/libssl.a Architectures in the fat file: $HOME/ssl/lib/libssl.a are: i386 x86_64

然后是测试程序:

#include <openssl/opensslconf.h> #include <openssl/ssl.h> int main(int argc, char* argv[]) { SSL_library_init(); return 0; }

并且:

$ clang -arch i386 -arch x86_64 -I $HOME/ssl/include test.c -o test.exe -L $HOME/ssl/lib -lssl -lcrypto $ DYLD_LIBRARY_PATH=$HOME/ssl/lib; ./test.exe $

DYLD_LIBRARY_PATH

用于在 OS X 上构建动态库的情况。


如果需要,您可以删除非多架构安装:


rm -rf $HOME/ssl-x86 rm -rf $HOME/ssl-x64

只是对此的后续:

0
投票

那是因为每个配置都有自己的

文件,并且每个平台的BIGNUM都不同。

OpenSSL 3.2.1 专为 macOS x86 和 arm 构建,在每个平台上生成相同的头文件。

因此,您可以使用任一构建中的标头并丢弃另一个构建,而不会出现问题。

© www.soinside.com 2019 - 2024. All rights reserved.