makefile 主要是編譯就是用來編譯原始檔的
makefile的檔案命名:makefile 或 makefile
makefile的規則或者說寫法就三個部分:目標、依賴、命令
具體怎麼寫呢
目標:依賴看乙個小例子(tab縮排)命令
執行gcc命令
這就是乙個最簡單的makefile,但是它最大問題是,如果你修改了中乙個.c檔案,在gcc編譯的時候會把所有的c檔案都編譯一遍,這樣效率就很低,所以可以把他們分開寫,先編譯成.o二進位制檔案。這樣就是第二個例子
main.o :main.c
gcc main.c -c
add.o :add.c
gcc add.c -c
sub.o :sub.c
gcc sub.c -c
mul.o :mul.c
gcc mul.c -c
這樣當你更改某乙個.c檔案後,只會編譯你修改的那個c檔案,編譯成.o二進位制檔案,而不用把所有的都編譯一遍,節省很多時間。
那makefile是怎麼知道要重新編譯的是哪乙個檔案呢。
原理是:
如果依賴存在就判斷是否需要更新也就是小目標是否要執行,
判斷的依據是目標和依賴的時間,如果目標的時間大於依賴的時間,不更新,反之需要更新。說白了就是它會根據檔案時間的變化檢測你有沒有更改原始檔,更改了就要更新。因為一定是現有依賴才有的目標,目標.o檔案時間要晚於依賴的時間也說成大於。也就是說一旦更改了依賴檔案,這個檔案最終時間就在目標之後了,依賴時間大於了目標時間,說明你修改了依賴檔案,這時就需要更新。
但是上面這個makefile寫的太冗餘了。下面看下面乙個例子改進一下:
前面說makefile就像乙個指令碼,那它就可以有變數和函式。所以先看一下變數,變數你可以自己定義,makefile本身也提供了幾個固定的變數。
自定義變數:makefile裡面自定義變數沒有型別 直接賦值就行,例如:obj = a.o b.o c.o 或者 obj = 10 ,不講道理的使用,
但是變數不能直接使用要取出變數的值,用$符號,例如$(obj)
makfile提供的變數:cc 、cpplags、ldflags、libs等
cc=」gcc -march=k8 -o2 -s」就是在gcc編譯的時候需要指定一下頭檔案和庫檔案目錄,寫起來太長了,你就講路徑賦值給相應的變數,這是一種規範,你隨便給別的變數也能用。甚至很多makefile檔案中編譯都沒有gcc的字樣就是把gcc賦值給了cc。當然也可以把這些值設定到環境變數中去export ldflags="-l/var/***/lib -l/opt/mysql/lib -wl,r/var/***/lib -wl,r/opt/mysql/lib" ;ldflags = -l/var/***/lib -l/opt/mysql/lib
libs = -lmysqlclient -liconv
cppflags='-i/usr/local/libjpeg/include -i/usr/local/libpng/include'
自動變數:$@、$<、$^,makefile提供了幾個變數表示著固定的意思,不能對他們賦值且只能在規則命令中使用。
$@:規則中的目標改寫例二$<:規則中的第乙個依賴
$^:規則中的所有的依賴
現在這個makefile的可移植性很差obi = main.o add.o sub.o mul.o
$(target):$(obj)
gcc $(obj) -o $(target) 這一行就可以替換成 gcc $^ -o $@
%.o:%.c %模式匹配代表所有的.o檔案和所有的.c檔案
gcc -c $< -o $@
這裡看一下makefile的函式
makefile中所有的函式都有返回值,下面介紹兩個makefile的函式
(1)wildcard查詢指定資料夾下指定型別的檔案
src = $(wildcard ./*.c) 當前目錄下所有的.c檔案並賦值給src
(2)patsubst匹配替換
obj = $(patsubst %.c, %.o,$(src)) 把src變數中所有.c檔案替換為.o檔案
前面說的makefile最後生成的是只有第一目標,也就終極目標。其實makefile也可以生成不是終極目標的目標,src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.c,$(src))
$(target):$(obj)
gcc $^ -o $@
%.o:%.c
gcc -c $< -o $@
呼叫使用 :make 目標名 ,例如乙個makefile最後會執行make clean清理專案
執行make hello 會列印hello,makefilesrc = $(wildcard ./*.c)
obj = $(patsubst %.c,%.c,$(src))
$(target):$(obj)
gcc $^ -o $@
%.o:%.c
gcc -c $< -o $@
hello:
echo "hello,makefile"
如果我們加乙個,清理專案的操作,表示如果執行失敗刪除前面生成的檔案。
clean:這裡有會有個問題就是,如果當前目錄下有同名的clean檔案,make clean就不會執行。前面例二就說了,makefile根據依賴的時間來判斷會不會更新,但是這裡clean沒有依賴。-mkdir /abc
-rm $(obj)&(target) -f #-f表示強制執行 ,命令前的'-'號表示當前命令失敗向下執行
解決這個問題的方法是寫乙個偽目標 .phony:clean ,注意phony前面有個'.'符號。
完整的就是
好了makefile就是這麼簡單。src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.c,$(src))
$(target):$(obj)
gcc $^ -o $@
%.o:%.c
gcc -c $< -o $@
.phony:clean
clean:
-mkdir /abc
-rm $(obj)&(target) -f
最後寫乙個小例子
在plus目錄下有兩個目錄include和src,現在在plus目錄下編寫makefile,編譯src下的原始檔,需要include中的標頭檔案。
cppflas = ./include
src = $(wildcard ./src/*.c)
obj = $(patsubst %.c,%.c,$(src))
$(target):$(obj)
gcc $^ -o $@
%.o:%.c
echo $<
gcc -c $< -i $(cppflags) -o $@
上面可以甚至讓 cppflas = '-i./include',這樣gcc中就不用再加引數 -i了
Visual Unit 簡明教程
visual unit,簡稱vu,是新一代單元測試工具,功能強大,使用簡單,完全視覺化,不需編寫測試 vu的測試結果使程式行為一目了然,有助於整理程式設計思路,提高程式設計效率和正確性,並能快速排錯 vu還增強偵錯程式功能 如自由後退 用例切換 提高除錯的效率 vu能達到空前的測試完整性,輕鬆完成語...
MYSQL簡明教程
dos進入mysql命令 c mysql h 127.0.0.1 u root p enter password mysql 進入完成 建立資料庫 create database databasename 使用指定資料庫進行操作 方法1 use database databasename 方法2 m...
Struts Hibernate簡明教程
jboss 資助的開源專案,當前比較流行的持久層框架,是一種先進的 jdbc 封裝框架。優點 提高了資料訪問層的開發效率,使我們不必直接呼叫 jdbc 來訪問關係型資料庫。hibernate 建立在物件導向的基礎之上,開發人員只需針對物件進行操作,不必再關心資料庫的連線關閉,sql的執行,以及 re...