Make的黑魔术咒文
29 Jul 2012作为Spellbook,也就是小抄,我才不会介绍make到底是什么呢!
咒文三要素
……也就是规则(rule)啦。每条规则都包括以下三部分:
- Targets
- Prerequisites
- Commands
实际写出来是这个样子的:
target1 target2 ... : preq1 preq2
cmd1
cmd2
规则的触发条件很简单: 当prerequisites中某项的修改时间新于targets中的某项,则执行commands部分。
咒文好长我不想重复读怎么办
……请使用变量(variables)
CC = g++
OBJECTS = hello.o bye.o
greeting : $(OBJECTS)
$(CC) -o $@ $(OBJECTS)
$@
是规则中的目标名;- 使用
+=
添加新条目进入列表OBJECTS += hey.o
; - 使用
=
时,若等号左边没被用到,等号右边就不会展开;当需要等号右边在定义时马上被展开的话,改用:=
; ?=
仅在该变量从未被设置过时生效
写依赖项好麻烦啊怎么办
……请使用隐含规则(Implicit Rule)以及-M
选项
# 定义隐含规则
%.d : %.cpp
$(CC) $(CFLAGS) $(CPPFLAGS) -M $< > $@
# 当参数不为clean时
ifeq($(findstring $(MAKECMDGOALS), clean),)
-include $(OBJECTS:.o=.d)
endif
呜啊这个例子好复杂,能不解释么……(逃)
-M
选项可以从源文件中产生规则;如果是GNU C编译器的话,可以换成-MM
, 该选项不会生成系统头文件的prerequisites$<
是规则中的第一个prerequisite的名称$(CC)
使用的编译器的名称$(CFLAGS)
传入编译器的选项$(CPPFLAGS)
传入预处理器的选项$(OBJECTS:.o=.d)
将OBJECTS里每项的后缀从.o改成.d
呜啊.d/.o文件都生成在.c文件的目录里了好讨厌
……请把它们扔到单独的文件夹中
BUILDDIR = build
SOURCES = hello.cpp bye.cpp
OBJECTS = $( addprefix $(BUILDDIR)/,$(SOURCES :.cpp=.o) )
DEPS = $( OBJECTS :.o=.d)
# ...
$( BUILDDIR )/%.o : %.cpp
$(CC) $( CFLAGS ) $( CPPFLAGS ) -o $@ -c $<
$( BUILDDIR )/%.d : %.cpp
$(CC) $( CFLAGS ) $( CPPFLAGS ) -MT $(@:.d=.o) -M $< > $@
还、还要解释么……
-MT
选项强制指定target为$(@:.d=.o)
好复杂的赶脚有没有实例呢
………… source link
- 引入了
config.mak
文件,用来分离放置用户自定义的选项 - 因为
clean
不是文件,所以将其声明为.PHONY
- 加入了
$(Q)
这样的黑魔术,使用make Q=
能输出详细内容
No comments
Comments are closed