make 是Linux/Unix下的编译工具,在C项目中广泛使用,Linux内核也是通过makefile进行编译的,很多开源项目也是通过工具生成makefile文件,从而编译源文件。如果是个人项目,项目规模不大,还是推荐手写makefile文件,makefile文件的结构也会比较清晰,定制修改也比较方便。今天写一个makefile模板供参考。
目录结构
.
├── inc
│ └── max.h
├── makefile
└── src
├── main.c
├── makefile
└── max.c
inc目录保存头文件, src保存源文件。./makefile 为控制类型Makefile,主要重要是进入到各个子目录执行子目录里的Makefile文件。./src/makefile 则对src目录下的源文件进行编译。下面分别看看两个makefile的内容。
- ./makefile
SUBDIRS := ./src
RECURSIVE_MAKE := @for subdir in $(SUBDIRS); \
do \
make -C ?subdir || exit 1; \
done
RECURSIVE_CLEAN := @for subdir in $(SUBDIRS); \
do \
( cd ?subdir && make clean ) || exit 1; \
done
all:
$(RECURSIVE_MAKE)
clean:
$(RECURSIVE_CLEAN)
包含两个子命令,all 命令是进入到 SUBDIRS 定义的子目录集合中分别执行子目录中的makefile文件。clean 则是进入到子目录中,执行makefile中定义的clean操作。
- ./src/makefile
TARGET := ../main
ROOT_DIR := $(shell pwd)
CC := gcc
LD := gcc
INCS := ../inc
CCFLAGS := -g -O0 -W -Wall -I$(INCS)
LIBS :=
LDFLAGS :=
SRCS := ${wildcard *.c}
OBJS := ${patsubst %.c, %.o, $(SRCS)}
all: $(OBJS)
$(LD) -o $(TARGET) $(OBJS) $(LIBS) $(LDFLAGS)
%.o: %.c
$(CC) -c $(CCFLAGS) -o $@ $< $(LIBS)
clean:
rm -f *.o $(TARGET)
该文件将src目录下的*.c文件编译成 *.o文件,再连接成目标可执行文件。
- 执行make命令
make[1]: Entering directory '/home/blue/note/Linux-C/Makefile-template/src'
gcc -c -g -O0 -W -Wall -I../inc -o main.o main.c
gcc -c -g -O0 -W -Wall -I../inc -o max.o max.c
gcc -o ../main main.o max.o
make[1]: Leaving directory '/home/blue/note/Linux-C/Makefile-template/src'