PB是如何工作的?

时间:2022-02-18 19:54:45

http://chenyq2008.spaces.live.com/blog/cns!F73164AC8D0D8D50!252.entry

PB是如何工作的?

【使用pbxmlutils打开工程文件】

随便打开一个控制台窗口。先找到pbxmlutils工具所在的路径。比如我的:

D:/Program Files/Microsoft Platform Builder/6.00/cepb/IdeVS/pbxmlutils.exe

然后就执行下面的命令, 这样就可以打开一个工程文件, 不需要vs2005就可以构建nk。

pbxmlutils /getbuildenv /workspace "工程文件所在路径/OSDesign1.pbxml" /config "SMDK2440A ARMV4I Release" > Env.bat

 

call Env.bat

 

@echo off

call %_TARGETPLATROOT%/%_TGTPLAT%.bat

这和在vs2005里面打开工程文件一样,接下来就可以执行blddemo命令来构建平台了。

Pbxmlutils.exe打开工程文件时候调用wince.bat初始化cpu类型, 路径等等环境变量, 其中最主要的是建立了变量_DEPTREES, 逻辑比较简单, 就是遍历public下各个自目录下的cesysgen目录下是否存在makefile文件, 如果存在就增加到_DEPTREES

_DEPTREES=winceos dcom gdiex ie script servers shellsdk shell rdp wceshellfe wceappsfe directx voip datasync netcfv2 SQLCE cellcore ostest mediaapps speech FP_VOIP OSDesign3

_DEPTREES就长得这个样子的。 里面就是各个小模块,结构称之为树。组件是以树的形式安排, 每一个树就是public或者private下面的子目录。

使用了上面方法, 在普通的控制台就可以打开工程编译了, 不用启动pb或者vs2005. 我是在wince6下测试的。

用户主要接口blddemo命令

BldDemo [[no]clean][[no]cleanplat][nuke][nurel][Parms for CEBUILD]

用途:构建命令。伪代码如下:

Blddemo(clean, norel, Parms)

{

 cebuild(Parms); //build操作系统, project和平台模块。

 

 if (!norel)  buildrel();  // release copy

 

 if (!nomakeimage)   makeimg(); // makeimg

 

 cesysgen();  //

}

blddemo是直接提供给用户的接口, 调用一系列处理完成整个过程。最常用的是BldDemo -q和BldDemo clean -q。 简单介绍下,如果clean参数带上, 则清理之前编译构建遗留的文件。 Cleanplat把bsp目录下target和lib目录清理。Nuke则相当clean+cleanplat。如果指定norel,那么sysgen和build完后不会release copy和makeimage, 如果指定nomakeimg, 则不会makeimage。buildrel是release copy步骤,把需要的文件拷贝到指定目录准备打包。 makeimg打包image。

 

【重头戏:cebuild.bat】

cebuild [-h] [-r] [-q] [-d deptree_entry] [build_flags]

用途:build操作系统, project和平台模块。伪代码如下:

 

cebuild(Parms)

{

i(Parms == “-qbsp”)  // -qbsp的意思是只处理bsp。

goto skipdeptree;

// build all the trees. _DEPTREES在前面打开项目时候在wince.bat赋了值。

i(_QBLDNEWDEPTREES == "")

_QBLDNEWDEPTREES = _DEPTREES;

 

for (遍历_QBLDNEWDEPTREES

 cebldtree(TreeName, preproc);  // cebldtree , ce_build_tree.

 

for (遍历_DEPTREES

 cebldtree(TreeName, postproc); 

 

skipdeptree:

if (!SIGN_WITH_RELEASE_KEY)

ManagedCodeSign(); // 和托管代码相关处理,先忽略

 

      SysgenPlatform(preproc);

cebuild1(platform, common);

cebuild1(platform, bsp);

Sysgenplatform(postproc);

 

// build 开发者指定目录。 指定路径:

// %_WINCEROOT%/deelopr/%USERNAME%/Source

Build(user_path); // build是ms提供的编译链接工具。

}

 

cebldtree(TreeName, proc)

{

 if (Parms == -q)    // 这里就是参数-q作用的地方了。之所以Quick的原因了。

goto skip_compile;

 

 cebuild1(private, TreeName); // 编译链接private代码。

 cebuild1(public, TreeName); // 编译链接public代码。

 

skip_compile:

sysgen( ); // 除了winceos,在树里要求子目录cesysgen下存在makefile.

}

 

 

【万佛朝宗】

项目不管多么恢弘, 离不开编译和链接。 编译工具就是cl.exe, 链接工具就是link.exe, 在sdk目录下。 今时今日, 都在用make工具, MS使用nmake, 自动根据时间戳来判断编译哪些。 更进一步的, 在nmake之上, MS用build.exe来处理代码。 据说MS大部分产品都是这样的, winddk也是, 所以总感觉搞ddk和wince那么相似。Build使用了dirs + source 文件来建筑整个代码结构的大厦。 废话到此。

所以上面的过程, 仍然没有看到build或者nmake。继续往下挖掘就看到答案了:

cebuild1()

{

build(); 

}

 

Sysgen(Parms)

{

 cesysgen(); // 执行目录树/oak/misc/cesysgen.bat 

 nmake(); 

}

PB如何工作的?(二)

【sysgen变量】

创建一个工程项目的时候就要选择各种功能组件, 每选择一个就设置其对应的sysgen变量等于1, 比如选择ABC后, IDE就会自动设定了环境变量SYSGEN_ABC=1,并且最后会写入工程文件pbxml保存。 所以打开一个工程项目, 就自动获得并设置好了所有选定的sysgen变量。

 

【树 -- TREES】

编译活动就是把树逐个编译。

之前说过, 树是public下面子目录,一个子目录有可能是就是一个树, 如果是树, 那么树下就会有目录cesysgen, 它下还有makefile文件。除了这些树外,还包括了一颗最大的树:winceos和一棵项目树如下的OSDesign1

dep trees: winceos dcom gdiex ie script servers shellsdk shell rdp wceshellfe wceappsfe directx voip datasync netcfv2 SQLCE cellcore ostest mediaapps speech FP_VOIP OSDesign1

这片树林是由wince.bat建立的。

编译一棵树是分2个步骤:第一次是preproc, 第二次是postproc在编译这些树的时候, 如果没有使用“-q”选项, 那么在编译每棵树的时候都会到private和public目录里面去兜一圈, 找到与自己的树名相同的目录, 编译一遍代码。 winceos树对应的是common目录和winceos目录, 里面海量代码大概要编译几个小时。除非自己修改或者补丁 造成的代码更新, 否则还是别那么干吧。 Private目录是可选的, 如果安装pb时候选了share code, 那么就会有private目录,里面全是代码。

winceos是最特别的树, 也是占用我们编译时间最多的。

 

【细说sysgen过程】

接下来, 就对每一颗树进行sysgen。如下:

Sysgen -p 树名 -b clean preproc/postproc

如果是winceos树, 省略参数 -p 树名。换言之,不带-p参数的话,它的默认树名为common,即winceos。

sysgen过程就2个步骤:1.cesysgen,2.nmake

1. cesysgen有3个功能, 检查, 报告和设置。检查功能就是检查sysgen变量是不是等于1. 报告功能就是报告当前所有的sysgen变量等。 cesysgen最主要的功能是设置环境变量给nmake使用, 指定需要哪些模块MODULES和组件COMPONENTS。流程是这样的, sysgen首先调用的是项目目录下的cesysgen.bat, 然后它调用位于public/cebase/oak/misc目录下的cesysgen.bat, 然后这个cesysgenpreproc,pass1,pass2步骤来逐个调用位于同一目录下的树名.bat 以及cebasecesysgen.bat如果,他们存在的话。

2. nmake失败会导致常见的“error SYSGEN0000: error(s) in sysgen phase”错误提示。不少人拿这个错误来询问原因, 其实这只是个提示,还需要结合日志build.log来检查具体的错误原因,个别情况下,可以考虑修改下makefile辅助调试准确定位错误。

【模块和组件 -- MODULES and COMPONENTS】

http://msdn.microsoft.com/en-us/library/ms924511.aspx 

前面说到cesysgen设置变量给nmake处理。 设置些什么变量? 怎么解决模块和组件之间的依赖关系?

一棵树由许多模块组成,