文章出处:
http://www.cnblogs.com/Dreamxi/archive/2011/04/11/2012514.html
1:首先是Makefile.def:
————————————————————————————————————————
在所有驱动的makefile中有!INCLUDE $(_MAKEENVROOT)/makefile.def
找到(_MAKEENVROOT)/makefile.def所在地方C:/WINCE500/PUBLIC/COMMON/OAK/MISC(这个路径下真是很多wince的精华所在,sysgen菜单的批处理文件就在这里了)
现在来看看这个makefile.def是什么东西。我觉得这个是真的makefile的前奏。
makefile.def非常庞大,不过都是一些环境变量的判断等,比如RELEASETYPE 的判断等,如果没有设置就是默认的。
在它的最后有
!IF EXIST(./makefile.inc)
! IFDEF WINCETARGETFILES
! INCLUDE ./makefile.inc
! ELSE IFDEF WINCETARGETFILE0
! INCLUDE ./makefile.inc
! ELSE IF "$(SPECIAL_IRC_DEPENDENT)" != "0" && "$(SPECIAL_IRC_DEPENDENT)" != ""
#
# Added for internationalization
#
! INCLUDE ./makefile.inc
! ENDIF
!ENDIF
!IF EXIST($(_PROJECTROOT)/oak/misc/makefilepost.inc)
! INCLUDE $(_PROJECTROOT)/oak/misc/makefilepost.inc
!ENDIF
!IF "$(BSP_TW8816_KEY)"=="1"
CDEFINES=$(CDEFINES) -DBSP_TW8816_KEY
!ENDIF
——————从这个可以看出,他结束之后到makefile了:真的好复杂啊。
++++++++++++++++++++++++++++++继续.................
makefile.def: Including C:/WINCE500/public/common/oak/misc/sources.ReleaseType_DEFAULT
Creating appropriate directories and deleting COMMON.LOC
Copying base resources to C:/WINCE500/public/common/oak/lib/ARMV4I/retail/0409
mkdir C:/WINCE500/public/common/oak/lib/ARMV4I/retail/0409 > nul 2>&1
xcopy /I C:/WINCE500/public/common/oak/lib/ARMV4I/retail/*.res C:/WINCE500/public/common/oak/lib/ARMV4I/retail/0409
把一些资源文件拷贝到下面这个路径(拷贝之前创建)
C:/WINCE500/PUBLIC/COMMON/OAK/LIB/ARMV4I/RETAIL/0409
+++++++++++++++++++++++++++++++继续..................
现在以2410 SDHC的DLL是如何生成的为例子在build.log找到相应信息。
BUILD_MARKER:LINK_DLL_END
nmake /NOLOGO C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/target/ARMV4I/retail/sdhc_sc2410.dll
makefile.def: Invoked with predefined settings:
TARGETNAME: sdhc_sc2410
TARGETTYPE: DYNLINK
RELEASETYPE: OAK
TARGETLIBS: C:/WINCE500/public/common/oak/lib/ARMV4I/retail/sdhc_sc2410_lib.lib C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/ceddk.lib C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/sdcardlib.lib C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/sdhclib.lib C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/sdbus.lib C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/sdk/lib/ARMV4I/retail/coredll.lib
SOURCELIBS:
DEFFILE: C:/WINCE500/public/common/oak/lib/ARMV4I/retail/sdhc_sc2410.def
EXEENTRY: WinMain
DLLENTRY: DllEntry
makefile.def: BUILDROOT is C:/WINCE500/public/common/cesysgen
0 Please add _COMMONPUBROOT and __PROJROOT to your tree''s cesysgen/sources file.
Directory: C:/WINCE500/PUBLIC/COMMON/CESYSGEN
TARGETNAME: sdhc_sc2410
makefile.def: Including C:/WINCE500/public/common/oak/misc/sources.ReleaseType_OAK//没有设置ReleaseType即默认OAK了
BUILD_MARKER:LINK_DLL_START Linking C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/sdhc_sc2410.lib
link -lib -out:C:/WINCE500/PBWorkspaces/KITL/WINCE500/smdk2440a_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/sdhc_sc2410.lib -def:C:/WINCE500/public/common/oak/lib/ARMV4I/retail/sdhc_sc2410.def -machine:thumb @C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/nm16D.tmp
————现在知道这个wince下自带的驱动是如何生成的了。哈哈。
——————————————————————————————————————————
——————————————————————————————————————————
现在再来看BSP下的驱动是如何生成的DLL的。
Linking /WINCE500/PLATFORM/SMDK2440A/Src/Drivers/camera/ directory.
BUILD: [00:0000000746:PROG ] ''NMAKE.EXE -i -c BUILDMSG=Stop. LINKONLY=1 NOPASS0=1 MAKEDLL=1''
BUILD: [01:0000000747:INFO ] makefile.def: BUILDROOT is C:/WINCE500/PLATFORM/SMDK2440A
BUILD: [01:0000000748:INFO ] makefile.def: Including C:/WINCE500/PLATFORM/SMDK2440A/sources.cmn
BUILD: [01:0000000749:INFO ] Directory: C:/WINCE500/PLATFORM/SMDK2440A/Src/Drivers/camera
BUILD: [01:0000000750:INFO ] TARGETNAME: camera
BUILD: [01:0000000751:INFO ] makefile.def: Including C:/WINCE500/public/common/oak/misc/sources.ReleaseType_PLATFORM
BUILD: [01:0000000752:PROGC ] Linking C:/WINCE500/platform/smdk2440a/lib/ARMV4I/retail/camera.lib
BUILD: [01:0000000753:INFO ] link -lib -out:C:/WINCE500/platform/smdk2440a/lib/ARMV4I/retail/camera.lib -def:camera.def -machine:thumb @C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/nm91C.tmp
BUILD: [01:0000000754:INFO ] Microsoft (R) Library Manager Version 7.10.4017
BUILD: [01:0000000755:INFO ] Copyright (C) Microsoft Corporation. All rights reserved.
BUILD: [01:0000000756:INFO ]
BUILD: [01:0000000757:INFO ] -nodefaultlib
BUILD: [01:0000000758:INFO ] -ignore:4001
BUILD: [01:0000000759:INFO ] -subsystem:windowsce,5.00
BUILD: [01:0000000760:INFO ] obj/ARMV4I/retail/camera.obj
BUILD: [01:0000000761:INFO ] C:/WINCE500/platform/smdk2440a/lib/ARMV4I/retail/ceddk.lib
BUILD: [01:0000000762:INFO ] Creating library C:/WINCE500/platform/smdk2440a/lib/ARMV4I/retail/camera.lib and object C:/WINCE500/platform/smdk2440a/lib/ARMV4I/retail/camera.exp
BUILD: [01:0000000763:INFO ] set LIB=C:/WINCE500/sdk/CE/lib
BUILD: [01:0000000764:PROGC ] Linking C:/WINCE500/platform/smdk2440a/target/ARMV4I/retail/camera.dll
BUILD: [01:0000000765:INFO ] link /LARGEADDRESSAWARE -out:C:/WINCE500/platform/smdk2440a/target/ARMV4I/retail/camera.dll
—————从这个camera驱动可以看出,BSP和微软自带的驱动生成DLL几乎是一致的,只是第一次生成的lib位置不同而已。
看了build.log文件
已经得出答案:我们选sysgen没有编译微软的源代码,我们装上PB的时候他的源代码的lib已经存在他规定的路径了。
我们实现的过程就是把他的lib拷贝到工程的相应的路径下,makefile再把他转换成DLL——最后打包
注意虽然BSP下的直接规定生成DLL,但是首先也是生成lib的,最后也和微软自带驱动一样,生成DLL
2:source
A、SOURCES文件的结构:
首先我们来看一个SOURCES文件,如下所示,SOURCES主要包括了一些用户的宏定义,这些宏会被MAKEFILE和NMAKE使用,来编译项目的源代码。
!if "$(BSP_NOHSMMC_CH0)"=="1" ##如果SMDK6410.BAT中SET BSP_NOHSMMC_CH0=1那么这个项目将不被编译。
SKIPBUILD=1
!endif
SYNCHRONIZE_DRAIN=1
RELEASETYPE=PLATFORM##生成文件存放的位置
TARGETDEFNAME=s3c6410_hsmmc
DEFFILE=$(TARGETDEFNAME).def##指定DLL文件导出接口函数
TARGETNAME=s3c6410_hsmmc0 ##DLL文件名称
TARGETTYPE=DYNLINK ##表示生成DLL文件
DLLENTRY=DllEntry ##DLL入口地址
##以下是源文件里用的到宏的定义
CDEFINES=$(CDEFINES) # -D_SMDK6410_CH0_EXTCD_ # -D_SMDK6410_CH0_WP_
##以下是头文件的路径列表
INCLUDES=$(INCLUDES);../s3c6410_hsmmc_lib
##以下是要动态链接的库文件
TARGETLIBS= /
$(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/ceddk.lib /
$(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib /
$(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/DriverLib.lib
##以下是要静态链接到目标文件中的库文件列表
SOURCELIBS= /
$(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/sdcardlib.lib /
$(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/sdbus2.lib /
$(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/s3c6410_hsmmc0_lib.lib
SOURCES=s3c6410_hsmmc.cpp##要编译的源文件。
B、SOURCES文件调用的流程:
在要被构建的目录中,如果该目录中包含SOURCES文件,那么在相同的目录下一定还有MAKEFILE文件,通常MAKEFILE只包含一行内容:!INCLUDE $(_MAKEENVROOT)/makefile.def
其中_MAKEENVROOT = E:/E600/PUBLIC/COMMON/OAK/MISC (用SET命令查看),其中WINCE600/PUBLIC/COMMON/OAK/MISC/makefile.def 文件大概有3000行,是补所有WINCE 项目共享的公用MAKEFILE模板,在中间可以找到:
!INCLUDE $(MAKEDIR)/sources
这样makefile.def就包含了本地的SOURCES文件。因此,当构建系统在某个目录中调用NMAKE时,NMAKE会去使用该目录中的MAKEFILE,然后MAKEFILE把makefile.def展开到本地,makefile.def还会把本地的SOURCES文件包含进来,这样本地SOURCES文件中定义的宏与makefile.def中的宏共同起作用,就形成了一份完整的可被NMAKE使用的MAKEFILE。
c:Sources文件(告诉编译器和连接器如何编译及连接本驱动程序)
TARGETNAME=SPI //驱动动态库名字
RELEASETYPE=PLATFORM //发布类型,BSP包中的一个驱动
TARGETTYPE=DYNLINK //目标类型为动态库
TARGETLIBS=$(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib //需要连接的库
DEFFILE=SPI.def //.def文件名称
DLLENTRY=DllEntry//动态入口函数名称 :DllEntry
SOURCES=SPI.c//要编译的源代码
3、SOURCES.CMN文件的调用:
sources.cmn文件调用流程也同SOURCES文件一样的。从WINCE600/PUBLIC/COMMON/OAK/MISC/makefile.def 文件中如下代码可以看出:
!IF EXIST($(BUILDROOT)/sources.cmn)
! MESSAGE makefile.def: Including $(BUILDROOT)/sources.cmn
! INCLUDE $(BUILDROOT)/sources.cmn
!ENDIF
技巧:
尽量将驱动中用到的宏,放到PLATFORM/sources.cmn里面来定义,这样有一个好处,就是宏定义直观,方便查看,修改快捷。
sources.cmn是Common Source文件,BSP内所有的源代码编译都会用到该文件。里面定义一些比较常用的名词或环境变量或路径
source文件是针对特定目录的,只对当前目录有效。是针对当前目录的一些编译单位的环境变量或指定如何编译DLL等(将哪些文件或库编译进去)