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

通常,很多使用make进行构建的项目,当存在多级目录时,使用递归方式构建,例如:
cd subdir && make

也就是说,在子目录下构建时,首先要切换当前工作目录到子目录,然后再启动一个make进程解释执行当前目录下的Makefile。在编译一些规模稍大一点的软件时,我们经常看到make不断通过cd命令切换目录,原因就在于此。

但是,kbuid并没有采用切换目录的方式。在kbuild中,make的当前工作目录永远是顶层目录,当编译子目录时,kbuild通过命令行选项-f将子目录的Makefile传递给make,从而达到编译子目录的目的。kbuild使用的典型方式如下:
$(MAKE) $(build)=<subdir> [target]

其中MAKE是make的内部变量,读者把它理解为make即可。变量build在Makefile.build中定义:
linux-3.7.4/scripts/Kbuild.include:
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build
         obj

只有当在子目录进行make时,变量KBUILD_SRC才会被设置为子目录,否则,在顶层目录进行make时,该变量值为空,所以make的内嵌函数if的返回值为else部分。但是因为if函数的else部分为空,所以该函数返回值为空。正如注释中所说,变量build相当于下面这段脚本的简写:
-f scripts/Makefile.build obj=

我们进一步把上面的make命令展开:
make -f scripts/Makefile.build obj=<subdir> [target]

也就说,通过命令行参数-f,指定Makefile为scripts目录下的Makefile.build。而当make解释执行Makefile.build时,再将子目录中的Makefile包含到Makefile.include中来,动态地组成子目录的真正的Makefile。

既然通过指定Makefile的方式编译多级目录,而make又始终工作在顶层目录下,那么必然要在顶层工作目录中跟踪编译所在的子目录。为此,kbuild定义了两个变量:src和obj。其中,src始终指向需要构建的目录;obj指向构建的目标存放的目录。并约定,在引用源码树中业已存在的对象时使用变量src,引用编译时动态生成的对象使用变量obj。kbuild在脚本中小心地维护着这两个变量的值。实际上,因为构建的目标存放的目录与源文件经常在同一个目录下,所以大部分情况下这两个变量均指向同一个目录。

理解了kbuild中这两个变量的意义后,读者一定看明白了上述make命令中参数“obj=<subdir>”的意义,就是设置变量obj的值,记录编译所在的子目录。而在Makefile.build的一开头,变量src的值也被设置为$(obj)。
linux-3.7.4/scripts/Kbuild.include:
src := $(obj)
PHONY := __build
__build:
...

下面,我们就结合构建IA32架构下的内核映像bzImage,探讨内核映像的具体构建过程。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1. Makefile的包含
下一篇:3.2.2 构建过程概述
相关文章
图文推荐
3.3.6 GNOME的软件管
3.3.5 GNOME的文件管
3.3.4 GNOME的窗口管
3.3.3 收藏夹和快捷
排行
热门
文章
下载
读书

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