如何通过KSP将多模块Feature Flag合并为统一集合?
问题描述
我想用KSP生成项目中所有模块(app、module1到moduleN)的Feature Flag完整列表。目前已经实现了代码处理器来收集各模块中带@FeatureFlag注解的内容,KSP处理器作为所有模块的依赖。
每个模块会生成如下形式的Feature Flag集合:
Module 1:
#build/generated/ksp/main/kotlin/package internal val featuresFlags : Set<FeatureFlag> = setOf(settingsFeatureFlag, profileFeatureFlag)
Module 2:
#build/generated/ksp/main/kotlin/package internal val featuresFlags : Set<FeatureFlag> = setOf(fingerprintFeatureFlag)
Module N:
#build/generated/ksp/main/kotlin/package internal val featuresFlags : Set<FeatureFlag> = setOf(/* 0到N个FeatureFlag */)
我需要把这些分散的集合合并成一个统一的集合,期望在Feature Flag模块中得到:
internal val featuresFlags : Set<FeatureFlag> = setOf(settingsFeatureFlag, profileFeatureFlag, fingerprintFeatureFlag, ...) // 合并所有模块的结果
但遇到了KSP的限制,尝试跨模块写入结果时出现错误:
[ksp] java.lang.IllegalStateException: requested path is outside the bounds of the required directory
解决方案
KSP的设计限制决定了处理器只能写入当前模块的生成目录,无法直接跨模块写入文件,可通过以下思路实现合并:
方案1:Gradle任务+元数据收集
- 每个模块的KSP处理器除了生成当前模块的
featuresFlags集合,额外生成一份元数据文件(JSON/Protobuf格式均可),记录当前模块所有Feature Flag的全限定名,输出到模块的build/intermediates目录。 - 在Feature Flag模块中编写Gradle任务,遍历所有模块的元数据文件,读取并汇总所有Feature Flag的全限定名。
- 用该任务调用KotlinPoet或直接拼接字符串,生成包含所有Feature Flag的统一
featuresFlags集合文件,写入Feature Flag模块的KSP生成目录。
方案2:注解标记+跨模块扫描
- 让Feature Flag模块依赖所有业务模块(app、module1到moduleN)。
- 修改KSP处理器,给每个模块生成的
featuresFlags添加自定义注解(比如@FeatureFlagCollection),同时将属性可见性调整为internal + @PublishedApi或public(根据项目权限需求选择)。 - 在Feature Flag模块中编写KSP处理器,扫描所有依赖模块中带
@FeatureFlagCollection的属性,收集所有Feature Flag实例,生成统一的合并集合。
方案3:统一命名规范+静态聚合
- 每个模块的KSP处理器生成的集合统一使用相同包名+固定类名(比如
com.your.package.FeatureFlagHolder),属性命名为moduleFeatures。 - 在Feature Flag模块中,生成聚合类导入所有模块的
moduleFeatures并合并:
internal val featuresFlags: Set<FeatureFlag> = setOf( com.your.package.module1.FeatureFlagHolder.moduleFeatures, com.your.package.module2.FeatureFlagHolder.moduleFeatures, // ... 其他模块 ).flatten().toSet()
可通过Gradle动态生成导入语句,确保所有模块的生成类可被Feature Flag模块访问。
内容的提问来源于stack exchange,提问作者rafaelasguerra
相关产品推荐
相关产品推荐

