如何将所有C文件编译成目标文件并将它们放在子目录中?
我有三个目录:
[image]text
- 其中main.c位于usr
- 其中init_var1.c和init_var2.c位于sources1
- 头文件所在的位置include
- 此目录应包含由1和2下列出的目录中的C源文件制作的目标文件。我写了这个obj
:
Makefile
但输出是
CC=gcc
O_DIR = ./../obj
I_DIR = ./../include
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:.c=.o)
OBJECTS := $(addprefix $(O_DIR)/,$(OBJECTS))
all: $(OBJECTS)
$(OBJECTS): $(SOURCES)
$(CC) -c -I$(I_DIR) $< -o $@
但是,我需要
make[1]: enter directory «/home/alexey/exercise/ex_makefile/source»
gcc -c -I./../include init_var1.c -o ../obj/init_var1.o
gcc -c -I./../include init_var1.c -o ../obj/init_var2.o
make[1]: out from directory «/home/alexey/exercise/ex_makefile/source»
请帮忙,怎么办呢?
答案 0 :(得分:2)
您将SOURCES
设置为等于*.c
的通配符扩展。这将扩展为所有.c文件的列表,因此,行
$(OBJECTS): $(SOURCES)
扩展为类似
a.o b.o c.o ... : a.c b.c c.c ...
请注意,这在语义上是错误的,因为每个目标文件都不应该依赖所有源文件。
由于automatic variable $<
表示第一个先决条件的名称,因此每个目标文件a.o
,b.o
,c.o
等等使用源文件a.c
创建。
您想要的是pattern rule:
您可以通过编写模式规则来定义隐式规则。模式规则看起来像普通规则,除了它的目标包含字符'%'(恰好是其中之一)。目标被认为是匹配文件名的模式; '%'可以匹配任何非空子字符串,而其他字符只匹配自己。
这将允许您使每个目标文件仅依赖于其相应的源文件(并且它还将$<
扩展为正确的文件,因为第一个先决条件将是仅先决条件)。因此,您的规则应如下所示:
%.o : %.c
$(CC) -c -I$(I_DIR) $< -o $(O_DIR)/$@
事实上,GNU make手册的examples page for pattern rules有一个与你的规则非常相似的例子。