Makefile模式规则中的目录通配符

3
我正在尝试创建一个Makefile,通过tic编译位于目录中的terminfo文件。tic还会自动将它创建的termcap文件复制到系统或用户特定的目标文件夹中。对于普通用户,如果terminfo文件是例如screen-256color-bce-s.terminfo,它将被编译并复制到~/.terminfo/s/screen-256color-bce-s。因此,它看起来像这样:
terminfo/screen-256color-bce-s.terminfo => /home/user/.terminfo/s/screen-256color-bce-s
terminfo/screen-256color-s.terminfo => /home/user/.terminfo/s/screen-256color-s

如果我在我的 Makefile 中放入下面这样的内容:
TISRC = $(wildcard terminfo/*.terminfo)
TIDST = $(foreach x, $(TISRC), $(HOME)/.terminfo/$(shell basename $x|cut -c 1)/$(shell basename $x .terminfo))

$(HOME)/.terminfo/s/%: terminfo/%.terminfo
    @echo "$< => $@"
    @tic $<

install: $(TIDST)

它可以工作。然而,我想要让它更通用,使用目标中的通配符,即:

$(HOME)/.terminfo/**/%: terminfo/%.terminfo
    @echo "$< => $@"
    @tic $<

我希望能够将terminfo文件添加到我的本地存储库。然而,上述方法并不奏效。如何在模式规则中指定通配符目录?


我认为你不能这样做;Make 在通配符方面表现不佳。 - Beta
2个回答

7
你可以使用 GNU Make 辅助扩展功能来实现这一点:
all : ${HOME}/.terminfo/x/a
all : ${HOME}/.terminfo/y/b

.SECONDEXPANSION:
${HOME}/.terminfo/%: terminfo/$$(notdir $$*).terminfo
    @echo "$< ---> $@"

输出:

[~/tmp] $ make
terminfo/a.terminfo ---> /home/max/.terminfo/x/a
terminfo/b.terminfo ---> /home/max/.terminfo/y/b

值得一提的是,Make 提供了一些路径操作函数,因此您不需要真正调用 shell 进行操作。


@Beta 好吧,有时候人们希望make有类似于正则表达式模式匹配的功能,例如 /([[:word:]]+)/([[:word:]]+) : /build/\1/obj/\2.o。但这会使选择更具体的规则变得困难。使用%模式时,最具体的模式是其中%匹配最少数量字符的模式,如果我没记错的话。 - Maxim Egorushkin

1

我认为你不能按照你尝试的方式使用通配符,但如果你不介意使用eval技巧,你可以实现你想要的效果,而无需明确拼写所有目录路径:

TISRC = $(wildcard terminfo/*.terminfo)
BASENAMES = $(notdir $(basename ${TISRC}))

MKDST = ${HOME}/.terminfo/$(shell echo $1 | cut -c 1)/$1
TIDST := $(foreach s,${BASENAMES},$(call MKDST,$s))
DIRLTRS = $(notdir $(patsubst %/,%,$(sort $(dir ${TIDST}))))

install: ${TIDST}

# $1 - Directory Name
# $2 - File name
define T
${HOME}/.terminfo/$1/$2 : terminfo/$2.terminfo
    @echo "$$< => $$@"
    tic $$<
endef

# This is the tricky part: use template T to make the rules you need.
$(foreach d,${DIRLTRS},$(foreach f,${BASENAMES},$(eval $(call T,$d,$f))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接