1. 程式人生 > >讓C/C++程式一次編譯可以釋出到多版本Linux之上

讓C/C++程式一次編譯可以釋出到多版本Linux之上

最近頁遊開放平臺比較多, 每個平臺要求的Linux版本各不相同, 這給開發人員部署伺服器帶來了很大的困難. 在本機Linux編譯的程式,釋出時即便將依賴的so附帶到目標Linux環境,仍然會碰到依賴及版本問題,例如:

[[email protected] 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發行版的glibc配備非常高. 但是上文中的釋出的Linux版本為CentOS 5.8

使用/lib/libc.so.6 檢視libc版本為2.5, 遠遠低於開發環境的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作業系統的特有elf載入順序. (可以參考此文). 雖然可以很大程度上解決Windows早期版本的dll hell問題, 但是給部署帶來了很大難度

一般常見的解決方法是, 找到一個與目標Linux版本及glibc版本一致的Linux, 將程式碼及依賴包放在之上編譯, 完成後再發布.這種方法與Linux下常見軟體安裝方法類似. 但是對於商用伺服器部署步驟來說未免繁瑣, 安全性低.

還有一種方法,使用靜態連結. 將所有可執行檔案檔案依賴的靜態庫, 系統庫,全部靜態連結到可執行檔案中,可以一次性解決這個問題

步驟:

    1. 在gcc連結命令列中新增-static -static-libgcc -static-libstdc++

    2. 將第三方依賴庫開啟靜態連結開關, 將原來連結.so的庫,全改為連結.a

    3. gcc對連結庫順序很敏感, 連結庫順序需要按照從前至後為:  專案產生的靜態庫 > 第三方庫靜態庫 > 系統靜態庫

    4. 連結時, 若有未解決的symbol, 可以嘗試在最後新增-lpthread及-lrt解決

在釋出版本Linux上執行可能遇到的問題:

terminate called after throwing an instance of 'std::runtime_error'

what(): locale::facet::_S_create_c_locale name not valid

解決方法: 執行之前執行export LC_ALL="C"

相關推薦

C/C++程式編譯可以釋出版本Linux之上

最近頁遊開放平臺比較多, 每個平臺要求的Linux版本各不相同, 這給開發人員部署伺服器帶來了很大的困難. 在本機Linux編譯的程式,釋出時即便將依賴的so附帶到目標Linux環境,仍然會碰到依賴及版本問題,例如: [[email protected] bin]# ldd wkcenter ./

C#程式在一個終端中只允許開啟,防止開啟

using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; names

c++中ifstream讀取整個文件

轉載 .com code 讀取 include char pan ring 一次 轉載:http://www.cnblogs.com/kex1n/p/4028428.html 第一種方法: 讀取至std::string的情況: #include <string>

C語言最後作業--總結報告

優秀 有時 編程 一道 c語言 視野 body 每次 自己 1、當初你是如何做出選擇計算機專業的決定的? 經過一個學期,我對計算機有了些了解,並不像報誌願那會,只知道計算機是學習方面涉及電腦這麽膚淺的了解。而網絡工程學科涉及軟件也涉及硬件,通過網絡工程導論課也慢慢懂得了網

C語言最後作業---總結報告

開始 期末考試 繼續 專業知識 計算機 直接 做出 以及 -- 1.當初你是如何做出選擇計算機專業的決定的?經過一個學期,你的看法改變了麽,為什麽? 你覺得計算機是你喜歡的領域嗎,它是你擅長的領域嗎? 為什麽? 上大學前我覺得自己未來沒什麽明確的目標,個人的小愛好就是學

C#實現類只例項化(被個類訪問呼叫)

C#簡單寫法如下: public  class  Singleton {      private  static  Singleton _instance =  n

如何使用emacs編寫c語言程式,並編譯執行之

vi和emacs被分別被稱為編輯器之神和神之編輯器。vi的入門精通都很難,emacs入門容易,精通難;vi使用起來不停地切換模式,而emacs則不停地ctrl,meta等組合鍵。因此,高德納大師說操作

C#系列——記業務需求:物件的深拷貝

  這篇隨筆著實在意料之外,主要是源於上週開發BS的一個業務,需要用到物件的深拷貝。說的直白一點,就是將物件記憶體分配區和引用完全拷貝一份新的。這種需求以前就遇到過,怎麼解決的已經記不清了。這次趁著這個機會將物件的深拷貝這個知識點記錄下。   先來說說業務場景,直接上程式碼:        //0.反

C#Winform程式如何使用ClickOnce釋出並自動升級(圖解)

有不少朋友問到C#Winform程式怎麼樣配置升級,怎麼樣打包,怎麼樣釋出的,在這裡我解釋一下打包和釋出 關於打包的大家可以看我的文章C# winform程式怎麼打包成安裝專案(圖解) 其實打包是打包

怎樣又編譯linux內核

聲卡 class 補丁 相關 穩定 主板 inux 系統 內容 linux作為自由軟件。在廣大愛好者的支持下,內核版本號不斷更新。新的內核修訂了就得內核的bug,並添加了很多新的特性。假設用戶須要使用這些新的特性或者依據自己的系統量身定做一個更高效或更穩定的內核,就須要

揭秘數據庫面試,你技術面試

得此寶典 讓技術面試更簡單 大家可以叫我老張,網名superZS!一直從事數據庫行業10余年,工作於某數據庫服務公司,兼數據庫資深講師,就面試中大家遇到的比較困惑的數據庫問題,和剛進入數據庫領域的同學們,我在這裏給大家做一個詳細的總結,希望對大家在工作或者面試中有所幫助,老師會傾囊相授,道行尚淺,大家

maven自己主動編譯,解決你每次代碼改動須要又編譯的繁瑣

mvn clean span ng- ips 每次 servlet trac 問題 文件夾 maven結構的項目,我們在每次改動代碼後都會須要手動編譯,以下命令能夠解決此問題。僅僅要代碼改動。會自己主動幫你編譯。 進入項目文件夾運行:mvn -U eclipse:

簡單java單例模式(單擊,如何視窗只顯示

1.將實現功能的建構函式設為private 2.在寫一個public的構造方法: 如下: private static AddPerson addPerson = null;  public static  synchronized AddPerson GetInstance

Ubuntu系統編寫shell指令碼程式安裝個軟體包

#!/bin/sh sudo apt-get install gcc g++ python -y sudo apt-get install gcc g++ python python-dev -y sudo apt-get install mercurial -y sudo apt-get install b

詳解 Java“編譯,到處執行”的跨平臺功能

   Java的跨平臺功能和它的Java虛擬機器(簡稱 JVM)的中介作用是分不開的。所謂跨平臺的“平臺”指:作業系統。沒錯,就是我們接觸的Linux和Windows等作業系統。Java跨平臺,通俗的

使用Java程式分段讀取所有資料(如海量資料)並計數處理

前段時間遇到一個問題,很簡單就是定時任務刪除資料庫中三個月前的資料;無非就是delete...from...where;當時的需求要考慮這幾個問題: 1.效率 2.一次讀取全部 3.保留部分資料 先說一下當時的需求,刪除三個月前的動態(團隊動態),但有些團隊的動

.NET限制程式只能執行一個例項

利用System.Threading名稱空間下的Mutex類,可以限制應用程式,讓它不能同時執行多個例項。 在WinForm程式中,可以將Mutex類嵌在Main()函式中,程式碼如下: static class Program { /// <

java程式 改變指定目錄下所有檔案編碼(包括子目錄中的檔案)

package transCoding; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInpu

java-編譯到處執行

知識用自己的話表述出來才會印象深刻。 java為何是一次編譯到處執行?因為java進過編譯後成為位元組碼檔案(class檔案),然後通過jvm(java虛擬機器)將位元組碼檔案翻譯成機器碼。所以不同作業系統linux、windows分別安裝各自版本的jvm就可以執行java

服務釋出之後,圖形驗證碼亂碼的服務排查

由於業務拓展,新買了臺系統為centOS7的伺服器,配置完jdk和nginx之後,將服務釋出到伺服器上並部署啟動,然後重新整理頁面,神奇的事情就出現了:第一個想到的問題,就是進行本地除錯,發現一切正常;於是在生成驗證碼文字的地方加上了logger輸出,再次釋出程式到伺服器上,