Posted on 2008-11-09 12:18
小蘇 閱讀(11033)
評(píng)論(3) 編輯 收藏 引用
使用gcc生成可執(zhí)行文件時(shí),大部分時(shí)候我們需要連接我們自己打包(AR)好的一些庫(kù)文件,對(duì)于中大型(50萬(wàn)代碼行以上)項(xiàng)目上,你將面對(duì)數(shù)個(gè)項(xiàng)目組,最好的情況是每個(gè)項(xiàng)目組發(fā)布自己的打包.ar文件,這些.ar文件之間沒(méi)有任何依賴(lài)關(guān)系, 然后由持續(xù)集成(ci)小組對(duì)這些包進(jìn)行連接,不幸的是,這幾乎是不可能的, 我們?cè)谶B接時(shí)還是遇到了liba.ar和libb.ar相互依賴(lài)的情況。
因?yàn)間cc的庫(kù)是個(gè)有點(diǎn)怪怪的特性,在看-l幫助時(shí)可以看到:
-l library
Search the library named library when linking. (The second alter-
native with the library as a separate argument is only for POSIX
compliance and is not recommended.)
It makes a difference where in the command you write this option;
the linker searches and processes libraries and object files in the
order they are specified. Thus, foo.o -lz bar.o searches library z
after file foo.o but before bar.o. If bar.o refers to functions in
z, those functions may not be loaded.
出于知識(shí)產(chǎn)權(quán)保護(hù)的考慮,每一個(gè)項(xiàng)目組可能只允許看到自己的代碼和別的項(xiàng)目組的頭文件,這給CI小組帶來(lái)了很頭痛的事情,很多時(shí)候你不得不把庫(kù)順序來(lái)回調(diào)整。我也遇到了這樣讓人崩潰的情形,問(wèn)題是對(duì)于liba.ar和libb.ar相互以來(lái)的情形,你可能最終采取丑陋的做法,將其中一個(gè)庫(kù)在前后放兩次:
gcc -o out.bin liba.ar libb.ar liba.ar -lrt
否則,您將不得不面對(duì) "xx not referenced"之類(lèi)的錯(cuò)誤。
看看gcc的幫助,有下面的選項(xiàng)
-Xlinker option
Pass option as an option to the linker. You can use this to supply
system-specific linker options which GCC does not know how to rec-
ognize.
If you want to pass an option that takes an argument, you must use
-Xlinker twice, once for the option and once for the argument. For
example, to pass -assert definitions, you must write -Xlinker
-assert -Xlinker definitions. It does not work to write -Xlinker
"-assert definitions", because this passes the entire string as a
single argument, which is not what the linker expects.
也就是說(shuō),-Xlinker是將連接選項(xiàng)傳給連接器的,趕快看看ld的幫助有沒(méi)有解決庫(kù)順序的選項(xiàng)吧:
-( archives -)
--start-group archives --end-group
The archives should be a list of archive files. They may be either
explicit file names, or -l options.
The specified archives are searched repeatedly until no new unde-
fined references are created. Normally, an archive is searched
only once in the order that it is specified on the command line.
If a symbol in that archive is needed to resolve an undefined sym-
bol referred to by an object in an archive that appears later on
the command line, the linker would not be able to resolve that ref-
erence. By grouping the archives, they all be searched repeatedly
until all possible references are resolved.
Using this option has a significant performance cost. It is best
to use it only when there are unavoidable circular references
between two or more archives.
不錯(cuò),我們有個(gè)有點(diǎn)怪異的選項(xiàng),-(和-),它能夠強(qiáng)制"The specified archives are searched repeatedly"
god,這就是我們要找的啦。
最終的做法:
gcc -o output.bin -Xlinker "-(" liba.ar libb.ar -Xlinker "-)" -lrt
這樣可以解決庫(kù)順序的問(wèn)題了!問(wèn)題是,如果你的庫(kù)相互間的依賴(lài)如果錯(cuò)綜復(fù)雜的話(huà),可能會(huì)增加連接的時(shí)間,不過(guò),做架構(gòu)設(shè)計(jì)的都應(yīng)該能考慮到這些問(wèn)題吧。