• Erlang的crypto模块与最新的openssl动态链接库不兼容的问题与解决方案


    在2014新年伊始,增买了一台阿里云服务器,装的系统是CentOS 6.3 64位,装完Erlang后,出现了下面的情况:

    ./configure --without-javac --with-ssl=/usr/local/ssl --enable-hipe --enable-threads --enable-smp-support --enable-kernel-poll
    make
    make install
    
    
    Eshell V5.10.4 (abort with ^G)
    1> crypto:start().
    ** exception error: undefined function crypto:start/0
    2>
    =ERROR REPORT==== 5-Jan-2014::14:40:26 ===
    Unable to load crypto library. Failed with error:
    "load_failed, Failed to load NIF library: '/usr/local/lib/erlang/lib/crypto-3.2/priv/lib/crypto.so: undefined symbol: EC_GROUP_new_curve_GF2m'"
    OpenSSL might not be installed on this system.
    =ERROR REPORT==== 5-Jan-2014::14:40:26 ===
    The on_load function for module crypto returned {error,
    {load_failed,
    "Failed to load NIF library: '/usr/local/lib/erlang/lib/crypto-3.2/priv/lib/crypto.so: undefined symbol: EC_GROUP_new_curve_GF2m'"}}

    它提示我可能是没有安装openssl,但我可以确定是有装的,这是让我折腾纠结的开始。。。
    于是就重装openssl,怀疑是erlang对最新版本的openssl支持不友好,一次次尝试之后,仍没有解决问题。

    然后我单独去编译Erlang的crypto模块,出现了以下情况:

    [root@AY140104155419164de9Z crypto]# pwd
    /root/otp_src_R16B03/lib/crypto
    [root@AY140104155419164de9Z crypto]# make
    === Entering application crypto
    ...
    make[2]: Entering directory `/root/otp_src_R16B03/lib/crypto/c_src'
    /usr/bin/install -c -d ../priv/obj/x86_64-unknown-linux-gnu
    gcc -c -o ../priv/obj/x86_64-unknown-linux-gnu/crypto.o -Werror=return-type -Wall -Wstrict-prototypes -Wmissing-prototypes -Wdeclaration-after-statement -DUSE_THREADS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS -D_POSIX_THREAD_SAFE_FUNCTIONS -g -O2 -I/root/otp_src_R16B03/erts/x86_64-unknown-linux-gnu -fno-tree-copyrename -D_GNU_SOURCE -fPIC -DHAVE_DYNAMIC_CRYPTO_LIB -I/usr/include -I/usr/include -I/root/otp_src_R16B03/erts/emulator/beam -I/root/otp_src_R16B03/erts/include -I/root/otp_src_R16B03/erts/include/x86_64-unknown-linux-gnu -I/root/otp_src_R16B03/erts/include/internal -I/root/otp_src_R16B03/erts/include/internal/x86_64-unknown-linux-gnu -I/root/otp_src_R16B03/erts/emulator/sys/unix crypto.c
    crypto.c: In function ‘ec_key_new’:
    crypto.c:3018: warning: implicit declaration of function ‘EC_GROUP_new_curve_GF2m’
    crypto.c:3018: warning: assignment makes pointer from integer without a cast
    /usr/bin/install -c -d ../priv/lib/x86_64-unknown-linux-gnu

    看到这些信息之后,开始猜测是最新版本的openssl的动态链接库有问题,
    也请教了余峰老大,叫我在centos 6.2环境下测试一下,
    于是在一台老服务器上编译当前最新版的erlang R16B03,没有出现问题,
    但是,更新了OpenSSL后,同样的问题出现了。 

    [Rolong] ~# yum -y install openssl
    ...
    Resolving Dependencies
    --> Running transaction check
    ---> Package openssl.x86_64 0:1.0.0-27.el6_4.2 will be updated
    --> Processing Dependency: openssl = 1.0.0-27.el6_4.2 for package: openssl-devel-1.0.0-27.el6_4.2.x86_64
    ---> Package openssl.x86_64 0:1.0.1e-16.el6_5.1 will be an update
    --> Running transaction check
    ---> Package openssl-devel.x86_64 0:1.0.0-27.el6_4.2 will be updated
    ---> Package openssl-devel.x86_64 0:1.0.1e-16.el6_5.1 will be an update
    --> Finished Dependency Resolution

    openssl被更新后就出问题了,所以新安装的系统,默认都是新版本的openssl,这种环境下安装Erlang都会遇到和上面一样的问题。

    新版本的openssl编译出来的动态链接库的问题?于是我下载了几个版本(包括最新的)的openssl源码来安装尝试,都一样的在编译erlang的crypto模块时出现了新的错误,主要是提示了这一句:

    /usr/bin/ld: /usr/local/ssl/lib/libcrypto.a(cryptlib.o): relocation R_X86_64_32 against `OPENSSL_ia32cap_P' can not be used when making a shared object; recompile with -fPIC

    从这里知道了openssl默认编译出来的libcrypto.a是没有加-fPIC参数的,当重定位被引用的代码段数据对象时出错了,于是打开openssl源码的Makefile,做如下修改:

    CC= gcc
    CFLAG= -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
    DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE
    
    # CFLAG加上-fPIC参数,以相对地址的方式编译链接库。修改后:
    
    CC= gcc
    CFLAG= -fPIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
    DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE

    修改后重新编译链接,问题就解决了。

    PS:如果安装了多个版本并且安装在不同位置的情况下,要确保编译crypto时是用到了你加了-fPIC后编译出来的openssl动态库,因为Makefile中设置了多个搜索路径,也可以按实际情况对Makefile稍作修改。


    转载请注明出处,原文链接:http://blog.csdn.net/zhongruixian/article/details/17929831

  • 相关阅读:
    @value传值到static字段
    [Err] 1701
    eclipse search只能打开一个文件
    FTPClient登录慢的问题
    nginx克隆之后问题
    centos-ftp搭建
    addEventListener和attachEvent的区别 分类: JavaScript 2015-05-12 19:03 702人阅读 评论(0) 收藏
    python中使用eval() 和 ast.literal_eval()的区别 分类: Python 2015-05-11 15:21 1216人阅读 评论(0) 收藏
    初学者必知的Python中优雅的用法 分类: Python 2015-05-11 15:02 782人阅读 评论(0) 收藏
    javascript中函数声明和函数表达式的区别 分类: JavaScript 2015-05-07 21:41 897人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3509025.html
Copyright © 2020-2023  润新知