標籤:
使用google protobuf時,出現錯誤
/usr/bin/ld: /usr/local/lib/libprotobuf.a(message_lite.o): relocation R_X86_64_32S against `_ZTVN6google8protobuf11MessageLiteE‘ can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libprotobuf.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
搜了下,幾篇文章如下:
查看整個編譯過程,編譯過程中看到沒有-fPIC選項,如何加進去
看protobuffer的README和INSTALL文檔,看到需要添加特殊編譯選項,需要在執行configure的時候引入,
於是make clean; make uninstall
./configure CXXFLAGS=-fPIC
查看編譯檔案,發現已經有了編譯選項-fPIC,再次執行編譯安裝
重新編譯器,這次沒有報錯,沒有出錯,問題解決。
另外回答;
原因:
-fPIC 是個神馬東東呢?
選項 -fPIC
PIC是Position-Independent-Code的縮寫。在電腦系統中,PIC和PIE(Position-IndependentExecutable)是可以在主存中不同位置執行的目標代碼。PIC經常被用在共用庫中,這樣就能將相同的庫代碼為每個程式映射到一個位置,不用擔心覆蓋掉其他程式或共用庫。
因為so動態庫編譯的時候加上了 -fPIC,但是串連的 libprotobuf.a檔案並不是 -fPIC產生的,所以就報錯了。
那就是說串連的 libprotobuf.aa 檔案,也需要加上 -fPIC 選項進行編譯了。
gcc -fPIC選項
使用 -fPIC 選項,會產生 PIC 代碼。.so 要求為 PIC,以達到動態連結的目的,否則,無法實現動態連結。 non-PIC 與 PIC 代碼的區別主要在於 access global data, jump label 的不同。比如一條 access global data 的指令,non-PIC 的形勢是:ld r3, var1PIC 的形式則是:ld r3, [email protected],意思是從 GOT 表的 index 為 var1-offset 的地方處指示的地址處裝載一個值,即 [email protected] 處的4個 byte 其實就是 var1 的地址。這個地址只有在啟動並執行時候才知道,是由 dynamic-loader(ld-linux.so) 填進去的。 再比如 jump label 指令non-PIC 的形勢是:jump printf ,意思是調用 printf。PIC 的形式則是:jump [email protected],意思是跳到 GOT 表的 index 為 printf-offset 的地方處指示的地址去執行,這個地址處的代碼擺放在 .plt section,每個外部函數對應一段這樣的代碼,其功能是呼叫dynamic-loader(ld-linux.so) 來尋找函數的地址(本例中是 printf),然後將其地址寫到 GOT 表的 index 為 printf-offset 的地方,同時執行這個函數。這樣,第2次呼叫 printf 的時候,就會直接跳到 printf 的地址,而不必再尋找了。 GOT 是 data section, 是一個 table, 除專用的幾個 entry,每個 entry 的內容可以再執行的時候修改;PLT 是 text section, 是一段一段的 code,執行中不需要修改。每個 target 實現 PIC 的機制不同,但大同小異。比如 MIPS 沒有 .plt, 而是叫 .stub,功能和 .plt 一樣。 可見,動態連結執行很複雜,比靜態連結執行時間長;但是,極大的節省了 size,PIC 和動態連結技術是電腦發展史上非常重要的一個裡程碑。
/usr/bin/ld: libs/X86_64/libglog.a(libglog_la-logging.o): relocation R_X86_64_32S against `_ZTVN6google4base6LoggerE‘ can not be used when making a shared object; recompile with -fPIC libs/X86_64/libglog.a: could not read symbols: Bad value collect2: error: ld returned 1 exit status
只能安裝錯誤提供的方法重現編譯libglog.a了,然後,替換了libglog.
CXXFLAGS="-O3 -fPIC" ./configure --prefix=glog-0.3.3/install
參考:http://zrj.me/archives/1066
gcc報錯 can not be used when making a shared object; recompile with -fPIC