1. 程式人生 > >編譯時混合使用動態庫和靜態庫

編譯時混合使用動態庫和靜態庫

         編譯某個測試程式碼時,出現了下面的錯誤:

# g++ -std=c++11 -o testlurkcli main.cpp -L. -llurkcli-lasl -static
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status

         這個錯誤,是在最後的連結階段,沒有找到 libstdc++,libm,libc等這幾個庫。正常而言,這幾個庫的動態庫都是存在的,這裡因為使用了”-static”選項,導致連結時沒有找到這幾個庫的靜態版本。

         網上查了一下,大部分是推薦把這幾個庫的靜態庫版本找到並軟連線到/usr/lib64/中。

         不過這裡採用一種動態庫和靜態庫混合編譯的方法去解決。具體編譯過程如下:

# g++ -std=c++11 main.cpp liblurkcli.a libasl.a -lpthread-o testlurkcli

         或者:

# g++ -std=c++11 main.cpp -L.  -llurkcli -lasl -lpthread -o testlurkcli

         或者:

# g++ -v -std=c++11 main.cpp -L. -Wl,-Bstatic -llurkcli-lasl -Wl,-Bdynamic -lpthread  -otestlurkcli

         注意,最後一種方式,使用-Wl,-Bstatic以及-Wl,-Bdynamic,給聯結器ld傳遞連結選項,-Wl,-Bstatic使得後面的-l庫使用靜態連線的方式,而-Wl,-Bdynamic使得後面的-l庫使用動態連結的方式。所以,上面的命令中,-llurkcli –lasl使用的是靜態連線,而-lpthread,以及聯結器自己預設連線的-lstdc++, -lm, -lgcc_s, -lgcc, -lc, -lgcc_s, -lgcc,都是採用的動態連結。

         下面的話,摘自:

https://ftp.gnu.org/pub/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html#SEC3

-Bdynamic

-dy

-call_shared

Link against dynamic libraries. This isonly meaningful on platforms for which shared libraries are supported. Thisoption is normally the default on such platforms. The different variants ofthis option are for compatibility with various systems. You may use this optionmultiple times on the command line: it affects library searching for -l optionswhich follow it.

-Bstatic

-dn

-non_shared

-static

Do not link against shared libraries. Thisis only meaningful on platforms for which shared libraries are supported. Thedifferent variants of this option are for compatibility with various systems.You may use this option multiple times on the command line: it affects librarysearching for -l options which follow it.