WinCE中sources文件中targetlibs与sourcelibs的作用与区别
在WinCE里面,編譯和鏈接的必備文件sources,做過WinCE BSP開發的一定都很熟悉,其中有2個關鍵字,targetlibs和sourcelibs,一直讓我對其中的區別很感興趣,故查閱了一些資料,與大家分享。
??? 其實只要搜索以下就會得到一些基本的答案,比如:
TARGETLIBS,如果一個庫以DLL的形式提供給調用者,就需要用TARGETLIBS,它只鏈接一個函數地址,系統執行時會將被鏈接的庫加載。比如coredll.lib就是這樣的庫文件。即動態鏈接。
SOURCELIBS,將庫中的函數實體鏈接進來。即靜態鏈接,用到的函數會在我們的文件中形成一份拷貝。
這個答案已經基本解決問題了,但是這個答案讓我們能看到更深入的東西:
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
總的來說就是先編譯了你自己在sources里指定的源文件,在鏈接階段,先將所有的sourcelibs鏈接在一起成為一個lib,然后與targetlibs指定的lib一起參與鏈接。
當然這里targetlibs指定的可以是dll的lib文件,在CE的幫助文件中,有說明targetlibs可以使用import libraries or static libraries。但是sourcelibs說明中指出一般用在把許多小的lib合并為一個大的lib。
還有關于用法的一些說明:
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一直在回答相關的問題,并且強調只是一些link的順序問題,可以參看makefile.def。
?
為了把問題弄清楚,看了下makefile.def因為很少接觸makefile文件,所以憑有限的makefile知識,來解讀下(MS的全自動化編譯工具害人啊)
注:由于對makefile了解有限,如果分析有錯誤的地方請大家指出
1. 關于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)
??? <<NOKEEP
??? 可以看出,是忽略了TARGETLIBS的東西
2. 關于DLL
??? 有些條件判斷,但是鏈接順序都是
??? $(TARGETOBJFILES)
??? $(SOURCELIBS)
??? $(TARGETLIBS)
3. 關于EXE
??? $(TARGETOBJFILES)
??? $(TARGETLIBS)
??? $(SOURCELIBS)
由此對
EXEs
??? Only TARGETLIBS get linked, anything in SOURCELIBS is ignored
產生了一些質疑
關于鏈接順序:
??? 在我的印象里,應該是出現同樣的symbol,優先鏈接第一個出現的(查了半天也沒有找到文檔作為證明,不過我用bcc試了一下,默認是鏈接第一個出現的)。
??? 這樣就說明了鏈接順序帶來的影響,比如你的源文件里有一個func這個函數的實現,但是在sourcelibs里包含的func1.lib里面也有同樣函數的實現,這時候會使用你的源文件里面的func實現,而不是func1.lib里面的,同樣對應于targetlibs
??? 這樣做可以使用一些stub,比如KITL.c在BSP的兩個地方實現Src\Kernel\Kern和Src\Kernel\Oal,而kern下的就是個stub,里面什么也沒做,用來關閉KITL功能,OAL下的才是功能實體,在鏈接過程中,kern下使用TARGETLIBS來引入oal.lib,但是OAL下KITL.c里面的函數實現都已經被kern下的KITL.c替換了,這個生成的kern.exe后續會在common.bib里面被加入NK.exe(關閉KITL的時候)。而Src\Kernel\Kernkitl下生成的kernkitl.exe也引入了oal.lib,由于自身沒有KITL的實現函數,所以實現代碼就是OAL里面的代碼,在打開KITL的時候就會加入NK.exe。
??? 以下是common.bib的關于KITL的片斷:
??? IF IMGNOKITL
?????? nk.exe????????? $(_FLATRELEASEDIR)\kern.exe???????????????? NK? SHXL
??? ENDIF IMGNOKITL
??? IF IMGNOKITL !
?????? nk.exe????????? $(_FLATRELEASEDIR)\kernkitl.exe???????????? NK? SHXL
??? ENDIF IMGNOKITL !
?
這里也就說明了KITL開關的原理(build層面的關閉)
?
從上面的說明,我們是否可以得到以下結論:
1. 對于LIBS,targetlibs是沒有使用的, 對于DLL和EXE,只是鏈接順序的不同
2. 在build DLL和EXE時需要小心相同函數的覆蓋關系
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的WinCE中sources文件中targetlibs与sourcelibs的作用与区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java初学者不得不知的概念,JDK,J
- 下一篇: WinCE流驱动加载的控制