1. 程式人生 > >vivi的Makefile檔案解析(4)

vivi的Makefile檔案解析(4)

    vivi的主makefile解析完了,但是如果仔細分析vivi的原始碼會發現,在實際的vivi的原始碼還有很多其他的makefile,這裡我們這麼進行分類,在vivi/下的Makefile我們稱之為主makefile,在 arch/目錄下的makefile稱之為平臺makefile,而在其他目錄下的makefile稱之為子makefile,這樣的分類是根據它的功能來劃分的,在一些的子目錄下,都有獨立的makefile,需要完成編譯工作,而總的工作是由主makefile來排程的,那麼這些子makefile只怎麼來完成工作的,這裡需要注意一個非常重要的檔案:Rules.make,這是檔案編譯所需要共同遵守的規則。 這是drivers/下的一個makefile

#
# Makefile for the Linux kernel device drivers.
#
# 15 Sep 2000, Christoph Hellwig
# Rewritten to use lists instead of if-statements.
#

subdir-y := serial
subdir-$(CONFIG_MTD) += mtd

include $(TOPDIR)/Rules.make

它的結構非常的簡單,subdir-y : = serial 這是需要注意的一個地方。makefile真是通過subdir-y這種形式的指令碼來完成目錄的遍歷的,這裡的subdir-$(CONFIG_MTD) +

= mtd 其實也是subdir-y的形式,應為在.config配置檔案中,CONFIG_MTD只用兩種格式:y或者n,這樣,如果在make menuconfig中,選了mtd相關選項,那麼這個subdir-$(CONFIG_MTD) 就程式設計subdir-y了,這樣subdir-y就包含了兩個目錄:serial mtd,同時在這個檔案中還可以看到,包含了檔案$(TOPDIR)/Rules.make ,而變數 subdir-y會在 Rules.make 中用到。

   我們來看一下另外一個makefile,在這個目錄中沒有下一級目錄。

這是一個在目錄drivers/serial/下的makefile

O_TARGET        := serial.o

obj-y := serial_core.o
obj-$(CONFIG_SERIAL_GETCMD_STD)    += getcmd.o
obj-$(CONFIG_SERIAL_GETCMD_EXT)    += getcmd_ext.o
obj-$(CONFIG_SERIAL_TERM)    += term.o
obj-$(CONFIG_SERIAL_XMODEM)    += xmodem.o
obj-$(CONFIG_SERIAL_YMODEM)    += ymodem.o
obj-$(CONFIG_SERIAL_ZMODEM)    +=

zmodem.o

include $(TOPDIR)/Rules.make

在serial/下,沒有下一級的目錄,所以在這個makefiel中沒有看到subdir-y 這樣的變數,表示在個目錄下沒有下一級的目錄,這是make就會編譯這個目錄下的檔案,編譯完成後,返回上級目錄,再在上一級目錄中執行相同的動作,直到所有的目錄中的檔案讀編譯完為止,具體就是先從根目錄一直往下到,直到目錄的最底層,然後開始編譯,編譯完一個返回上次曾,然後按照字母順序繼續編譯其他的目錄。但是同時會發現,在這個makefile中,沒有其他的編譯選項,情況是這樣的,所有的子makefile都包含Rules.make, 這裡包含了通用的make規則。下邊我們來解析下:

#
# This file contains rules which are shared between multiple Makefiles.
#
#
# False targets.
#
.PHONY: dummy

#
# Special variables which should not be exported
#下邊的申明瞭這些變數不會被匯出,只在本檔案內使用
unexport EXTRA_AFLAGS
unexport EXTRA_CFLAGS
unexport EXTRA_LDFLAGS
unexport EXTRA_ARFLAGS
unexport SUBDIRS
unexport SUB_DIRS
unexport ALL_SUB_DIRS
unexport O_TARGET

unexport obj-y
unexport obj-n
unexport obj-
unexport export-objs
unexport subdir-y
unexport subdir-m
unexport subdir-n
unexport subdir-

上邊是一些簡單的申明,我們繼續:

#
# Get things started.
#
first_rule: sub_dirs
    $(MAKE) all_targets

both-m : = $(filter $(mod-subdirs), $(subdir-y))
SUB_DIRS    : = $(subdir-y)
ALL_SUB_DIRS    : = $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))


#
# Common rules 通用規則
#

%.s: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $([email protected]) -S $< -o [email protected]


# 通用預處理規則
%.i: %.c
    $(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $([email protected]) $< > [email protected]

# 隱含規則, 把.c生成.o檔案
%.o: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $([email protected]) -c -o [email protected] $<
    @ ( /
     echo 'ifeq ($(strip $(subst $(comma), : , $ ( CFLAGS) $(EXTRA_CFLAGS) $([email protected]))), $ $ ( strip $$(subst $$(comma), : , $ $ ( CFLAGS) $$(EXTRA_CFLAGS) $$([email protected]))))' ; /
     echo 'FILES_FLAGS_UP_TO_DATE + = [email protected]' ; /
     echo 'endif' /
    ) > $(dir [email protected])/.$(notdir [email protected]).flags

%.o: %.s
    $(AS) $(AFLAGS) $(EXTRA_CFLAGS) -o [email protected] $<

%.s: %.S
    $(CPP) $(AFLAGS) $(EXTRA_AFLAGS) $([email protected]) $< > [email protected]

%.o: %.S
    $(CC) $(AFLAGS) $(EXTRA_AFLAGS) $([email protected]) -c -o [email protected] $<


%.lst: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $([email protected]) -g -c -o $* . o $<
    $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
#
#
#
all_targets: $(O_TARGET) $(L_TARGET)

這部分程式碼中,最為關鍵的部分在這裡

first_rule : sub_dirs
    $(MAKE) all_targets

both-m
: = $(filter $(mod-subdirs) ,
$(subdir-y))
SUB_DIRS    
: =
$(subdir-y)
ALL_SUB_DIRS    
: = $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))

這裡first_rule依賴sub_dirs,先看看sub_dirs:

#
# A rule to make subdirectories
#
# "這裡的sort函式對資料夾進行排序"
subdir-list = $(sort $(patsubst %, _subdir_%, $ ( SUB_DIRS)))
sub_dirs: dummy $(subdir-list)

ifdef SUB_DIRS
$(subdir-list) : dummy
 $(MAKE) -C $(patsubst _subdir_%, % , $ @ )
endif

這裡的sort函式是對目錄按照字母順序進行排序,然後依次進入各個目錄。$(MAKE) -C $(patsubst _subdir_%, % , $ @ ) 中的-C 選項的意思就是進入目錄,由於SUB_DIRS包含有多個目錄,所以是依次進入,這樣你就會知道為什麼很多時候,我們在makefile的時候會看到如下的語句:

make[1]: Entering directory `/tmp/vivi/drivers'
make -C mtd
make[2]: Entering directory `/tmp/vivi/drivers/mtd'
make -C maps
make[3]: Entering directory `/tmp/vivi/drivers/mtd/maps'
make all_targets
make[4]: Entering directory `/tmp/vivi/drivers/mtd/maps'
make[4]: Nothing to be done for `all_targets'.
make[4]: Leaving directory `/tmp/vivi/drivers/mtd/maps'
make[3]: Leaving directory `/tmp/vivi/drivers/mtd/maps'

make -C nand

現在明白它是怎麼實現的了,注意到最後一條語句了嗎? make -C nand , 這句話的意思就是進入到目錄nand中去,這是引數-C的作用,這裡的C是大寫。
  這裡簡單的把編譯的通用規則貼出來,這些程式碼都通用,可以在以後的開發過程中加入這些程式碼到自己的Makefile中去。

#
# Common rules 通用規則
#

%. s: %. c
    $( CC) $( CFLAGS) $( EXTRA_CFLAGS) $( [email protected]) - S $< - o [email protected]


# 通用預處理規則
%. i: %. c
    $( CPP) $( CFLAGS) $( EXTRA_CFLAGS) $( [email protected]) $< > [email protected]

# 隱含規則, 把. c生成. o檔案
%. o: %. c
    $( CC) $( CFLAGS) $( EXTRA_CFLAGS) $( [email protected]) - c - o [email protected] $<
    @ ( /
     echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $([email protected]))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$([email protected]))))' ; /
     echo 'FILES_FLAGS_UP_TO_DATE += [email protected]' ; /
     echo 'endif' /
    ) > $( dir [email protected]) / . $ ( notdir [email protected]) . flags

%. o: %. s
    $( AS) $( AFLAGS) $( EXTRA_CFLAGS) - o [email protected] $<

%. s: %. S
    $( CPP) $( AFLAGS) $( EXTRA_AFLAGS) $( [email protected]) $< > [email protected]

%. o: %. S
    $( CC) $( AFLAGS) $( EXTRA_AFLAGS) $( [email protected]) - c - o [email protected] $<


%. lst: %. c
    $( CC) $( CFLAGS) $( EXTRA_CFLAGS) $( [email protected]) - g - c - o $* . o $<
    $( TOPDIR) / scripts/makelst $* $( TOPDIR) $( OBJDUMP)

需要注意的是,在上的編譯工作,會把.c檔案依次程式設計成.o檔案,這樣太多的.o檔案是不便於管理的,通常情況下,我們都會很多的.o檔案連線成一個.o檔案,這裡是vivi中的實現:

#
# Rule to compile a set of . o files into one . o file
#
ifdef O_TARGET
$( O_TARGET) : $( obj- y)
    rm - f [email protected]
    ifneq "$(strip $(obj-y))" "" # strip函式: 去空格函式
    $( LD) $( EXTRA_LDFLAGS) - r - o [email protected] $( filter $( obj- y) , $^)
    else
    $( AR) rcs [email protected] # "AR" 打包工具,在做庫檔案時會用到這個工具
    endif
    @ ( /
     echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_LDFLAGS) $$(obj-y))))' ; /
     echo 'FILES_FLAGS_UP_TO_DATE += [email protected]' ; /
     echo 'endif' /
    ) > $( dir [email protected]) / . $ ( notdir [email protected]) . flags
endif # O_TARGET

現在整個vivi的makefile就解析到這裡了, 而我們需要知道的是vivi的Makefile實質上是完全參照kernel的makefile的,kernel的makefile跟這個是一樣的,只是目錄 更多,系統跟龐雜一些,我們對linux的認識更加深入了一層,現在好好的理一下思路。嘿嘿,東西有點多,有點亂啊。

相關推薦

vivi的Makefile檔案解析(4)

    vivi的主makefile解析完了,但是如果仔細分析vivi的原始碼會發現,在實際的vivi的原始碼還有很多其他的makefile,這裡我們這麼進行分類,在vivi/下的Makefile我們稱之為主makefile,在 arch/目錄下的makefile稱之為平臺makefile,而在其他目錄下的

JavaEE-SSM:007 Mybatis的配置檔案解析4

1.系統級別的typeHandler   2.自定義typeHandler   想要自己實現typeHandler,需要實現TypeHandler<T>介面,T就是你要轉換的Java型別 setParameter(PreparedSta

JDK動態代理(4)ProxyGenerator生成代理類的位元組碼檔案解析

通過前面幾篇的分析,我們知道代理類是通過Proxy類的ProxyClassFactory工廠生成的,這個工廠類會去呼叫ProxyGenerator類的generateProxyClass()方法來生成代理類的位元組碼。ProxyGenerator這個類存放在su

Java解析xml檔案4種方式

java解析xml分為兩類,4種,分別為SAX解析,dom解析,jdom,dom4j.以下具體舉例使用4種方式來實現對一個.xml檔案進行解析: 有命名為dome.xml的檔案, <?xml version="1.0" encoding="UTF-8"?> &l

JDK動態代理[4]----ProxyGenerator生成代理類的位元組碼檔案解析

通過前面幾篇的分析,我們知道代理類是通過Proxy類的ProxyClassFactory工廠生成的,這個工廠類會去呼叫ProxyG

Mybatis原始碼分析(1)—— Mapper檔案解析

感覺CSDN對markdown的支援不夠友好,總是伴隨各種問題,很惱火! xxMapper.xml的解析主要由XMLMapperBuilder類完成,parse方法來完成解析: public void parse() { if (!configuration.isRes

nginx1-dns域名解析|nginx入門|win下搭建|配置檔案解析

DNS域名解析器 DNS,域名系統,是網際網路上作為域名和IP地址相互對映的一個分散式資料庫 目的:將域名轉化成ip 過程 ------------------本機------------------ 1.輸入網址(www.163.com) 2.瀏覽器檢查快取中有沒有這個域名

linux中/etc/passwd檔案解析

在Linux /etc/passwd檔案中每個使用者都有一個對應的記錄行,它記錄了這個使用者的一些基本屬性。系統管理員經常會接觸到這個檔案的修改以完成對使用者的管理工作。 它的內容類似下面的例子: 從上面的例子我們可以看到,/etc/passwd中一行記錄對應著一個使用者,每行記錄又被

Tomcat配置檔案解析

Tomcat作為一個開源的輕量級web容器,使用非常廣泛; 其配置檔案一般都在 server.xml中配置; server.xml中的每一個元素都對應tomcat的一個元件,位於 tomcat的conf目錄下面 一個完整的 server.xml(tomcat 7) <?xml ve

EasyUI內部CSS檔案解析

  .panel { overflow: hidden;/*溢位*/ text-align: left; margin: 0; border: 0; -moz-border-radius: 0 0 0 0; -webkit-borde

SPI驅動檔案解析

三:SPI裝置驅動程式 在板檔案中新增SPI裝置   <span style="color:#444444"><strong>static </strong> <strong>struct</strong> spi_b

netty原始碼解解析(4.0)-1 核心架構

netty是java開源社群的一個優秀的網路框架。使用netty,我們可以迅速地開發出穩定,高效能,安全的,擴充套件性良好的伺服器應用程式。netty封裝簡化了在伺服器開發領域的一些有挑戰性的問題:jdk nio的使用;多執行緒併發;擴充套件性。它還提供了多種應用層協議的支援:http/https/web

netty源碼解解析(4.0)-1 核心架構

coder style out ava 默認 mage 網絡框架 分享圖片 輸入 netty是java開源社區的一個優秀的網絡框架。使用netty,我們可以迅速地開發出穩定,高性能,安全的,擴展性良好的服務器應用程序。netty封裝簡化了在服務器開發領域的一些有挑戰性的問題

檔案解析漏洞小結

一、IIS 5.x/6.0解析漏洞利用方法有兩種 1.目錄解析 /xx.asp/xx.jpg 漏洞原理:在網站下建立名字為 xx.asp的資料夾,其目錄內的任何副檔名的檔案都被IIS當作asp檔案來解析並執行。(php的也是一樣) 漏洞利用:  例如建立目錄&nb

初識.NetCore-web mvc程式初始檔案解析

    之前一直做netframework相關的開發,最近公司的專案想向微服務靠近,在經過各個技術選型之後,決定使用netcore。   但是理想很豐滿,現實很骨感。在使用netcore進行微服務相關開發之前,先需要把netcore學會。自己工作也有個五六年了,從來沒有做過一次正式的總結歸

circos配置檔案解析

歡迎關注微信公眾號《生信修煉手冊》! Circos 的核心就是配置檔案的編寫,在配置檔案中,包含兩個方面的內容: 資料 引數 作為一款視覺化工具,毫無疑問肯定是需要建立在資料的基礎上的。有了資料之後,如何展示,會有許多的引數需要設定和調整,這些引數就是我們需要

案例解析4步驟大段文字變身為PPT

在製作PPT的時候,我們經常需要將一大段的文字轉換為PPT。面對這種需求,很多人都會有一種無從下手的感覺,今天我們就通過兩個案例,給大家介紹通過4個步驟讓大段文字變身為PPT。 上週我給深圳供電局的同事們做了一場關於PPT課件製作技巧的培訓。在準備課程的時候,我按照慣例到深圳供電局的官網,找素材來設

PE檔案解析 基礎篇

PE檔案解析 基礎篇 來源 https://bbs.pediy.com/thread-247114.htm 前言 之前學習了PE格式,為了更好的理解,決定寫一個類似LoadPE的小工具。 編譯器是VS2015,採用MFC框架。 此係列文章採用邊介紹知識點,邊寫程式碼的

MemoryModule閱讀與PE檔案解析(一)

參考連結 https://github.com/fancycode/MemoryModule 本文閱讀github 上MemoryModule 程式碼的同時,介紹PE 檔案相關的基礎知識。       該專案實現“手

關於使用JAVA進行MIB檔案解析

       最近工作上有功能需求解析MIB檔案,在網上找了一圈之後發現都是不全的,很多論壇的提問及回答都是很多年前的,最後經過摸索找到了完整的解析方法,因此做個記錄,也希望給其他需要的人一個幫助。