读书频道 > 系统 > linux > 深度探索Linux操作系统系统构建和原理解析
1. Makefile的包含
2013-09-28 15:50:42     我来说两句 
收藏    我要投稿   
全书一共8章:第1章介绍了如何准备工作环境。在第2章中构建了编译工具链,这是后面构建操作系统各个组件的基础。在这一章中,不仅详细讲解了工具链的构建过程,而且还通过对编译链接过程的探讨,深入讨论了工具链  立即去当当网订购

Makefile的包含是很多复杂的项目中常用的方法之一。通常的做法是将共同使用的变量或规则定义在一个文件中,在需要使用的Makefile中使用关键字“include”来包含这个文件。kbuild中多处使用了包含的方式,其中关键的两处我们需要特别指出。

(1)顶层Makefile包含平台相关的Makefile

为了Linux能够方便地支持多平台,kbuild必须方便添加对新平台的支持,同时上层的Makefile不需要做大的改动,甚至不需要改动。所以,kbuild将与平台无关的变量、规则等放到了顶层的Makefile中,平台相关的部分定义在各个平台的“顶层”Makefile中。所谓各个平台的“顶层”Makefile,即arch/$(SRCARCH)目录下的Makefile。在顶层的Makefile中包含平台的“顶层”Makefile,脚本如下所示:
linux-3.7.4/Makefile:
include $(srctree)/arch/$(SRCARCH)/Makefile

其中变量SRCARCH的值就是平台相关部分所在的目录,对于IA32架构,SRCARCH的值为x86。顶层Makefile包含了平台的“顶层”Makefile后,才组成了真正的Makefile。这也是为什么我们在顶层目录执行“make bzImage”这样的命令时,可以编译内核映像,却在顶层目录下的Makefile中找不到目标bzImage的原因,因为其在平台的“顶层”Makefile中。

(2)Makefile.build包含各个子目录下的Makefile

为了方便Linux开发者能够编写Makefile,kbuild考虑得不可谓不周到,在牺牲自己的同时(kbuild的实现非常烦琐),确实让Linux的开发者们享受了便捷。比如,kbuild将所有与编译过程相关的公共的规则和变量都提取到scripts目录下的Makefile.build中,而具体的子目录下的Makefile文件则可以写得非常简单和直接。

kbuild定义了若干变量,如obj-y、obj-m等,用于记录参与编译过程的文件。这些变量就像钩子或者回调函数,各个子目录Makefile只需为其赋值,设置参与编译的文件即可,其他事情都由Makefile.build处理。甚至最简单的Makefile可以简单到只有一行语句:
linux-3.7.4/fs/notify/dnotify/Makefile:
obj-$(CONFIG_DNOTIFY)       += dnotify.o

在编译时,Makefile.build会指导make将要编译的子目录下的Makefile文件包含到Makefile.include中动态地组成完整的Makefile文件,脚本如下:
linux-3.7.4/scripts/Makefile.build:
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),
   $(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)

理论上,要包含Makefile文件,一条include命令就够了,为什么这里实现得如此复杂?

一是因为src的值是相对于顶层目录的,所以在顶层目录执行make没有任何问题。但是如果make不是在顶层目录执行的,那么就需要使用绝对路径来定位编译的子目录了。这就是为什么既然有了src,还要定义变量kbuild-dir。src是kbuild中定义的一个变量,始终指向需要构建的目录,kbuild-dir则是加上了绝对路径的src。make使用内嵌函数filter来判断编译所在的目录的路径是否是以绝对路径表示,即以“/”开头,如果不是,则冠以$(srctree)。srctree记录内核顶层目录的绝对路径。以笔者的环境为例,srctree的值是/vita/build/linux-3.7.4。在一般情况下,构建都发生在顶层目录下,在子目录下构建是为内核开发人员提供的特性。

二是因为子目录下的“Makefile”文件毕竟不是一个真正意义上的Makefile,所以kbuild的设计者的初衷是希望使用Kbuild这个名字。所以,我们看到,在确定kbuild-file时,使用make的内嵌函数wildcard首先尝试匹配子目录下是否存在Kbuild这个文件。如果有则优先使用Kbuild,否则使用Makefile。但是事实上,在内核目录的绝大部分子目录下,人们还是更习惯使用Makefile这个名字。

 

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:3.2.1 kbuild简介
下一篇:2. 使用指定Makefile的方式进行递归
相关文章
图文推荐
3.3.6 GNOME的软件管
3.3.5 GNOME的文件管
3.3.4 GNOME的窗口管
3.3.3 收藏夹和快捷
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站