在这一小节中,我们将介绍一种有效的编译手段来提高代码的编译效率。
我们看到,在前面的所有例子中,程序都是采用一种“单打独斗”的编译方法来编译的。程序在编写完成后,需要程序员手动运行命令去编译链接,最终生成可以运行的程序。当然,如果只是编译一两个文件,这似乎并不是什么问题。但一旦程序的规模扩大,需要编译的文件增多,程序编译过程就将会给我们带来极大的负担。
因此,这样的编译方式很显然不合适对操作系统进行。幸好make工具可以帮助我们解决所有的问题。
make工具能够自动地按照我们的要求依次编译指定的源程序,在项目工程中是一个不可或缺的工具。make工具功能非常强大,而在使用make工具的同时,我们还需要写一个Makefile文件。顾名思义,Makefile文件就是专门供make命令使用的文件,里面记录的都是编译源代码的具体细节。这里我们给出了相对通用的Makefile文件模板,内容如下。
代码2-8
对于不熟悉Linux或Makefile的读者来说,这段代码就像天书一样。这里我们不会深入研究Makefile的写法,只需要知道其用法即可。毕竟这些知识离操作系统的原理还是比较远的。
代码2-8可以作为一个模板,只需要稍做修改就能使用。具体的方法是,如果我们需要添加并编译新的源文件,只需要在变量OBJ中增加与源文件同名的目标文件即可,仅此而已,这个文件就可以用来编译我们自己的操作系统了,其他参数无须修改。
如果读者想要在其他场合下使用该模板,那么当需要修改编译选项时,可以将其添加到变量CFLAGS或ASFLAGS中,LDFLAGS变量代表链接选项,同样可以根据实际情况更改。CC、LD、OBJCOPY则代表编译工具,也可以自行确定。
这里需要强调的是,在编译的过程中,除-nostdlib之外,我们使用了另一个不太常用的GCC编译选项,那就是-nostartfiles。简单地说,这个选项的作用就是不允许编译器使用默认的启动文件。因为我们要写的是一个操作系统,系统的启动是自行处理的,不需要编译器帮我们添加。同时,在程序中我们通过-lgcc在编译时链接libgcc.a这一函数库,这样,ARM中的一些基本运算(如除法)就不需要我们在操作系统中亲自实现了。
将代码2-8保存到名为Makefile的文件中。此时我们便可以进行编译了,确保所有的文件都在同一个目录下,打开一个终端,切换到源代码所在目录,同时运行如下命令。
命令2-6
这样就会得到与上一节同样的结果,所付出的仅仅是适当修改Makefile文件中的OBJS变量的内容,并在终端敲四个字母。
如果想要同时删除所有编译生成的文件,只保留程序代码,可以通过如下命令来实现。
命令2-7