Makefile变量扩展中的多后缀截断问题求助
解决Makefile中批量截断多个后缀的问题
我最近在Makefile里碰到个头疼的问题:需要给一批包名批量移除不同的后缀(比如OPT1、OPT2),折腾了好几种写法都没成功,好在最后找到了解决办法,分享给大家。
先说说我的场景:
- 已经在Makefile里指定了
SHELL=/bin/bash强制使用bash - 变量
PKG_LIST存着一堆文件夹名,比如packageFsOPT1 packageAdc packageMemOPT2,部分名称带OPT1/OPT2后缀,部分不带 - 存在一个tmp目录,里面包含
packageFs、packageAdc这类不带后缀的子文件夹
最开始处理单个后缀时,这段代码能正常工作,顺利截断OPT1后缀:
for pkg in $(PKG_LIST) ; do \ cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \ cp -a tmp/$${pkg%OPT1} $(DEST_DIR) ; \ done
但要同时处理OPT1和OPT2时就卡壳了:
- 我试了
cp -a tmp/$${pkg%+(OPT1|OPT2)} $(DEST_DIR),直接在控制台测试是有效的,但放到Makefile里完全没作用,后缀没被截断,导致找不到目标文件夹复制失败 - 又尝试把截断后的结果存到变量里:
pkg_stripped=$(shell echo ${pkg%+(OPT1|OPT2)}),结果这个变量直接为空,还是不行
可行解决方案
方案一:开启bash扩展通配符
Makefile默认没开启bash的extglob扩展通配符,所以+(...)这种写法不生效,我们只需要在循环里手动开启即可:
for pkg in $(PKG_LIST) ; do \ cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \ shopt -s extglob ; \ cp -a tmp/$${pkg%+(OPT1|OPT2)} $(DEST_DIR) ; \ done
方案二:用sed做字符串替换
如果觉得依赖bash扩展不太稳妥,也可以用sed来处理包名,不管是OPT1还是OPT2都能精准替换掉:
for pkg in $(PKG_LIST) ; do \ cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \ pkg_stripped=$$(echo "$$pkg" | sed 's/OPT1$$\|OPT2$$//') ; \ cp -a tmp/$$pkg_stripped $(DEST_DIR) ; \ done
这里sed的表达式s/OPT1$$\|OPT2$$//会匹配行尾的OPT1或OPT2,然后替换为空,完美实现后缀截断效果。
内容的提问来源于stack exchange,提问作者AirconBento
相关产品推荐
相关产品推荐

