這裡采用簡單的3個檔案fun.c fun.h main.c來說明3中情況下Makefile的寫法
/* fun.h */
void fun();
/* fun.c */
#include <stdio.h>
void fun()
{
printf("fun!!!\n");
}
/* main.c */
#include "fun.h"
int main()
{
fun();
return 0;
}
1、單目錄單個Makefile
Makefile
main.c
fun.c
fun.h
# Makefile
fun:main.c fun.c fun.h
gcc -o $@ $^
clean:
rm fun
2、多目錄單個Makefile
Makefile
src/
main.c
fun.c
include
fun.h
1)直接指明檔案路徑
# Makefile
fun:src/main.c fun.o
gcc -o $@ $^ -Iinclude
fun.o:src/fun.c include/fun.h
gcc -c $^
clean:
rm fun *.o
2)通過VPATH來添加Makefile查找檔案的路徑,這樣雖然Makefile能夠找到src/fun.c和include/fun.h,
但是GCC還是找不到main.c中的fun.h,需要添加CFLAGS += -Iinclulde
# Makefile
VPATH := src:include
CFLAGS += -Iinclude
fun:main.c fun.o
gcc -o $@ $^ $(CFLAGS)
fun.o:fun.c fun.h
gcc -c $^
clean:
rm fun *.o
以上說明:
對于fun:main.c fun.o
gcc -o $@ $^ $(CFLAGS)
這裡如果沒有$(CFLAGS),那麼得在main.c檔案中将包含的頭檔案由#include"fun.h"改成#include"../include/fun.h",即如下對應:
$(CFLAGS) + #include "fun.h" 在程式main.c中沒有指明fun.h的具體位置,得靠$(CFLAGS)去尋找。 或者
#include "../include/fun.h" 通過程式直接指明所需頭檔案的位置。這樣就不用$(CFLAGS)去尋找。
3、多目錄多個Makefile
Makefile
main.c
src
Makefile
fun.c
fun.h
# 根目錄Makefile
all:fun
fun:main.c src/fun.o
gcc -o $@ $^ -Isrc
src/fun.o:$(wildcard src/*.c src/*.h)
make -C src/
clean:
rm fun src/fun.o src/fun.h.gch
為了得到編譯fun所需的src/fun.o,需要make -C src/,進去到src/目錄去執行裡面的makefile
# src/Makefile
fun.o:fun.c fun.h
gcc -c $^
當執行完src/Makefile之後,回到根目錄Makefile繼續執行。
注意:
src/fun.o:$(wildcard src/*.c src/*.h)
make -C src/
如果不加src/fun.o的依賴檔案$(wildcard src/*.c src/*.h),存在這種情況,如果修改的fun.c或者fun.h檔案,然後執行make
make會提示沒有什麼做的,因為根目錄下的Makefile看到本層的main.c和src/fun.o都沒有變化,而沒有看到src/下的檔案變化,除非将src/下的檔案添加作為這邊的依賴檔案,Makefile會檢視這些依賴檔案是否有更新。
其他
其實寫Makefile,最關鍵的是要找到include,src下的檔案,這些位置都是要相對Makefile的位置而來
上面幾個例子中
Makefile
src
main.c
fun.c
include
fun.h
Makefile與src,include在同一層,如果要找到fun.c,fun.h
1)可以使用絕對路徑src/fun.c,include/fun.h來找到。
2)或者另外一種辦法通過VPATH來指明源檔案搜尋的位置,通過CFLAGS來指明頭檔案的位置
VPATH=src:include
CFLAGS+=-Iinclude