【问题标题】:What do $< and $@ mean in makefiles?在 makefile 中 $< 和 $@ 是什么意思?
【发布时间】:2026-01-25 00:10:02
【问题描述】:

我的 docs/csv 目录中有 a.csv,b.csv, ...,我需要将每个文件转换为 json 文件。

我按照这个question 来写一个这样的Makefile。

SRCS = $(wildcard docs/csv/*.csv)
DESTS = $(patsubst docs/csv/%.csv, scripts/data/%.lua, $(SRCS))

all: $(DESTS)

$(DESTS): $(SRCS)
    echo $@
    echo $<

但每次我运行 make all 时,echo $@ 都会按预期显示每个文件,但 echo $&lt; 总是在我的 csv 文件夹中显示名为 items.csv 的单个文件。

【问题讨论】:

  • 你的问题标题不准确——我差点把它标记为重复。
  • make 附带一本手册,其中回答了您的问题。告诉我们手册中有哪些不清楚的地方。

标签: makefile


【解决方案1】:

问题在于这条规则:

$(DESTS): $(SRCS)
    ...

每个 lua 文件都依赖于all csv 文件,我认为这不是你想要的。由于$&lt; 扩展到第一个先决条件,因此每个目标都得到相同的 (items.csv)。

试试这个:

all: $(DESTS)

scripts/data/%.lua: docs/csv/%.csv 
    echo $@
    echo $<

【讨论】:

    【解决方案2】:

    $

    FIRST 依赖项的名称。对所有依赖项使用 $^

    $@

    是当前目标的名称

    【讨论】:

    • 我需要变量匹配$@,如果$@是scripts/data/a.lua那么我需要docs/csv/a.csv,是否有这样的变量,或者我的makefile有什么问题。
    【解决方案3】:

    Automatic Variables 上的 GNU make 手册页非常有用。它是这样说的:

    $@

    规则目标的文件名。如果目标是存档成员,则“$@”是存档文件的名称。在一个 具有多个目标的模式规则(请参阅模式简介 规则),“$@”是导致规则配方的目标的名称 运行。

    $&lt;

    第一个先决条件的名称。如果目标从隐式规则中获得其配方,这将是由 隐式规则(请参阅隐式规则)。

    顺便说一句,您可能希望将您的 make 规则编写为 模式规则

    %.lua : %.csv
        <rules for making a lua from a csv>
    

    【讨论】: