MSCE C++官网一步步学习搬运2

第二章、制作文件mke详解

MicroStation的老版本是支持跨平台开发的,所以其开发架构并没有沿用微软的体系而是采用了类似Unix/Linux的开发体系,即利用制作文件来控制整个项目的生成过程。如果您在Unix或Linux下用GCC做过开发的话,相信会对这套系统有似曾相识之感。下图是一个完整的生成ma和dll的流程。

MSCE C++官网一步步学习搬运2

 

其中带有阴影线的块为源代码(有头文件、资源文件、类型文件和C++文件),需要我们手工编写;矩形块为一些执行程序,包括资源编译器、类型生成器、MDL库打包程序、C++源文件编译器、目标对象链接器等;其它块为生成的中间文件或最终文件。

MDL程序中的资源分命令表资源、对话框资源、消息资源、类型资源等,它们最终都生成到了ma(ma为MicroStation Application的缩写)这个文件中。这些都是Bentley公司特有的,必须按照规定的语法来写这些资源文件(可惜的是Bentley没有提供像VS中那样直观的可视化工具来生成这些资源文件,所以,对于刚接触MDL开发的人来说往往会感觉很繁琐)。而MDL中的C++源文件到动态链接库的生成过程和我们普通的C++文件编译和链接过程是相同的,都是调用的微软VS下的编译器cl.exe和链接器link.exe将cpp文件生成obj文件,再进而将obj文件(可能是多个)链接成一个dll文件。这两部分几乎独立的过程都是靠一个mke文件来控制的。

 

下面我们以上一章的mke文件为基础来详细解释这个制作文件的语法和今后工作中需要修改的一些地方。

在制作文件中存在如下6中需要掌握的语法:

  • 注释:以#号开头的行为注释行,bmake程序出现mke文件时会忽略这些行
  • 宏定义:如appName = HelloWorld这样的形式。appName被称为宏名称,HelloWorld被称为宏的值
  • 宏展开:以$(宏名称)形式表达。如果$(appName)$(oext)被展开后就是cpp
  • 依赖:比如$(o)$(appName).rsc : $(baseDir)$(appName).r这样的形式,前者依赖于后者。当后者发生修改后,前者需要重新生成。否则会忽略这样的行。这样做的目的是为了加快整个项目的生成速度,仅对修改的内容生成目标文件
  • 规则:如
$(mdlapps)$(appName).ma     : $(appRscs)
        $(msg)
        > $(o)make.opt
        -o$@
        $(appRscs)
        <
        $(RLibCmd) @$(o)make.opt
        ~time

 这样的形式。由$(appRscs)生成$(appName).ma时,在所有mki(制作文件的头文件)中没有默认的规则,这里列出了显式的规则。最终调用的是命令$(RLibCmd)将多个rsc文件打包成了一个ma文件。$(RLibCmd)展开后其实就是SDK中bin文件夹下而rlib.exe。

【注】:在依赖下面空了一行而没有直接跟规则的,表示到mki中查找默认规则!!!

  • 语句:如%include或%ifdef等这样以%开头的。要么执行包含动作,要么执行一些条件分支功能。

详细的mke文件语法可从SDK帮助文档MicroStationApi.chm的Creating a Makefile and Using the bmake Utility一节中查得。要想更深入地理解mke文件,还需要您读系统的mki文件,这些文件定义了许多系统内置的宏定义和规则。

 

接下来我们总结一下实用中你需要关心的几点,只要把握了这几点,今后新建mke文件和修改mke文件基本上就都可以了。

  • appName定义项目名称。当你要新建一个项目时,需要复制出一个文件夹,修改各文件名后,在mke文件中将appName这个宏的值修改为你新项目的名称;
  • 每增加一个.cpp文件需要修改appObjs的定义以及增加一行生成obj的行。注意,行尾的反斜杠符号是续行符,该续行符之后一定不能再有空格。
$(o)XXX$(oext) : $(baseDir)XXX.cpp $(baseDir)XXX.h
  • 如果调用了其他库中的函数,需要将含有该函数的库文件名添加到LINKER_LIBRARIES宏定义中
  • 如果引用了其他系统的头文件,需要设置dirToSearch指向新的头文件所在的文件夹,然后包含mki。
  • 根据项目的不同,可能会含有命令表资源文件、对话框资源文件等等,需要将各资源文件都定义到appRscs宏中,类似cpp文件,每增加一个资源源文件.r就要增加一行从.r生成.rsc的定义。在mke中已经定义好了有关命令资源的处理行,只需要取消行首的注释符#号即可。

 

上一篇:数据结构实验之栈与队列六:下一较大值(二)


下一篇:MSCE C++官网一步步学习搬运1