Android 多模块注解处理

Android multi modules annotation processing

在多模块中 Android 项目注释处理仍然作为第一个任务在任何编译完成之前执行,然后触发完整编译。当然,这是在进入 app 模块之前按模块完成的。

设想一些子模块依赖于其他子模块的情况,编译将失败,因为依赖项无法在它所依赖的模块中找到生成的类的定义只是因为它们还没有生成。

我想知道是否有一种方法可以使用 gradle 或任何其他方式强制先执行所有子模块注释处理,然后以自动方式编译整个项目。这意味着如果我有 3 个模块,我们将它们命名为 appservicesexecutors,其中 services 取决于 executors

我正在寻找的是构建树将按以下顺序进行:

  1. 对所有未编译的模块进行注解处理
  2. 然后调用完整的项目编译

到目前为止,我使用 java compiler's 选项 -proc:{none;only} 发现了一些有前途的线索,其中值 only 应该调用注释处理而无需任何进一步编译。我已经尝试将此 option 传递给我的编译器,但 仍然 编译按顺序进入每个子模块的子模块。

有什么想法吗?

经过对这个主题的深入调查、长时间的阅读以及许多茶杯和咖啡杯,我发现我的项目设置不太正确,我还发现了 Kotlin android 插件有它自己的悲伤和阴暗的事实,我希望我能在这个答案中澄清,所以喝一杯 tee/coffee 并享受阅读。

  1. 有没有办法触发两次kotlin编译? 简短的回答是 NO!,这仅仅是因为 gradle 它自己有一个 Acyclic 依赖图,这意味着不应该有 循环 依赖关系,因此每个 gradle 调用一个任务只会 运行 一次。
  2. 我们如何解决这个限制? 有两种选择,要么我们添加一个新的 Source set(对于 android,这将通过添加一个新的 buildType)或者简单地打破 chicken/egg 困境的奇迹并使用人工制品。

我已经对每一种可能的解决方案进行了大量试验,但仍然有些东西闻起来有腥味。首先,here 是我向 gradle 用户询问我的问题的线程。尽管它没有解决我的问题,但它仍然阐明了问题本身的根源,chicken/egg 困境

为了进一步澄清我的问题,我继续进行调查并询问 kotlin 开发人员如何使用 kotlin gradle 插件来做到这一点。请找到答案here

简短的故事:无法直接扩展 kotlinCompile gradle 任务,因为有一个 "code around" 启动编译。我的意思是当然,但为什么它以这种方式设计得非常糟糕?为什么像 kotlin 这样美丽的语言必须匆忙生产那个特定的 据说功能强大的 插件,主要是为什么它的源代码从那以后就再也没有 updated/reviewed 了?

解决这个问题的方法是使用它们的句柄 KotlinCompilation 入口点。我个人不喜欢这个解决方案,因为它限制了灵活性,而且还进一步抽象了编译任务。

另一种使用 gradle 的有前途的方法是 artifacts 模块自行构建并生成一个工件(在我们的例子中通常是一个 jar),它将被其他项目使用。这听起来很酷吧?不幸的是,无法将此库添加到 consumers 的类路径中,编译将失败。

这些是我的发现,如果我理解有误,请随时更新我的​​知识或纠正我。

编码愉快!