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

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-02 05:42:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-02 05:42:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-02 05:42:05       82 阅读
  4. Python语言-面向对象

    2024-04-02 05:42:05       91 阅读

热门阅读

  1. Pytorch:Pytorch入门基础

    2024-04-02 05:42:05       37 阅读
  2. Hystrix、Resilience4j和Sentinel对比

    2024-04-02 05:42:05       37 阅读
  3. wpf ContextMenu

    2024-04-02 05:42:05       36 阅读
  4. HarmonyOS Connect生态设备UX体验设计

    2024-04-02 05:42:05       41 阅读
  5. 邦芒面试:面试中如何巧妙应对“缺点”提问

    2024-04-02 05:42:05       36 阅读
  6. cpu与缓存的关系

    2024-04-02 05:42:05       33 阅读
  7. macOS上QT打开麦克风和摄像头的权限问题

    2024-04-02 05:42:05       41 阅读