makefile的功能太過強大,完全個人總結,知 識有限,歡迎糾正錯誤!
main.c
#include "main.h"
int main()
{
printf_hello();
printf_ok();
return ;
}
main.h
#ifndef _MAIN_H
#define _MAIN_H
#include "hello.h"
#include "ok.h"
#endif
printf_hello.c
#include "hello.h"
void printf_hello(void)
{
printf("hello!\n");
printf_thanks();
}
void printf_thanks(void)
{
printf("thanks!!!\n");
}
hello.h
#ifndef _HELLO_H
#define _HELLO_H
#include <stdio.h>
void printf_thanks(void);
void printf_hello(void);
#endif
printf_ok.c
#include "ok.h"
void printf_ok(void)
{
printf("ok!!!\n");
printf_thanks();
}
ok.h
#ifndef _OK_H_
#define _OK_H_
#include <stdio.h>
void printf_ok(void);
extern void printf_thanks(void);
#endif
在編譯六個文件組成的項目時,可以不用寫makefile文件因為文件的數量比較的少所以
可以直接在linux系統下直接使用 gcc main.c printf_hello.c printf_ok.c -o main
編譯成執行文件 main ,可以直接./main執行此文件即可。(上面的所有的文件必須
在一個文件夾中,才可以編譯,否則 將會報錯說找不到目標文件)。
當項目比較大的時候,文件可能幾千甚至更多的時候,我們可以先創建一個工程文件名
為project的文件夾,之后在其中在創建兩個文件夾,一個取名為inc ,另一個取名為
src 。在inc中我們通常是放.h文件,而在src中我們通常放的是.c文件和makefile文件。
一般的makefile文件如下:
main:main.o printf_hello.o printf_ok.o
gcc main.o printf_hello.o printf_ok.o -o main
main.o:main.c
gcc -c -I ../inc/ main.c -o main.o
printf_hello.o:printf_hello.c
gcc -c -I ../inc/ printf_hello.c -o printf_hello.o
printf_ok.o:printf_ok.c
gcc -c -I ../inc/ printf_ok.c -o printf_ok.o
clean:
-rm -f *.o main //移除后綴為.o和目標文件
每一個gcc命令的最后加上 -g 就可以使用 gdb 編譯!!!
makefile 通常有三種寫法 Makefile , makefile , GNU makefile
第一種使用較多,因為大寫的M的 ASCII 較小系統擺放文件時將其放在了前面。
調用make命令可輸入
target是Makefile文件中定義的目標之一,如果省略target,make就將生成
Makefile文件中定義的第一個目標。
例如:在上面的例子中我們可以輸入 make main.o 或 make printf_hello.o
等等 ,但是如果你輸入的是make main.o 那么他只會執行gcc -c -I ../inc/ main.c
-o main.o 這一個命令!而單獨的一個“make”命令等價于make main命令,
由于依賴的關系所以下面的命令都執行除了clean命令外(clean命令和他們沒有
依賴的關系)。
因為main是Makefile文件中定義的第一個目標,make首先將其讀入,然后從第一行
開始執行,把第一個目標main作為它的最終目標,所有后面的目標的更新都會影響到
main的更新。
如果直接在linux系統下敲擊make命令,則系統執行的命令是makefile,而
不是執行的是Makefile文件的命令。如果文件夾中既有makefile 也有Makefile文
件,我們需要使用make的命令,make -f Makefile 就可以執行Makefile的文
件的命令。而以上的makefile文件可以通過更改頭文件的路徑而更改,.h文件不必
改變。
make的執行過程:
1.如果目標文件的時問戳比依賴文件還早,就按規則中定義的命令更新目標文件。
2.如果該規則中的依賴文件又是其他規則中的目標文件,那么依照規則鏈不斷執行這
個過程,直到Makefile文件的結束,至少可以找到一個不是規則生成的最終依賴文
件,獲得此文件的時間戳
3.然后從下到上依照規則鏈執行目標文件的時間戳比此文件時間戳舊的規則,直到最
頂層的規則
#include "../inc/ok.h" //將相對路徑添加到頭文件中
void printf_ok(void)
{
printf("ok!!!\n");
printf_thanks();
}
#include "../inc/hello.h" //將相對路徑添加到頭文件中
void printf_hello(void)
{
printf("hello!\n");
printf_thanks();
}
void printf_thanks(void)
{
printf("thanks!!!\n");
}
#include "../inc/main.h" //將相對路徑添加到頭文件中
int main()
{
printf_hello();
printf_ok();
return ;
}
修改后的makefile文件:
main:main.o printf_hello.o printf_ok.o
gcc main.o printf_hello.o printf_ok.o -o main
main.o:main.c
gcc -c main.c -o main.o
printf_hello.o:printf_hello.c
gcc -c printf_hello.c -o printf_hello.o
printf_ok.o:printf_ok.c
gcc -c printf_ok.c -o printf_ok.o
clean:
-rm -f *.o main
Makefile的變量
(1)變量名不包括: “ :” 、“ # ” 、“ = ”
(2)變量名是大小寫敏感的,“ foo ”與“ Foo ”代表不同的變量
(3)預留大寫字母作為作為控制隱含規則參數或者用戶重載命令選項
Makefile中的變量分為:
用戶自定義變量
預定義變量、
自動變量
1.用戶自定義的變量
例如將上面的makefile改變:
A=main.o printf_hello.o printf_ok.o
B=gcc
main:$(A)
$(B) $(A) -o main
main.o:main.c
$(B) -c main.c -o main.o
printf_hello.o:printf_hello.c
$(B) -c printf_hello.c -o printf_hello.o
printf_ok.o:printf_ok.c
$(B) -c printf_ok.c -o printf_ok.o
clean:
-rm -f *.o main
2.預定義變量
A=main.o printf_hello.o printf_ok.o
B=gcc
$@ 目標文件的完整名稱
$< 第一個依賴的文件名稱
main:$(A)
$(B) $(A) -o $@
main.o:main.c
$(B) -c $< -o $@
printf_hello.o:printf_hello.c
$(B) -c $< -o $@
printf_ok.o:printf_ok.c
$(B) -c $< -o $@
clean:
-rm -f *.o main
也可以寫成:
main:$(A)
$(B) -o $@ $(A)
main.o:main.c
$(B) -c -o $@ $<
printf_hello.o:printf_hello.c
$(B) -c -o $@ $<
printf_ok.o:printf_ok.c
$(B) -c -o $@ $<
clean:
-rm -f *.o main
3. 自動變量
實際上,make可以使工作更加自動化,也就是說,make知道一些默認
的動作,它有一些稱作隱含規則的內置的規則。
如上例完全可以寫成:
A=main.o printf_hello.o printf_ok.o
B=gcc
$@ 目標文件的完整名稱
$< 第一個依賴的文件名稱
main:$(A)
$(B) $(A) -o $@
clean:
-rm -f *.o main
可以省略最后兩條,因為Makefile的隱式規則指出都可由“ .c ”文件使用
以下命令生成:
$(B) $(CFLAGS) $(CPPFLAGS) -c –o file.o file.c
CFLAGS CPPFLAGS 是系統的默認的變量為空 ,我們可以給他賦值,也
可以不理會!!!
makefile還有一種模式規則可以將makefile變更為:
A=main.o printf_hello.o printf_ok.o
B=gcc
main:$(A)
$(B) -o $@ $(A)
%.o:%.c //代表了一系列這樣的文件
$(B) -c -o $@ $<
clean:
-rm -f *.o main
1.模式規則是用來定義相同處理規則的多個文件的,模式規則可以引入用戶自定義
變量,為多個文件建立相同的規則,從而簡化Makefile的編寫。
2.模式規則中相關文件前必須用“ % ”
|