編寫通用的Makefile

2022-08-18 19:36:17 字數 4994 閱讀 1844

乙個應用程式的形成是少不了一下幾個步驟的。

1. 預處理    #檢查語法錯誤、包含標頭檔案、展開#if、#define等巨集定義

2. 編譯     #把.c檔案轉換為彙編檔案.s

3. 彙編     #把.s彙編轉換為機器碼.o

4. 鏈結     #和庫檔案等組合在一起

只有經過了上面幾個步驟才能形成乙個可執行的應用程式

用gcc -o test test.c這個命令就可以將上面的四個步驟全部完成。加上編譯指令-v可以看到詳細的編譯過程。

介紹一下makefile中常用的函式。

用法是:

$(wildcard pattern...)

在makefile中,它被展開為已經存在的、使用空格分開的、匹配此模式的所有檔案列表。如果不存在任何符合此模式的檔案,函式會忽略模式字元並返回空。

一般我們可以使用「$(wildcard *.c)」來獲取工作目錄下的所有的.c檔案列表。

$(foreach var,list,text)

函式功能:

如果需要(存在變數或者函式的引 用) ,首先展開變數「var」和「list」的引用;

而表示式「text」中的變數 引用不展開。執行時把「list」中使用空格分割的單詞依次取出賦值給變數 「var」 ,然後執行「text」表示式。

重複直到「list」的最後乙個單詞(為 空時結束) 。

「text」中的變數或者函式引用在執行時才被展開,因此如果在 「text」中存在對「var」的引用,那麼「var」的值在每一次展開式將會到 的不同的值。

格式:$(patsubst ,,)

名稱:模式字串替換函式——patsubst。

功能:查詢中的單詞(單詞以「空格」、「tab」或「回車」「換行」分隔)是否符合模式,如果匹配的話,則以替換。這裡,可以包括萬用字元「%」,表示任意長度的字串。如果中也包含「%」,那麼,中的這個「%」將是中的那個「%」所代表的字串。(可以用「\」來轉義,以「\%」來表示真實含義的「%」字元)

返回:函式返回被替換過後的字串。 

$(filter pattern…,text)

函式名稱:過濾函式—filter。

函式功能:過濾掉字串「text」中所有不符合模式「pattern」的單詞,保留所 有符合此模式的單詞。可以使用多個模式。模式中一般需要包含模式字 符「%」。存在多個模式時,模式表示式之間使用空格分割。

返回值:空格分割的「text」字串中所有符合模式「pattern」的字串。

函式說明:「filter」函式可以用來去除乙個變數中的某些字串.

在編譯的時候加上-wp,-md即可自動生成依賴檔案。

如果需要編譯子目錄下的原始檔則在makefile中加上obj-y += 子目錄的名稱

在子目錄的makef中寫上obj-y += 子目錄中的原始檔.o

示例:

#

# makefile topdir

#cross_compile := arm-linux-          #指定交叉工具鏈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 objdump objcopy

cflags := -wall -o2

cflags += -i $(shell pwd)/include  

ldflags := -lm -lfreetype      #編譯選項

export cflags ldflags

topdir :=$(shell pwd)

export topdir

target :=show_file                #生成的目標檔案

obj-y +=main.o                    #當前目錄下的原始檔

obj-y += sub/                     #當前目錄下的子目錄 all:

make -c ./ -f $(topdir)/makefile.build    

$(cc) $(ldflags) -o $(target) built-in

.o     #編譯為目標檔案

clean:

rm -f $(shell find -name "

*.o"

) rm -f $(target)

distclean:

rm -f $(shell find -name "

*.o"

) rm -f $(shell find -name "

*.d"

) rm -f $(shell find -name "*~"

) rm -f $(target)

#

# makefile.build

#phony :=__build

__build:

obj-y :=subdir-y :=include makefile          #包含本目錄下的makefile

__subdir-y := $(patsubst %/, %, $(filter %/,$(obj-y)))

subdir-y += $(__subdir-y)

subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in

.o)cur_objs := $(filter-out %/, $(obj-y))

dep_files := $(foreach

f,$(cur_objs),.$(f).d)

dep_files :=$(wildcard $(dep_files))

ifneq ($(dep_files),)

include $(dep_files)

endif

phony += $(subdir-y)

__build:$(subdir-y) built-in

.o$(subdir-y) :

make -c $@ -f $(topdir)/makefile.build

built-in

.o : $(cur_objs) $(subdir_objs)

$(ld) -r -o $@ $^

%.o : %.c

$(cc) $(cflags) -wp,-md,[email protected] -c -o $@ $<.phony : $(phony)

#

# makefile subdir

#obj-y := test1.o

下面的乙個是編譯當前目錄下所有的.c檔案 不包含子目錄

#

# makefile topdir##

target :=show_file #生成的目標檔案

cross_compile := /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-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

export strip objdump objcopy

cflags := -wall -o2

cflags += -i $(shell pwd)/include  

ldflags := -lm -lfreetype

export cflags ldflags

cur_file = $(wildcard *.c)

cur_objs := $(cur_file:.c=.o)

all: $(cur_objs)

$(cc) $(cflags) -o $(target) $^clean:

rm -f $(shell find -name "

*.o"

) rm -f $(target)

distclean:

rm -f $(shell find -name "

*.o"

) rm -f $(shell find -name "*~"

) rm -f $(target)

sd

linux 通用makefile編寫

一般當我們的工程檔案較多的時候,使用gcc工具直接敲編譯命令比較麻煩,所以寫makefile的好處就來了,每次只需要敲一下make就能編譯 這裡分享乙個萬能版的,當前目錄不管多少檔案,都只需要make一下,不用修改makefile,直接生成main可執行程式 以下是makefile 交叉編譯工具鏈 ...

乙個通用Makefile的編寫

我們在linux環境下開發程式,少不了要自己編寫makefile,乙個稍微大一些的工程下面都會包含很多.c的原始檔。如果我們用gcc去乙個乙個編譯每乙個原始檔的話,效率會低很多,但是如果我們可以寫乙個makefile,那麼只需要執行乙個make就ok了,這樣大大提高了開發效率。但是makefile的...

編寫乙個簡單通用的makefile

author 李超 date 2012 05 06 縱然makefile 的規則還是相當多的,編寫乙個大規模的軟體,良好的 makefile 架構是方便維護程式編譯的關鍵。學習 makefile 的時間週期還是比較長的,為了寫出規範的 需要在很短的時間內編寫乙個 makefile 這裡給給出乙個 m...