Solaris 编译安装 erlang R16B02


问题:

因为pkgin安装的erlang 14b版本的加密模块有bug,所以自行编译安装了Erlang R16B01.安装完成后,启动加密库有报错,如下:
[root@db1-233 /]# erl
Erlang R16B02 (erts-5.10.3) [source] [smp:16:16] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V5.10.3  (abort with ^G)
1> crypto:start().
** exception error: undefined function crypto:start/0
2> 
=ERROR REPORT==== 2-Nov-2013::14:50:28 ===
Unable to load crypto library. Failed with error:
"load_failed, Failed to load NIF library: 'ld.so.1: beam.smp: fatal: relocation error: file /opt/local/lib/erlang/lib/crypto-3.1/priv/lib/crypto.so: symbol EC_POINT_new: referenced symbol not found'"
OpenSSL might not be installed on this system.
=ERROR REPORT==== 2-Nov-2013::14:50:28 ===
The on_load function for module crypto returned {error,
                                                 {load_failed,
                                                  "Failed to load NIF library: 'ld.so.1: beam.smp: fatal: relocation error: file /opt/local/lib/erlang/lib/crypto-3.1/priv/lib/crypto.so: symbol EC_POINT_new: referenced symbol not found'"}}

原因:

/usr/local/lib/erlang/lib/crypto-3.1/priv/lib/crypto.so 使用了/usr/lib/libcrypto.so.0.9.8 而不是/opt/local/lib/libcrypto.so.0.9.8,但是/usr/lib/libcrypto.so.0.9.8 沒有 EC_POINT_new 這個函數。

解决办法:

必須使用以下指令編譯
CFLAGS="-m64 -I/opt/local/include" CXXFLAGS="-m64 -I/opt/local/include" LDFLAGS="-m64 -L/opt/local/lib/amd64 -L/opt/local/lib" ./configure
make
make install

執行
必須使用以下指令執行 erl
LD_LIBRARY_PATH=/opt/local/lib /usr/local/bin/erl
或者把变量写入到profile里:
vi /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/local/lib
用户目录下:
vi /home/xxx/.bashrc
export LD_LIBRARY_PATH=/opt/local/lib
Erlang的crypto模块与最新的openssl动态链接库不兼容的问题与解决方案
由于写得比较简略,很多同学还是很纠结这个问题,所以在此补充一下具体的操作过程,希望对同学们有帮助! 
错误信息:
Eshell V5.10.3  (abort with ^G)
1> crypto:start().
** exception error: undefined function crypto:start/0
2>
=ERROR REPORT==== 12-Mar-2014::17:09:15 ===
Unable to load crypto library. Failed with error:
"load_failed, Failed to load NIF library: '/usr/local/lib/erlang/lib/crypto-3.1/priv/lib/crypto.so: undefined symbol: EC_GROUP_new_curve_GF2m'"
OpenSSL might not be installed on this system.
=ERROR REPORT==== 12-Mar-2014::17:09:15 ===
The on_load function for module crypto returned {error,
                                                 {load_failed,
                                                  "Failed to load NIF library: '/usr/local/lib/erlang/lib/crypto-3.1/priv/lib/crypto.so: undefined symbol: EC_GROUP_new_curve_GF2m'"}}
解决办法: 
1、下载openssl源码
    wget http://www.openssl.org/source/openssl-1.0.1f.tar.gz
    tar zxvf openssl-1.0.1f.tar.gz
2、进入源码目录,如果不是新下载解压的目录,而且以前有编译安装过的,进入目录后执行make clean以确保能重新编译
    cd openssl-1.0.1f
3、为了不要和已安装的openssl混淆,这里指定一个新的安装目录
    ./config --prefix=/opt/ssl 
4、config之后,会生成Makefile,打开Makefile找到gcc,在CFLAG参数列表里加上-fPIC
    vim Makefile 
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
5、编译并安装
    make && make install
6、现在进入你的erlang源码安装目录,如果已经编译安装过erlang,为确保能重新编译,先执行:
    make clean
7、加上openssl安装路径重新configure,如果有安装多个版本的erlang,为了可以方便找到新安装的erl,这里可以指定一个新的安装目录,示例如下:
   ./configure --with-ssl=/opt/ssl/ --prefix=/opt/erlang
8、编译并安装
    make && make install
9、运行刚才安装的erlang
   /opt/erlang/bin/erl
Eshell V5.10.3  (abort with ^G)
1> crypto:start().
ok
2>
10、小结
很多同学根据我上一篇文章重装后仍然失败的原因,常见的有如下几个:
1、加-fPIC参数重装openssl后,不明确新编译出来的静态库libcrypto.a在哪里,如果以前有安装过的,不明确是否被覆盖;
2、对于已经编译安装过的源码目录,没有执行make clean;
2、重装erlang时,没有具体指定最新安装的ssl目录;
3、重装erlang后,直接执行erl时,仍然执行了老的erl,可以加上完整路径执行erl尝试,用whereis erl查看一下默认执行路径。