查看帮助一是man make,二是进入www.gnu.org,找到make的帮助文档(更详细)。
一、Makefile的格式如下:
目标/伪目标:依赖/伪依赖
命令(前面必须加上tab键)
BIN是用户自定义变量,CC ,CFLAGS是预定义变量,$* 不包括扩展名的目标文件 $< 第一个依赖文件的名称 $@ 目标文件 $^ 所有不重复的依赖文件,这些是自动变量和环境变量。
.PHONY :说明这些是make的命令。
执行make 目标/伪目标,就是为了生成目标/伪目标。如果Makefile中没有加.PHONY: clean,如果此时当前目录下正好有clean文件,执行make clean时,系统会认为已经生成了clean文件,所以不会再执行Makefile中的clean。
二、Makefile四种使用方式
1、文件分布在同一目录下,只有一个Makefile
| -- Makefile
| -- main.c(包括main函数,其余为空)
| -- add.c
| -- sub.c
| -- add.h
| -- sub.h
Makefile代码如下:
.PHONY:clean CC=gcc CFLAGS=-Wall -g OBJECTS=main.o add.o sub.o main:$(OBJECTS) $(CC) $(CFLAGS) $^ -o $@ main.o:main.c $(CC) $(CFLAGS) -Wall -g -c $< -o $@ add.o:add.c add.h $(CC) $(CFLAGS) -Wall -g -c $< -o $@ sub.o:sub.c sub.h $(CC) $(CFLAGS) -Wall -g -c $< -o $@ clean: rm -f main $(OBJECTS)
make执行后,默认make main,依次寻找依赖文件,如果只改动了sub.c,那么其他的不会重新编译。只会执行gcc -Wall -g sub.c -o sub.o gcc -Wall -g main.o sub.o add.o -o main。代码上面7到12行,可以替换为以下代码:
%.o:%.c $(CC) $(CFLAGS) -c $< -o $@
2、文件分布在不同目录下,只有一个Makefile
| -- Makefile
| -- main.c(包括main函数,其余为空)
| -- bll/
| | -- bll.c
| | -- bll.h
| -- dal/
| | -- dal.c
| | -- dal.h
| -- ui/
| | -- ui.c
| | -- ui.h
Makefile代码如下:
CC = gcc CFLAGS =-Wall -g BIN = main SUBDIR = $(shell ls -d */) #结果为/bll /dal /ui ROOTSRC = $(wildcard *.c) #结果为main.c ROOTOBJ = $(ROOTSRC:%.c=%.o) #结果为main.o SUBSRC = $(shell find $(SUBDIR) -name '*.c') #结果为bll.c dal.c ui.c SUBOBJ = $(SUBSRC:%.c=%.o) #结果为bll.o dal.o ui.o $(BIN):$(ROOTOBJ) $(SUBOBJ) $(CC) $(CFLAGS) $(ROOTOBJ) $(SUBOBJ) -o $(BIN) %o:%.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)
3、文件分布在不同目录下,多个Makefile
| -- Makefile
| -- test1/
| | -- Makefile
| | -- tes1.c(包括main函数)
| -- test2/
| | -- Makefile
| | -- tes2.c(包括main函数)
根目录下Makefile代码如下:
SUBDIRS = test1 test2 .PHONY:default all clean $(SUBDIRS) default:all all clean: $(MAKE) $(SUBDIRS) TARGET=$@ #make test1 test2 TARGET=all(传递参数),此句话为了生成test1,test2伪目标,所以调用了$(SUBDIRS) $(SUBDIRS): $(MAKE) -C $@ $(TARGET) #make -C test1 test2 all 执行tes1和test2目录下的Makefile,而且是all伪指令
test1/中Makefile代码如下:
CC = gcc BIN = test1 OBJS = test1.o .PHONY: all clean print all:print $(BIN) print: @echo "----- make all in $(PWD) -----"#@表示不输出此行 $(BIN):$(OBJS) $(CC) $(OBJS) -o $@ %.o:%.c $(CC) -c $< -o $@ clean: @echo "----- make clean in $(PWD) -----" rm -f $(BIN) $(OBJS)test2/中Makefile代码如下:
CXX = g++ BIN = test2 OBJS = test2.o CPPFLAGS = -Wall -g .PHONY: all clean print all:print $(BIN) print: @echo "----- make all in $(PWD) -----" $(BIN):$(OBJS) $(CXX) $(OBJS) -o $@ .o:%.cpp $(CXX) -c $< -o $@ clean: @echo "----- make clean in $(PWD) -----" rm -f $(BIN) $(OBJS)