1. 程式人生 > >gcc/g++靜態連結和動態連結解決glibc版本不相容的問題

gcc/g++靜態連結和動態連結解決glibc版本不相容的問題

      寫程式時,在開發的linux平臺編譯的程式,到了測試的linux平臺往往不能使用,大部分是由於glibc的版本存在差異導致的,為了解決glibc版本相容的問題,可以使用靜態連結的方式連結glibc相關的庫,但同時也會遇到需要連結部分so庫的情況。

      預設情況下,gcc/g++使用的是動態連結,連結時,優先查詢待連結的so庫是否存在,如果存在,則連結so庫;如果不存在,則查詢.a是否存在,如果存在則連結.a庫;那麼,如何同時連結靜態庫和動態庫呢?幸好gcc/g++也提供了靜態連結和動態連結的選項,如下:

-Wl,-Bstatic  指示後面的連結使用靜態連結方式連結

-Wl,-Bdynamic  指示後面的連結使用動態連結方式連結

如:

         1、g++ main.cpp -lboost_system -lboost_thread      -o main

                連結時,優先連結libboost_system.so和libboost_thread.so庫,如果不存在.so庫,則連結libboost_system.a和libboost_thread.a庫,這是預設連結的方式

         2、g++ main.cpp -Wl,Bstatic -lboost_system -lboost_thread -o main

                      連結時,只連結libboost_system.a和libboost_thread.a庫,如果不存在則報錯

       3、g++ main.cpp -Wl,Bdynamic -lboost_system -lboost_thread -o main

                     連結時,只連結libboost_system.so和libboost_thread.so庫,如果不存在則報錯

那麼,在連結的時候,如何指定部分庫使用靜態連結的方式,部分庫使用動態連結的方式呢?如下:

          g++ main.cpp -Wl,Bstatic -lboost_system -lboost_thread   -Wl,Bdynamic -locci -lclntsh -lnnz11 -o main

         連結時,-wl,BStatic之後的庫使用靜態連結的方式,而-Wl,Bdynamic之後的庫使用動態連結的方式。

這樣,就達到了部分鏈採用靜態連結,部分庫採用動態連結的目的。

 特別注意:-Wl,Bstatic選項要在-Wl,Bdynamic之前

接上,如何將glibc靜態連結到程式中從而避免由於glibc版本的差異致程式不能正常執行呢?

        安裝glibc時,預設只安裝了.so庫,沒有安裝.a庫,所以首先需要安裝glibc的.a庫:yum install glibc-static

       其次,增加編譯選項:-lstdc++,如下:

                g++ main.cpp -Wl,BStatic -lboost_system -lboost_thread -lstdc++   -Wl,Bdynamic -locci -lclntsh -lnnz11 -o main

       這樣完成編譯、連結以後,boost_system、boost_thread、glibc庫是以靜態的方式連結到程式中,即使glibc的版本存在差異,也能正常執行程式;occi、clntsh、nnz11等庫則以動態鏈勢頭的方式連結到程式中,執行時,so的版本必須要匹配。

     針對於高版本的gcc/g++,提供了-static選項。