kbuild Makefile

一般情况下,如果需要编译kernel的某个模块,我们通常在Makefile中使用如下格式:

1
2
3
4
drivers/usb/host/Makefile

obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o

通过配置CONFIG_XXX来决定编译某个模块为 build-in 或者是编译成module。
但是,在 drivers/usb/gadget/Makefile文件中,有如下的用法:

1
2
3
obj-$(CONFIG_USB_LIBCOMPOSITE)  += libcomposite.o
libcomposite-y := usbstring.o config.o epautoconf.o
libcomposite-y += composite.o functions.o configfs.o u_f.o

其中libcomposite为目标,下面两行表示要生成这个目标的依赖,也就是需要usbstring.cconfig.ccomposite.c等。
关于这两种用法的解释,在Documentation/kbuild/makefiles.txt3.1 Goal definitions3.3 Loadable module goals - obj-m做了详细的描述,现摘录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
--- 3.1 Goal definitions

Goal definitions are the main part (heart) of the kbuild Makefile.
These lines define the files to be built, any special compilation
options, and any subdirectories to be entered recursively.

The most simple kbuild makefile contains one line:

Example:
obj-y += foo.o

This tells kbuild that there is one object in that directory, named
foo.o. foo.o will be built from foo.c or foo.S.

If foo.o shall be built as a module, the variable obj-m is used.
Therefore the following pattern is often used:

Example:
obj-$(CONFIG_FOO) += foo.o

$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module).
If CONFIG_FOO is neither y nor m, then the file will not be compiled
nor linked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
--- 3.3 Loadable module goals - obj-m

$(obj-m) specifies object files which are built as loadable
kernel modules.

A module may be built from one source file or several source
files. In the case of one source file, the kbuild makefile
simply adds the file to $(obj-m).

Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o

Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'

If a kernel module is built from several source files, you specify
that you want to build a module in the same way as above; however,
kbuild needs to know which object files you want to build your
module from, so you have to tell it by setting a $(<module_name>-y)
variable.

Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_I4L) += isdn.o
isdn-y := isdn_net_lib.o isdn_v110.o isdn_common.o

In this example, the module name will be isdn.o. Kbuild will
compile the objects listed in $(isdn-y) and then run
"$(LD) -r" on the list of these files to generate isdn.o.

Due to kbuild recognizing $(<module_name>-y) for composite objects,
you can use the value of a CONFIG_ symbol to optionally include an
object file as part of a composite object.

Example:
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o dir.o file.o ialloc.o inode.o ioctl.o \
namei.o super.o symlink.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o \
xattr_trusted.o

In this example, xattr.o, xattr_user.o and xattr_trusted.o are only
part of the composite object ext2.o if $(CONFIG_EXT2_FS_XATTR)
evaluates to 'y'.

Note: Of course, when you are building objects into the kernel,
the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
kbuild will build an ext2.o file for you out of the individual
parts and then link this into built-in.o, as you would expect.