2

我在这里有简单的makefile:

SOURCES= $(wildcard *.c)
OBJECTS= $(patsubst %.c, %.o, $(SOURCES))
NAMES= $(patsubst %.c, %, $(SOURCES))
CC=gcc
CFLAGS= -Wall -c -o     
TASKS_IN_DIRS= $(addprefix obj/,$(OBJECTS)) $(addprefix bin/,$(NAMES))

all: $(NAMES)

$(NAMES): %: %.o $(OBJECTS)
    $(CC) -o bin/$@ obj/$^
$(OBJECTS): %.o: %.c 
    $(CC) $(CFLAGS) obj/$@ $<
clean:
    rm -rf $(TASKS_IN_DIRS)
  1. 获取所有 c 文件名。
  2. 用它们制作简单的名称(不带扩展名)和对象名称。
  3. 做事

重要的是 - 一切正常,但每次我打印 make(编译和链接所有文件)时都有效。即使我没有改变任何东西并且我连续做了几次,依赖关系有问题吗?

我期望像“blabla 是最新的”这样的东西。

4

2 回答 2

6
$(OBJECTS): %.o: %.c 
    $(CC) $(CFLAGS) obj/$@ $<

正在您的当前目录中查找 .o 文件。因为他们不在那里,所以正在重建他们。

以下做你想要的。

SOURCES= $(wildcard *.c)
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
OBJECTS:= $(addprefix obj/,$(OBJECTS))
NAMES:= $(patsubst %.c, %, $(SOURCES))
NAMES:= $(addprefix bin/,$(NAMES))
CC=gcc
CFLAGS= -Wall -c -o
TASKS_IN_DIRS=$(OBJECTS) $(NAMES)

all: $(NAMES)

$(NAMES): $(OBJECTS)
    $(CC) -o $@ $<

obj/%.o: %.c
    $(CC) $(CFLAGS) $@ $<

clean:
    rm -rf $(TASKS_IN_DIRS)
于 2013-03-24T13:20:32.173 回答
5

你撒谎了。您承诺每个$(NAMES)目标都在当前目录中创建其目标文件,但由于$(CC) -o bin/$@ obj/$^它是在bin目录中创建的。

在下一次make调用时,它找不到目标文件并再次运行每个命令。

Makefile 的硬性和快速规则:每个非 PHONY 目标必须$@在其命令中的某处使用纯文本来指示它创建的文件。

于 2013-03-24T13:43:23.317 回答