您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > Linux内核Makefile
LinuxLinuxLinuxLinux内核2.62.62.62.6MakefileMakefileMakefileMakefile文件===目录===1概述===2角色分工===3内核编译文件---3.1目标定义---3.2内嵌对象-obj-y---3.3可加载模块-obj-m---3.4导出符号---3.5库文件-lib-y---3.6目录递归---3.7编译标记---3.8命令依赖---3.9依赖关系---3.10特殊规则===4辅助程序---4.1简单辅助程序---4.2组合辅助程序---4.3定义共享库---4.4C++语言使用方法---4.5辅助程序编译控制选项---4.6何时建立辅助程序---4.7使用hostprogs-$(CONFIG_FOO)===1概述Makefile包括五部分:Makefile顶层Makefile文件.config内核配置文件arch/$(ARCH)/Makefile机器体系Makefile文件scripts/Makefile.*所有内核Makefiles共用规则kbuildMakefiles其它makefile文件通过内核配置操作产生.config文件,顶层Makefile文件读取该文件的配置。顶层Makefile文件负责产生两个主要的程序:vmlinux(内核image)和模块。顶层Makefile文件根据内核配置,通过递归编译内核代码树子目录建立这两个文件。顶层Makefile文件文本一个名为arch/$(ARCH)/Makefile的机器体系makefile文件。机器体系Makefile文件为顶层makefile文件提供与机器相关的信息。每一个子目录有一个makefile文件,子目录makefile文件根据上级目录makefile文件命令启动编译。这些makefile使用.config文件配置数据构建各种文件列表,并使用这些文件列表编译内嵌或模块目标文件。scripts/Makefile.*包含了所有的定义和规则,与makefile文件一起编译出内核程序。===2角色分工人们与内核makefile存在四种不同的关系:*用户*用户使用makemenuconfig或make命令编译内核。他们通常不读或编辑内核makefile文件或其他源文件。*普通开发者*普通开发者维护设备驱动程序、文件系统和网络协议代码,他们维护相关子系统的makefile文件,因此他们需要内核makefile文件整体性的一般知识和关于kbuild公共接口的详细知识。*体系开发者*体系开发者关注一个整体的体系架构,比如sparc或者ia64。体系开发者既需要掌握关于体系的makefile文件,也要熟悉内核makefile文件。*内核开发者*内核开发者关注内核编译系统本身。他们需要清楚内核makefile文件的所有方面。本文档的读者对象是普通开发者和系统开发者。===3内核编译文件内核中大多数makefile文件是使用kbuild基础架构的makefile文件。本章介绍kbuild的makefile中的语法。3.1节“目标定义”是一个快速导引,后面各章有详细介绍和实例。---3.1目标定义目标定义是makefile文件的主要部分(核心)。这些目标定义行定义了如何编译文件,特殊的兼容选项和递归子目录。最简单的makefile文件只包含一行: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,那么这个文件不会被编译和链接。---3.2内嵌对象-obj-ymakefile文件将为编译vmlinux的目标文件放在$(obj-y)列表中,这些列表依赖于内核配置。Kbuild编译所有的$(obj-y)文件,然后调用$(LD)-r合并这些文件到一个built-in.o文件中。built-in.o经过父makefile文件链接到vmlinux。$(obj-y)中的文件顺序很重要。列表中文件允许重复,文件第一次出现将被链接到built-in.o,后续出现该文件将被忽略。链接顺序之所以重要是因为一些函数在内核引导时将按照他们出现的顺序被调用,如函数(module_init()/__initcall)。所以要牢记改变链接顺序意味着也要改变SCSI控制器的检测顺序和重数磁盘。例如:#drivers/isdn/i4l/Makefile#内核ISDN子系统和设备驱动程序Makefile#每个配置项是一个文件列表obj-$(CONFIG_ISDN)+=isdn.oobj-$(CONFIG_ISDN_PPP_BSDCOMP)+=isdn_bsdcomp.o---3.3可加载模块-obj-m$(obj-m)表示对象文件(objectfiles)编译成可加载的内核模块。一个模块可以通过一个源文件或几个源文件编译而成。makefile只需简单地它们加到$(obj-m)。例如:#drivers/isdn/i4l/Makefileobj-$(CONFIG_ISDN_PPP_BSDCOMP)+=isdn_bsdcomp.o注意:在这个例子中$(CONFIG_ISDN_PPP_BSDCOMP)含义是'm'。如果内核模块通过几个源文件编译而成,使用以上同样的方法。Kbuild需要知道通过哪些文件编译模块,因此需要设置一个$(module_name-objs)变量。例如:#drivers/isdn/i4l/Makefileobj-$(CONFIG_ISDN)+=isdn.oisdn-objs:=isdn_net_lib.oisdn_v110.oisdn_common.o在这个例子中,模块名isdn.o.Kbuild首先编译$(isdn-objs)中的object文件,然后运行$(LD)-r将列表中文件生成isdn.o.Kbuild使用后缀-objs、-y识别对象文件。这种方法允许makefile使用CONFIG_符号值确定一个object文件是否是另外一个object的组成部分。例如:#fs/ext2/Makefileobj-$(CONFIG_EXT2_FS)+=ext2.oext2-y:=balloc.obitmap.oext2-$(CONFIG_EXT2_FS_XATTR)+=xattr.o在这个例子中,如果$(CONFIG_EXT2_FS_XATTR)表示'y',则ext2.o只有xattr.o组成部分。注意:当然,当你将对象文件编译到内核时,以上语法同样有效。因此,如果CONFIG_EXT2_FS=y,Kbuild将先编译ext2.o文件,然后链接到built-in.o。---3.4导出符号目标在makefile文件中没有特别导出符号的标记。---3.5库文件-lib-yobj-*中的object文件用于模块或built-in.o编译。object文件也可能编译到库文件中--lib.a。所有罗列在lib-y中的object文件都将编译到该目录下的一个单一的库文件中。包含在0bj-y中的object文件如果也列举在lib-y中将不会包含到库文件中,因为他们不能被访问。但lib-m中的object文件将被编译进lib.a库文件。注意在相同的makefile中可以列举文件到buit-in内核中也可以作为库文件的一个组成部分。因此在同一个目录下既可以有built-in.o也可以有lib.a文件。例如:#arch/i386/lib/Makefilelib-y:=checksum.odelay.o这样将基于checksum.o、delay.o创建一个lib.a文件。对于内核编译来说,lib.a文件被包含在libs-y中。将“6.3目录表”。lib-y通常被限制使用在lib/和arch/*/lib目录中。---3.6目录递归makefile文件负责编译当前目录下的目标文件,子目录中的文件由子目录中的makefile文件负责编译。编译系统将使用obj-y和obj-m自动递归编译各个子目录中文件。如果ext2是一个子目录,fs目录下的makefile将使用以下赋值语句是编译系统编译ext2子目录。例如:#fs/Makefileobj-$(CONFIG_EXT2_FS)+=ext2/如果CONFIG_EXT2_FS设置成'y(built-in)或'm'(modular),则对应的obj-变量也要设置,内核编译系统将进入ext2目录编译文件。内核编译系统只使用这些信息来决定是否需要编译这个目录,子目录中makefile文件规定那些文件编译为模块那些是内核内嵌对象。当指定目录名时使用CONFIG_变量是一种良好的做法。如果CONFIG_选项不为'y'或'm',内核编译系统就会跳过这个目录。---3.7编译标记EXTRA_CFLAGS,EXTRA_AFLAGS,EXTRA_LDFLAGS,EXTRA_ARFLAGS所有的EXTRA_变量只能使用在定义该变量后的makefile文件中。EXTRA_变量被makefile文件所有的执行命令语句所使用。$(EXTRA_CFLAGS)是使用$(CC)编译C文件的选项。例如:#drivers/sound/emu10k1/MakefileEXTRA_CFLAGS+=-I$(obj)ifdefDEBUGEXTRA_CFLAGS+=-DEMU10K1_DEBUGendif定义这个变量是必须的,因为顶层makefile定义了$(CFLAGS)变量并使用该变量编译整个代码树。$(EXTRA_AFLAGS)是每个目录编译汇编语言源文件的选项。例如:#arch/x86_64/kernel/MakefileEXTRA_AFLAGS:=-traditional$(EXTRA_LDFLAGS)和$(EXTRA_ARFLAGS)用于每个目录的$(LD)和$(AR)选项。例如:#arch/m68k/fpsp040/MakefileEXTRA_LDFLAGS:=-xCFLAGS_$@,AFLAGS_$@CFLAGS_$@和AFLAGS_$@只使用到当前makefile文件的命令中。$(CFLAGS_$@)定义了使用$(CC)的每个文件的选项。$@部分代表该文件。例如:#drivers/scsi/MakefileCFLAGS_aha152x.o=-DAHA152X_STAT-DAUTOCONFCFLAGS_gdth.o=#-DDEBUG_GDTH=2-D__SERIAL__-D__COM2__\-DGDTH_STATISTICSCFLAGS_seagate.o=-DARBITRATE-DPARITY-DSEAGATE_USE_ASM这三行定义了aha152x.o、gdth.o和seagate.o文件的编译选项。$(AFLAGS_$@)使用在汇编语言代码文件中,具有同上相同的含义。例如:#arch/arm/kernel/MakefileAFLAGS_head-armv.o:=-DTEXTADDR=$(TEXTADDR)-traditionalAFLAGS_head-armo.o:=-DTEXTADDR=$(TEXTADDR)-traditional---3.9依赖关系内核编译记录如下依赖关系:1)所有的前提文件(both*.cand*.h)2)CONFIG_选项影响到的所有文件3)编译目标文件使用的命令行因此,假如改变$(CC)的一个选项,所有相关的文件都要重新编译。---3.10特殊规则特殊规则使用在内核编译需要规则定义而没有相应定义的时候。典型的例子如编译时头文件的产生规则。其他例子有体系makefile编译引导映像的特殊规则。特殊规则写法同普通的Make规则。Kbuild(应该是编译程序
本文标题:Linux内核Makefile
链接地址:https://www.777doc.com/doc-4580888 .html