本文是与《C++编程基础及应用》(暂定名)第12章 - 编译及构建配套的操作指南,用于演示在Windows命令行环境下使用mingw编译器手工编译并运行程序的过程。
版权声明
本文可以在互联网上自由转载,但必须:注明出处(作者:海洋饼干叔叔)并包含指向本页面的链接。
本文不可以以纸质出版为目的进行改编、摘抄。
1. 准备mingw编译环境
在Windows菜单中找到命令提示符(通过输入cmd进行查找),然后点击进入。
在命令提示符中执行命令 gcc -v, 期望如果如下图所示。
如果系统报告“未知的程序”’gcc’ 不是内部或外部命令,也不是可运行的程序或批处理文件“,则说明mingw编译环境尚未得到正确的安装及配置。请按照下述链接中的第一部分进行安装及配置。
http://codelearn.club/2022/09/vsccpp/
3. 准备示例代码目录及文件
在D:\Demo目录里准备如下的三个源代码文件,如果读者的计算机上没有D盘,那就使用C:\Demo目录。
其中,compute.h内容如下:
1 |
|
文件compute.c内容如下:
1 |
|
文件area.c内容如下:
1 |
|
3. 使用命令行编译并运行
如下图所示,在Windows命令提示符(终端)中依次执行如表1所列的命令,完成上述3个源代码文件的编译,并成功执行了名为area.exe的可执行文件。
命令 | d: |
---|---|
说明 | 切换当前盘符为D盘,如果读者使用的是C:\Demo目录,则不要执行该命令。 |
命令 | cd \Demo |
说明 | 将当前目录切换为当前盘符下的\Demo目录,示例的3个源代码文件在该目录里。cd是操作系统终端命令,意为改变目录(change directory)。 |
命令 | dir |
说明 | 终端命令,显示当前目录下的所有文件及子目录。执行结果显示当前目录下有area.c、compute.h及compute.c三个文件。 |
命令 | gcc area.c compute.c –o area |
说明 | 使用gcc编译器编译area.c及compute.c两个C语言程序文件,生成名为area的可执行目标文件。请注意,头文件compute.h不被视为一个单独的编译单元,所以未在命令中列出。上述命令行中的-o选项意为指定输出文件的名称。该文件执行完成后,再次执行dir,可见当前目录下多了一个名为area.exe的文件,其扩展名exe说明该文件是一个可执行文件(executable file)。 |
命令 | area.exe |
说明 | 载入并执行当前目录下名为area.exe的可执行目标文件。在执行该命令后,操作系统会将该程序载入内存,然后将执行点转移至该程序的起始处。随后的执行结果可见,area成功计算并打印了半径为4.1的圆的面积。 |
上述示例程序的编译/构建过程可用下图表示:
4. 预处理
执行命令
1 | gcc -E compute.c -o compute.i |
或者
1 | cpp compute.c compute.i |
都可以对源代码文件compute.c进行预处理,对应的输出文件为compute.i。如下图所示:
结果文件compute.i系文本文件,可以使用任意文字编辑软件,比如记事本, 打开。当然,也可以使用Visual Studio Code或者Qt Creator等IDE环境来查看。
在作者的计算机上,compute.i的内容如下:
1 | # 0 "compute.c" |
编译预处理的具体工作原理请参阅教材第12章。
5. 编译
使用下述命令可以将compute.i进行编译,得到包含汇编语言指令的结果文件compute.s。
同理,compute.s也是文本文件,可用记事本,Visual Studio Code,Qt Creator等工具打开查看。在作者的计算机上,compute.s的内容如下,其包含的是x86的汇编语言指令序列。
1 | .file "compute.c" |
6. 汇编
在Windows命令行中执行下述命令之一,可以将compute.s汇编成可重定位目标文件(relocatable object file)compute.o,其为包含机器语言指定的二进制文件。
1 | as compute.s -o compute.o |
结果文件compute.o是二进制文件,直接查看其内容只会得到一堆0和1。在Windows命令行里,可以通过下述命令对其进行反汇编,查看其中的汇编语言指令:
7. 链接
对于编译单元compute.c,经过预处理-编译-汇编之后我们得到可重定位目标文件compute.o。
我们对编译单元area.c进行类似处理,得到可重定位目录文件area.o。
这样,我们就有了两个可重定位目标文件,分别是area.o及compute.o,其中,area.o包含了对compute.o内部的函数的调用。
通过下述命令,我们将area.o及compute.o链接为一个整体,得到可执行文件area.exe,然后再次执行area.exe。