在WinCE里面,編譯和鏈接的必備文件sources,做過(guò)WinCE BSP開(kāi)發(fā)的一定都很熟悉,其中有2個(gè)關(guān)鍵字,targetlibs和sourcelibs,一直讓我對(duì)其中的區(qū)別很感興趣,故查閱了一些資料,與大家分享。
其實(shí)只要搜索以下就會(huì)得到一些基本的答案,比如:
TARGETLIBS,如果一個(gè)庫(kù)以DLL的形式提供給調(diào)用者,就需要用TARGETLIBS,它只鏈接一個(gè)函數(shù)地址,系統(tǒng)執(zhí)行時(shí)會(huì)將被鏈接的庫(kù)加載。比如coredll.lib就是這樣的庫(kù)文件。即動(dòng)態(tài)鏈接。
SOURCELIBS,將庫(kù)中的函數(shù)實(shí)體鏈接進(jìn)來(lái)。即靜態(tài)鏈接,用到的函數(shù)會(huì)在我們的文件中形成一份拷貝。
這個(gè)答案已經(jīng)基本解決問(wèn)題了,但是這個(gè)答案讓我們能看到更深入的東西:
This is componentization feature of Windows CE.
The link has two steps. First, whatever is in SOURCELIBS gets combined in a
signle library yourproductname_ALL.lib. In the second step, executable
module is linked from that library and all the targetlibs.
This is done to allow stubs to be conditionally linked: if the function is
defined into your source already, stubs get excluded. If it is not there,
stubbed version (returning ERROR_NOT_IMPLEMENTED or something to that
effect) gets linked in instead.
If the link were to be performed in just one step, it would be impossible to
predict which version (real or stub) would get included. As it is,
implemented functions have a priority over stubs.
--
Sergey Solyanik
Windows CE Core OS
總的來(lái)說(shuō)就是先編譯了你自己在sources里指定的源文件,在鏈接階段,先將所有的sourcelibs鏈接在一起成為一個(gè)lib,然后與targetlibs指定的lib一起參與鏈接。
當(dāng)然這里targetlibs指定的可以是dll的lib文件,在CE的幫助文件中,有說(shuō)明targetlibs可以使用import libraries or static libraries。但是sourcelibs說(shuō)明中指出一般用在把許多小的lib合并為一個(gè)大的lib。
還有關(guān)于用法的一些說(shuō)明:
EXEs
Only TARGETLIBS get linked, anything in SOURCELIBS is ignored
DLLs
SOURCELIBS and TARGETLIBS get linked, in that order
LIBs
Only SOURCELIBS get linked, anything in TARGETLIBS is ignored
Google groups 上Steve Maillet一直在回答相關(guān)的問(wèn)題,并且強(qiáng)調(diào)只是一些link的順序問(wèn)題,可以參看makefile.def。
為了把問(wèn)題弄清楚,看了下makefile.def因?yàn)楹苌俳佑|makefile文件,所以憑有限的makefile知識(shí),來(lái)解讀下(MS的全自動(dòng)化編譯工具害人?。?/div>
注:由于對(duì)makefile了解有限,如果分析有錯(cuò)誤的地方請(qǐng)大家指出
1. 關(guān)于LIBS的link
!IF "$(TARGETTYPE)" == "LIBRARY"
$(_RELEASELIBDIR)\$(TARGETNAME).lib: $(TARGETOBJFILES) $(SOURCELIBS)
@echo BUILD_MARKER:LINK_STATIC_LIBRARY_START Linking $@
$(LIBRARIAN) -out:$(_RELEASELIBDIR)\$(TARGETNAME).lib $(MACHINEOPTION) @<<
-ignore:4001
$(LIBDEFINES)
-nologo
-nodefaultlib
$(LINKER_SUBSYSTEM)
$(TARGETOBJFILES)
$(SOURCELIBS)
<< span>
可以看出,是忽略了TARGETLIBS的東西
2. 關(guān)于DLL
有些條件判斷,但是鏈接順序都是
$(TARGETOBJFILES)
$(SOURCELIBS)
$(TARGETLIBS)
3. 關(guān)于EXE
$(TARGETOBJFILES)
$(TARGETLIBS)
$(SOURCELIBS)
由此對(duì)
EXEs
Only TARGETLIBS get linked, anything in SOURCELIBS is ignored
產(chǎn)生了一些質(zhì)疑
關(guān)于鏈接順序:
在我的印象里,應(yīng)該是出現(xiàn)同樣的symbol,優(yōu)先鏈接第一個(gè)出現(xiàn)的(查了半天也沒(méi)有找到文檔作為證明,不過(guò)我用bcc試了一下,默認(rèn)是鏈接第一個(gè)出現(xiàn)的)。
這樣就說(shuō)明了鏈接順序帶來(lái)的影響,比如你的源文件里有一個(gè)func這個(gè)函數(shù)的實(shí)現(xiàn),但是在sourcelibs里包含的func1.lib里面也有同樣函數(shù)的實(shí)現(xiàn),這時(shí)候會(huì)使用你的源文件里面的func實(shí)現(xiàn),而不是func1.lib里面的,同樣對(duì)應(yīng)于targetlibs
這樣做可以使用一些stub,比如KITL.c在BSP的兩個(gè)地方實(shí)現(xiàn)Src\Kernel\Kern和Src\Kernel\Oal,而kern下的就是個(gè)stub,里面什么也沒(méi)做,用來(lái)關(guān)閉KITL功能,OAL下的才是功能實(shí)體,在鏈接過(guò)程中,kern下使用TARGETLIBS來(lái)引入oal.lib,但是OAL下KITL.c里面的函數(shù)實(shí)現(xiàn)都已經(jīng)被kern下的KITL.c替換了,這個(gè)生成的kern.exe后續(xù)會(huì)在common.bib里面被加入NK.exe(關(guān)閉KITL的時(shí)候)。而Src\Kernel\Kernkitl下生成的kernkitl.exe也引入了oal.lib,由于自身沒(méi)有KITL的實(shí)現(xiàn)函數(shù),所以實(shí)現(xiàn)代碼就是OAL里面的代碼,在打開(kāi)KITL的時(shí)候就會(huì)加入NK.exe。
以下是common.bib的關(guān)于KITL的片斷:
IF IMGNOKITL
nk.exe $(_FLATRELEASEDIR)\kern.exe NK SHXL
ENDIF IMGNOKITL
IF IMGNOKITL !
nk.exe $(_FLATRELEASEDIR)\kernkitl.exe NK SHXL
ENDIF IMGNOKITL !
這里也就說(shuō)明了KITL開(kāi)關(guān)的原理(build層面的關(guān)閉)
從上面的說(shuō)明,我們是否可以得到以下結(jié)論:
1. 對(duì)于LIBS,targetlibs是沒(méi)有使用的, 對(duì)于DLL和EXE,只是鏈接順序的不同
2. 在build DLL和EXE時(shí)需要小心相同函數(shù)的覆蓋關(guān)系
這些都是基于WinCE5的代碼,以上結(jié)論成立的因素:
對(duì)于結(jié)論1,需要熟悉NMake的朋友說(shuō)明下我的解釋是否正確
對(duì)于結(jié)論2, 需要熟悉鏈接器的朋友說(shuō)明下我對(duì)鏈接規(guī)則的解釋是否正確
PS:
wince下link如果都是庫(kù)的話(huà),同名函數(shù)不能自動(dòng)覆蓋,ktil.c的同名函數(shù)覆蓋是通過(guò)obj覆蓋庫(kù)來(lái)實(shí)現(xiàn)的
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。