【问题标题】:Build Multiarch OpenSSL on OS X在 OS X 上构建多架构 OpenSSL
【发布时间】:2014-10-21 05:33:16
【问题描述】:

我需要在 OS X 上为 32 位和 64 位架构构建 OpenSSL。我需要为./Configure 提供哪些选项,以便将两种架构都构建到同一个 .a 文件中?

【问题讨论】:

    标签: macos openssl x86-64 i386


    【解决方案1】:

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

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

    提供 -arch x86_64 -arch i386 将导致构建失败,因为 OpenSSL 的构建系统形成命令的方式。另见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.hbn-x86.hbn-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
    

    【讨论】:

    • OpenSSL 构建页面现在链接到这个答案。多年来,我一直想知道为什么他们不能拥有与所有平台匹配的标头,而不是他们拥有的那些废话,就像 opnessl 与所有其他项目一样。
    猜你喜欢
    • 1970-01-01
    • 2017-02-11
    • 2018-02-13
    • 1970-01-01
    • 2011-05-04
    • 2020-03-21
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多