我正在谈论这个问题,该人已使用该任务的生成文件更新了他的最终解决方案。我很难理解它是如何完成的。
有一个规则:
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o $@
我无法理解,但凭直觉我知道它会做什么。几乎所有其他事情都非常清楚。谢谢!
这是一个静态模式规则。第一个字段是一个目标列表,第二个是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 自动执行此操作,这是您可能不应该尝试的高级技术。
这一行解释了如何从源文件 (.c) 获取目标文件 (.o),它避免了为每个 .c 文件重复该行。
对象将在 OBJDIR 中,源在 SRCDIR
$(CC) 将包含编译器,CFLAGS 将包含编译器的选项,-c 告诉 gcc 将源代码编译为对象。
例如:
CC = gcc
CFLAGS = -g -Wall
可以转换成gcc -g -Wall -c test.c -o test.o