目前的makefile:
CC = g++
BIN = main
OBJ = main.o Message.o
LIB = -lcjson
INC =
FLAGS = $(INC) -Wall -g
main:main.o Message.o
@$(CC) $(OBJ) -o $(BIN) $(LIB)
main.o: main.cpp Message.h
@$(CC) -c main.cpp -o main.o $(FLAGS)
Message.o: Message.cpp Message.h
@$(CC) -c Message.cpp -o Message.o $(FLAGS)
.PHONY:clean
clean:
@rm $(BIN) $(OBJ)
要想更进一步,需要三个常用自动变量:
- $< 第一个依赖文件,若有多个目标文件,依次编译依赖文件
- $^ 所有依赖文件的集合
- $@ 目标文件的集合
给个大型项目用的makefile模板,可以做到构建多个目标文件:
target1=server //服务器运行目标文件server
target2=client //客户端目标文件client
src=$(wildcard *.c) //用wildcard函数找到所有.c文件,server.c、client.c、wrap.c
deps=$(wildcard *.h) //用wildcard函数找到所有的.h文件,wrap.h
obj=$(patsubst %.c,%.o,$(src)) //用patsubst函数将所有.c文件替换成.o文件
all:$(target1) $(target2) //目标文件server和client,多个目标文件一定形成此依赖关系
$(target1):server.o wrap.o //server的依赖为server.o和wrap.o
gcc $^ -o $@ -Wall //利用gcc编译器生成可执行文件server
$(target2):client.o wrap.o //client的依赖为client.o和wrap.o
gcc $^ -o $@ -Wall //利用gcc编译器生成可执行文件client
%.o:%.c $(deps) //任意一个.o中间目标文件的依赖是其对应的.c文件,如:client.o的依赖为client.c
gcc -c $< -o $@ -Wall //根据目标文件编译的需求依次将依赖编译成对应的中间目标文件
.PHONY:clean //伪文件,需要在终端输入make clean才会调用
clean:
-rm -rf $(target1) $(target2) $(obj) //删除所有的目标文件以及中间目标文件,用于重新编译。
如果只有一个目标文件,也可以这样:
target=main //想要生成的可执行文件名称可自定义,此处为main
src=$(wildcard *.c)
deps=$(wildcard *.h)
obj=$(patsubst %.c,%.o,$(src))
$(target):$(obj)
gcc $^ -o $@ -Wall
%.o:%.c $(deps)
gcc -c $< -o $@ -Wall
.PHONY:clean
clean:
-rm -rf $(target) $(obj)
总结
归纳为我个人喜好的风格,如下:
单目标模板
CC = gcc
LIB = -lcjson
INC = -I "/usr/......"
FLAGS = $(INC) -Wall -g
TARGET = main
SRC=$(wildcard *.c)
HEADS=$(wildcard *.h)
OBJ=$(patsubst %.c, %.o, $(SRC))
$(TARGET):$(OBJ)
@$(CC) $^ -o $@ $(LIB)
%.o: %.c $(HEADS)
@$(CC) -c $< -o $@ $(FLAGS)
.PHONY:clean
clean:
@rm $(TARGET) $(OBJ)
多目标模板
CC = gcc
LIB = lcjson
INC = -I"/usr/local/lib/mylib.h"
FLAGS = $(INC) -Wall -g
TARGET_1=server
TARGET_2=client
SRC=$(wildcard *.c)
HEADS=$(wildcard *.h)
OBJ=$(patsubst %.c, %.o, $(SRC))
ALL: $(TARGET_1) $(TARGET_2)
$(TARGET_1):server.o
@$(CC) $^ -o $@ $(LIB)
$(TARGET_2):client.o
@$(CC) $^ -o $@ $(LIB)
%.o: %.c $(HEADS)
@$(CC) -c $< -o $@ $(FLAGS)
.PHONY:clean
clean:
@rm $(TARGET_1) $(TARGET_2) $(OBJ)