如何排查 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 问题解决。

相关推荐
coisini.cn34 分钟前
基于CentOS Stream 9平台搭建RabbitMQ3.13.4以及开机自启
linux·运维·服务器·rabbitmq·centos stream 9
苦藤新鸡1 小时前
用网络编程完成windows和linux跨平台之间的通信(服务器)
linux·网络·windows
JIAWAP2 小时前
Linux环境安装Maven
java·linux·centos·maven
真果粒wrdms3 小时前
【SQLite3】常用API
linux·服务器·c语言·jvm·数据库·oracle·sqlite
Tassel_YUE4 小时前
iptables配置实现NAT(随手记)
linux·运维·服务器·网络·iptables
IT利刃出鞘5 小时前
SecureCRT--使用sftp上传和下载文件
linux·运维·服务器
踩着阴暗的自己向上爬8 小时前
Day05-04-持续集成总结
linux·运维·ci/cd
qyhua9 小时前
Linux内网端口转公网端口映射
linux·运维·服务器
j.king10 小时前
开源GTKSystem.Windows.Forms框架让C# winform支持跨平台运行
linux·c#·gtk
stackY、11 小时前
【Linux】:程序地址空间
linux·算法