You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Makefile中从SRVS变量提取指定扩展名的无后缀文件名列表

解决Makefile中提取特定扩展名文件并生成无扩展名列表的问题

没问题,我来帮你搞定这个需求!你需要从逗号分隔的SRVS变量里筛选出指定扩展名的文件,再去掉扩展名生成foreach可用的列表,用Makefile内置函数就能轻松实现,不需要依赖shell命令(当然也可以用,但内置函数更高效)。

核心思路拆解

要达成目标,我们只需要三步:

  1. 把逗号分隔转成空格分隔:Makefile默认用空格作为列表分隔符,所以先把SRVS里的,替换成空格,得到标准列表。
  2. 过滤特定扩展名的文件:用filter函数筛选出符合目标扩展名的文件。
  3. 去掉扩展名:用basename函数剥离每个文件名的扩展名,得到纯文件名。

完整代码示例

假设你的SRVS变量是Test1.java,test2.c,test3.c,test4.java,test5.c,我们可以这样处理:

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

# 提取所有.java文件,生成无扩展名的列表
JAVA_SRVS := $(basename $(filter %.java, $(subst ,, $(SRVS))))

# 提取所有.c文件,生成无扩展名的列表
C_SRVS := $(basename $(filter %.c, $(subst ,, $(SRVS))))

# 测试foreach循环
.PHONY: process-java process-c all

all: process-java process-c

process-java:
	@$(foreach srv, $(JAVA_SRVS), echo "Processing Java service: $(srv)";)

process-c:
	@$(foreach srv, $(C_SRVS), echo "Processing C service: $(srv)";)

各部分解释

  • $(subst ,, $(SRVS)):将SRVS中的逗号替换为空格,把字符串Test1.java,test2.c...转换成Makefile可识别的列表Test1.java test2.c...。
  • $(filter %.java, ...):只保留列表中以.java结尾的文件名,这里会得到Test1.java test4.java。
  • $(basename ...):去掉每个文件名的扩展名,最终得到Test1 test4,正好是你需要的无扩展名列表。
  • 之后直接把JAVA_SRVS或C_SRVS传入foreach循环即可,因为它们已经是标准的空格分隔列表了。

更通用的函数封装

如果需要频繁提取不同扩展名的文件,可以封装成一个可复用的函数,这样更灵活:

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

# 自定义函数:参数1=目标扩展名(比如.java),参数2=原始SRVS变量
extract_services = $(basename $(filter %$(1), $(subst ,, $(2))))

# 调用函数提取不同类型的文件
JAVA_SRVS := $(call extract_services,.java,$(SRVS))
C_SRVS := $(call extract_services,.c,$(SRVS))

这样不管你要提取.py还是.go的文件,只需要调用$(call extract_services,.py,$(SRVS))就能得到对应的无扩展名列表了。

内容的提问来源于stack exchange,提问作者Sven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:26:43