什么是工程文件
为了使用 CodeWarrior 来创建一个应用程序,你必须创建许多文件来构成一个工程(Project)。该工程的设置和所有这些文件的指针都被存放在一个工程文件中。这些设置包括编译和链接设置、源文件、库文件以及它们之间用于产生最终程序的相互关系。你可以将这个工程文件看作该工程的大脑:它保存了所有文件相互依存的关系并知道如何将它们组合成为一个可用的应用程序。工程窗口依次显示了这些关于你的程序和该程序所包含的文件的信息,并允许你只需轻松点击就可以修改这个工程。图2-1显示了工程窗口的外观。
图 2-1: 显示工程信息的工程窗口(图示为空的情况)
大多数组成你的程序的文件都是原始的文本文件。这些文件包含了你在 CodeWarrior 的编辑器中键入的源代码。在某些情况下,你还将使用一些预编译的源码和头文件。在进行数学运算和 I/O 操作时,你还要使用到一些库文件,比如 Metrowerks 标准库(Metrowerks Standard Library,MSL)
通常,你都是使用 C 或 C++ 来编写源代码,但通过给 CodewWarrior 的集成开发环境加装相应的插件(plug-in),你也可以在 CodeWarrior 中使用其它语言来进行编程。别忘了,CodeWarrior 可是一个可扩展的集成开发环境。通过给它安装一些插件,你就可以扩展它的功能。比如说,加入有人开发了一种新的叫做 Z++ 的编程语言,你就可以为 CodeWarrior 创建一个相应的插件使之能够支持 Z++ 语言,而且你还可以拿这个插件卖好多钱,让所有使用 CodeWarrior 编程的人都使上 Z++ 语言。那该多好!:)
现在你知道了 CodeWarrior 是如何使用文件的了。下面我们来详细地学习有关工程窗口的知识。
工程窗口
当你启动 CodeWarrior 并打开或创建一个工程时,工程窗口就会显示出来。该窗口用于管理整个工程的所有文件以及这个工程将要产生的目标(targets)文件。一个工程包含了足够的信息来编译一个或多个目标文件。所谓的目标(target)文件就是当你编译程序时,由 CodeWariior 创建出来的(通常是)一个应用程序或库文件。一些程序可以编译产生多个目标文件。比如,你可以编写一个程序来创建一个 DLL 和一个调用该 DLL 的主应用程序。在 CodeWarrior 的工程中,你可以定义一个目标来产生 DLL,定义另一个目标来产生应用程序。通过这种方式,你的工程只需编译一次就可产生所有需要的目标文件或片断。图 2-2 显示了“Hello World”程序的工程窗口。
图 2-2: Hello World 程序的工程窗口(其中显示了所有包含于该程序中或用于编译该程序的文件)
你可以看到,在这个工程窗口中确实包含了一些项目。在窗口的顶端有三个标签(tab)页:文件标签(如图2-2显示)、链接顺序标签页和目标文件标签页(后两个标签页将在后续课程中讲述)。在这几个标签页的上方,有一个用于选择要编译的目标文件的下拉菜单。在本例中,我们选择的是 Hello World 工程的调试版本。在下拉菜单的右边有几个图标,它们的存在允许你不必使用菜单命令就可以方便地编译、链接和运行这个工程。
注意: 在某些版本的 CodeWarrior 中,链接标签被称为段(segments)标签。有些人可能在某些 X86 的处理器上编程时使用的是分段(segmented)代码。但使用 Windows 版的 CodeWarrior 工具时就不是这样,这是产生的 X86 代码使用的是"扁平的"(flat),或者叫做非分段的(unsegmented) 内存空间。
顾名思义,文件标签页列出了在工程中所有可能用到的文件。你可以通过创建一些组(用文件夹图标表示)来分门别类地管理这些文件,并可以帮助你方便地了解哪些文件将被使用。在本例中,我们将 C 程序(以.c为后缀名的文件)全都放到一个叫做 Source 的组中,同时将库文件放到另一个组中,以便整洁明了地管理这些文件。
在 Sources 组中有一个 main.c 文件。因为我们还没有编译这个工程,所以在每个文件对应的 Code 和 Data 栏中显示数字的都是零。一旦我们编译了这个工程,这些数字就将显示出来,表示源码转换为机器代码后实际的代码量和数据量。可是,库文件 ANSICX86.LIB 和 MWCRTL.LIB 后面显示的是 n/a 。这表示索虽然这些文件被显示在这里,但是它们并不是 Hello World 目标文件的一部分。这两个文件是用于不可调试(non-debugging)开发的,而本例不是这种情况。如果我们从菜单中修改本例的目标文件为 Release(发布) 版本时,这两个文件就用得上了。这时这些文件后面的 Code 和 Data 栏目就会显示相应的数值。
注意 : 在 Data 和 Code 栏右端的 Target 栏目中的小子弹头也是用来表示该文件是否被当前编译生成的目标文件使用到。
再往右边去,是 Debug 栏(用一个绿色的小虫子表示),它是用于告诉你对应的文件在编译时是否要产生调试信息。我们将在第五课中详细论述这部分内容。最后,我们来看看在每一行最右端的弹出菜单,它是用于打开文件、更新源码、打开包含的头文件等等操作的快捷方式,具体是什么才作,要看它所代表的项目的类型而定。
现在让我们来编译这个 Hello World 工程并看看编译后的工程窗口的情况。我们从 Project 菜单中选择 Make 命令来编译该工程。这将更新所有需要编译的文件并产生相应的输出文件——在本例中是 Hello World 这个应用程序。
图 2-3: 编译工程后的工程窗口的显示情况
从图2-3中我们可以看到,工程窗口发生了一些变化。Code 和 Data 栏都显示了当前工程中对应项的相应的数字。如果你打算看看编译前后存放这些文件的目录的话,你会发现编译后在该目录下产生了一些新的文件,如图2-4所示。
图 2-4: 编译后将在工程目录中产生一些新的文件
在本例中,编译工程后在工程目录中产生了一个新的文件。这就是 X86 目标文件输出——生成一个叫做 Hello World x86 的应用程序。其它一些一直存在于这个目录中的文件是: .mcp 文件—工程文件本省,以及 .c 源文件—包含了应用程序源码的文件。Hello World Data 目录中还包含了由 CodwWarrior 生成的各种各样的支持文件。现在你还不必去关心这些文件。如果你正在编译目标文件的调试版本,你会看到更多的文件被产生出来,这些文件中可能包含着符号(symbolic)调试信息。集成开发环境的调试器使用这些符号信息来记录在高层次源码中的操作轨迹。我们将在第五课中详细讲述这方面内容。
现在你已经了解了这些文件是如何结合在一起被编译生成一个目标文件的。让我们来运行这个目标文件并看看它的运行结果是什么样。你双击 Hello World x86 应用程序,就会有如图 2-5所示的结果显示出来。
图 2-5: Hello World 应用程序的运行结果
你来试试看
总有一天,你自己也能编写出象 Hello World 这样充满激情和意义深远的程序来。这是完全有可能的。只要你有决心努力工作,学完本课你就可以编写这个程序了。下面我们给出该程序的源代码:
#include
void main(void) {
int c;
printf("Hello World on Windows!\n");
c = getchar();
}
就这么多!你没想到会这么简单吧?你可以试试看将 "Hello World on Windows!" 这句话换成一句别的什么内容。要不了多久,你就能自己编写一些不仅能显示文本而且还能执行你指定的其它任务的应用程序了。但在此之前,你还需要学习第四课,有关链接的知识。
关于getchar()函数
那些有经验的 C 程序员可能会问,上述代码中使用的 字符输入函数 getchar() 用在这里是什么意思。通常地,当一个应用程序执行完毕后,它就会终止,然后操作系统就会立即清除该应用程序输出。这样,当上述应用程序显示完“Hello World on Windows!”后,为了避免系统立即将该程序地输出清除,我们在程序中添加了一个 getchar() 函数,使程序在此处暂停,直到有键盘输入时整个程序会终止。这样我们才有足够的时间来看清楚该程序的输出。
这是一个正常的操作,而不是一个 bug。实际上,CodeWarrior 也提供了一个适用于此处的库函数,这个库函数中的 C 控制台 I/O 函数步不仅可以在程序显示完毕后锁定应用程序,而且还可以让你将输出的文本信息存储到一个文件中去。