这是针对单元测试的makefile。已经建立的目录结构是:
srca/ contains sources
srcb/ contains sources
test/ contains UT sources and Makefile
test/Debug is to contain objects
如果我不关心在Test中创建对象(.o,.gcda等),我可以让它工作,具有以下内容:
.PHONY = all build
all: build
vpath %.c ../srca ../srcb
SRC = \
../srca/a.c \
../srcb/b.c \
test.c
OBJDIR=
OBJ = $(addprefix $(OBJDIR),$(notdir $(patsubst %.c, %.o , $(SRC))))
$(OBJ): $(OBJDIR)/%.o : %.c
Debug/UnitTest.exe: $(OBJ)
gcc $(OBJ) -o ./Debug/UnitTest.exe
build: Debug/UnitTest.exe
当我尝试通过将OBJDIR设置为Debug /来将对象构建到Debug中时,我得到如下错误:
test1.mk:16: target `Debug/a.o' doesn't match the target pattern
设置OBJ的行从另一个stackoverflow帖子中解除,我承认我不遵循它,但它适用于上述情况。此外,当OBJDIR为空时,不需要以下行:
$(OBJ): $(OBJDIR)/%.o : %.c
但如果我在OBJDIR是“Debug /”时省略它,我会得到
make: *** No rule to make target `Debug/a.o', needed by `Debug/UnitTest.exe'. Stop.
因此,当OBJDIR不为空时,该规则会有所帮助,但还不够。
答案 0 :(得分:1)
您对OBJDIR
(空字符串),OBJ
(patsubst
)和%.o: %.c
规则的定义是导致问题的主要原因。在您的示例中,OBJ
的值为:
a.o b.o test.o
您的%.o: %.c
规则扩展为:
a.o b.o test.o: /%.o : %.c
实际上,a.o b.o test.o
与/%.o
模式不匹配。您应该将OBJDIR
和OBJ
的定义替换为:
OBJDIR = .
OBJ = $(addprefix $(OBJDIR)/,$(notdir $(patsubst %.c,%.o,$(SRC))))
请注意,我还删除了patsubst
函数调用中的空格:必须小心处理make
个空格。避免在不需要的地方放置空格,由于变量值中的前导或尾随空格,您将避免细微的错误,难以理解和修复。
如果OBJDIR
设置为.
以外的其他设置,例如Debug
,您将遇到另一个问题:隐式规则不能像这样工作,您必须添加一个明确的配方:
$(OBJ): $(OBJDIR)/%.o : %.c
gcc -c $< -o $@
答案 1 :(得分:0)
对于记录,这是工作的makefile:
.PHONY = all build
all: build
vpath %.c ../srca ../srcb
SRC = \
../srca/a.c \
../srcb/b.c \
test.c
OBJDIR=Debug/
OBJ = $(addprefix $(OBJDIR),$(notdir $(patsubst %.c,%.o,$(SRC))))
$(OBJ): $(OBJDIR)%.o : %.c
gcc -c $< -o $@
Debug/UnitTest.exe: $(OBJ)
gcc $(OBJ) -o ./Debug/UnitTest.exe
build: Debug/UnitTest.exe