Wince6.0 源代碼配置文件

********************************LoongEmbedded********************************

作者:LoongEmbedded(kandi)

時間:2011.9.9

類別:WINCE 系統開發

********************************LoongEmbedded********************************

WINCE的編譯工具Build.exe通過WINCE源代碼配置文件提供的下面的信息來編譯指定的目錄及子目錄的源代碼(source code):

1)    要貫穿的目錄。

2)    要編譯的C和微軟的的Visual C++文件。

3)    創建的二進制文件。

 

WINCE源代碼配置文件是指下面類型的文件

1)    Dirs File

指dirs文件,用於識別包含源代碼的子目錄,也就是要編譯的源代碼所在的目錄。

2)    Make File

指文件夾下面的makefile文件,包含要編譯和鏈接源代碼所需要的變量。

3)    Module-Definition File

比如是power按鍵驅動文件下下面的PowerButton.DEF文件,包含在一個可執行或者dll文件中定義的共用符號、函數和變量的聲明。

4)    Sources File

包含編譯源代碼所需要的宏變量。

 

編譯工具貫穿一個目錄樹,先查找dirs文件,然後是sources文件。其中dirs文件指定要包含的源代碼或是另外的包含sources文件的子目錄。當編譯工具在當前的目錄定位到一個sources文件,它就調用Nmake tool(Nmake.exe)來編譯指定的C或C++源代碼文件,並且根據包含在makefile文件的鏈接規則來鏈接目標模塊。

WINCE源代碼配置文件 - 男兒當自強 - 男兒當自強的博客

圖1

下面就來分別學習這四種源代碼配置文件:

1. dirs文件

dirs文件是一個text文件,它指定了包含要編譯的源代碼的目錄,如SMDK6410 \SRC下的dirs內容:

DIRS =    \

    common        \

    oal            \

    kitl            \

    drivers        \

bootloader

這表示SMDK6410 \SRC目錄下的dirs文件要編譯common、oal、kitl、drivers和bootloader目錄下或者是這些目錄下的子目錄的源代碼文件。

 

Dirs文件內容中使用DIRS、DIRS_CE和OPTIONAL_DIRS關鍵字來如何編譯指定的目錄

1)    DIRS

如上面所示,DIRS用於指定要編譯的目錄,其中DIRS=*表示要編譯當面所有的目錄,另外上面的例子也可以改爲下面的方式來指定要編譯的目錄

DIRS=common oal kitl dirvers bootloader

也就是用空格鍵把要編譯的目錄隔開,但這樣不直觀,不提倡採用這樣的方式。

 

2)    DIRS_CE

只有DIRS_CE指定的目錄下的源代碼被寫進WINCE運行時鏡像的時候才編譯該目錄下的源代碼,如camera驅動下的dirs文件內容如下:

DIRS_CE=\

CAMERA_PDD\

OV9650_MODULE\

S3C6410_camera\

DLL

3)    OPTIONAL_DIRS

指定可以選擇編譯的目錄,比如OPTIONAL_DIRS=projectA,如果要編譯projectA目錄,可以設置BUILD_OPTIONS= projectA,然後運行build命令就可以了。

 

2. makefile文件

源代碼樹的每個子目錄(subdirectory)下面有一個sources文件和一個makefile文件,如下圖:

WINCE源代碼配置文件 - 男兒當自強 - 男兒當自強的博客

圖2

在應用開發環境中(an application development enviroment),比如VS2005中,一個makefile文件包含所有的命令、宏定義、和用於指定如何編譯的可選項,但是,相比之下,PB(Platforom Builder)中的makefile文件只包含有對一個共用的makefile的引用,如下:

WINCE源代碼配置文件 - 男兒當自強 - 男兒當自強的博客

圖3

而圖上中提到的環境變量_MAKEENVROOT在\PUBLIC\COMMON\OAK\MISC中的wince.bat中定義,見下圖:

WINCE源代碼配置文件 - 男兒當自強 - 男兒當自強的博客

圖4

圖4中環境變量_WINCEROOT,再結合圖1我們可知_WINCEROOT=F:\WINCE600,這樣就可以確定完整的路徑了,同時就可以推斷出這個被WINCE各部分共享的編譯文件也就在F:\WINCE600\PUBLIC\COMMON\OAK\MISC下,文件名爲makefile.def。

 

在Build.exe定位dirs和sources文件後,它設置一個內部環境變量,然後Nmake.exe使用此環境變量來附加(append) sources.cmn文件到適當的子目錄下的sources文件中。接下來,Nmake.exe使用makefiel.def文件來把當前的一系列環境變量轉換成對編譯器、鏈接器或其他工具的調用,這樣就可以編譯sources文件中指定的源代碼或者是鏈接需要指定的目標模塊(object modules)。

 

3.  xxx.def文件

xxx.def文件是一個模塊定義文件,它包含一個可執行或者dll文件中定義的共用符號、函數和變量的聲明,這些聲明是可執行文件(一般是dll文件)向外導出的接口,比如PowerButton驅動的PowerButton.def文件,內容如下:

LIBRARY    PWR

 

EXPORTS

    PWR_Init

    PWR_Deinit

    PWR_Open

    PWR_Close

    PWR_Read

    PWR_Write

    PWR_Seek

    PWR_IOControl

    PWR_PowerUp

PWR_PowerDown

雖然所有的可執行文件都能使用xx.def文件,但它主要用於鏈接器來定義dll的導出函數,xx.def文件的包含有下面的內容,,簡要描述常用的部分:

1)    NAME

2)    LIBRARY

此聲明告訴鏈接器創建一個DLL和此聲明部分必須先於其他聲明的部分,同時,鏈接器創建一個入口庫(an import library),除非在編譯的時候採用export文件(.export),在此不知道是哪裏決定是否生成.export文件的,我試過,就算是把我的PowerButton.def文件的內容清空,在對PowerButton驅動編譯的時候,也會在PLATFORM\SMDK6410\lib\ARMV4I\retail目錄下生成smdk6410_PwrBtn.exp和smdk6410_PwrBtn.lib文件,這兩個文件我似乎沒有在哪裏指定要生成啊????????????????

3)    STACKSIZE

4)    SECTIONS

5)    EXPORT

此聲明使一個或多個定義被有效導出給其他應用,主要是用於導出dll文件中的函數接口,這樣系統或者應用可以通過把此dll裝載到自己的內存空間後就可以使用這些導出的接口函數了。

6)    VERSION

 

4.  sources文件

sources文件設置目錄中源代碼的宏定義,這樣Build.exe就可以用這些宏定義來決定如何編譯和鏈接源代碼。在Build.exe解析(parsers)一個sources文件之後,Nmake.exe把sources文件併入共用的makefile文件Makefile.def中,Build.exe只遵照宏的指派和忽略其他指示。下面就來學習一下sources文件中的知識點。

 

1)     SYNCHRONIZE_DRAIN

Help文檔中的說明如下:

When you perform a build on a development workstation that has multiple processors, this creates the possibility that different Build Tool (Build.exe) threads might be running on different processors.

In this case, you must ensure that your build process is ordered so that Build.exe does not attempt to build a product without first building its dependencies.

If this macro definition is set to 1 in a directory's sources file, Build.exe builds that directory last.

A directory containing a sources file that uses this macro is not built until all other directories are built. For example, this macro definition allows you to ensure that all preceding library (.lib) files are built before building the current directory, which depends on the previous libraries.

Use this macro, and the related SYNCHRONIZE_BLOCK macro, very sparingly. When encountered, these macros completely stall the build process until synchronization is complete.

If a directory uses this macro, list the directory last in its parent dirs file

 

上面的重點就是如果在sources文件中設置了SYNCHRONIZE_DRAIN=1,那麼Build.exe會最後才構建此文件,也就是說先編譯dirs文件中其他的sources文件中沒有設置了SYNCHRONIZE_DRAIN=1的文件,最後再編譯sources文件中定義了此宏的文件,這樣就可以解決了庫依賴的問題,在這樣的情況下,我們就要確保WINCE操作系統的構建過程是有順序的,以便於Build.exe不會嘗試去構建一個它的依賴文件都還沒有構建的文件,否則就會產生找不到庫的錯誤。還要注意的一點就是,如果那個目錄文件中的sources文件設置了SYNCHRONIZE_DRAIN=1,我們還要應該把此目錄文件放在dirs文件的dirs表示行的最後面,這樣也說明了dirs中只是的文件也是有順序的。

 

2)     TARGETNAME

編譯生成的目標文件的文件名,不包括擴展名,比如:

TARGETNAME = s3c6410_touch

表示觸摸屏驅動生成的目標文件名爲s3c6410_touch。

 

3)     TARGETTYPE

生成的目標文件的類型,可以是下面三種類型

LIBRARY:目標文件是一個靜態鏈接庫文件(.lib)。

DYNLINK:目標文件是一個動態鏈接庫文件(.dll)。

PROGRAM:目標文件是一個可執行文件(.exe)。

 

4)     RELEASETYPE

此宏定義設置爲另個標示(flag):RELEASEDIR和RELEASELIBDIR,用於指定編譯的時候生成的二進制文件和庫文件存放的目錄,下圖是RELEASETYPE的取值說明

WINCE源代碼配置文件 - 男兒當自強 - 男兒當自強的博客

圖5

 

5)     DLLENTRY

如果TARGETYPE=DYNLINK,那麼宏DLLENTRY的定義是用於指定此dll文件的入口函數,如果沒有爲DLLENTRY賦值,就默認此dll的入口函數爲_DllMainCRTStartup,下面就來介紹DLLENTRY可能的取值:

 

⑴_DllMainCRTStartup

此函數是一個dll首先的C運行時(Runtime)入口點,此函數在C運行時中定義。當dll文件被映射到進程的地址空間的時候,操作系統調用此函數來初始化C運行時和調用全局變量的初始化,接下來會調用DllMain函數;在卸載dll的時候,操作系統會調用_DllMainCRTStartup函數來deinitialize C運行時和釋放初始化時的內存佔用。

 

因爲_DllMainCRTStartup會調用DllMain函數,所以我們的dll要定義DllMain函數,但不需要導出DllMain函數,其函數原型如下:

BOOL DllMain(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved);

 

⑵DllMain

Dll直接的入口函數,如果你的應用中使用C運行時,在我們的dll被進程attach的時候,那麼此函數負責執行C運行時任何的初始化,並且在dll被進程detach的時候,負責deinitialize C運行時和釋放初始化時的內存佔用。

 

如果DLLENTRY=DllMain,那麼我們的dll中就一定要定義此函數,和上面的原型一樣,當然,也可以不需要導出此函數,操作系統自己可以調用到這個函數。

 

⑶_DllEntryCRTStartup

dll基本(basic)的C運行時入口函數,此函數也是在C運行時中定義的,其作用和_DllMainCRTStartup函數類似,但是它會調用DllEntry函數,而不是DllMain函數,所以如果DLLENTRY=_DllEntryCRTStartup,那麼就必須定義但不一定需要導出的DllEntry函數,此函數原型如下:

BOOL DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved);

 

 

WINCE系統中C運行時庫(CRT)提供很多有用的函數來使編程更加容易,CRT存在於(reside in)coredll.dll和corelibc.lib中,我們可以通過鏈接coredll.lib來鏈接在coredll.dll中CRT的一部分。corelibc.lib包含CRT的啓動函數,初始之外,我們必須要鏈接它包含的其他CRT函數來首先確保最適宜的性能。

 

6)     DEFFILE

指定此模塊的.def文件,我們知道模塊是通過.def文件來導出此模塊的接口的。

 

7)     PRECOMPILED_INCLUDE

指定預編譯頭文件的名字,如果設置了此項,在編譯的過程中將enable指定的頭文件來參與編譯。

 

8)     TARGETLIBS

指定要鏈接到目標可執行文件(.exe或.dll)中的的其他(additional)庫文件和對象文件(.obj)。此宏代表性地只用於在我們的模塊需要鏈接輸出庫(export library)時,比如coredll.lib,ceddk.lib等,這些庫文件就是輸出庫,它們導出一些共用的函數給應用程序或者是模塊,這樣就可以使用這些共用的函數了。

 

9)     SOURCELIBS

指定要鏈接到我們的模塊中的庫文件,代表性地只用於鏈接靜態庫(static library),靜態庫是一個包含對象、函數和數據的文件。根據我的觀察,SOURCELIBS中指定要鏈接的庫一般是針對某個驅動用的而不是整個系統可以共用的庫,而TARGETLIBS指定的要鏈接的庫是一些共用的庫。

 

10) SOURCES

指定要編譯的源代碼文件。

11) SKIPBUILD

如果SKIPBUILD=1,則跳過而不會編譯此目錄。

12) PREPROCESSDEFFILE

如果設置爲1,必須預先處理包含了路徑指示的.def文件,觸摸屏驅動中PDD

層的sources文件就設置了這一項。

 

13) INCLUDES

指定額外的要搜索的頭文件,只有在要包含的頭文件是私有的(private)的情況下才使用此宏,因爲標準的共用的頭文件被自動包含進來。

 

14) WINCEOEM

設置該值,表示需要使用系統下一些共用的輸入庫(import library)和頭文件,此宏一般是系統級的部分來設置,比如是BSP包中的一些驅動。

 

15) WINCEMAP

用於指定在編譯過程中生成相應的.map文件,默認的情況下此宏設置爲1,此.map文件對於debug很有幫助。

 

Sources文件中還有一些其他的宏變量,詳細請參考MSDN中的help文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章