Linux源码下Makefile详解(参照Documentation\kbuild\makefiles.txt和资料)



1.Makefile的作用

 (1)决定编译哪些文件

 (2)怎样编译这些文件

 (3)怎样连接这些文件,最重要的是它们的顺序如何

2.Linux内核Makefile分类

*********************************************************************

  顶层Makefile:它是所有Makefile文件的核心,从总体上控制着内核的编译、

              连接

 .config   :配置文件,在配置内核时生成,所有Makefile文件(包括顶层

             目录及各级子目录)都是根据.config来决定使用哪些文件

arch/$(ARCH)/Makefile:对应于体系结构的Makefile,它用来决定哪些体系结

                     构相关的文件参与内核的生成,并提供一些规则来生成

                     特定格式的内核映像

scripts/Makefile.* : Makefile共用的通用规则、脚本等

kbuild Makefile :各级子目录下的Makefile,被上一层Makefile调用来编译

                当前目录下的文件

*********************************************************************

3.根据Makefile的作用分析这5类文件

(1)决定编译哪些文件

 Linux内核的编译过程从顶层Makefile开始,然后递归地进入各级子目录调用它们的Makefile,分为3个步骤:

  (1)顶层Makefile决定内核根目录下哪些子目录将被编译进内核

      顶层Makefile中有如下内容:

       init-y      := init/

       drivers-y := drivers/ sound/ firmware/

       net-y    := net/

       libs-y      := lib/

       core-y      := usr/

        ......................

        core-y     += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

     顶层Makefile将这13个子目录分为5类,除去include目录和后面不包

  含内核源码的目录外,还有一个arch目录在arch/$(ARCH)/Makefile中被包

  含进内核,在顶层Makefile中直接包含了这个Makefile,如下所示:

          452  include $(srctree)/arch/$(SRCARCH)/Makefile

  (2)arch/$(ARCH)/Makefile决定arch/$(ARCH)目录下哪些文件、哪些目录将

     被编译进内核

       arch/arm/Makefile中有如下内容:

      100  head-y     := arch/arm/kernel/head$(MMUEXT).o

                                       arch/arm/kernel/init_task.o

           ...............................................

      196  core-y  +=arch/arm/kernel/ arch/arm/mm/ arch/arm/common/

      197  core-y  +=$(machdirs) $(platdirs)

      198  core-$(CONFIG_FPE_NWFPE)  +=arch/arm/nwfpe/

      199  core-$(CONFIG_FPE_FASTFPE)   +=$(FASTFPE_OBJ)

      200  core-$(CONFIG_VFP)   += arch/arm/vfp/

            ...............................................

      204  libs-y   :=arch/arm/lib/ $(libs-y)

    

      第100行中MMUEXT在arch/arm/Makefile前面定义,对于没有MMU的处

   理器,使用文件head-nommu.S;对于有MMU的处理器,使用head.S文件

      CONFIG_XXXX在配置内核时定义,它的值有3种:y、m或空

      编译内核时将依次进入init-y、core-y、libs-y、drivers-y和net-y 

   所列出的目录中执行它们的Makefile,每个子目录都会生成一个

   built-in.o(libs-y所列的目录下,有可能生成lib.a文件)。最后,head-y

   所表示的文件将和这些built-in.o、lib.a一起被连接成内核映像文件 

   vmlinux

  (3)各级子目录下的Makefile决定所在目录下哪些文件将被编译进内核,哪

     些文件将被编译成模块(驱动程序),进入哪些子目录继续调用它们的

     Makefile

         在配置内核时,生成配置文件“.config”,根据.config中定义的各

     个变量决定编译哪些文件,Makefile使用如下语句间接包含.config文

     件(因为包含的是"include/config/auto.conf"文件):

              486  -include include/config/auto.conf

         在"include/config/auto.conf"文件中,变量的值为y或m

         1)obj-y用来定义哪些文件被编进(built-in)内核

             obj-y中定义的.o文件由当前目录下的.c或.S文件编译生成,

          它们连同下级子目录的built-in.o文件一起被组合成(使用

         “$(LD)-R”命令)当前目录下的built-in.o文件,这个built-in.o

           文件被它的上一层Makefile使用

         2)obj-m用来定义哪些文件被编译成可加载模块(Loadable module)

             obj-m中定义的.o文件由当前目录下的.c或.S文件编译生成,

          它们被编译成模块,一个模块可以由一个或几个.o文件组成,对于

          多个源文件的模块,除在obj-m中增加一个.o文件外,还要定义

          一个<module_name>-objs变量来告诉Makefile这个.o文件由哪些  

          文件组成

              例如:

             obj-$(CONFIG_ISDN) += isdn.o

             isdn-objs :=isdn_net_lib.o isdn_v110.o isdn_common.o

          3)lib-y用来定义哪些文件被编成库文件

              liy-y中定义的.o文件由当前目录下的.c或.S文件编译生成,

           它们被打包成当前目录下的一个库文件:lib.a ;同时出现在

           obj-y和lib-y中的.o文件,不会被包含进lib.a中,要把这个

           lib.a编译进内核中,需要在顶层Makefile中libs-y变量中列出

           当前目录

           4)obj-y、obj-m还可以指定要进入的下一层子目录

               obj-$(CONFIG_JFFS2_FS)  += jffs2/

(2)怎样编译这些文件----编译选项、连接选项是什么

   这些选项可分为3类:

    1)全局的

       适用于整个内核代码,在顶层Makefile和arch/$(ARCH)/Makefile中

    定义,这些选项的名称为CFLAGS(编译C文件的 选项)、AFLAGS(编译汇编

   文件的选项)、LDFLAGS(连接文件的选项)、 ARFLAGS(制作库文件的选项)

     2)局部的

         在各个子目录中定义,针对当前Makefile中的所有文件,名称分别

     为:EXTRA_CFLAGS、EXTRA_AFLAGS、EXTRA_LDFLAGS、EXTRA_ARFLAGS

     3)个体的

         仅适用于某个文件,如果想针对某个文件定义它的编译选项,可以使

     CFLAGS_$@,AFLAGS_$@,前者用于编译某个C文件,后者用于编译某

     个汇编文件。$@表示某个目录文件

 (3)怎样连接这些文件,它们的顺序如何

    在顶层Makefile中,目录名的后面直接加上built-in.o或lib.a,表示

  要连接进内核的文件,如下所示:

        init-y     := $(patsubst %/, %/built-in.o, $(init-y))

        core-y     := $(patsubst %/, %/built-in.o, $(core-y))

        drivers-y   :=$(patsubst %/, %/built-in.o, $(drivers-y))

        net-y      := $(patsubst %/, %/built-in.o, $(net-y))

        libs-y1    := $(patsubst %/, %/lib.a, $(libs-y))

        libs-y2    := $(patsubst %/, %/built-in.o, $(libs-y))

        libs-y     := $(libs-y1) $(libs-y2)

  patsubst是个字符串处理函数,它的用法如下:    

        $( patsubst  pattern, replacement,text)

     表示寻找“text”中符合格式“pattern”的字,用“replacement”代替

  它们,比如init-y的初值为“init/”,经过变换后变为“init/built-in.o”

      再如下所示:

         vmlinux-init := $(head-y) $(init-y)

         vmlinux-main := $(core-y) $(libs-y) $(drivers-y)$(net-y)

         vmlinux-all := $(vmlinux-init) $(vmlinux-main)

         vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds

      vmlinux-all表示所有构成映象文件vmlinux的目标文件,可知这些目标文件的顺序为head-y、init-y、core-y、libs-y、drivers-y、net-y

4.总结

(1)配置文件.config中定义了一系列的变量,Makefile将结合它们来决定哪些

  文件被编译进内核、哪些文件被编译成模块、涉及哪些子目录

(2)顶层Makefile和arch/$(ARCH)/Makefile决定根目录下哪些子目录、

  arch/$(ARCH)目录下哪些文件和目录将被编译进内核

(3)各级子目录下的Makefile决定所在目录下的哪些文件将被编译进内核,哪些

  文件被编译成模块(即驱动程序),进入哪些子目录继续调用它们的Makefile

(4)顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、

  连接选项,即全局选项

(5)各级子目录下的Makefile中可以设置影响当前目录下所有文件的编译、连接

  选项,即局部选项

(6)顶层Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)

    kernel/vmlinux.lds生成内核映象文件vmlinux

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值