在OS X上构建Multiarch OpenSSL

时间:2014-08-27 14:54:01

标签: macos openssl x86-64 i386

我需要在OS X上为32位和64位架构构建OpenSSL。我需要为./Configure提供哪些选项,以便为两个体系结构构建相同的.a文件?

1 个答案:

答案 0 :(得分:18)

  

./配置,以便我为两个架构构建相同的.a文件?

您必须小心使用OpenSSL和multiarch库,因为该库不是多安全的。这是因为每个配置都有自己的<openssl/opensslconf.h>文件,每个平台的BIGNUM都不同。

由于OpenSSL的构建系统形成命令的方式,提供-arch x86_64 -arch i386将导致构建失败。另请参阅Getting libcrypto ar error while compiling OpenSSL for Mac

下面详述的相同程序也适用于iOS。唯一改变的是-arch。对于iOS,您可能会使用armv7armv7sarm64i386(用于32位模拟器调试)和x86_64(用于64位模拟器)调试)。

还需要另一个不太明显的技巧。 OpenSSL硬编码基于--prefix--openssldir的一些默认路径,因此您必须为安装目录构建32位,安装,然后移动它;然后为安装目录构建64位,安装,然后移动它;然后在安装目录中创建fat库。另请参阅How to determine the default location for openssl.cnf?

最后, 取代OS X提供的OpenSSL。 OpenSSL 1.0.x和1.1.x与Apple的0.9.8版OpenSSL 二进制兼容。由于不兼容,以下过程使用$HOME/ssl。您可以使用/usr/local/ssl或任何其他适合您口味的地点。


在开始之前,OpenSSL wiki在Compilation and Installation上有一个页面。有很多选项供config使用。选择适合您口味的。我总是使用no-ssl2,通常使用no-ssl3no-comp。在移动设备上,我使用no-srpno-pskno-hwno-dsono-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.hopensslconf-x64.h bn-x86.hbn-x64.h,创建新的{{1} },创建一个新的<openssl/opensslconf.h>,最后创建多树库。

<openssl/bn.h>

新&lt; opensslconf.h&gt;

如果您还没有这样做,请创建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

新&lt; bn.h&gt;

创建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 */ 的库的x86版本以及位于$HOME/ssl-x86的库的x64版本。您可以在$HOME/ssl-x64lipo合并$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

最后,测试一下。验证库是multiarch:

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 
$
如果您在OS X上构建动态库,则使用

DYLD_LIBRARY_PATH


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

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