## Kbuild
MODULE_NAME = helloworld
$(MODULE_NAME)-objs := hello.o
obj-m := $(MODULE_NAME).o
一般不需要在Makefile里包含如下代码,这样写完全是为了兼容老版本的Kbuild系统。KERNELRELEASE变量在Kernel Makefile里定义的,因此只有在第二次由Kbuild读取这个Makefile文件时才会解析到Kbuild的内容。
ifneq ($(KERNELRELEASE),)
include "Kbuild"
else
...
endif
外部头文件
有时需要连接内核源代码外部的系统头文件,但Kbuild系统默认的系统头文件都在内核源代码内部,如何使用外部的头文件呢?这个可以借助于Kbuild 系统的特殊规则:
·
EXTRA_CFLAGS
EXTRA_CFLAGS可以给Kbuild系统添加外部系统头文件,
EXTRA_CFLAGS += $(ext_include_path)
一般外部头文件可能位于外部模块源文件的目录内,如何指定呢?这可以借助$(src)或$(obj)
·
$(src)/$(obj)
$(src)是一个相对路径,它就是Makefile/Kbuild文件所在的路径。同样$(obj)就是编译目标保存的路径,默认就是源代码所在路径。
因此,我们修改Kbuild文件添加 EXTRA_CFLAGS 来包含外部头文件尽管在这个驱动里没有引用外部系统头文件:
## Kbuild
MODULE_NAME = helloworld
$(MODULE_NAME)-objs := hello.o
EXTRA_CFLAGS := -I$(src)/include
obj-m := $(MODULE_NAME).o
//=========================================
Linux Kernel Makefiles
This document describes the Linux kernel Makefiles.
=== Table of Contents
=== 1 Overview
=== 2 Who does what
=== 3 The kbuild files
--- 3.1 Goal definitions
--- 3.2 Built-in object goals - obj-y
--- 3.3 Loadable module goals - obj-m
--- 3.4 Objects which export symbols
--- 3.5 Library file goals - lib-y
--- 3.6 Descending down in directories
--- 3.7 Compilation flags
--- 3.8 Command line dependency
--- 3.9 Dependency tracking
--- 3.10 Special Rules
--- 3.11 $(CC) support functions
--- 3.12 $(LD) support functions
=== 4 Host Program support
--- 4.1 Simple Host Program
--- 4.2 Composite Host Programs
--- 4.3 Defining shared libraries
--- 4.4 Using C++ for host programs
--- 4.5 Controlling compiler options for host programs
--- 4.6 When host programs are actually built
--- 4.7 Using hostprogs-$(CONFIG_FOO)
=== 5 Kbuild clean infrastructure
=== 6 Architecture Makefiles
--- 6.1 Set variables to tweak the build to the architecture
--- 6.2 Add prerequisites to archprepare:
--- 6.3 List directories to visit when descending
--- 6.4 Architecture-specific boot images
--- 6.5 Building non-kbuild targets
--- 6.6 Commands useful for building a boot image
--- 6.7 Custom kbuild commands
--- 6.8 Preprocessing linker scripts
=== 7 Kbuild syntax for exported headers
--- 7.1 header-y
--- 7.2 objhdr-y
--- 7.3 destination-y
--- 7.4 unifdef-y (deprecated)
=== 8 Kbuild Variables
=== 9 Makefile language
=== 10 Credits
=== 11 TODO
·
Goal definitions
Example:
obj-y += foo.o
告诉kbuild,在文件夹中又一个叫做foo.o的object。foo.o将会被从foo.c或者foo.S被构建。
如果foo.o被构建成一个
模块,则将使用变量
obj-m。
Example:
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO)要么是y(built-in)要么是m(module)。如果CONFIG_FOO既不是y也不是m,那么文件将不会被编译也 不会被连接。
·
Built-in object goals - obj-y
kbuild Makefiles在
$(obj-y)列表中为vmlinux指明object文件。这个列表依靠内核 的配置。
在
$(obj-y)中的文件的顺序是非常重要的。列表中允许两个相同的文件:
第一个实 体将被连接到built-in.o,后面的实体将会
被忽略。
连接的顺序也很重要,因为在boot过程中某些函数(module_init()/_initcall)将会
按顺序出现。因 此,如果改变了连接顺序,将会改变你的SCSI控制器的检测顺序,你的磁盘也同时被重新编号了。
Example:
#drivers/isdn/i4l/Makefile
# Makefile for the kernel ISDN subsystem and device drivers.
# Each configuration option enables a list of files.
obj-$(CONFIG_ISDN) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
·
Loadable module goals - obj-m
$(obj-m)指明object文件作为可装载的内核模块被构建。一个模块可能从一个或者多个源文件被构建。 kbuild maefile只是简单的将源文件加到%(obj-m)
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
注意这里$(CONFIG_ISDN_PPP_BSDCOMP)是m.
Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'。
如果一个内核模块从多个源文件构建,KBuild就必须要知道你想从哪些部分构建模块。因此,你不得不设置
$(-objs) 变量来告诉KBuild。
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
在这个例子中,模块名是isdn.o,Kbuild将会编译列在
$(isdn-objs)
的object 文件,然后在这些文件的列表中调用"$(LD) -r"来产生isdn.o。
Kbuild使用
后缀-objs,-y来识别混合的object文件。这允许Makefiles使用变量
CONFIG_sambol来 决定一个object是否是混合object的的一部分。
Example:
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
在这个例子中,如果$(CONFIG_EXT2_FS_XATTR)是y,则xattr.o只是混合object文件ext2.o的一部分。
注意,当你构造一个objects到内核中时,上面的语法当然也能够工作。因此,如果你让CONFIG_EXT2=Y,KBuild将会为你构建一个独立 的ext2.o文件,并且连接到built-in.o。
·
Library file goals - lib-y
用
obj-*连接的Objects在指明的文件夹中被用作模块或者综合进built-in.o。也又可能被列出的 objects将会被包含进一个库,lib.a。所有用lib-y列出的objects在那个文件夹中被综合进单独的一个库。列在obj-y和附加列在 lib-y中的Objects将不会被包含在库中,因为他们将会被任意的存取。对于被连接在lib-m中,连续的objects将会被包含在lib.a 中。值得注意的是kbuild makefile可能列出文件用作built-in,并且作为库的一部分。因此,同一个文件夹可能包含一个built-in.o和lib.a文件。
Example:
#arch/i386/lib/Makefile
lib-y := checksum.o delay.o
这里讲会创建一个基于checksum.o和delay.o的库文件。对于kbuild,识别一个lib.a正在被构建,这个文件夹应该被列在
libs-y中。
lib-y的 使用方法通常被限制在lib/和arc/*/lib中。
·
Descending down in directories
一个Makefile只负责在他自己的文件夹中构建objects。 在子文件夹中的文件应该由子文件夹中的Makefiles来照顾。如果你知道他们,build系统将会自动递归地用在子文件夹中的make。
在这种情况下
obj-y和
obj-m就被使用了。ext2存在于不同的文件夹 中,Makefile出现在fs/,则告诉kbuild从后面的参数下来。
Example:
#fs/Makefile
obj-$(CONFIG_EXT2_FS) += ext2/
如果CONFIG_EXT2_FS被设置成y(built-in)或者m(modular),相应的obj-变量将会被设置,并且kbuild将会从 ext2文件夹继承下来。Kbuild只会使用这些信息来决定它需要访问这些文件夹,而在子文件夹中的Makefile来指 明哪些是modules哪些是built-in。
当赋值文件夹名字的时候,使用CONFIG_variable是很好的选择。这允许kbuild完全的跳过文件夹,而不管CONFIG_option是否 是y或者m。
·
Compilation flags
EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS。
所有的EXTRA_ variables只应用在kbuild中,他们被赋值的地方。EXTRA_variables应用在kbuild makefile中所有的可执行的命令。
$(EXTRA_CFLAGS) 指明用$(CC)编译C文件的时候的选项。
Example:
# drivers/sound/emu10k1/Makefile
EXTRA_CFLAGS += -I$(obj)
ifdef DEBUG
EXTRA_CFLAGS += -DEMU10K1_DEBUG
endif
这里的变量是必须的,因为顶层的Makefile拥有变量
$(CFLAGS)并且用它来作为整个树的编译标志当编译汇编源文件的时候
$(EXTRA_AFLAGS), 和每个文件夹的选项是相似的。
Example:
#arch/x86_64/kernel/Makefile
EXTRA_AFLAGS := -traditional
$(EXTRA_LDFLAGS)和
$(EXTRA_ARFLAGS) 对于每个文件夹的$(LD)和$(AR)选项是类似的。
Example:
#arch/m68k/fpsp040/Makefile
EXTRA_LDFLAGS := -x
CFLAGS_$@, AFLAGS_$@
CFLAGS_$@和
AFLAGS_$@只应用到当前kbuild makefile的命令。
$(CFLAGS_$@) 为每个文件的$(CC)指明选项。
$@
部分有一个字面上的值,指明它是为那个文件。
Example:
# drivers/scsi/Makefile
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ /
-DGDTH_STATISTICS
CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
These three lines specify compilation flags for aha152x.o,
gdth.o, and seagate.o
$(AFLAGS_$@) is a similar feature for source files in assembly
languages.
Example:
# arch/arm/kernel/Makefile
AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
本文来自ChinaUnix博客,如果查看原文请点:
http://blog.chinaunix.net/u3/94284/showart_1896000.html
注:本文内容基本是翻译linux 代码树。../Documentation/kbuild/makefiles.txt(by imjacob)