Linux下 a檔案的合併

2021-09-25 12:03:39 字數 3518 閱讀 4403

涉及到命令工具:ar,tranlib

.a 檔案的結構和.tar檔案就沒有什麼區別。 x 命令解出來, a 命令新增, t命令列表

假設a.a, b.a c.a 在/usr/local/lib目錄下

mkdir /tmp/libabc

cd /tmp/libabc

ar x /usr/local/lib/a.a

ar x /usr/local/lib/b.a

ar x /usr/local/lib/c.a

ar cru libabc.a *.o

ranlib libabc.a

/*以下部分引用

ar基本用法

ar命令可以用來建立、修改庫,也可以從庫中提出單個模組。庫是一單獨的檔案,裡面包含了按照特定的結構組織起來的其它的一些檔案(稱做此庫檔案的member)。原始檔案的內容、模式、時間戳、屬主、組等屬性都保留在庫檔案中。

下面是ar命令的格式:

ar [-][abcfilnopssuvv] [membername] [count] archive files...

例如我們可以用ar rv libtest.a hello.o hello1.o來

生成乙個庫,庫名字是test,鏈結時可以用-ltest鏈結。該庫中存放了兩個模組hello.o和hello1.o。選項前可以有『-'字元,也可以

沒有。下面我們來看看命令的操作選項和任選項。現在我們把部分稱為操作選項,而[abcfilnopssuvv]部分稱為任選項。

中的操作選項在命令中只能並且必須使用其中乙個,它們的含義如下:

d:從庫中刪除模組。按模組原來的檔名指定要刪除的模組。如果使用了任選項v則列出被刪除的每個模組。

m:該操作是在乙個庫中移動成員。當庫中如果有若干模組有相同的符號定義(如函式定義),則成員的位置順序很重要。如果沒有指定任選項,任何指定的成員將移到庫的最後。也可以使用'a','b',或'i'任選項移動到指定的位置。

p:顯示庫中指定的成員到標準輸出。如果指定任選項v,則在輸出成員的內容前,將顯示成員的名字。如果沒有指定成員的名字,所有庫中的檔案將顯示出來。

q:快速追加。增加新模組到庫的結尾處。並不檢查是否需要替換。'a','b',或'i'任選項對此操作沒有影響,模組總是追加的庫的結尾處。如果使用了任選項v則列出每個模組。 這時,庫的符號表沒有更新,可以用'ar s'或ranlib來更新庫的符號表索引。

r:在庫中插入模組(替換)。當插入的模組名已經在庫中存在,則替換同名的模組。如果若干模組中有乙個模組在庫中不存在,ar顯示乙個錯誤訊息,並不替換其他同名模組。預設的情況下,新的成員增加在庫的結尾處,可以使用其他任選項來改變增加的位置。

t:顯示庫的模組表清單。一般只顯示模組名。

x:從庫中提取乙個成員。如果不指定要提取的模組,則提取庫中所有的模組。

下面在看看可與操作選項結合使用的任選項:

a:在庫的乙個已經存在的成員後面增加乙個新的檔案。如果使用任選項a,則應該為命令列中membername引數指定乙個已經存在的成員名。

b:在庫的乙個已經存在的成員前面增加乙個新的檔案。如果使用任選項b,則應該為命令列中membername引數指定乙個已經存在的成員名。

c:建立乙個庫。不管庫是否存在,都將建立。

f:在庫中截短指定的名字。預設情況下,檔名的長度是不受限制的,可以使用此引數將檔名截短,以保證與其它系統的相容。

i:在庫的乙個已經存在的成員前面增加乙個新的檔案。如果使用任選項i,則應該為命令列中membername引數指定乙個已經存在的成員名(類似任選項b)。

l:暫未使用

n:與count引數一起使用,在庫中有多個相同的檔名時指定提取或輸出的個數。

o:當提取成員時,保留成員的原始資料。如果不指定該任選項,則提取出的模組的時間將標為提取出的時間。

p:進行檔名匹配時使用全路徑名。ar在建立庫時不能使用全路徑名(這樣的庫檔案不符合posix標準),但是有些工具可以。

s:寫入乙個目標檔案索引到庫中,或者更新乙個存在的目標檔案索引。甚至對於沒有任何變化的庫也作該動作。對乙個庫做ar s等同於對該庫做ranlib。

s:不建立目標檔案索引,這在建立較大的庫時能加快時間。

u:一般說來,命令ar r...插入所有列出的檔案到庫中,如果你只想插入列出檔案中那些比庫中同名檔案新的檔案,就可以使用該任選項。該任選項只用於r操作選項。

v:該選項用來顯示執行操作選項的附加資訊。

v:顯示ar的版本。

/*以上部分引用

/*以下部分引用

靜態庫檔案需要使用「ar」來建立和維護。當給靜態庫增建乙個成員時(加入乙個.o檔案到靜態庫中),「ar」可直接 將需要增加的.o檔案簡單的追加到靜態庫的末尾。之後當我們使用這個庫進行連線生成可執行檔案時,鏈結程式「ld」卻提示錯誤,這可能是:主程式使用了之 前加入到庫中的.o檔案中定義的乙個函式或者全域性變數,但連線程式無法找到這個函式或者變數。 

這個問題的原因是:之前我們將編譯完成的.o檔案直接加入到了庫的末尾,卻並沒有更新庫的有效符號表。連線程式進行連線時,在靜態庫的符號索引表中無法定 位剛才加入的.o檔案中定義的函式或者變數。這就需要在完成庫成員追加以後讓加入的所有.o檔案中定義的函式(變數)有效,完成這個工作需要使用另外乙個 工具「ranlib」來對靜態庫的符號索引表進行更新。 

我們所使用到的靜態庫(文件檔案)中,存在這樣乙個特殊的成員,它的名字是「__.symdef」。它包含了靜態庫中所有成員所定義的有效符號(函式名、 變數名)。因此,當為庫增加了乙個成員時,相應的就需要更新成員「__.symdef」,否則所增加的成員中定義的所有的符號將無法被連線程式定位。完成 更新的命令是: 

ranlib archivefile 

通常在makefile中我們可以這樣來實現: 

libfoo.a: libfoo.a(x.o) libfoo.a(y.o) ... 

ranlib libfoo.a 

它所實現的是在更新靜態庫成員「x.o」和「y.o」之後,對靜態庫的成員「__.symdef」進行更新(更新庫的符號索引表)。 

如果我們使用gnu ar工具來維護、管理靜態庫,我們就不需要考慮這一步。gnu ar本身已經提供了在更新庫的同時更新符號索引表的功能(這是預設行為,也可以通過命令列選項控制ar的具體行為。可參考 gnu ar工具的man手冊)。 

gnu工具中ar是用來製作庫檔案.a的,但同時還提供了乙個ranlib,從手冊上看ranlib相當於ar -s,為什麼這樣呢?

這是由於最早在unix系統上ar程式是單純用來打包多個.o到.a(類似於tar做的事情),而不處理.o裡的符號表。linker程式則需 要.a檔案提供乙個完整的符號表,所以當時就寫了單獨的ranlib程式用來產生linker所需要的符號資訊,也就是說那時,產生乙個對linker合 格的的.a檔案需要做ar和ranlib兩步 。

很快,unix廠商就發現ranlib做得事情完全可以合併到ar裡面去,於是ar程式的公升級版本就包括了ranlib的功能,但早期的很多專案的makefile都已經是按照兩步式的方法生成.a,所以為了保證這些早期檔案的相容性,ranlib被保留下來了。

如今,gnu/linux系統上,ranlib依然存在,當然大部分專案已經不使用它了,因為ar -s就做了ranlib的工作。

歷史通常是進步和妥協的混合!

/*以上部分引用

Linux下 a檔案的合併

涉及到命令工具 ar,tranlib a 檔案的結構和.tar檔案就沒有什麼區別。x 命令解出來,a 命令新增,t命令列表 假設a.a,b.a c.a 在 usr local lib目錄下 mkdir tmp libabc cd tmp libabc ar x usr local lib a.a a...

Linux下分割合併檔案

切割合併檔案在linux下用split和cat就可以完成。下面舉些例項進行說明。1.檔案切割 檔案切割模式分為兩種 文字檔案 二進位制模式。1.1文字模式 按最大檔案大小切割 按文字行數切割。1.1.1最大檔案大小切割 split c 5k duanxin split 將文字檔案duanxin按每塊...

Linux下分割合併檔案

切割合併檔案在linux下用split和cat就可以完成。下面舉些例項進行說明。1.檔案切割 檔案切割模式分為兩種 文字檔案 二進位制模式。1.1文字模式 文字模式只適用於文字檔案,用這種模式切割後的每個檔案都是可讀的。文字模式又分為兩種 按最大檔案大小切割 按文字行數切割。1.1.1最大檔案大小切...