**:
目的:
基本掌握了
make
的用法,能在
linux
系統上程式設計。
環境:
linux
系統,或者有一台
linux
伺服器,通過終端連線。一句話:有
linux
編譯環境。
準備:
準備三個檔案:
file1.c, file2.c, file2.h
file1.c:
#include
#include "file2.h"
int main()
file2.h:
#ifndef file2_h_
#definefile2_h_
#ifdef __cplusplus
extern "c"
#endif
#endif
file2.c:
#include "file2.h"
void file2print()
基礎:
先來個例子:
有這麼個
makefile
檔案。(檔案和
makefile
在同一目錄)
=== makefile
開始===
helloworld:file1.o file2.o
gcc file1.o file2.o -o helloworld
file1.o:file1.c file2.h
gcc -c file1.c -o file1.o
file2.o:file2.c file2.h
gcc -c file2.c -o file2.o
clean:
rm -rf *.o helloworld
=== makefile
結束===
乙個makefile
主要含有一系列的規則,如下:
a: b
(tab)
(tab)
每個命令行前都必須有
tab符號。
上面的makefile
檔案目的就是要編譯乙個
helloworld
的可執行檔案。讓我們一句一句來解釋:
helloworld : file1.o file2.o
:helloworld
依賴file1.o file2.o
兩個目標檔案。
gcc file1.o file2.o -o helloworld
:編譯出
helloworld
可執行檔案。
-o表示你指定
的目標檔名。
file1.o : file1.c
:file1.o
依賴file1.c
檔案。gcc -c file1.c -o file1.o
:編譯出
file1.o
檔案。-c
表示gcc
只把給它的檔案編譯成目標檔案,
用原始碼檔案的檔名命名但把其字尾由
「.c」
或「.cc」
變成「.o」
。在這句中,可以省略
-o file1.o
,編譯器預設生成
file1.o
檔案,這就是
-c的作用。
file2.o : file2.c file2.h
gcc -c file2.c -o file2.o
這兩句和上兩句相同。
clean:
rm -rf *.o helloworld
當使用者鍵入
make clean
命令時,會刪除
*.o
和helloworld
檔案。如果要編譯
cpp檔案,只要把
gcc改成
g++就行了。
寫好makefile
檔案,在命令列中直接鍵入
make
命令,就會執行
makefile
中的內容了。
到這步我想你能編乙個
helloworld
程式了。
上面提到一句,如果要編譯
cpp檔案,只要把
gcc改成
g++就行了。但如果
makefile
中有很多
gcc,那不就很麻煩了。
第二個例子:
=== makefile
開始===
objs = file1.o file2.o
cc = gcc
cflags = -wall -o -g
helloworld : $(objs)
$(cc) $(objs) -o helloworld
file1.o : file1.c file2.h
$(cc) $(cflags) -c file1.c -o file1.o
file2.o : file2.c file2.h
$(cc) $(cflags) -c file2.c -o file2.o
clean:
rm -rf *.o helloworld
=== makefile
結束===
這裡我們應用到了變數。要設定乙個變數,你只要在一行的開始寫下這個變數的名字,後
面跟乙個
= 號,後面跟你要設定的這個變數的值。以後你要引用
這個變數,寫乙個
$ 符號,後面是圍在括號裡的變數名。
cflags = -wall -o –g
,解釋一下。這是配置編譯器設定,並把它賦值給
cfflags
變數。-wall
:輸出所有的警告資訊。-o:
在編譯時進行優化。-g:
表示編譯
debug
版本。這樣寫的
makefile
檔案比較簡單,但很容易就會發現缺點,那就是要列出所有的
c檔案。如果你新增乙個
c檔案,那就需要修改
makefile
檔案,這在專案開發中還是比較麻煩的。
學到這裡,你也許會說,這就好像程式設計序嗎?有變數,也有函式。其實這就是程式設計序,只不過用的語言不同而已。
第三個例子:
=== makefile
開始===
cc = gcc
xx = g++
cflags = -wall -o –g
target = ./helloworld
%.o: %.c
$(cc) $(cflags) -c $< -o $@
%.o:%.cpp
$(xx) $(cflags) -c $< -o $@
sources = $(wildcard *.c *.cpp)
objs = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(sources)))
$(target) : $(objs)
$(xx) $(objs) -o $(target)
chmod a+x $(target)
clean:
rm -rf *.o helloworld
=== makefile
結束===函式1
:wildcard
產生乙個所有以
'.c'
結尾的檔案的列表。
sources = $(wildcard *.c *.cpp)
表示產生乙個所有以.c,
.cpp
結尾的檔案的列表,然後存入變數
sources
裡。函式2:
patsubst
匹配替換,有三個引數。第乙個是乙個需要匹配的式樣,第二個表示用什麼來替換它,第三個是乙個需要被處理的由空格分隔的列表。
objs = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(sources)))
表示把檔案列表中所有的
.c,.cpp
字元變成
.o,形成乙個新的檔案列表,然後存入
objs
變數中。
%.o: %.c
$(cc) $(cflags) -c $< -o $@
%.o:%.cpp
$(xx) $(cflags) -c $< -o $@
這幾句命令表示把所有的
.c,.cpp
編譯成.o
檔案。這裡有三個比較有用的內部變數。
$@ 擴充套件成當前規則的目的檔名,
$<
擴充套件成依靠
列表中的第乙個依靠檔案,而
$^ 擴充套件成整個依靠的列表(除掉了裡面所有重
復的檔名)。
chmod a+x $(target)
表示把helloworld
強制變成可執行檔案。
到這裡,我想你已經能夠編寫乙個比較簡單也比較通用的
makefile
檔案了,上面所有的例子都假定所有的檔案都在同乙個目錄下,不包括子目錄。
那麼檔案不在乙個目錄可以嗎?
怎麼編寫
makefile
生成靜態庫?
你還想更上一層樓嗎?
請聽下回分解。
linux程式設計 makefile檔案
今天我想說說這個makefile檔案了,makefile檔案?可能是我孤陋寡聞吧,原來在windows平台上我還真沒有聽說過這個東東,其實也是有的,只是我們沒有接觸到罷了。makefile檔案,是個什麼東西?有什麼用?怎麼來寫?這就是我要說的。我們都清楚,用傳統c c 語言開發乙個程式,都要經歷這幾...
linux程式設計 Makefile檔案
linux程式設計 makefile檔案 今天我想說說這個makefile檔案了,makefile檔案?原來在windows平台上我還真沒有弄過這個東東,其實也是有的,只是我們沒有接觸到罷了。makefile檔案,是個什麼東西?有什麼用?怎麼來寫?這就是我要說的。我們都清楚,用傳統c c 語言開發乙...
Linux程式設計 Makefile 使用
在先前的文章中,我們已經學習了 gcc 和 gdb 的使用。本節,我們將介紹 makefile 的使用。makefile帶來的好處就是 自動化編譯 一但寫好,只需要乙個 make 命令,整個工程便可以完全編譯,極大的提高了軟體的開發效率 特別是對於那些專案較大 檔案較多的工程 make是乙個命令工具...