1. 程式人生 > >一個通用的Makefile(轉載)

一個通用的Makefile(轉載)

轉載於 : http://www.cnblogs.com/lidabo/p/4521123.html

一 makefile的作用

    Makefile是用於自動編譯和連結的,一個工程有很多檔案組成,每一個檔案的改變都會導致工程的重新連結,但是不是所有的檔案都需要重新編譯,Makefile中記錄有檔案的信 息,在make時會決定在連結的時候需要重新編譯哪些檔案。Makefile的宗旨就是:讓編譯器知道要編譯一個檔案需要依賴其他的哪些檔案。當那些依賴檔案有了改變,編譯器會自動發現最終的生成檔案已經過時,而應該重新編譯相應的模組。 makefile帶來的好處就是—"自動化編譯",一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟體開發的效率。預設的情況下,make命令會在當前目錄下按順序找尋檔名為"GNUmakefile"、"makefile"、"Makefile"的檔案,找到了解釋這個檔案。當然也可以使用make -f DIR/makefile 來指定用於makefile檔案

二 makefile語法簡述

2.1 makefile規則

target ... : dependencies ... 
            command

target目標檔案,可以是Object File,也可以是執行檔案,還可以是一個標籤 
dependencies就是,要生成那個target所需要的檔案或是目標。 
command也就是make需要執行的命令。(任意的Shell命令,可以有若干行)

    這是一個檔案的依賴關係,也就是說,target這一個或多個的目標檔案依賴於dependencies中的檔案,其生成規則定義在command中。dependencies 中如果有一個以上的檔案時間要比target檔案要新的話,command所定義的命令就會被執行。這就是 Makefile的規則。也就是Makefile中最核心的內容。在Makefile中的命令,必須要以[Tab]鍵開始。

2.2 變數定義

    Makefile中變數的定義一般有兩種: =和:=。 =符號定義的變數叫延時變數,只有在使用的時候才擴充套件開來; :=符號定義的變數為立即變數,一旦定義就擴充套件。 使用=定義的變數不能追加新值,使用:=定義的變數可以使用+=追加新值

2.3 檔案指示

    在Makefile使用include關鍵字可以把別的Makefile包含進來,這很像C語言的#include,被包含的檔案會原模原樣的放在當前檔案的包含位置。include的語法是:include <filename> filename可以是當前作業系統Shell的檔案模式(可以保含路徑和萬用字元)

2.4 偽目標

    偽目標並不是一個檔案,只是一個標籤,由於偽目標不是檔案,所以make無法生成它的依賴關係和決定 它是否要執行。我們只有通過顯示地指明這個目標才能讓其生效。當然,偽目標的取名不能和檔名重名,不然其就失去了偽目標的意義了。當然,為了避免和檔案重名的這種情況,我們可以使用一個特殊的標記.PHONY來顯示地指明一個目標是偽目標,向make說明,不管是否有這個檔案,這個目標就是偽目標。

2.5 自動化變數

    $<    第一個依賴檔案的名稱

    $?    所有的依賴檔案,以空格分開,這些依賴檔案的修改日期比目標的建立日期晚

    [email protected]    目標的完整名稱

    $^    所有的依賴檔案,以空格分開,不包含重複的依賴檔案

 三 通用的makefile例項

工程必備:

頂層Makefile 頂層Makefile.build 子目錄Makefile

編譯過程:

    從頂層開始遞迴進入子目錄,當進入到一個目錄的最底層時,開始使用GCC編譯,再將該層的所有.o檔案打包成build-in.o,返回它的上一層目錄再遞迴進入子目錄,當編譯完所有的子目錄後,就開始編譯頂層的.c檔案,最後將頂層的.o檔案和頂層每個子目錄的build-in.o連結成我們的目標檔案

頂層Makefile解析(隨工程而變):

#----------------------------------------------指定編譯工具鏈---------------------------------------------------

CROSS_COMPILE =                             #指定編譯器種類

AS        = $(CROSS_COMPILE)as         #

LD        = $(CROSS_COMPILE)ld          #連結工具

CC        = $(CROSS_COMPILE)gcc       #編譯工具

CPP        = $(CC) -E                             #

AR        = $(CROSS_COMPILE)ar         #打包工具

NM        = $(CROSS_COMPILE)nm       #
 

STRIP        = $(CROSS_COMPILE)strip              #優化工具

OBJCOPY        = $(CROSS_COMPILE)objcopy   #

OBJDUMP        = $(CROSS_COMPILE)objdump  #

export AS LD CC CPP AR NM                           #將定義的變數匯出,方便其他makefile使用

export STRIP OBJCOPY OBJDUMP                   #將定義的變數匯出,方便其他makefile使用
 

CFLAGS := -Wall -O2 -g                                    #編譯器引數

CFLAGS += -I $(shell pwd)/include                     #指定編譯器標頭檔案(根據實際專案手動修改)

LDFLAGS := -lm -lfreetype -lvga                         #指定編譯器連結庫(根據實際專案手動修改)

export CFLAGS LDFLAGS                                #將定義的變數匯出,方便其他makefile使用

TOPDIR := $(shell pwd)                                     #獲得當前程式的頂層目錄

export TOPDIR                                                 #輸出頂層目錄

 TARGET := show_file                                      #編譯後的程式名(根據實際專案手動修改)

#-------------------------頂層要生成的.o檔案以及頂層資料夾(根據實際專案手動修改)------------------

obj-y += main.o

obj-y += display/

obj-y += draw/

obj-y += encoding/

obj-y += fonts/

#--------------------------------------------頂層的第一個規則(預設規則)-----------------------------------------

all :

    make -C ./ -f $(TOPDIR)/Makefile.build           #進入當前目錄,使用頂層的makefile.build進行編譯

    $(CC) $(LDFLAGS) -o $(TARGET) built-in.o    #將編譯好的built-in.o檔案連結生成我們的目標檔案

#------------------------------------------------頂層的清除規則-------------------------------------------------------

clean:

    rm -f $(shell find -name "*.o")                        #刪除所有的.o檔案

    rm -f $(shell find -name "*.d")                        #刪除所有的.d檔案

    rm -f $(TARGET)                                         #刪除目標檔案

.PHONY:all clean

頂層Makefile.build解析(無需改動):

PHONY := __build                                        #定義一個PHONY變數

__build:                                                       #開頭說明__build偽目標,使其成為Makefile.build的第一個目標

obj-y :=                                                        #定義當前目錄的目標變數,初始值為空

subdir-y :=                                                    #定義當前目錄的子目錄變數,初始值為空

include Makefile                                              #將當前目錄的Makefile包含進來,初始化obj-y

                                                                   #obj-y:=a.o b.o c/ d/

__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))   #篩選出當前目錄的目標變數中的子目錄,並且去掉/

                                                                                   #$(filter %/, $(obj-y)):c/ d/

                                                                                   #__subdir-y:c d

subdir-y += $(__subdir-y)                                           #將開始定義的subdir-y賦值為__subdir-y

                                                                                   #subdir-y:c d

subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)  #對於subdir-y裡面的每一個值(目錄),增加一個相應的目錄/built-in.o的變數值

                                                                                   #subdir_objs:c/built-in.o d/built-in.o

cur_objs := $(filter-out %/, $(obj-y))                            #得到obj-y中的.o檔案

                                                                                   #cur_objs:a.o b.o

dep_files := $(foreach f,$(cur_objs),.$(f).d)                #對於所有的.o檔案,定義它的依賴檔名

                                                                                   #dep_files: .a.d .b.d

dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)                                                    #根據依賴檔名,判斷依賴檔案是否存在,存在就包含就來

    include $(dep_files)

endif

PHONY += $(subdir-y) #將$(subdir-y)也加入到變數PHONY中

--------------------------------------------Makefile. build的第一個規則--------------------------------------------------------------

__build : $(subdir-y) built-in.o                                    #第一個規則

$(subdir-y):                                                                #第一個規則的第一個依賴規則

    make -C [email protected] -f $(TOPDIR)/Makefile.build              #依次進入該子目錄變數裡面儲存的值,使用的Makefile.build進行編譯

 built-in.o : $(cur_objs) $(subdir_objs)                       #第一個規則的第二個依賴規則

      $(LD) -r -o [email protected] $^                                                 #該規則的命令:將該目錄下的.o和$(subdir_obj)打包成built-in.o檔案

dep_file = [email protected]                                                        #

%.o : %.c                                                                   #第一個規則的第二個依賴規則的依賴規則 

$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o [email protected] $<          #用於將目錄下所有的.c檔案編譯成.o檔案

.PHONY : $(PHONY)                                                  #將PHONY宣告為偽目標

 子目錄Makefile(隨工程而變):

子目錄的Makefile就是包含該目錄下所有的目標檔名和子目錄資料夾名。

例如任何一個子目錄可寫成:

objs-y := a.o

objs-y += b.o

objs-y += c/

objs-y += d/

四 示例工程

     http://pan.baidu.com/share/link?shareid=145262&uk=101680913

相關推薦

一個通用Makefile轉載

轉載於 : http://www.cnblogs.com/lidabo/p/4521123.html 一 makefile的作用     Makefile是用於自動編譯和連結的,一個工程有很多檔案組成,每一個檔案的改變都會導致工程的重新連結,但是不是所有的檔案都需要重新編

送你一個勵志故事轉載

轉載 MARK一下 作者:守望者1028 連結:https://www.nowcoder.com/discuss/55353 來源:牛客網   本面試主要分成三塊內容: 第一部分:知識水平的提升方法與面試技巧,針對非科班或者知識面薄弱的同學,講解準備校招與校招過程中應該具備的能力與

自定義一個更好用的SwipeRefreshLayout彈力拉伸效果詳解轉載

dsc drag 常數 lane swipe loading 數據改變 高中數學 tca 轉自: 自定義一個更好用的SwipeRefreshLayout(彈力拉伸效果詳解) 前言 熟悉SwipeRefreshLayout的同學一定知道,SwipeRefreshLayout是

一個程序員寫不出代碼了,該怎麽辦?轉載

保持 解決 為我 水平 身體 min height 開源 軟件工程 翻譯作者:碼農網-小峰 轉載地址:http://www.codeceo.com/article/what-to-do-programming-sucks.html 原文標題:What Do You Do W

通用 Makefilemakefile中的notdir,wildcard和patsubst

and har alt table free modify sources follow rul notdir,wildcard和patsubst是makefile中幾個有用的函數,以前沒留意過makefile中函數的用法,今天稍微看看~ 1、makefile裏的函數

linux 將一個服務器上的文件或文件夾拷貝到另一個服務器上轉載

轉載 oca href 計算機名稱 http 目錄命令 遠程服務器 target blog 復制文件或目錄命令: 復制文件: (1)將本地文件拷貝到遠程 scp 文件名用戶名@計算機IP或者計算機名稱:遠程路徑 本地192.168.1.8客戶端 scp /r

看到一個牛人的群聊天記錄,超贊!轉載

top 不出 說明 話題 悲劇 最好的 至少 防止 自己 下面是聊天記錄原文(http://bbs.csdn.net/topics/390114474來自csdn-bbs): “ 2012/2/2 15:13:23 有一個原則 2012/2/2 15:13:

轉載】BP增強 新增自定義螢幕 KNA1 通用資料英文

測試通過。 其他參考(中文):https://blog.csdn.net/guangcong2009/article/details/80569877                 英文:http://www.

專案管理級別的自動萬能通用makefile模板:t-makefile freetoo

  專案管理級別的自動萬能通用makefile模板:t-makefile (freetoo)   t-makefile原始碼及示例專案下載連結(會不定期更新): https://github.com/freetoo/t-makefile  

一個老程式設計師十年生涯總結轉載

今年是我大學畢業滿10年的日子,也是我投身IT技術的第10年。一直想能對過去的經歷做些回顧與反思,以更      好地走向未來,但總沒有筆。剛好CSDN舉辦“講述程式設計師的故事”徵文,這件事成了一個引子,我終於趁著暑期有時間,敲了一天鍵盤,便有了這篇人生自述。       10年對於一個人

java中判斷字串是否是一個整數轉載

1.使用型別轉換判斷   try {                  String str="123abc";                  int num=Integer.valueOf(str);//把字串強制轉換為數字                  retu

一個完整的URL包括的內容轉載

假設這是一個url地址http://localhost:8080/a/b/c?a=1&b=2#abc,裡面包含的部分:protocol: 'http:',//協議host: 'localhost:8080',port: '8080',//埠hostname: 'localhost',域名hash: '

一個男人關心的東西 決定了他的層次轉載

一個男人關心的東西 決定了他的層次   一、擁有自信和風度 男人到了二十幾歲後,就要開始學著用心去經營自己了,它體現在自己的思想與涵養上。自信是一個男人最重要的品質,自信的男人就你像一隻在暴風雨中戰鬥的海鷗。海鷗所要說的只有一句話“讓暴風雨來的再猛烈些吧”,只因為它無所畏懼。一

一個管道工的成功移民經歷轉載

一個管道工的成功移民經歷從 FeedzShare來自: 山寨畫報 - FeedzShare   釋出時間:2010年12月06日,  已有 4 人推薦本人大學畢業後分在江蘇省一個地級市的國營機床廠工作,分在科室裡做做行政工作,朝九晚五,簡單枯燥。老婆在一私營服裝廠工作,早晨7

空降到一個測試團隊如何管理?轉載

成功做好空降兵的策略是什麼? 新官上任三把火怎麼燒? 我的經驗很簡單:以靜制動,先立後破。遇事則急,遇人則緩。 以靜制動     很多人剛剛走上更高的管理職位時都容易心浮氣躁。“春風得意馬蹄疾”,很有“一日看盡長安花”的慾望,迫不及待的想做出一番成績,。人最得意的

關於android動畫的一個總結轉載

轉自:https://mp.weixin.qq.com/s?__biz=MzIxMTg5NjQyMA==&mid=2247483735&idx=1&sn=d2092ef4dd3c6726a211c84c4509e8b9&chksm=974f105ca038994a4

轉載如何用PHP開發一個完整的網站 講解開發流程 多人開發

引言: 一個清楚的目標定位學習 PHP 才更有動力和方向,約有 30% 的 PHPer 因為學習到一半而沒有明確的方向而最終放棄或擱淺。 手頭收藏一些好的常用類或方法,能提高我們的開發的速度。如:分頁、上傳、字元過濾、資料庫操作、生成 HTML HTML HTML 、檔

一個jmter介面測試的demo轉載

轉載地址忘了。。。 將下面的程式碼貼上儲存為demotest.jmx檔案,然後再jmeter中開啟 <?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1.2" properti

C++】判斷一個圖是否有環 無向圖 有向圖轉載

沒有找到原文出處,請參考一下連結: 一、無向圖: 方法1: 如果存在迴路,則必存在一個子圖,是一個環路。環路中所有頂點的度>=2。   n演算法:        第一步:刪除所有度<=1的頂點及相關的邊,並將另外與這些邊相關的其它頂點的度減一。