zoukankan      html  css  js  c++  java
  • linux源码Makefile详解

    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

     

  • 相关阅读:
    HDU4529 郑厂长系列故事——N骑士问题 —— 状压DP
    POJ1185 炮兵阵地 —— 状压DP
    BZOJ1415 聪聪和可可 —— 期望 记忆化搜索
    TopCoder SRM420 Div1 RedIsGood —— 期望
    LightOJ
    LightOJ
    后缀数组小结
    URAL
    POJ3581 Sequence —— 后缀数组
    hdu 5269 ZYB loves Xor I
  • 原文地址:https://www.cnblogs.com/Daniel-G/p/3284831.html
Copyright © 2011-2022 走看看