天天看點

單目錄單個Makefile、多目錄單個Makefile、多目錄多個Makefile

這裡采用簡單的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