这是我发明的"
的makefileCFLAGS = gcc -Isourcfiles
EXE_DIR = ../bin/exefile
OBJECT_DIR = objectfiles
SOURCEFILES = $(wildcard sourcefiles/*.c *.c)
all: $(OBJECT_DIR)/%.o
gcc -o $(EXEFILE) $<
$(OBJECT_DIR)/%.o: $(SOURCEFILES)
$(CFLAGS) -c $<
问题是目标$(OBJECT_DIR)/%.o
从未被执行过。
一些建议?
答案 0 :(得分:1)
你犯了几个错误。 (你应该从更简单的事情开始。)
此:
all: $(OBJECT_DIR)/%.o
gcc -o $(EXEFILE) $<
不是模式规则,“%”不是通配符。此规则有一个先决条件,一个名为objectfiles/%.o
的文件,可能不是您想要的。你没有告诉我们你如何定义EXEFILE
(如果你这样做),它可能不是“全部”,所以这个规则实际上并不构建一个名称是规则目标的文件,这可能会导致问题。
此:
$(OBJECT_DIR)/%.o: $(SOURCEFILES)
$(CFLAGS) -c $<
是模式规则,但它使所有源文件成为每个目标文件的先决条件。然后它只使用这些文件中的第一个(aardvark.c
或其他东西)来构建所需的对象,无论所需的对象是什么。然后它将目标文件放在当前目录中,而不是objectfiles
。将gcc
放入CFLAGS
非常具有误导性。
首先,让我们为对象制定模式规则:
CC = gcc
CFLAGS = -Isourcfiles
$(OBJECT_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJECT_DIR)/%.o: sourcefiles/%.c
$(CC) $(CFLAGS) -c $< -o $@
(我们需要两个规则,因为源文件位于两个不同的位置 - 这不是最优雅的解决方案,但它是最简单的。)在理解这些规则之前不要继续。
现在,对于可执行文件,我们需要一个目标文件列表。假设您的源文件是red.c
,blue.c
和sourcefiles/green.c
。
SOURCEFILES = $(wildcard sourcefiles/*.c *.c)
# This is red.c blue.c sourcefiles/green.c
SOURCENAMES = $(notdir $(SOURCEFILES))
# This is red.c blue.c green.c
OBJECTNAMES = $(SOURCENAMES:.c=.o)
# This is red.o blue.o green.o
OBJECTFILES = $(addprefix $(OBJECT_DIR)/, $(OBJECTNAMES))
# This is objectfiles/red.o objectfiles/blue.o objectfiles/green.o
现在我们可以编写可执行文件的规则:
$(EXEFILE): $(OBJECTFILES)
gcc -o $@ $^
一旦你有了这个工作,就可以进一步改进。