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

相关推荐
赖small强1 天前
【Linux 网络基础】HTTPS 技术文档
linux·网络·https·tls
写代码的学渣1 天前
ubuntu 22.04 新装的系统 xshell 连不上
linux·运维·ubuntu
序属秋秋秋1 天前
《Linux系统编程之进程环境》【环境变量】
linux·运维·服务器·c语言·c++·操作系统·系统编程
云计算练习生1 天前
linux shell编程实战 10 Git工具详解与运维场景实战
linux·运维·git
虚伪的空想家1 天前
KVM的ubuntu虚机如何关闭安全启动
linux·安全·ubuntu
t198751281 天前
在Ubuntu 22.04系统上安装libimobiledevice
linux·运维·ubuntu
skywalk81631 天前
linux安装Code Server 以便Comate IDE和CodeBuddy等都可以远程连上来
linux·运维·服务器·vscode·comate
晚风吹人醒.1 天前
缓存中间件Redis安装及功能演示、企业案例
linux·数据库·redis·ubuntu·缓存·中间件
Hard but lovely1 天前
linux: pthread库的使用和理解
linux
这儿有一堆花2 天前
Kali Linux:探测存活到挖掘漏洞
linux·运维·服务器