如何告诉默认目标(全部:)执行此目标:$(OBJECT_DIR)/%。o:

时间:2015-09-04 08:21:22

标签: makefile gnu-make

这是我发明的"

的makefile
CFLAGS = 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从未被执行过。 一些建议?

1 个答案:

答案 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.cblue.csourcefiles/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 $@ $^

一旦你有了这个工作,就可以进一步改进。