在 Makefile 中的变量扩展中截断后缀
Chopping suffixes in variable expansion within a Makefile
如标题所述,如果我需要提供多个后缀,我无法从包名称中删除后缀 (pattern-list)
注意:我在 Makefile (SHELL=/bin/bash
)
中强制使用 bash
DEST_DIR
: Makefile 变量
PKG_LIST
:Makefile 变量,包含文件夹名称列表(例如“packageFsOPT1 packageAdc packageMemOPT2 .....”)。
有些名字可能有 OPT1 后缀,有些则没有。
tmp
:存在的文件夹,包含文件夹 packageFs、packageAdc、packageMem.....
这里是执行从 tmp 复制到 dest 的 Makefile 部分以及名称截断:
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 确实是从 packageFsOPT1 中切下来的。
但我需要的是能够截断不同的后缀。在这种情况下 OPT1 或 OPT2
我试过这个:
cp -a tmp/$${pkg%+(OPT1|OPT2)} $(DEST_DIR) ; \
如果直接在控制台中而不是在 Makefile 中进行测试(无法切碎 => OPT1 保留在文件夹名称中,它不存在 => 复制失败)
我有点像这样的东西(但导致 pkg_stripped 为空):
pkg_stripped=$(shell echo ${pkg%+(OPT1|OPT2)}) ; \
cp -a tmp/$$pkg_stripped $(DEST_DIR) ; \
有人知道吗?
编辑: 解决方案
两者之一(使用扩展全局)
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)
查看MadScientist答案
也许使用GNU make函数更简单?像这样:
for pkg in $(patsubst %OPT1,%,$(patsubst %OPT2,%,$(PKG_LIST))) ; do \
cp -a tmp/$${pkg} $(DEST_DIR) ; \
done
如果你有像 fooOPT1OPT2 这样的名字(两者都将被删除),这会做错事(也许?),但这也可以解决。
预计到达时间
如果您需要两者,则必须在 shell 中完成。您不能在配方中使用 $(shell ...)
:这是一个 make 函数,因此它在 shell 开始之前由 make 扩展:它不能对任何 shell for 循环的值进行操作当然是变量。
为此我会简单地使用 sed
:
for pkg in $(PKG_LIST) ; do \
prefix=$$(echo "$$pkg" | sed 's/OPT[12]$$//'); \
cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \
cp -a tmp/$$prefix $(DEST_DIR) ; \
done
如标题所述,如果我需要提供多个后缀,我无法从包名称中删除后缀 (pattern-list)
注意:我在 Makefile (SHELL=/bin/bash
)
DEST_DIR
: Makefile 变量PKG_LIST
:Makefile 变量,包含文件夹名称列表(例如“packageFsOPT1 packageAdc packageMemOPT2 .....”)。 有些名字可能有 OPT1 后缀,有些则没有。tmp
:存在的文件夹,包含文件夹 packageFs、packageAdc、packageMem.....
这里是执行从 tmp 复制到 dest 的 Makefile 部分以及名称截断:
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 确实是从 packageFsOPT1 中切下来的。 但我需要的是能够截断不同的后缀。在这种情况下 OPT1 或 OPT2
我试过这个:
cp -a tmp/$${pkg%+(OPT1|OPT2)} $(DEST_DIR) ; \
如果直接在控制台中而不是在 Makefile 中进行测试(无法切碎 => OPT1 保留在文件夹名称中,它不存在 => 复制失败)
我有点像这样的东西(但导致 pkg_stripped 为空):
pkg_stripped=$(shell echo ${pkg%+(OPT1|OPT2)}) ; \
cp -a tmp/$$pkg_stripped $(DEST_DIR) ; \
有人知道吗?
编辑: 解决方案
两者之一(使用扩展全局)
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)
查看MadScientist答案
也许使用GNU make函数更简单?像这样:
for pkg in $(patsubst %OPT1,%,$(patsubst %OPT2,%,$(PKG_LIST))) ; do \
cp -a tmp/$${pkg} $(DEST_DIR) ; \
done
如果你有像 fooOPT1OPT2 这样的名字(两者都将被删除),这会做错事(也许?),但这也可以解决。
预计到达时间
如果您需要两者,则必须在 shell 中完成。您不能在配方中使用 $(shell ...)
:这是一个 make 函数,因此它在 shell 开始之前由 make 扩展:它不能对任何 shell for 循环的值进行操作当然是变量。
为此我会简单地使用 sed
:
for pkg in $(PKG_LIST) ; do \
prefix=$$(echo "$$pkg" | sed 's/OPT[12]$$//'); \
cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \
cp -a tmp/$$prefix $(DEST_DIR) ; \
done