makefile:从不同的src目录编译来分离obj目录

时间:2017-09-08 22:21:51

标签: makefile

这是针对单元测试的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不为空时,该规则会有所帮助,但还不够。

2 个答案:

答案 0 :(得分:1)

您对OBJDIR(空字符串),OBJpatsubst)和%.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模式不匹配。您应该将OBJDIROBJ的定义替换为:

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