查看帮助一是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)