makefile - 在 Makefile 中使用后缀规则
问题描述
假设有ac、bc、cc、tt/at.c、tt/bt.c、fff/af.c、fff/bf.c。所以我像这样制作Makefile:
OBJS=a.o b.o c.o
SRCS=$(OBJS:.o=.cc)
OBJS_TT=at.o bt.o
SRCS_TT=tt/at.c tt/bt.c
OBJS_FFF=af.o bf.o
SRCS_FFF=fff/af.c fff/bf.c
TARGET=test
.cc.o:
gcc -c $<
$(OBJS_TT):
gcc -c $(SRCS_TT)
$(OBJS_FFF):
gcc -c $(SRCS_FFF)
all:
gcc -o $(TARGET) $(OBJS) $(OBJS_TT) $(OBJS_FFF)
如果添加 tt 目录下的 C 文件,我必须在 SRCS_TT & OBJS_TT 中添加文件名。有没有办法改进make文件?如何使用后缀规则处理所有 c 文件(包括目录中的文件)?
解决方案
当源文件位于不同目录时,一种常见的解决方案是在构建目录中构建同构目录结构。这样,您可以拥有多个具有相同文件名(例如util.cc
)但位于不同目录中的源,并且目标文件不会发生冲突,因为它们被构建到不同的目录中。
一个创建同构构建目录结构的工作示例,还具有自动生成的头文件依赖项:
build_dir := build
all : ${build_dir}/test
.SECONDEXPANSION:
.SECONDARY:
test_srcs := a.cc b.cc x/c.cc y/d.cc
${build_dir}/test : ${test_srcs:%.cc=${build_dir}/%.o} | ${build_dir}/
g++ -o $@ ${LDFLAGS} ${LDLIBS} $^
# Include the auto-generated dependencies.
-include ${test_srcs:%.cc=${build_dir}/%.d}
# Compile and generate dependency files.
${build_dir}/%.o : %.cc | $$(dir $$@)
g++ -o $@ -c -MD -MP ${CPPFLAGS} ${CXXFLAGS} $<
# Directory build rules. while loop to handle races on mkdir during parallel builds.
${build_dir}/%/ : | ${build_dir}/
while ! mkdir -p $@; do true; done
# Build root directory rule.
${build_dir}/ :
mkdir -p $@
# Don't try to rebuild these, these are generated when compiling.
${build_dir}/%.d : ;
clean :
rm -rf ${build_dir}
.PHONY : all clean
使用示例:
$ mkdir x y
$ touch b.cc x/c.cc y/d.cc
$ echo "int main() {}" > a.cc
$ make
mkdir -p build/
g++ -o build/a.o -c -MD -MP a.cc
g++ -o build/b.o -c -MD -MP b.cc
while ! mkdir -p build/x/; do true; done
g++ -o build/x/c.o -c -MD -MP x/c.cc
while ! mkdir -p build/y/; do true; done
g++ -o build/y/d.o -c -MD -MP y/d.cc
g++ -o build/test build/a.o build/b.o build/x/c.o build/y/d.o
$ tree build/
build/
├── a.d
├── a.o
├── b.d
├── b.o
├── test
├── x
│ ├── c.d
│ └── c.o
└── y
├── d.d
└── d.o
2 directories, 9 files
$ make
make: Nothing to be done for 'all'.
$ make clean
rm -rf build
推荐阅读
- javascript - 使用 AJAX 查询填充表单字段
- html - 填充高度元素内的滚动元素
- jquery - jQuery class filtering and css transform delaying/blocking animation in section below it
- java - 如何在 SpringBoot 的 AuthenticationManagerBuilder 中设置范围子树
- r - 比较 5 k-mer 向量并找到唯一的向量
- java - 在多租户环境中发送电子邮件
- pandas - Pandas 获取数字分类数据的 dummies()
- android - 运行“ionic cordova build android”命令时如何解决无效或意外令牌问题?
- php - 在 Eloquent 关系中隐藏外国 id 列
- java - 如何将此嵌套的 json 字符串转换为 java 对象?