Makefile中的变量目标

24

我正在尝试编译一组目标,但似乎只完成了第一个目标。以下是我的 makefile 的简化版本,显示了错误。

  OBJECTS = abc def ghi
  SOURCES = abc.c def.c ghi.c

  $(OBJECTS):     $(SOURCES)
          @echo target is $@, source is $<

在shell中,

  $ touch abc.c def.c ghi.c
  $ make

当我运行make命令时,我得到以下输出:

  target is abc, source is abc.c

似乎只执行了第一个目标。

如果我将$<替换为$^,输出结果是:

  target is abc, source is abc.c def.c ghi.c

我的问题是,是否可以像使用(%:%)模式一样在变量上执行扩展?

1个回答

30

试试这个:

  OBJECTS = abc def ghi

  all: $(OBJECTS)

  $(OBJECTS):%:%.c
          @echo target is $@, source is $<

问题在于:

  1. 默认目标(即您只需键入“make”时Make所选择的目标)是makefile中的第一个目标,这是`abc`。
  2. 您将所有源文件都作为每个对象的前提条件。也就是说,三个源文件是`abc`的先决条件;它们还是`def`和`ghi`的先决条件。

谢谢,这对我的特定问题有效。在四年后,我有一个问题:$(OBJECTS):%:%.c 是什么意思?我理解为:对于任何给定的对象,将相应的.c文件作为先决条件。但是额外的%:是什么意思呢?希望你能帮忙解答! - Nebula
2
@Nebula:静态模式规则的说明可以在这里找到(http://www.gnu.org/software/make/manual/make.html#Static-Pattern)。该规则不假设Make知道等效的.c文件是什么,它更加通用。它的意思是:对于此列表中的任何目标(`$(OBJECTS)`),取整个目标名称(`%`),并添加“.c”(`%.c`)以获取前置条件。 - Beta
嗨 @Beta,非常感谢!这解释得很清楚。现在我的生活更加完整了 =p - Nebula
1
这里有一个问题:如何反过来做呢?例如,如果您有一堆zip文件要创建,那么“OBJECTS=f1.zip f2.zip f3.zip”,并且您希望您的依赖关系为“f1 f2 f3”等。我尝试了类似于“$(ZIPS):%:$(ZIPS:.zip=)”的东西,但似乎不起作用。 - Kelly Beard
2
@KellyBeard:没问题,$(ZIPS):%.zip:% - Beta
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接