** 编辑问题 **
以下是典型的Makefile
模板:
TARGET = my_prog # project name
CC = gcc -o
CFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): $(OBJECTS)
@$(CC) $(TARGET) $(CFLAGS) $(SOURCES)
@echo "Compilation complete!"
clean:
@$(rm) $(TARGET) $(OBJECTS)
@echo "Cleanup complete!"
问题:为什么第11行(@S(CC) $(TARGET) ...
)在调用make
时仍然回响?
答案:因为问题出在默认规则中,第11行也没问题。
** 更新 **
我现在有Makefile
# project name
TARGET = my_prog
CC = gcc -c
CFLAGS = -Wall -I.
LINKER = gcc -o
LFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): $(OBJECTS)
$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
$(OBJECTS): $(SOURCES) $(INCLUDES)
$(CC) $(CFLAGS) $(SOURCES)
clean:
$(rm) $(TARGET) $(OBJECTS)
问题:为什么$(CC) $(CFLAGS) $(SOURCES)
被执行 n 次,其中 n 是源文件的数量?
** 更新2 **
这是解决这个问题的好方法吗(似乎有效......)?
$(TARGET): obj
$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
obj: $(SOURCES) $(INCLUDES)
$(CC) $(CFLAGS) $(SOURCES)
答案 0 :(得分:5)
命令$(CC) $(CFLAGS) $(SOURCES)
执行n次,因为规则执行了n次,因为要构建n个对象,因为$(TARGET)
规则有很多对象作为先决条件。如果希望命令仅运行一次,请将所有这些先决条件替换为单个PHONY
先决条件,其规则执行命令。
但是没有理由这样做。您可以使命令更具选择性,以便它只构建一个作为实际目标的对象。这样Make不会浪费时间一遍又一遍地重建相同的对象,如果更改了一个或两个源文件,Make将仅重建相关对象,而不是全部:
$(OBJECTS): %.o : %.c $(INCLUDES)
$(CC) $(CFLAGS) $<
这条规则是保守的 - 它假设每个对象都依赖于每个标题,因此它有时会不必要地重建事物。如果您了解真正的依赖关系,或者使用更先进的技术自动完成,您可以更好地实现它。
修改:
您的“更新2”是一个不错的解决方案,但我建议您添加一行
.PHONY: obj
告诉Make,没有名为“obj”的文件。否则,Make每次都会运行obj
规则,尝试构建该文件。
如果您更改一个源文件,例如, foo.c
,Make将重建所有对象。
我上面使用的$<
是automatic variable。它意味着“第一个先决条件”。因此,当Make尝试构建foo.o
时,它将评估为foo.c
。
修改:
Jack Kelly(诅咒他!)指出我错误的PHONY目标是如何工作的:obj
规则将始终运行,TARGET
规则也是如此,无论是否源文件是否已更改。所以“更新2”方法是有效的,但很粗糙。
答案 1 :(得分:1)
我认为输出来自生成.o文件,而不是geverating my_prog
您似乎没有创建.o文件的规则,因此make使用的是默认值。
尝试这个:
@echo "starting compilation"
在第11行构建命令之前的行
你可以看到在gcc行之后输出“开始编译”。
也许第10行应该是:
$(TARGET): $(SOURCES)