如何編寫Makefile

本博客(http://blog.csdn.net/livelylittlefish)貼出作者(三二一、小魚)相關研究、學習內容所做的筆記,歡迎廣大朋友指正!

編寫Makefile
 
1. 一個例子
假設我們有下面這樣的一個程序,源代碼如下:

view plaincopy to clipboardprint?
/* filename: main.c */
 
#include "mytool1.h" 
#include "mytool2.h"  
 
int main(int argc,char **argv)  
{  
    myprint1("hello");  
    myprint2("world");  
}  
 
 
/* filename: mytool1.h */
#ifndef _MYTOOL_1_H 
#define _MYTOOL_1_H  
void myprint1(char *print_str); 
#endif  
   
 
/* filename: mytool1.c */
#include "mytool1.h"  
void myprint1(char *print_str)  
{  
    printf("This is mytool1 print %s\n",print_str);  
}  
 
   
/* filename: mytool2.h */
#ifndef _MYTOOL_2_H 
#define _MYTOOL_2_H  
void myprint2(char *print_str); 
#endif  
 
   
/* filename: mytool2.c */
#include "mytool2.h"  
void myprint2(char *print_str)  
{  
    printf("This is mytool2 print %s\n",print_str);  

/* filename: main.c */
#include "mytool1.h"
#include "mytool2.h"
int main(int argc,char **argv)
{
    myprint1("hello");
    myprint2("world");
}

/* filename: mytool1.h */
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void myprint1(char *print_str);
#endif
 
/* filename: mytool1.c */
#include "mytool1.h"
void myprint1(char *print_str)
{
    printf("This is mytool1 print %s\n",print_str);
}
 
/* filename: mytool2.h */
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void myprint2(char *print_str);
#endif
 
/* filename: mytool2.c */
#include "mytool2.h"
void myprint2(char *print_str)
{
    printf("This is mytool2 print %s\n",print_str);
}

我們可以這樣來編譯:
gcc -c main.c
gcc -c mytool1.c
gcc -c mytool2.c
gcc -o main main.o mytool1.o mytool2.o
這樣也可以產生main程序,且不是很麻煩。但如果有一天我們修改了其中的一個文件(比如說mytool1.c),那麼難道我們還要重新輸入上面的命令嗎?也許你會說,這個很容易解決啊,我寫一個SHELL腳本,讓她幫我去完成不就可以了。是的,對於這個程序來說,是可以的,但如果我們的程序有幾百個源程序的時候,怎麼辦?難道也要編譯器重新一個一個的編譯?
爲此,聰明的程序員們想出了一個很好的工具來做這件事情,這就是make。我們只要執行一下make命令,就可以把上面的問題解決掉。在我們執行make命令前,要先編寫Makefile文件。
對於上面的例子,一個可能的Makefile的文件如下。

view plaincopy to clipboardprint?
#此行爲註釋  
main: main.o mytool1.o mytool2.o  
gcc -o main main.o mytool1.o mytool2.o  
main.o: main.c mytool1.h mytool2.h  
gcc -c main.c  
mytool1.o: mytool1.c mytool1.h  
gcc -c mytool1.c  
mytool2.o: mytool2.c mytool2.h  
gcc -c mytool2.c 
#此行爲註釋
main: main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o: main.c mytool1.h mytool2.h
gcc -c main.c
mytool1.o: mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o: mytool2.c mytool2.h
gcc -c mytool2.c

有Makefile文件後,不管我們什麼時候修改了源程序當中的什麼文件,我們只要執行make命令,我們的編譯器都只會去編譯與我們修改的文件有關的文件,其它的文件不會處理。
2. Makefile的編寫規則
Makefile文件中,註釋以"#"開始
Makefile文件中最重要的是描述文件的依賴關係的說明,其一般的格式爲:
target: components
TAB rule
第一行表示的是依賴關係,第二行是規則。
例如上面那個Makefile文件的第二行:main: main.o mytool1.o mytool2.o,表示我們的目標(target)main的依賴對象(components)是main.o mytool1.o mytool2.o
當依賴的對象在目標修改後修改的話,就要去執行規則行所指定的命令。
例如上面那個Makefile文件的第三行:gcc -o main main.o mytool1.o mytool2.o
注意:規則行中的TAB表示那裏是一個TAB 鍵。
3. Makefile的常用變量
Makefile 有三個非常有用的變量:$@,$^,$<。其意義爲:
$@:目標文件
$^:所有的依賴文件
$<:第一個依賴文件
如果使用上面三個變量,上面那個Makefile文件可簡化爲:

view plaincopy to clipboardprint?
#這是簡化後的Makefile  
main: main.o mytool1.o mytool2.o  
gcc -o $@ $^  
main.o: main.c mytool1.h mytool2.h  
gcc -c $<  
mytool1.o: mytool1.c mytool1.h  
gcc -c $<  
mytool2.o: mytool2.c mytool2.h  
gcc -c $< 
#這是簡化後的Makefile
main: main.o mytool1.o mytool2.o
gcc -o $@ $^
main.o: main.c mytool1.h mytool2.h
gcc -c $<
mytool1.o: mytool1.c mytool1.h
gcc -c $<
mytool2.o: mytool2.c mytool2.h
gcc -c $<

4. Makefile 的缺省規則
..c.o:
gcc -c $<
這個規則表示所有的.o文件都是依賴於相應的.c文件的,例如mytool.o 依賴於mytool.c。
這樣上面那個Makefile還可以簡化爲:

view plaincopy to clipboardprint?
#這是再一次簡化後的Makefile  
main: main.o mytool1.o mytool2.o  
gcc -o $@ $^  
..c.o:  
gcc -c $< 
 
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/livelylittlefish/archive/2009/01/28/3854220.aspx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章