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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM