大家好,这里是没事造轮子,今天咱们聊聊C语言的源码是如何编译成应用程序的,以及在使用 SDL 开发游戏 之前的工程属性配置。

我们平时开发程序,首先要做的就是编写源代码,如果你用的是C语言,那么最后得到的是一个或若干个 C语言的源文件。这些源文件是人类可读的文本文件,在交给机器运行之前,需要将它们翻译成机器可以识别指令。

编译流程

这里以 Windows 为例,首先 .c 后缀结尾的源文件需要先经过预处理器处理,预处理器的主要工作是翻译 # 号开头的预处理指令。得到了预处理文件之后,我们可以使用编译器将其翻译成汇编文件,汇编文件是 .asm 后缀的文本文件,该文件内是一行行的汇编指令。接着我们可以使用汇编器将汇编文件翻译成机器指令,这些指令会保存在 .obj 为后缀的文件中,该文件是二进制文件,它的字节编码是机器指令而不是人类能够识别的字符,该文件经常被叫做目标文件。变成应用程序的最后一步就是将我们自己写的目标文件和其他第三方提供的目标文件以某种方式合并到一起,这个过程叫做链接,链接的结果就是最终的可执行程序,该程序可以被加载到内存中由系统执行。

因为我们在以后开发游戏的过程中会使用SDL,所以在游戏最终链接的时候,需要提供 SDL 的开发库,常用的开发库一般以两种形式对外提供,一种是动态库的形式,另一种是静态库的形式。

在游戏链接的过程中使用哪种库是由我们自身决定的。动态库一般独立于可执行程序而存在,程序在运行期间可以按需加载,并且动态库可以被多个程序共享,这样即减少了程序运行所需要的内存,又减少了程序编译后的文件大小。而静态库和动态库不同,因为静态库最终会被链接到可执行程序中,所以使用静态库编译的程序文件会更大,运行期间也会占用更多的内存,并且静态库无法和其它程序所共享。但是静态库有一个好处是应用程序可以保持单一的文件,并且因为包含动态库的可执行程序在运行的过程中可能会需要定位函数位置,所以理论上静态库的程序装载和运行的速度会略快一点。

1. 动态库

如果你准备使用 SDL 的动态库,那么可以直接去官网下载官方提供的开发包,开发包中包含开发所需要的头文件和库文件。不过只有这些还不够,我们还需要官方支持的扩展库,目前需要的扩展库有三种,它们分别是用于图片加载的 SDL_image、用于文字渲染的 SDL_ttf,以及用于音频播放的 SDL_mixer。除了这些之外,SDL 还包括用于网络方面的扩展库,不过咱们目前只涉及单机游戏的开发,所以暂时可以不管。

官网

下载好这些库之后,将它们解压统一放到一个目录下,方便以后在开发中使用。

目录结构

在开发过程中,如果你想引用第三方动态库,则需要至少两样东西,一个头文件,一个是动态库。头文件一般被放到 include 目录下,可以直接将该目录添加到项目属性中。而动态库文件则有两种使用方式,一种是直接使用 Windows 操作系统提供的动态库加载接口,该接口可以直接加载动态库文件。不过这种方法需要书写相关的代码,比较麻烦。另一种简单的方式是使用和动态库一起的导入库,只需要和头文件一样在项目中配置好即可。具体过程可以参考我博客上工程属性配置 的相关文章。

2. 静态库

如果你也喜欢将小游戏浓缩到一个文件中,那么推荐你使用静态库的链接方式。不过因为 SDL 官方并不提供静态库,所以你需要去官网下载源码,自行编译。除了 SDL 自身之外,我们还需要使用几个 SDL 的扩展库,这几个扩展库可以简化你的工作,其中包括用于图片加载的 SDL_image、用于文字渲染的 SDL_ttf,以及用于音频播放的 SDL_mixer。这三种扩展库每种都包含一些其它的第三方依赖关系,如果你想要使用静态库,你需要将它们全部编译为静态库,整个依赖网络如下:

静态编译依赖库

编译的过程不难,但是比较繁琐,如果大家不想自己编译可以直接去我的博客下载

在开发过程中,如果你想引用第三方静态库,那么至少需要两样东西,一个头文件,一个静态库自身。头文件和静态库都可以在工程属性中配置,非常方便。具体过程可以参考我博客上工程属性配置 的相关文章。