能否将Make目标依赖层级注入目标运行环境?
Makefile依赖链传递问题解答
1. 默认情况下目标c无法知晓触发依赖链
默认执行make a时,Make会按a→b→c的顺序检查依赖并执行规则,但每个目标的子shell是独立启动的,Make不会自动将完整依赖链信息传递给子shell,因此目标c的执行环境中没有触发它的依赖链数据。
2. 可以通过自定义变量传递实现依赖链注入
可以通过递归调用Make或手动传递变量的方式,将依赖层级信息注入每个子shell的环境中,以下是两种可行方案:
方案1:递归Make传递调用链
修改Makefile,通过递归调用时传递自定义变量CHAIN来构建完整依赖链:
a: @$(MAKE) CHAIN="a" b b: @$(MAKE) CHAIN="$(CHAIN)->b" c c: @echo "触发依赖链: $(CHAIN)->c" @echo in c
执行make a后,c的输出会包含完整依赖链:
触发依赖链: a->b->c in c
方案2:非递归的变量传递(硬编码式)
如果目标层级较少,也可以直接在每个目标的规则中显式定义依赖链变量:
a: b @echo "当前触发链: a" @echo in a b: c @echo "当前触发链: a->b" @echo in b c: @echo "当前触发链: a->b->c" @echo in c
这种方式实现简单,但目标数量较多时维护成本高,不如递归方式灵活。
补充:利用MAKEFLAGS自动传递变量
如果需要更通用的传递方式,可以借助MAKEFLAGS(递归Make时自动传递的变量集合)来传递链信息:
ifdef CHAIN CURRENT_CHAIN := $(CHAIN) else CURRENT_CHAIN := endif a: @$(MAKE) CHAIN="$(CURRENT_CHAIN)a->" b b: @$(MAKE) CHAIN="$(CURRENT_CHAIN)b->" c c: @echo "触发依赖链: $(CURRENT_CHAIN)c" @echo in c
执行make a同样会输出完整的依赖链信息。
内容的提问来源于stack exchange,提问作者Ross Rogers
相关产品推荐
相关产品推荐

