[DEBUG] QAT Nginx for docker 部署時"--with-ld-opt"出錯

goto2091發表於2022-04-21

layout: post
title: [DEBUG] QAT Nginx for docker 部署時"--with-ld-opt"出錯
subtitle: 記一次debug經歷
tags: [debug, linux]
comments: true


[DEBUG] QAT Nginx for docker 部署時"--with-ld-opt"出錯

在將 Openssl + QAT + async-mode-nginx 部署至docker的container中時,在執行async-mode-nginx的./configure時,出現瞭如下報錯:

checking for OS
+ Linux 4.18.0-305.el8.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
checking for gcc -pipe switch ... found
checking for --with-ld-opt="-Wl,-rpath=/root/openssl/lib -L/root/openssl/lib -lz" ... not found
./configure: error: the invalid value in --with-ld-opt="-Wl,-rpath=/root/openssl/lib -L/root/openssl/lib -lz"

"not found" , 找不到/root/openssl/lib這個目錄。但是實際上該目錄是存在的。起初我認為是docker container環境本身不支援"--with-ld-opt", 在bing和百度上搜尋,找到一些類似問題,解決方法是遮蔽了該引數。確實,遮蔽之後nginx順利編譯,但是如此,nginx就無法與openssl交叉編譯。

於是查詢了async-mode-nginx中與“--with-ld-opt”相關的程式碼,在該source目錄下的auto/lib/openssl/conf檔案中,有三段相似程式碼,第一段是這樣:

        if [ $ngx_found = no ]; then

            # FreeBSD port

            ngx_feature="OpenSSL library in /usr/local/"
            ngx_feature_path="/usr/local/include"

            if [ $NGX_RPATH = YES ]; then
                ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto"
            else
                ngx_feature_libs="-L/usr/local/lib -lssl -lcrypto"
            fi

            ngx_feature_libs="$ngx_feature_libs $NGX_LIBDL $NGX_LIBPTHREAD"

            . auto/feature
        fi

nginx的./configure會執行 check OS 過程,如果發現缺少某些庫,則會報錯退出,ngx_found這個變數如果為0,就會進入如下判斷,configure程式會依次尋找/usr/local/lib, /usr/pkg/lib和/opt/local/lib, 三個路徑如果都沒有找到openssl/lib, 則configure就會報錯退出。

我echo了ngx_found的值,發現是0,一般來說在host下,沒有出現為0的情況,所以不會走這三個判斷。

因此,我決定試一試把container中的nginx/auto/lib/openssl/conf檔案修改一下,把/usr/local/改成了本地的openssl地址:

     if [ $ngx_found = no ]; then

            # FreeBSD port
		   openssl_path=/root/openssl
            ngx_feature="OpenSSL library in $openssl_path"
            ngx_feature_path="$openssl_path/include"

            if [ $NGX_RPATH = YES ]; then
                ngx_feature_libs="-R$openssl_path/lib -L$openssl_path/lib -lssl -lcrypto"
            else
                ngx_feature_libs="-L$openssl_path/lib -lssl -lcrypto"
            fi

            ngx_feature_libs="$ngx_feature_libs $NGX_LIBDL $NGX_LIBPTHREAD"

            . auto/feature
        fi

再次編譯,nginx通過了,openssl和nginx順利交叉編譯。

這說明,async mode nginx在container中完全可以正常安裝,一定是編譯環節缺失了什麼才導致了出現--with-ld-opt出錯。

於是我搜尋nginx的--with-ld-opt引數, 發現它和--with-cc-opt引數一樣,都與PCRE庫密切相關。PCRE是Perl5的軟體庫,Perl5在文字處理和編譯安裝,系統運維上有重要作用,是很多軟體的輔助工具,在python出現之前Perl的使用範圍非常巨大,以至於今天仍是Linux系統自帶的語言。PCRE庫不是所有Linux系統自帶的,需要手動安裝。

於是在container(該container基於redhat8.4 ubi:213製作)中先更新了repo源,再執行:

yum install pcre2-tools.x86_64 pcre-devel.x86_64 zlib-static.x86_64 zlib

保守起見,conf檔案中還提到了zlib,所以一併安裝。

這次nginx的configure執行加上--with-ld-opt之後順利編譯,沒有再報錯。於是該BUG順利解決!唯一沒搞懂的是,為什麼當時執行的時候不是報找不到PCRE庫而是報找不到openssl檔案目錄。

這次debug, 感受就是一定要具體定位到錯誤產生的源頭,一定要儘可能直接看執行編譯的conf檔案是怎麼寫的,弄清楚編譯邏輯,知道錯從何處產生,大膽嘗試修改程式碼check問題,才可能快速尋找到解決辦法。

相關文章