最近頁游開放平臺(tái)比較多, 每個(gè)平臺(tái)要求的Linux版本各不相同, 這給開發(fā)人員部署服務(wù)器帶來了很大的困難. 在本機(jī)Linux編譯的程序,發(fā)布時(shí)即便將依賴的so附帶到目標(biāo)Linux環(huán)境,仍然會(huì)碰到依賴及版本問題,例如:
[root@localhost bin]# ldd wkcenter
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.7' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.8' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.11' not found (required by ./wkcenter)
linux-gate.so.1 => (0xffffe000)
liblog4cpp.so.4 => not found
libprotobuf.so.7 => not found
libboost_filesystem.so.1.48.0 => not found
libboost_system.so.1.48.0 => not found
libboost_thread.so.1.48.0 => not found
libboost_program_options.so.1.48.0 => not found
libunwind-x86.so.7 => not found
libluabind.so.0.9.0 => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x008ae000)
libm.so.6 => /lib/libm.so.6 (0x0044b000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00476000)
libc.so.6 => /lib/libc.so.6 (0x002c1000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0041d000)
librt.so.1 => /lib/librt.so.1 (0x00440000)
/lib/ld-linux.so.2 (0x002a2000)
上面紅字部分表示glibc及glibcxx庫依賴不正確. 本人使用的Linux編譯版本為Mint 11(基于Ubuntu), 一般Ubuntu發(fā)行版的glibc配備非常高. 但是上文中的發(fā)布的Linux版本為CentOS 5.8
使用/lib/libc.so.6 查看libc版本為2.5, 遠(yuǎn)遠(yuǎn)低于開發(fā)環(huán)境的2.11
GNU C Library stable release version 2.5, by Roland McGrath et al.
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-51).
Compiled on a Linux 2.6.9 system on 2012-02-21.
Available extensions:
The C stubs add-on version 2.1.2.
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
GNU libio by Per Bothner
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
RT using linux kernel aio
Thread-local storage support included.
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
由于Linux操作系統(tǒng)的特有elf加載順序. (可以參考此文). 雖然可以很大程度上解決Windows早期版本的dll hell問題, 但是給部署帶來了很大難度
一般常見的解決方法是, 找到一個(gè)與目標(biāo)Linux版本及glibc版本一致的Linux, 將代碼及依賴包放在之上編譯, 完成后再發(fā)布.這種方法與Linux下常見軟件安裝方法類似. 但是對(duì)于商用服務(wù)器部署步驟來說未免繁瑣, 安全性低.
還有一種方法,使用靜態(tài)鏈接. 將所有可執(zhí)行文件文件依賴的靜態(tài)庫, 系統(tǒng)庫,全部靜態(tài)鏈接到可執(zhí)行文件中,可以一次性解決這個(gè)問題
步驟:
1. 在gcc鏈接命令行中添加-static -static-libgcc -static-libstdc++
2. 將第三方依賴庫打開靜態(tài)鏈接開關(guān), 將原來鏈接.so的庫,全改為鏈接.a
3. gcc對(duì)鏈接庫順序很敏感, 鏈接庫順序需要按照從前至后為: 項(xiàng)目產(chǎn)生的靜態(tài)庫 > 第三方庫靜態(tài)庫 > 系統(tǒng)靜態(tài)庫
4. 鏈接時(shí), 若有未解決的symbol, 可以嘗試在最后添加-lpthread及-lrt解決
在發(fā)布版本Linux上運(yùn)行可能遇到的問題:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
解決方法: 執(zhí)行之前運(yùn)行export LC_ALL="C"