如何在Makefile中实现单词列表内模式的全局替换?解决patsubst仅替换首个%的问题
解决Makefile中patsubst无法替换多个%的问题
你遇到的这个情况确实是Makefile里patsubst的一个小限制——它只会把模式和替换文本里第一个%当作通配符,后面的%都会原样保留。不过要实现把test1 test2转换成build/test1/test1 build/test2/test2的目标,有几种很实用的方法:
方法1:用foreach循环逐个处理元素
这是最直观也最容易维护的方式,针对列表里的每个元素单独拼接路径:
test_list := test1 test2 target_list := $(foreach item, $(test_list), build/$(item)/$(item))
解释一下:foreach会遍历test_list里的每个元素,把每个item代入build/$(item)/$(item),最终拼接成你想要的结果。
方法2:嵌套使用函数组合实现
如果偏好基于模式替换的思路,可以先给第二个位置预留一个独特标记,再替换这个标记为对应的元素:
test_list := test1 test2 # 先把每个元素转成 build/testX/TEMP_MARK 的形式 temp_list := $(patsubst %, build/%/TEMP_MARK, $(test_list)) # 再把每个元素里的 TEMP_MARK 替换成对应的testX target_list := $(foreach entry, $(temp_list), $(subst TEMP_MARK, $(word 2, $(subst /, ,$(entry))), $(entry)))
这里先用patsubst生成带标记的临时列表,再通过subst和word函数提取路径中的目标元素,替换掉标记。不过这种写法比foreach直接拼接复杂一些,除非有特殊场景,不然更推荐第一种方法。
补充:有没有支持多%的patsubst变体?
遗憾的是,Makefile的内置函数里并没有直接支持替换多个%的patsubst变体。不过通过上面的foreach或者函数组合的方式,完全可以实现相同的效果,而且可读性也不差。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

