单目录单个Makefile、多目录单个Makefile、多目录多个Makefile

时间:2021-09-28 12:53:36
这里采用简单的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

3)再或者另外一种方法,通过VPATH来指明源文件搜索的位置,不通过CFLAGS而直接在源代码中指明头文件位置。

单目录单个Makefile、多目录单个Makefile、多目录多个Makefile