includeBuild + dependencySubstitution 可实现本地项目源码直连依赖,无需修改业务模块的 implementation 语句,也不依赖 mavenLocal();要求被引入项目是合法独立 Gradle 构建,路径不能含空格或中文,且 substitute module 坐标须与 implementation 声明完全一致。

直接用 includeBuild + dependencySubstitution 就能实现,不需要改业务模块的 implementation 语句,也不依赖 mavenLocal()。
includeBuild 要求被包含项目是合法 Gradle 构建
被引入的本地模块(比如 lib-common)必须自己能独立构建成功:
- 根目录下要有
settings.gradle或settings.gradle.kts,且能识别出 root project(哪怕只有一行rootProject.name = "lib-common") - 如果用了 Kotlin DSL,
build.gradle.kts必须声明必要插件(如java、maven-publish),否则includeBuild会解析失败,报错类似Could not resolve all dependencies for configuration ':compileClasspath' - 路径不能含空格或中文——Gradle 解析
settings.gradle时对特殊字符敏感,容易触发Project directory not part of the build
settings.gradle 里正确声明 includeBuild
在主项目(比如 app)的 settings.gradle 中添加:
includeBuild("../lib-common") {
dependencySubstitution {
substitute module("com.example:lib-common:1.0.0") with project(":")
}
}
关键点:
-
../lib-common是相对于当前settings.gradle的路径,不是相对于项目根目录;建议用相对路径,避免 CI 环境路径错位 -
substitute module(...)中的坐标必须和你在app/build.gradle里写的implementation 'com.example:lib-common:1.0.0'完全一致(包括group、name、version) -
with project(":")表示把整个被包含构建的 root project 当作替代源;如果它有多个子项目,需明确写成with project(":core")
为什么不用 mavenLocal()?
用 mavenLocal() 需要手动执行 publishToMavenLocal,每次改代码都要重复 publish → refresh → rebuild,而 includeBuild 是源码直连:
- 修改
lib-common的 Java/Kotlin 文件后,app编译时自动编译最新源码,无需 publish - 调试时能直接跳进
lib-common的源码断点,mavenLocal()只能跳到 jar 包反编译结果 - 但注意:复合构建默认不共享构建缓存,CI 上可能变慢;可加
org.gradle.caching=true到gradle.properties缓解
IDEA 同步失败常见原因
IntelliJ IDEA 常见同步卡住或提示 “No projects found”:
- 没关掉
Settings > Build > Gradle > Use Gradle from: Project SDK—— 改成Gradle wrapper,否则 IDEA 会用自带 Gradle 版本去解析includeBuild,版本不兼容就失败 -
lib-common的build.gradle里用了buildscript { dependencies { classpath ... } },但主项目没声明对应仓库 → 把google()、mavenCentral()等统一挪到allprojects { repositories { ... } }下 - IDEA 缓存污染:删掉
.idea/gradle.xml和.gradle/目录,再重新 Import Project
真正麻烦的是坐标匹配——substitute module(...) 里写的字符串必须和依赖声明一字不差,连大小写、冒号位置都不能错;一旦不一致,Gradle 就当没这回事,继续走远程仓库下载。











