代码之家  ›  专栏  ›  技术社区  ›  Matt Conway

设置makefile函数中变量的值时遇到问题

  •  0
  • Matt Conway  · 技术社区  · 6 年前

    目录结构(运行此示例)如下所示:

    example
     |-- Makefile
     |-- foo
     |    |-- foo.h (empty file)
     |-- bar
     |    |-- bar.h (empty file)
    

    makefile如下所示:

    TARGETS=foo bar
    
    define GEN_HEADER_RULE
    $(1)_INCS = $(wildcard $(1)/*.h)
    $(info $$($(1)_INCS) is [$($(1)_INCS)])
    $(info $$(wildcard $$(1)/*) is: [$(wildcard $(1)/*)])
    endef
    
    $(foreach t,$(TARGETS),$(eval $(call GEN_HEADER_RULE,$t)))
    
    all: 
        @echo "DONE"
    

    实际输出为:

    $(foo_INCS) is []
    $(wildcard $(1)/*) is: [foo/foo.h]
    
    $(bar_INCS) is []
    $(wildcard $(1)/*) is: [bar/bar.h]
    
    DONE
    

    预期产量为:

    $(foo_INCS) is [foo/foo.h]
    $(bar_INCS) is [bar/bar.h]
    

    我不明白为什么变量$(1)incs的值没有被设置为通配符函数的输出?通配符函数显然没有问题——如$info命令直接从中转储输出所示。

    我构造了这个简单的makefile来演示在更大的构建系统中遇到的相同问题。

    1 回复  |  直到 5 年前
        1
  •  1
  •   Renaud Pacalet    6 年前

    你忘了保护变量和函数不受双重扩展的影响。双全 $ 除了 $(1) 你应该看看你想要什么(除了第二个 $(info...) 这将产生比你期望的更多的产出)。

    host> cat Makefile
    TARGETS=foo bar
    
    define GEN_HEADER_RULE
    $(1)_INCS = $$(wildcard $(1)/*.h)
    $$(info $$$$($(1)_INCS) is [$$($(1)_INCS)])
    $$(info $$$$(wildcard $(1)/*) is: [$$(wildcard $(1)/*)])
    endef
    
    $(foreach t,$(TARGETS),$(eval $(call GEN_HEADER_RULE,$t)))
    
    all: 
        @echo "DONE"
    
    host> make
    $(foo_INCS) is [foo/foo.h]
    $(wildcard foo/*) is: [foo/foo.h]
    $(bar_INCS) is [bar/bar.h]
    $(wildcard bar/*) is: [bar/bar.h]
    DONE
    

    使用时 foreach-eval-call 请记住,第一个扩展是 eval-call 以及make在将结果解析为make语法时的第二个扩展。您经常需要避开第一个扩展( $$ )有时甚至是第二个( $$$$ )见 the GNU make manual 详细的解释。