在OS X上构建Multiarch OpenSSL

See*_*van 6 macos openssl x86-64 i386

我需要在OS X上为32位和64位架构构建OpenSSL.我需要提供哪些选项才能将./Configure两个体系结构构建到同一个.a文件中?

jww*_*jww 19

./Configure以便我为两个体系结构构建相同的.a文件?

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

-arch x86_64 -arch i386由于OpenSSL的构建系统形成命令的方式,供应将导致构建失败.另请参阅编译OpenSSL for Mac时获取libcrypto ar错误.

下面详述的相同程序也适用于iOS.唯一改变的是-arch.对于iOS,你可能会使用armv7,armv7s,arm64i386(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-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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

你需要复制一个套头(这并不重要),复制opensslconf-x86.h,opensslconf-x64.h bn-x86.hbn-x64.h创建一个新的<openssl/opensslconf.h>,创建一个新的<openssl/bn.h>,并最终创建multiarch库.

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
Run Code Online (Sandbox Code Playgroud)

新的<opensslconf.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 */
Run Code Online (Sandbox Code Playgroud)

新<bn.h>

创造$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 */
Run Code Online (Sandbox Code Playgroud)

图书馆

此时,您有一个位于的库的x86版本,以及位于的库$HOME/ssl-x86的x64版本$HOME/ssl-x64.你把它们与lipoat 结合起来$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
Run Code Online (Sandbox Code Playgroud)

共享图书馆

如果您配置了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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

最后,测试一下.验证库是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
Run Code Online (Sandbox Code Playgroud)

然后是一个测试程序:

#include <openssl/opensslconf.h>
#include <openssl/ssl.h>

int main(int argc, char* argv[])
{
  SSL_library_init();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

和:

$ 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 
$
Run Code Online (Sandbox Code Playgroud)

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


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

rm -rf $HOME/ssl-x86
rm -rf $HOME/ssl-x64
Run Code Online (Sandbox Code Playgroud)

  • OpenSSL 构建页面现在链接到此答案。多年来,我一直想知道为什么他们不能拥有与所有平台匹配的标题,而不是他们拥有的那些废话,就像 opnessl 与所有其他项目不同。 (2认同)