• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 298  文章 - 377  trackbacks - 0
            <2008年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            常用鏈接

            留言簿(34)

            隨筆分類

            隨筆檔案

            文章檔案

            相冊

            收藏夾

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            在發(fā)布linux-fpga系列文章 和PowerPC平臺Linux的移植系列文章后,很多朋友發(fā)mail來問我一些執(zhí)行軟件上面的問題,大部分都是和軟件所使用的鏈接庫相關(guān)的。Novell的官方網(wǎng)站上有一篇文章 對相關(guān)問題介紹得比較詳細(xì),我就參照該文章寫出中文版,希望能對遇到此類問題的朋友有所幫助。

            介紹

            很多時(shí)候,諸如glibc這種基本庫,由于有著不同的版本存在,如果正好你手上只有適用于某個(gè)版本的packages,就會遇到各種各樣的問題。所以,如果你打算在不同版本上使用這些軟件包,就需要尋找一個(gè)比較好的移植方法。而這篇文章正是介紹相應(yīng)方法的。在往下看之前,請確保你有能力安裝和配置相應(yīng)的文件(因?yàn)槲臋n中也會提供一些提示)。下面所有的示例都基于X86硬件平臺,如果你使用的是其他體系,那么可能示例代碼和相應(yīng)的技巧都需要改變。本文是在實(shí)際工程中所使用步驟的總結(jié)性描述,歡迎提出意見和指正。

            背景


            一個(gè)Linux程序通常都包含有執(zhí)行特定功能的機(jī)器代碼,而很多功能通常都由庫文件提供。程序員朋友都知道,庫文件又分為靜態(tài)版本和動態(tài)共享版本,當(dāng)一個(gè)程序被創(chuàng)建時(shí),開發(fā)者就會決定是使用動態(tài)庫還是靜態(tài)庫。在使用靜態(tài)庫的程序中,可能出現(xiàn)不同版本或者在靜態(tài)庫的基礎(chǔ)架構(gòu)上產(chǎn)生變化而引起的二進(jìn)制不兼容。由于C++的成熟但是未通用標(biāo)準(zhǔn)化,經(jīng)常會出現(xiàn)后者的情況。詳細(xì)點(diǎn)說,就是一些具體實(shí)現(xiàn)的細(xì)節(jié),比如,如果用于創(chuàng)建庫的編譯器版本不同,派生繼承格(derived inheritance lattices)中的虛擬函數(shù)進(jìn)行地址映射的機(jī)制,就會使相同庫擁有不同且互不兼容的版本。

            共享庫倒是有很多好處,機(jī)器代碼只需要加載到內(nèi)存一次;使用這個(gè)庫的不同程序都在共享它,而且只有程序具體所需要的數(shù)據(jù)才會在內(nèi)存中分配空間;另外,系統(tǒng)管理員可以很輕松得升級共享庫,而無需接觸那些使用這個(gè)庫的程序,這一點(diǎn)對于安全特性來說特別重要。

            說了半天,上面沒有一個(gè)特點(diǎn)是Linux特性,因?yàn)檫@些都是各種現(xiàn)代操作系統(tǒng)所使用或者支持庫的常規(guī)描述,所以就不廢話了,具體的細(xì)節(jié)建議Google。

            劇本

            終于進(jìn)入正題了。你遇沒遇到過這種問題,辛辛苦苦down下來一個(gè)新版本程序,正準(zhǔn)備在你新版本,最新推出的Linux系統(tǒng)上使用,卻發(fā)現(xiàn)不能運(yùn)行?恩,這種問題通常發(fā)生于libc4到libc5的轉(zhuǎn)換或者libc5到libc6的轉(zhuǎn)換,后者就是通常所說的glibc (the GNU C library)。

            C的庫基本上是所有UNIX/Linux系統(tǒng)中最重要的庫文件,因?yàn)樗鼈儼缪萘怂袘?yīng)用程序和內(nèi)核之間的接口角色。如果這種核心庫文件被改變,而這種改變又不向后兼容,那么,就可能導(dǎo)致整個(gè)系統(tǒng)都無法使用。

            當(dāng)然還有另外一種情況,一個(gè)程序已經(jīng)在一個(gè)使用了較新版本的庫的系統(tǒng)中被構(gòu)建,而你如今想將它安裝到你的當(dāng)前系統(tǒng)中,當(dāng)然,這種程序是不可能正常運(yùn)行的,原因就是程序很可能會使用到只有較新版本的庫文件中才會擁有的新的或者改動過的特性。正如所有人都知道的那樣,包含有舊版本庫所沒有的功能的新版本庫是不會被加載以及執(zhí)行的。下面以glibc舉例子:


            GLIBC 版本 文件名稱
            libc5 /lib/libc.so.5
            libc6 /lib/libc.so.6

            有時(shí)版本號還有附加后綴,比如libc.so.6.3.3.

            正如在背景中所描述的那樣,由版本號大于3.3的GNU C++所編譯的C++庫的二進(jìn)制不兼容性,會導(dǎo)致額外的復(fù)雜度,就算是在當(dāng)前包括了一致的API(Application Programming Interface)和ABI(Application Binary Interface)定義的標(biāo)準(zhǔn)化環(huán)境中也同樣如此。而且,未來C++ compilers和庫的版本是否會保持完全兼容,也尚未得知。針對這個(gè)內(nèi)容,LSB(Linux Standards Base)推薦所有的軟件開發(fā)商用C++開發(fā)軟件的時(shí)候,C++部分都使用靜態(tài)鏈接,不幸的是沒幾個(gè)開發(fā)商是遵循了這個(gè)推薦的。更糟糕的是,Linux的發(fā)布廠商通常都會創(chuàng)建自己版本的C++編譯器,卻沒有讓它們的共享庫和標(biāo)準(zhǔn)C++編譯器的一致。

            總的來說,如果你想運(yùn)行一個(gè)程序,卻失敗了,錯(cuò)誤信息和下面這條信息類似,那么這個(gè)問題可能能夠通過本文“解決方案”部分的建議來解決。

            運(yùn)行程序時(shí)的錯(cuò)誤信息

            ./a.out: relocation error: ./a.out: symbol errno, version GLIBC_2.0 not defined in file libc.so.6 with link time reference

            如果你恰好遇到像上面這樣的關(guān)于symbol errno的錯(cuò)誤信息,就說明你的程序被鏈接到了某個(gè)版本號低于2.3的glibc上。為了保證其線程安全的特性(每個(gè)線程盡量只訪問別的線程不訪問的變量或內(nèi)存,如果硬是要訪問同一變量或內(nèi)存的話,就要采用適當(dāng)?shù)幕コ鈾C(jī)制來避免由于線程切換而導(dǎo)致的不確定性),更新版本的glibc不再將errno作為全局變量來提供。在這種情況下,可能你不得不安裝擁有較老版本(比如2.2.5版本)的兼容環(huán)境。

            但是,如果你并沒有看見上述信息,而程序還是沒有按照你所想象那樣的正常運(yùn)行,那你可能就是遇到了上述介紹的C++相關(guān)問題。我們知道,運(yùn)行時(shí)鏈接器(runtime linker)用于將你的程序加載到內(nèi)存中,并負(fù)責(zé)解決任何和共享庫相關(guān)的依賴,它還能夠在你的系統(tǒng)中定位所需要的共享庫,并將它們加載到內(nèi)存中,但是,這個(gè)共享庫不一定適合目前你希望運(yùn)行的程序。這就是問題所在。

            解決方案

            等你確定了問題的源頭后,就可以創(chuàng)建一個(gè)兼容環(huán)境,來提供正常執(zhí)行程序所需要的功能特性。在這里強(qiáng)烈推薦一種方法,就是在標(biāo)準(zhǔn)系統(tǒng)文件路徑,例如/lib和 /usr/lib外安裝附加的庫文件,如下所示 :


            想移植的程序名 zoo
            用于安裝兼容文件的目錄地址的前綴 /opt/compat-env/zoo
            需要的庫 glibc-2.3.2-95.27
            libgcc-3.2.3-42 libstdc++-3.2.3-42
            所需要文件最初的源目錄 /root/zoo-src

            第一步

            在自行規(guī)定的目錄下創(chuàng)建路徑/bin和/lib:

            % prefix=/opt/compat-env/zoo
            % mkdir -p $prefix/bin $prefix/lib

            第二步
            將所需要的文件拷貝到相應(yīng)的位置:

            % srcdir=/root/zoo-src
            % cd $prefix/bin
            % cp -p $srcdir/zoo .
            % cd $prefix/lib
            % rpm2cpio $srcdir/glibc-2.3.2-95.27*.rpm | cpio -idvm ‘*libc*.so*’
            % find . -name ‘*libc*.so*’ -exec mv -v ‘{}’ . \;
            % rpm2cpio $srcdir/glibc-2.3.2-95.27*.rpm | cpio -idvm ‘*ld*.so*’
            % find . -name ‘*ld*.so*’ -exec mv -v ‘{}’ . \;
            % rpm2cpio $srcdir/libgcc-3.2.3-42*.rpm | cpio -idvm ‘*libgcc_so*.so*’
            % find . -name ‘*libgcc_so*.so*’ -exec mv -v ‘{}’ . \;
            % rpm2cpio $srcdir/libstdc++-3.2.3-42*.rpm | cpio -idvm ‘*libstdc*.so*’
            % find . -name ‘*libstdc*.so*’ -exec mv -v ‘{}’ . \;
            % rm -rf lib usr

            第三步
            創(chuàng)建一個(gè)腳本,用于建立合適的環(huán)境變量和啟動程序:

            % cd $prefix/bin
            % mv zoo zoo.exec
            % cat > zoo libcwait.c zoo
            posted on 2008-06-09 05:18 聶文龍 閱讀(722) 評論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            99久久精品国产一区二区蜜芽| 精品久久久久久成人AV| 99久久精品免费| 人人狠狠综合久久亚洲88| 久久久久亚洲AV无码去区首| 亚洲综合伊人久久综合| 88久久精品无码一区二区毛片| 国产成人久久777777| 国产一区二区三区久久精品| 香蕉久久夜色精品国产2020| 91精品婷婷国产综合久久 | 婷婷久久香蕉五月综合加勒比| 精品久久人人妻人人做精品| 99久久er这里只有精品18| 久久午夜夜伦鲁鲁片免费无码影视 | 伊人久久成人成综合网222| 天天久久狠狠色综合| 亚洲欧美国产日韩综合久久| 99精品久久精品一区二区| 国产精品成人无码久久久久久 | 伊人久久大香线蕉精品不卡| 狠狠色丁香久久婷婷综合五月 | 97精品依人久久久大香线蕉97| 国产精品久久免费| 亚洲综合熟女久久久30p| 国内精品久久久久久久影视麻豆| 亚洲乱码精品久久久久..| 日韩十八禁一区二区久久| 久久AAAA片一区二区| 国产精品99久久99久久久| 99久久无色码中文字幕人妻 | 国内精品伊人久久久久妇| 一级做a爰片久久毛片人呢| 久久久久久国产精品无码超碰| 久久久久高潮毛片免费全部播放| 久久久噜噜噜久久| 久久精品国产亚洲7777| 奇米影视7777久久精品人人爽| 国产—久久香蕉国产线看观看 | 日韩中文久久| 色偷偷88欧美精品久久久 |