【问题标题】:Makefile: do operation on files with specific extension from a variableMakefile:对变量中具有特定扩展名的文件进行操作
【发布时间】:2018-03-28 07:23:24
【问题描述】:

我正在制作一个需要能够执行以下操作的 Makefile:

来自用户给定的变量,SRVS,包含文件名,例如,

SRVS=Test1.java,test2.c,test3.c,test4.java,test5.c

生成具有特定扩展名的所有文件的列表,供 foreach 循环使用。 此列表不应再包含扩展名。 目前,我可以解析所有文件并将其放入可用列表中,但无法为扩展名这样做。 我有什么:

    $(foreach SRV, $(shell echo $(SRVS) | tr ',' ' '), \
         CLASSPATH=$(SELF)/default_runtime javac $(UJ_DIR)/services/java/$(SRV).java && \
         find $(UJ_DIR)/services/java/ -iname "$(SRV).class" -type f >> $(SELF)/files && \
) true

它将获取 SRVS 列表并生成可供 foreach 使用的列表及其中的代码。例如,上面的示例将导致 foreach 循环使用“test1 test2 test3 test4 test5”

我现在想指定扩展名,例如 .c,以便上面的示例生成“test2 test3 test5”。 你能帮帮我吗?

【问题讨论】:

  • 不要使用逗号分隔名称。 make 使用空格,所以使用空格作为分隔符。

标签: makefile


【解决方案1】:

首先,您不需要调用shell(这太慢了),因为有 make 内置函数可以满足您的需求。如果在变量SRVS 的定义中,您真的不能用空格(标准的make word 分隔符)而不是逗号来分隔文件名,subst 可以为您完成。但是有一个小技巧,因为逗号本身就是 make 函数的参数分隔符:

comma := ,
SRVS1 := $(subst $(comma), ,$(SRVS))

接下来,filter 是允许按扩展名选择文件的 make 函数:

SRVS2 := $(filter %.c,$(SRVS1))

最后,basename 删除了后缀:

SRVS3 := $(basename $(SRVS2))

演示:

$ cat Makefile
SRVS=Test1.java,test2.c,test3.c,test4.java,test5.c

comma := ,
SRVS1 := $(subst $(comma), ,$(SRVS))
SRVS2 := $(filter %.c,$(SRVS1))
SRVS3 := $(basename $(SRVS2))

all:
    $(info SRVS1 = $(SRVS1))
    $(info SRVS2 = $(SRVS2))
    $(info SRVS3 = $(SRVS3))

$ make -q
SRVS1 = Test1.java test2.c test3.c test4.java test5.c
SRVS2 = test2.c test3.c test5.c
SRVS3 = test2 test3 test5

或者,一次性:

$ cat Makefile
TAGS := $(basename $(filter %.c,$(subst $(comma), ,$(SRVS))))

all:
    $(info TAGS = $(TAGS))
$ make -q
TAGS = test2 test3 test5

【讨论】:

  • 这很好用,谢谢。作为参考,我现在只需通过您的方法创建几个变量(SRVS_C、SRVS_JAVA)并在 foreach 循环中调用它们。
  • 顺便说一句,看看你的foreach 循环,我怀疑你对 make 的使用与 make 哲学相去甚远,而且效率很低。如果您根据目标、先决条件和规则进行推理以从先决条件构建目标,您可能会得到更好的结果。 Make 不是另一种脚本语言,如 bash、perl 或 python。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-10
  • 2020-06-06
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多