/* 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而直接在源代码中指明头文件位置。