Makefile目标路径中有多个目录,$@仅包含顶级目录

Makefile目标路径中有多个目录,$@仅包含顶级目录,makefile,Makefile,我的Makefile中有这个目标,BUILD和SOURCE是目录路径 $(BUILD)/%.o: $(SOURCE)/%.c @echo "In target: "'(BUILD)/%.o: (SOURCE)/%.c' @echo "(BUILD) = $(BUILD)" @echo " @ = $@" @echo " (@D) = $(@D)" @echo &q

我的Makefile中有这个目标,BUILD和SOURCE是目录路径

$(BUILD)/%.o: $(SOURCE)/%.c
    @echo "In target: "'(BUILD)/%.o: (SOURCE)/%.c'
    @echo "(BUILD) = $(BUILD)"
    @echo "      @ = $@"
    @echo "   (@D) = $(@D)"
    @echo "   (@F) = $(@F)"
    gcc -o $@ $< $(CFLAGS)

那么,为什么
$@
$(@D)
,或者
$(@F)
不能像我期望的那样发挥作用呢?既然这是实际的目标,那么
$@
不应该是
build/debug/main.o


定义规则时,
BUILD
变量的值必须是
BUILD
。然后,在定义规则后的某个时间,您将
BUILD
变量的值更改为
BUILD/debug
。也许你是直接做的,或者你是通过一个特定于目标的变量来做的。但是,这是在给定规则的情况下,您获得您向我们展示的结果的唯一方法。

这很奇怪。您能给我们一个足够的生成文件来重现错误吗?您是正确的。通常我想使用
build
,但是如果我运行
makedebug
,我希望它使用
build/debug
(这样它就看不到没有
-g
编译的目标文件,并且假设目标是最新的)。好吧,你不能这样做(至少不像那样)。手册对此非常清楚:与自动变量一样,[特定于目标的]值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中)。这意味着您在定义目标或先决条件时不能使用这些值。这需要一个第二十二条军规:在定义目标之前,你无法知道要应用哪些特定于目标的变量,但在知道要应用哪些变量之前,你无法定义目标。。。
In target: (BUILD)/%.o: (SOURCE)/%.c
(BUILD) = build/debug
      @ = build/main.o
   (@D) = build
   (@F) = main.o
gcc -o build/main.o source/main.c -c -Iinclude -g