介绍源依赖
介绍
这篇文章介绍了一个新的 Gradle 依赖管理功能,称为“源依赖”。
通常,当您声明对库的依赖时,Gradle 会在二进制仓库(如 JCenter 或 Maven Central)中查找库的二进制文件,并下载这些二进制文件以在构建中使用。
源依赖允许您让 Gradle 自动从 Git 中检出库的源代码,并在本地计算机上构建二进制文件,而不是下载它们。
我们很乐意收到您对这个功能的反馈。请尝试使用它,并告知我们哪些对您有效,以及您遇到的任何问题。您可以在 Gradle 论坛上留下反馈,或在 Gradle native GitHub 仓库中提出问题。
您应该注意,此功能目前处于孵化阶段,并且在未来的 Gradle 版本中可能会以破坏性的方式发生更改。在未来的版本中此功能被提升为稳定版之前,请不要在生产环境中使用它。
如何尝试? #
您可以在 native-samples 仓库中找到许多使用源依赖的示例。C++ 构建是使用源依赖的自然场所,但这并非 C++ 特有的功能。源依赖适用于任何类型的构建,只要这些构建使用 Gradle 的依赖管理功能,例如 Java、Kotlin 或 Android 构建。您可以使用最新的 Gradle 4.10 或 nightly 版本来尝试此功能。
让我们看一个 示例应用程序。此示例展示了一个应用程序,该应用程序使用一个位于单独 Git 仓库中的库。
在构建文件中,源依赖看起来与二进制依赖相同。您声明对特定版本的 模块(例如库)的依赖。在这里,我们的示例需要版本 1.0 的“utilities”库
dependencies {
implementation 'org.gradle.cpp-samples:utilities:1.0'
}
您还需要告诉 Gradle 在哪里找到库的源代码。这类似于您需要在构建中定义一些二进制仓库来告诉 Gradle 在哪里找到二进制文件,但是,语法有所不同。在 settings.gradle
文件中,我们定义了一个源映射
sourceControl {
gitRepository("https://github.com/gradle/native-samples-cpp-library.git") {
producesModule("org.gradle.cpp-samples:utilities")
}
}
现在,当 Gradle 需要查找“utilities”库的版本时,它将在 Git 仓库中查找匹配的标签。Gradle 将检出匹配的 Git 标签,构建二进制文件并使结果可用。这与 包含构建 的工作方式相同。
这是在此示例上运行 gradle assemble
的结果
> Task :native-samples-cpp-library:list:compileDebugCpp
> Task :native-samples-cpp-library:utilities:compileDebugCpp
> Task :native-samples-cpp-library:list:linkDebug
> Task :compileDebugCpp
> Task :native-samples-cpp-library:utilities:linkDebug
> Task :linkDebug
> Task :installDebug
> Task :assemble
BUILD SUCCESSFUL in 4s
3 actionable tasks: 3 executed
Gradle 已克隆库的源代码,构建了库二进制文件,然后将应用程序链接到这些二进制文件。
您还可以使用略有不同的语法声明对分支的依赖。这个 示例应用程序 演示了如何做到这一点。
dependencies {
implementation('org.gradle.cpp-samples:utilities') {
version {
branch = 'release'
}
}
}
源依赖也适用于插件,但目前需要在 settings.gradle
中进行一些额外的配置才能工作。这个 示例库 展示了如何做到这一点。
源依赖有什么用? #
当您使用的模块的二进制文件在二进制仓库中不可用时,源依赖非常有用。例如
- 当您在库的分支上工作,并且尚未为此分支发布二进制文件时。例如,您可能想使用尚未合并或发布的某个分支中的错误修复。
- 当您使用的库发布源代码但不发布二进制文件时。这在 C++ 库和应用程序中很常见,其中库仅以源代码形式发布,您必须构建自己的二进制文件。
- 当您使用的原生库未针对您的目标平台发布二进制文件时。C++ 库或应用程序通常仅针对某些常见的操作系统或工具链发布二进制文件。要在其他平台上使用该库,您必须构建自己的二进制文件。
- 当您不想等待另一个系统(例如 CI 服务器)发布依赖项的二进制文件时。例如,您可能想尝试更改多个库。
源依赖使这些用例更易于实现。Gradle 负责自动检出正确版本的依赖项,确保在需要时构建二进制文件。它在运行构建的任何地方都这样做。检出的项目甚至不需要现有的 Gradle 构建。这个示例 展示了一个 Gradle 构建,它通过插件注入 Gradle 构建来使用两个没有构建系统的源依赖项。注入的配置可以执行常规 Gradle 插件可以执行的任何操作,例如包装现有的 CMake 或 Maven 构建。
源依赖可以与 Gradle 构建缓存 结合使用,当您的团队中的每个人都从源代码构建相同的依赖项时,可以使这些用例高效。Gradle 构建缓存确保一旦构建了二进制文件,它们将在其他任何地方重用。
源依赖可以与二进制依赖一起使用,您可以混合搭配,以便某些依赖从源代码构建,而另一些作为二进制文件下载。源依赖也与 复合构建 良好地协同工作。
这与复合构建有何不同? #
大多数情况下,没有区别。源依赖基于 Gradle 的 复合构建 功能,并添加了源代码的自动配置,以帮助处理一些特定的用例。
源依赖与包含构建在意图上有所不同。包含构建表示您当前正在处理的某个模块。无论在构建中请求哪个版本的模块,依赖项解析都将始终使用来自包含构建的二进制文件,以便您可以看到更改的效果。
另一方面,源依赖表示您使用的某个模块,但该模块恰好以源代码形式而不是二进制形式提供。依赖项解析将始终选择与构建中请求的任何内容匹配的源依赖项版本。使用包含构建,您可以修改源代码并直接查看更改,但使用源依赖项,您需要提交并推送更改才能看到其效果。
缺失的功能 #
源依赖支持在很大程度上是实验性的,并且缺少一些重要的功能
- 构建扫描 尚不支持使用源依赖的构建。
- IDE 支持在很大程度上尚不可用。当构建使用源依赖时,大多数 IDE 集成都会失败并出现错误。源依赖目前仅受 Gradle 的 C++ Xcode 集成支持。
- 依赖锁定 不支持源依赖。
- 源依赖也具有与 包含构建 相同的限制。
- 您不能在包含包含构建的构建上具有源依赖。但是,您可以在使用源依赖的构建上具有源依赖。
- 您还不能混合使用特定模块的源依赖和二进制依赖。每个模块必须来自 Git 仓库或二进制仓库,但不能同时来自两者。
- 仅支持 Git 仓库。
路线图 #
我们希望收到您的反馈,并在此基础上实现上面列出的缺失功能。一旦我们确信 DSL 和 API 有用且运行良好,我们将把该功能提升为稳定版。请在 Gradle 论坛 或 Gradle native GitHub 仓库中告诉我们您的想法。