首页 > 解决方案 > 在 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 文件(包括目录中的文件)?

标签: makefile

解决方案


当源文件位于不同目录时,一种常见的解决方案是在构建目录中构建同构目录结构。这样,您可以拥有多个具有相同文件名(例如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 

推荐阅读