2

我正在谈论这个问题,该人已使用该任务的生成文件更新了他的最终解决方案。我很难理解它是如何完成的。

有一个规则:

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    @$(CC) $(CFLAGS) -c $< -o $@

我无法理解,但凭直觉我知道它会做什么。几乎所有其他事情都非常清楚。谢谢!

4

2 回答 2

3

这是一个静态模式规则。第一个字段是一个目标列表,第二个是Make 用来隔离目标“词干”的目标模式,第三个是Make 用来构造先决条件列表的先决条件模式。

假设你有

SRCDIR = src
OBJDIR = obj
OBJECTS = obj/foo.o obj/bar.o obj/baz.o

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    @$(CC) $(CFLAGS) -c $< -o $@

如果您make obj/foo.o,Make 首先将此规则标识为要使用的规则(因为obj/foo.o在目标列表中$(OBJECTS)),将其与目标模式匹配obj/%.o并发现词干(与通配符匹配的部分%)是foo,然后将其插入到 prereq 模式中src/%.c并发现前提是src/foo.c

如果您还定义了变量

CC = gcc
CFLAGS = -thisflag -thatflag=something

那么规则中的命令就变成了

    @gcc -thisflag -thatflag=something -c src/foo.c -o obj/foo.o

(请注意,这$<是第一个先决条件,$@也是目标名称。)

回答您的另一个问题:是的,makefile 可以处理对头文件 () 的依赖关系,x.h因此如果头文件已被修改,Make 将重建目标。不,这个 makefile 不会那样做。您可以手动修改makefile,添加如下规则

a.o: x.h

假设您知道实际包含的内容,或者您​​可以让 makefile 自动执行此操作,这是您可能不应该尝试的高级技术。

于 2012-07-26T19:03:22.953 回答
1

这一行解释了如何从源文件 (.c) 获取目标文件 (.o),它避免了为每个 .c 文件重复该行。

对象将在 OBJDIR 中,源在 SRCDIR

$(CC) 将包含编译器,CFLAGS 将包含编译器的选项,-c 告诉 gcc 将源代码编译为对象。

例如:

  • CC = gcc

  • CFLAGS = -g -Wall

可以转换成gcc -g -Wall -c test.c -o test.o

于 2012-07-26T16:59:02.290 回答