乙個應用程式的形成是少不了一下幾個步驟的。
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...