咳咳咳、、、
当写完一个简单的cpp时又不依赖其他文件时,编译它多半是去手敲g++ -o xxx xxx.cpp。
或者下意识会想到make,那makefile里是不是又要加生成依赖。
像这样:
# 不经思考时的makefile
CC = g++
CXXFLAGS = -std=c++2a -g -Wall
LDFLAGS =
objs = test1 test2 test3
target: $(obj)
%.o:%.cpp
$(CC) $(CXXFLAGS) $(LDFLAGS) -c -o $@ $<
test1:test.o
$(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
test2:test.o
$(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
test3:test.o
$(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
clean:
rm -rf ${objs} *.o *.a *.so *.dylib *.dSYM
这明显不符合一个懒汉的操作。
那咋办、、、
既然想用make生成但是又舍不得动手指添加那行依赖,就要有个“自动生成依赖”的方法。
一般人会想主依赖一般是一个实体或者是我们需要的真正文件,其实不然。
我可以啥都不要就让他白白操作一波。
那么到了showtime:
# 为了偷懒,深思熟虑的makefile。
CC = g++
CXXFLAGS = -std=c++2a -g -Wall
LDFLAGS =
srcs = $(wildcard *.cpp) # makefile内置函数,意思是匹配当前目录下所有的cpp后缀文件。
bins = $(objs:%.cpp=%) # 利用通配换成bin的名字
# 主目标所依赖的文件,即是我们关心生成的可执行程序文件
# 若没有找到这些可执行程序的依赖会生成规则
# 看输出结果像是:
# %:%.cpp
# $(CC) $(CXXFLAGS) $(LDFLAGS) $(CPPFALGS) $< -o $@
target: $(bins)
clean:
rm -rf ${bins} ${objs} *.o *.a *.so *.dylib *.dSYM
解释都在注释里。
当想留下.o文件时又会遇到一个问题,上面介绍的方法会由cpp直接编成bin。
可以用下面方法
CC = g++
CXXFLAGS = -std=c++2a -g -Wall
LDFLAGS =
srcs = $(wildcard *.cpp)
objs = $(srcs:%.cpp:%.o)
bins = $(objs:%.o=%)
f =
define clean_files
rm -rf $(1:%=%.o) $1
endef
targets: $(objs) $(bins)
%:%.cpp
$(CC) -c -o $(@:%.o=%) $< $(CXXFLAGS) $(CPPFLAGS)
$(CC) -o $@ $(@:%.o=%) $(LDFLAGS) $(CPPFLAGS)
clean:
rm -rf ${bins} ${objs} *.o *.a *.so *.dylib *.dSYM
f:
$(call clean_files,$(f))
ps:
- 有个"f:"和"f ="的小设计解释:
当你需要指删除一个test和test.o时,总不能用test*吧, 亦不能动用两个指令分别删除这俩文件吧。遂加了这个"f:"是一个伪依赖(即不需要依赖的目标)。"f ="是在makefile做的传参。用法如下:
make f f=test2
- 替换函数看不明白的话看下下面:
srcs=x.c.c bar.c
objs=$(srcs:%.c=%.o) #<=> objs=$(patsubst %.c,%.o,$(srcs))
@echo $(srcs)
>> x.c.o bar.o # 结果