如何排查 configure 问题——以使用 LibreSSL 替换 OpenSSL 编译 axel 为例

案例背景

由于我们使用的 OS 版本比较低,系统最高 OpenSSL 库版本是 openssl-1.0.1e, 而 OpenSSL 在 1.1.0 之前默认是非线程安全的,因此,会导致 axel 偶现 crash

因此,解决这个问题就变成了升级 OpenSSL 以及使用静态库(因为升级生产环境所有机器的 OpenSSL 库不现实)。

configure help guide

在我们编译出了静态的 LibreSSL 库之后,就要想办法怎么让 axel 使用私有目录的 LibreSSL 库。首先想到的就是 help 指引:

复制代码
$ ./configure --help
Usage: ./configure [OPTION]... [VAR=VALUE]...

  --with-ssl=[openssl/wolfssl]
                          Which TLS/SSL implementation to use, default: openssl
  SSL_PREFIX  installation prefix of the TLS/SSL library
  SSL_CFLAGS  C compiler flags for SSL, overriding pkg-config
  SSL_LIBS    linker flags for SSL, overriding pkg-config

由于 LibreSSL 是 OpenSSL 的 fork, 因此,本质上它也是 OpenSSL, 我们通过 SSL_PREFIX 来指定库路径:

复制代码
./configure --prefix=/USER/.local SSL_PREFIX=/USER/.local && make && make install

make 阶段报错:

复制代码
/USER/.local/lib/libcrypto.a(libcrypto_la-a_string.o): In function `ASN1_STRING_get0_data':
/USER/test/axel/libressl-3.9.1/crypto/asn1/a_string.c:238: multiple definition of `ASN1_STRING_get0_data'
lib/ASN1_STRING_get0_data.o:/USER/test/axel/axel-2.17.13/lib/ASN1_STRING_get0_data.c:24: first defined here

可以看到 ASN1_STRING_get0_data 重复定义,而从 configure 阶段的输出可以看到 check ASN1_STRING_get0_data 的结果为 no:

复制代码
checking for openssl... yes
checking for ASN1_STRING_get0_data... no

为什么函数在 LibreSSL 中有定义且能链接到,而 check 结果却为 no, 事情到这里就陷入僵局了。

config.log

查看 configure 脚本发现,check 函数的过程是编译+链接,说变要么编译出错,要么链接出错,要是能查看编译和链接的详细参数就迎刃而解了。果不其然,有个 config.log 文件记录了 configure 阶段的详细日志:

复制代码
onfigure:9062: checking for ASN1_STRING_get0_data
configure:9062: gcc -o conftest -g -O2   conftest.c  -L/USER/.local/lib -lssl -lcrypto   >&5
/USER/.local/lib/libcrypto.a(libcrypto_la-err.o): In function `ERR_load_ERR_strings':
/USER/test/axel/libressl-3.9.1/crypto/err/err.c:672: undefined reference to `pthread_once'
/USER/.local/lib/libcrypto.a(libcrypto_la-crypto_init.o): In function `OPENSSL_init_crypto':
/USER/test/axel/libressl-3.9.1/crypto/crypto_init.c:60: undefined reference to `pthread_once'
/USER/.local/lib/libcrypto.a(libcrypto_la-conf_sap.o): In function `OpenSSL_config':
/USER/test/axel/libressl-3.9.1/crypto/conf/conf_sap.c:116: undefined reference to `pthread_once'
/USER/.local/lib/libcrypto.a(libcrypto_la-conf_sap.o): In function `OpenSSL_no_config':
/USER/test/axel/libressl-3.9.1/crypto/conf/conf_sap.c:136: undefined reference to `pthread_once'
/USER/test/axel/libressl-3.9.1/crypto/conf/conf_sap.c:136: undefined reference to `pthread_once'
/USER/.local/lib/libcrypto.a(libcrypto_la-err_all.o):/USER/test/axel/libressl-3.9.1/crypto/err/err_all.c:152: more undefined references to `pthread_once' follow
collect2: error: ld returned 1 exit status

我们发现,原来是链接时没有指定 pthread 库导致的。

pkg-config

从 config.log 可以看出,axel 依赖 libssl 和 libcrypto, 我们查看二者的依赖:

复制代码
$ cat .local/lib/pkgconfig/libcrypto.pc
#libcrypto pkg-config source file

prefix=/data/francishe/.local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: LibreSSL-libcrypto
Description: LibreSSL cryptography library
Version: 3.9.1
Libs: -L${libdir} -lcrypto
Libs.private: -lresolv -lpthread  
Cflags: -I${includedir}

libcrypto 确实依赖 pthread 库,修改 configure 参数为 ./configure --prefix=/USER/.local SSL_PREFIX=/USER/.local LIBS=-lpthread 问题解决。

相关推荐
123过去20 分钟前
pixiewps使用教程
linux·网络·测试工具·算法·哈希算法
H_老邪1 小时前
Linux 与 Docker 常用命令
linux·运维·服务器·docker
文静小土豆2 小时前
Linux 进程终止指南:理解 kill 与 kill -9 的核心区别与正确用法
linux·运维·服务器
不懒不懒2 小时前
安装python3.9.7和pycharm-community-2022.3.2.exe以及linux
linux·ide·python·pycharm
IMPYLH2 小时前
Linux 的 df 命令
linux·运维·服务器
wefg12 小时前
【Linux】会话、终端、前后台进程
linux·运维·服务器
zhixingheyi_tian2 小时前
Linux/Windows 免密登录
linux·运维·服务器
尤老师FPGA2 小时前
petalinux制作linux系统flash+sd卡启动
linux·运维·服务器
蓝天居士3 小时前
Linux实用功能代码集(4) —— 线程间消息队列(2)
linux
Name_NaN_None3 小时前
Linux 使用 Remmina 连接 Windows 远程桌面 ——「小白教程」
linux·网络·电脑·远程工作