Windows CE系统的build系统一向是让众多CE开发者头疼的东西,这里我就来概要地谈谈我对WindowsCE build系统的理解。完整的理解整个build的流程也有助于调试和排除一些build中遇到的问题。
首先,我们安装好的Platform builder中包含了Windows CE的公开源码以及私有源码build成的lib文件。正常情况下,我们建立一个新的Windows CE OS Design项目,然后选择build,就可以生成一个nk.bin文件。那么,我们就先来了解一下build分为哪些步骤:
首先,准确地说整个build过程被称作build demo, 在命令行中,blddemo是一个批处理命令,它是用于完整build整个Windows CE操作系统。它分为三个阶段:
1、build子项目阶段(为了不致混淆,我们约定,build子项目阶段简称build阶段,整个build过程称为build demo过程):build public目录中的所有子项目,build系统根据dirs文件和sources文件中的信息识别子项目并且(理论上)互不干涉地build各个子项目。build产生的库(lib)和二进制(dll、exe)文件将会根据不同标识被复制到主项目(见注)的oak和sdk目录中(OAK是给WinCE的OEM厂商使用的,SDK是给开发者使用的)。
2.System Generate(可暂译为系统生成,简称sysgen)阶段:将build阶段产生的库文件和私有源码build成的lib文件按照主项目的makefile文件指定的方式链接成exe或者dll文件,并且将生成的文件复制到release目录中。sysgen过程受到环境变量的控制,所有sysgen_开头的环境变量都是用于控制组件的。
3.Make Image阶段:根据主项目的bib文件将release目录中的一些exe文件写入nk.bin,作为ROM的镜像。
以上就是builddemo过程的简单描述,实际上,具体过程还有更多复杂的细节,例如:
1.build阶段有些子项目有依赖关系,所以sources中可以指定子项目的build次序
2.build阶段会有一些localization子项目,这些子项目负责从微软的数据文件中抽取相应的res文件
3.主项目cesysgen中有很多批处理文件,用于处理sysgen变量之间的依赖关系
4.Catalog是sysgen变量的图形化操作,但是它并不能控制所有sysgen变量
5.make image阶段会替换exe文件中的资源以完成本地化
6.make image前还有BSP的build过程
……
类似的具体细节有很多,大家可以留意build demo 中产生的log
接下来介绍几个build时比较实用的命令
blddemo :默认的完整build demo过程,会自动检测已经build完成的子项目并且跳过
blddemo –q :快速build demo过程,会跳过build子项目阶段,直接从sysgen开始,当更改sysgen变量之后可用此项
blddemo –c :清理子项目的build demo过程,会重新build所有子项目
blddemo clean –c :清理子项目及的build demo过程,会重新build所有子项目,并且删除sysgen产生的文件重新做sysgen
makeimg :重新生成nk.bin文件
makeimg –c :会清空release目录 重新copy sysgen产生的文件并且重新生成nk.bin文件
sysgen –p <主项目名> :重新sysgen某一个主项目
sysgen –p <主项目名> <模块名> :重新sysgen某一个主项目中的一个模块,一般而言一个模块对应一个二进制文件
build :build当前目录的子项目
build –c :重新build当前目录的子项目
注:主项目指public目录下的一级目录
编译方法
VS2005的"Build"中"Advanced Build Commands",有好几个WinCE 6.0的编译方式: (瞅着混乱)
"Sysgen":相当于执行命令"blddemo -q”,一般第一次编译或者是改变了"Catalog"中的item的时候,用之。
"Clean Sysgen":相当于执行命令"blddemo clean -q",按照文档上的说明,当修改了 %_WINCEROOT%PublicCEBASEOAKMiscCesysgen.bat的时候,或者改变了以SYSGEN,BSP为前缀的环境变量的时候,需要使用这个来编译。
一般只有第一次创建完工程的时候,才需要用"Sysgen"命令,以后只要是改变了SYSGEN为前缀的环境变量的设置或者是"Catalog"中的item,就需要使用"Clean Sysgen",而改变了以BSP为前缀的环境变量要看具体情况,也不一定就要用"Clean Sysgen"。
"Build and Sysgen":相当于执行命令"blddemo",当改变了public目录下的代码,比如你打了WinCE的patch,你就需要用这个了。
"Rebuild and Sysgen Clean":相当于执行命令"blddemo clean cleanplat -c",相当于清除上一次编译生成的文件,然后重新编译public目录和你的工程。
"Build and Sysgen Current BSP":相当于执行命令"blddemo -qbsp",仅编译platform目录下的代码。所以当改变了platform目录下的代码的时候或者说改变了BSP的代码的时候,可以用这个来编译。
"Rebuild and Clean Sysgen Current BSP":相当于执行命令"blddemo -qbsp -c",相当于完全重新编译platform目录下要编译的代码。
WinCE5.0/WinCE6.0下,通过command line实现自动化编译:
对于WinCE5.0:
1. pbxmlutils.exe
在“/Windows CE Platform Builder/5.00/CEPB/BIN”下面可以找到,这个命令可以从PB的文档中查到。主要作用是通过解析你的工程文件.pbxml来获得与该工程相关的环境变量,并产生一个脚本来设置这些环境变量。格式如下:
pbxmlutils /getbuildenv /workspace "%_WINCEROOT%/PBWorkspaces//.pbxml" /config ": " > SetEnv.bat
看着可能有点晕,我来举个例子:
pbxmlutils /getbuildenv /workspace "%_WINCEROOT%/PBWorkspaces/MyWorkspace/MyWorkspace.pbxml" /config "CEPC: x86_Release" > SetEnv.bat
其实就两个参数,第一个参数很多人都知道如何设置,第二个参数config可能有些人不太了解,你可以打开你的工程,然后查环境变量PBCONFIG的值,用这个值就可以了。
2. Blddemo.exe
这个应该比较熟悉。编译WinCE的时候,实际上就是调用Blddemo -q,不多说了。
3. buildsdk.exe
这个是用来编译SDK的。格式如下;
buildsdk [MyOSDesign.pbxml]
很简单,不过还是给个例子:
buildsdk "%_WINCEROOT%/PBWorkspaces/MyWorkspace/MyWorkspace.pbxml"
对于WinCE6.0:
1. pbxmlutils.exe
在“/Microsoft Platform Builder/6.00/cepb/IdeVS”下面可以找到,这个命令可以从PB的文档中查到。主要作用是通过解析你的工程文件.pbxml来获得与该工程相关的环境变量,并产生一个脚本来设置这些环境变量。格式如下:
pbxmlutils /getbuildenv /workspace "%_WINCEROOT%/OSDesigns///.pbxml" /config " " > SetEnv.bat
来举个例子:
pbxmlutils /getbuildenv /workspace "C:/WINCE600/OSDesigns/MyWorkspace/MyWorkspace/MyWorkspace.pbxml" /config "CEPC x86 Release" > SetEnv.bat
和WinCE5.0有些小的区别,要注意一下。同样如果不知道第二个参数config如何设置,可以打开工程,查环境变量PBCONFIG的值,用这个值就可以。
2. Blddemo.exe
这个和WinCE5.0用法一样。编译WinCE的时候,实际上就是调用Blddemo -q。
3. buildsdk.exe
这个是用来编译SDK的。格式如下;
buildsdk [MyOSDesign.pbxml] [MySdkConfig.sdkcfg]
很简单,不过还是给个例子:
buildsdk "/OSDesigns/MyWorkspace/MyWorkspace/MyWorkspace.pbxml" "/OSDesigns/MyWorkspace/MyWorkspace/SDKs/SDK1/SDK1.sdkcfg"
基本上,自动化编译所需的主要命令都已经介绍完了,下面介绍如何使用上面的命令实现:
对于WinCE5.0:
@echo off
@set _WINCEROOT=c:/wince500
@set _PBROOT="c:/Program Files/Windows CE Platform Builder/5.00"
@set PATH=%PATH%;c:/Program Files/Windows CE Platform Builder/5.00/cepb/bin
cd /D %_WINCEROOT%
if exist build.log del build.log
if exist build.wrn del build.wrn
if exist build.err del build.err
pbxmlutils /getbuildenv /workspace "%_WINCEROOT%/PBWorkspaces/MyDesign/MyDesign.pbxml" /config "Samsung SMDK2410: ARMV4I_Release" > buildenv.bat
call buildenv.bat
call %_TARGETPLATROOT%/%_TGTPLAT%.bat
call Blddemo -q
buildsdk "%_WINCEROOT%/PBWorkspaces/MyDesign/MyDesign.pbxml"
对于WinCE6.0:
@echo off
@set _WINCEROOT=d:/wince600
@set _PBROOT=C:/Program Files/Microsoft Platform Builder/6.00
@set PATH=%_PBROOT%/cepb/idevs;%PATH%
cd /D %_WINCEROOT%
if exist build.log del build.log
if exist build.wrn del build.wrn
if exist build.err del build.err
pbxmlutils /getbuildenv /workspace "%_WINCEROOT%/OSDesigns/MyDesign/MyDesign/MyDesign.pbxml" /config "CEPC x86 Release" > buildenv.bat
call buildenv.bat
call %_TARGETPLATROOT%/%_TGTPLAT%.bat
call Blddemo -q
call buildsdk "%_WINCEROOT%/OSDesigns/MyDesign/MyDesign/MyDesign.pbxml" "%_WINCEROOT%/OSDesigns/MyDesign/MyDesign/SDKs/SDK1/SDK1.sdkcfg"
上面针对WinCE5.0和WinCE6.0的两个命令略有不同,但是原理是一样的。只要有点Windows脚本命令的知识,了解WinCE的整个编译过程,看懂上面的代码应该没问题,这里就不作介绍了。
上面给出的只是例子,上面的代码,可以实现command line编译WinCE并且还可以导出SDK。如果想实现对多个工程进行编译,只需要对上面的脚本作些修改就可以了。上面的脚本完全可以改写成函数的形式,通过传递工程文件名和平台的config来编译WinCE,这样就可以对多个工程顺序进行编译,这里就不介绍了。