曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 7116|回复: 0
打印 上一主题 下一主题

[Kernel] Makefile.build 的作用

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2011-4-18 15:58:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在内核源码路径下,scripts/ 下有一个 Makefile.build 文件,这个文件的作用是对一个指定的目录进行编译。那么它是怎么做到的呢?答案正是通过 include 关键字。

对于 include 关键字,可以参考:http://www.groad.net/bbs/read.php?tid-3082.html 。这篇帖子里对 include 做了基本的介绍和演示,但其中有一句话比较重要:make 命令执行时,它会找到所有 include 所指定的文件,并将它们的内容放置在当前的位置。

这里通过修改内核源码根目录下的 Makefile 以及 Makefile.build 来观察整个作用过程。

首先了解,scripts 目录下有一个文件为 Kbuild.include 。这个文件里面对一些通用变量做了定义,其中它包含了对主 Makefile 文件中 $(build) 变量的定义:

###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build :=-f $(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj

而主 Makefile 文件又是通过以下语句将 Kbuild.include 包含进来:
include $(srctree)/scripts/Kbuild.include
这里需要提醒一下,Kbuild.include 里面没有定义任何的目标,所以这里用 include 包含一点问题都没有,如果是定义了目标,那可能会出现问题,而出现的问题就是下面要说的 Makefile.build 的情况。


接下来,在主 Makefile 的下面两行:

# We need some generic definitions (do not try to remake the file).
$(srctree)/scripts/Kbuild.include: ;
include $(srctree)/scripts/Kbuild.include
的底下添加:

stub:
@echo "=================================="
@make $(build)=helloworld

这里,我们自定义了自己一个 stub 目标,为的是跟踪 Makefile.build 的流程。

通过 make 的 -f 参数以及在 Makefile 文件间传递参数 这篇帖子我们知道 Makefile 文件之间是如何传递参数的。如上面,我们将 helloworld 这个参数传递给 $(build) 变量中。

接着手动在内核源码顶层目录下创建一个 helloworld 的目录。然后在这个目录中创建一个很简单的 Makefile 文件,其内容为:
all:
       @echo "hello world"

接着,转到 scripts 目录下,修改一下 Makefile.build 文件:

1. 屏蔽掉文件顶上的 __build: 这个目标:
#__build

2. 来到:

# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if$(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
这里,我们先屏蔽掉 include $(kbuild-file) 这一句,并在底下添加一个自定义的目标:

temp:
@echo "---------- $(kbuild-dir) -----------"
@echo "---------- $(kbuild-file) ------------"
现在可以测试一下 make stub 这个目标了:
[beyes@SLinux linux-2.6.34.9]$ make stub
==================================
---------- /home/beyes/kernel/linux-2.6.34.9/helloworld -----------
---------- /home/beyes/kernel/linux-2.6.34.9/helloworld/Makefile ------------
从输出可以看到:
$(kbuild-dir) 表示的是我们要编译的子目录 helloworld 。
$(kbuild-file) 表示的是要编译的子目录下的 Makefile 文件。而就是在这个文件中,它含有要编译的目标!
关于上面涉及的 filter 函数说明可参考:http://www.groad.net/bbs/read.php?tid-2940-fpage-2.html
关于 wildcard 说明可参考:http://www.groad.net/bbs/read.php?tid-2947.html

现在我们可以打开上面被屏蔽的  include $(kbuild-file)  这句话了,解除屏蔽后,我们再 make stub 一下看会有什么结果:
[beyes@SLinux linux-2.6.34.9]$ make stub
==================================
i am here
从输出可以看到,由于 include 的 $(kbuild-file) 中另有要生成的目标,从而转去生成那里的目标,而之前的 temp 目标就不再执行编译生成,也就是说 temp 目标被新 include 进来的 all: 目标给覆盖了 (override ) 。


最后,上面之所以要先屏蔽 __build 的目的是为了更好的演示如何将另外目录下的 Makefile 文件包含进来。如果没有屏蔽,那么将执行的是底下的 __build 目标,而不是我们自定义的 temp,因为 __build 已经先得到声明。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 20:01 , Processed in 0.070506 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表