C++ 库插件提供了用于构建 C++ 库的 tasks、约定和约定。 特别是,C++ 库提供了可供使用者使用的功能(即,使用此插件或其他 C++ 应用程序插件的项目)。

用法

build.gradle.kts
plugins {
    `cpp-library`
}
build.gradle
plugins {
    id 'cpp-library'
}

构建变体

C++ 库插件理解以下维度。 阅读 构建变体简介 以获取更多信息。

构建类型 - 始终设置为debugrelease

构建类型控制生成二进制文件的可调试性和优化。

  • debug - 生成调试符号且不优化二进制文件

  • release - 生成调试符号并进行优化,但从二进制文件中提取调试符号

Linkages - 默认为 shared

链接表示应创建共享库还是静态库。 库可以生成共享库、静态库或两者兼而有之。

链接可以按如下方式配置

示例 2. 配置库链接
build.gradle.kts
library {
    linkage = listOf(Linkage.STATIC, Linkage.SHARED)
}
build.gradle
library {
    linkage = [Linkage.STATIC, Linkage.SHARED]
}
目标机器 - 默认为构建主机

目标机器表示应用程序预期运行的机器。 目标机器由其操作系统和架构标识。 Gradle 使用目标机器来决定选择哪个工具链,这基于主机上的可用性。

目标机器可以按如下方式配置

build.gradle.kts
library {
    targetMachines = listOf(machines.linux.x86_64,
        machines.windows.x86, machines.windows.x86_64,
        machines.macOS.x86_64)
}
build.gradle
library {
    targetMachines = [
        machines.linux.x86_64,
        machines.windows.x86, machines.windows.x86_64,
        machines.macOS.x86_64
    ]
}

Tasks

下图显示了此插件添加的 tasks 之间的关系。

请注意,如图所示,C++ 库的默认链接是共享链接。

cpp shared library task graph
图 1. C++ 库插件默认 task 图

使用静态链接时,图表变为以下内容

cpp static library task graph
图 2. C++ 库插件仅静态库 task 图

变体相关的 Tasks

C++ 库插件基于库组件的变体创建 tasks。 阅读 构建变体简介 以获取更多信息。 以下图表显示了变体相关 tasks 之间的关系。

cpp library variant task graph
图 3. C++ 库插件变体相关 task 图
取决于 linkage 属性
compileVariantCpp (例如 compileDebugCppcompileReleaseCpp) - CppCompile

依赖于:所有为编译贡献源文件的 tasks :: 使用选定的编译器编译 C++ 源文件。

linkVariant (例如 linkDebuglinkRelease) - LinkSharedLibrary (共享链接)

依赖于:所有为链接库贡献的任务,包括通过项目依赖项解析的项目的 linkVariantcreateVariant tasks :: 使用选定的链接器从编译的对象文件链接共享库。

createVariant (例如 createDebugcreateRelease) - CreateStaticLibrary (静态链接)

使用选定的归档器从编译的对象文件创建静态库

assembleVariant (例如 assembleDebugassembleRelease) - Task (生命周期)

依赖于:linkVariant (共享链接) 或 createVariant (静态链接) :: 聚合 tasks,用于组装此库的特定变体。

生命周期 Tasks

C++ 库插件将其某些 tasks 附加到 基础插件章节 中记录的标准生命周期 tasks — C++ 库插件会自动应用这些 tasks

assemble - Task (生命周期)

依赖于:当链接包括 shared 时为 linkDebug,否则为 createDebug。 :: 聚合 task,用于组装项目中当前主机(如果存在)的共享库的调试变体(如果可用)。 此 task 由 基础插件 添加。

check - Task (生命周期)

聚合 task,用于执行验证 tasks,例如运行测试。 一些插件将它们自己的验证 task 添加到 check。 例如,C++ 单元测试插件 将其测试 task 附加到此生命周期 task。 此 task 由 基础插件 添加。

build - Task (生命周期)

依赖于:check, assemble :: 聚合 tasks,用于执行项目的完整构建。 此 task 由 基础插件 添加。

clean - Delete

删除构建目录及其中的所有内容,即 layout.buildDirectory 项目属性指定的路径。 此 task 由 基础插件 添加。

依赖管理

正如 C++ 库插件创建的 tasks 一样,多个配置是基于库组件的变体创建的。 阅读 构建变体简介 以获取更多信息。 下图描述了 C++ 库插件添加的配置

cpp library configurations
图 4. C++ 库插件配置
  • 白色配置是用户应该用来声明依赖项的配置。

  • 粉红色配置,也称为可消费配置(用 (C) 表示),是组件编译、链接或针对库运行时使用的配置。

  • 蓝色配置,也称为可解析配置(用 (R) 表示),是组件内部使用的,供其自身使用。

以下配置用于声明依赖项

api

用于声明 API 依赖项(请参阅 API 与实现部分)。 您应该在此处声明传递导出到使用者的依赖项,用于编译和链接。

implementation 扩展 api

用于声明主要组件的所有变体的实现依赖项(请参阅 API 与实现部分)。 您应该在此处声明纯粹内部且不打算暴露给任何变体的使用者的依赖项。

mainVariantImplementation (例如 mainDebugImplementationmainReleaseImplementation) 扩展 implementation

用于声明主要组件的特定变体的实现依赖项(请参阅 API 与实现部分)。 您应该在此处声明纯粹内部且不打算暴露给此特定变体的使用者的依赖项。

以下配置由使用者使用

cppApiElements 扩展 mainVariantImplementation

用于针对库进行编译。 此配置旨在供使用者使用,以检索针对库进行编译所需的所有元素。

variantLinkElements (例如 debugLinkElementsreleaseLinkElements) 扩展 mainVariantImplementation

用于针对库进行链接。 此配置旨在供使用者使用,以检索针对库进行链接所需的所有元素。

variantRuntimeElements (例如 debugRuntimeElementsreleaseRuntimeElements) extends `mainVariantImplementation

用于执行库。 此配置旨在供使用者使用,以检索针对库运行所需的所有元素。

以下配置由库自身使用

cppCompileVariant (例如 cppCompileDebugcppCompileRelease) 扩展 mainVariantImplementation

用于编译库。 此配置包含库的编译包含根目录,因此在调用 C++ 编译器来编译库时使用。

nativeLinkVariant (例如 nativeLinkDebugnativeLinkRelease) 扩展 mainVariantImplementation

用于仅链接库的共享库。 此配置包含库的库,因此在调用 C++ 链接器来链接库时使用。

nativeRuntimeVariant (例如 nativeRuntimeDebugnativeRuntimeRelease) 扩展 mainVariantImplementation

用于执行库。 此配置包含库的运行时库。

API 与实现

该插件公开了两个可用于声明依赖项的配置:apiimplementationapi 配置应用于声明由库 API 导出的依赖项,而 implementation 配置应用于声明组件内部的依赖项。

示例 4. 添加依赖项
build.gradle.kts
library {
    dependencies {
        api("io.qt:core:5.1")
        implementation("io.qt:network:5.1")
    }
}
build.gradle
library {
    dependencies {
        api "io.qt:core:5.1"
        implementation "io.qt:network:5.1"
    }
}

出现在 api 配置中的依赖项将传递地暴露给库的使用者,因此将出现在使用者的编译包含根目录和链接库中。 另一方面,在 implementation 配置中找到的依赖项将不会暴露给使用者,因此不会泄漏到使用者的编译包含根目录和链接库中。 这带来了一些好处

  • 依赖项不会泄漏到使用者的编译包含根目录和链接库中,因此它们永远不会意外地依赖于传递依赖项

  • 由于减少了包含根目录和链接库,因此编译速度更快

  • 当 implementation 依赖项更改时,重新编译次数更少,因为使用者不需要重新编译

约定

C++ 库插件为源文件和 tasks 添加了约定,如下所示。

项目布局

C++ 库插件假定项目布局如下所示。 这些目录都不需要存在或包含任何内容。 C++ 库插件将编译找到的任何内容,并忽略任何缺失的内容。

src/main/cpp

C++ 源代码,扩展名为 .cpp.C++.cc

src/main/headers

私有标头 - 编译库所需的标头,但使用者不需要

src/main/public

公共标头 - 编译库所需且使用者需要的标头

您可以通过在 library 脚本块上分别配置 sourceprivateHeaderspublicHeaders配置项目布局

compileVariantCpp Task

C++ 库插件为要构建的库组件的每个变体添加一个 CppCompile 实例(例如 compileDebugCppcompileReleaseCpp)。 阅读 构建变体简介 以获取更多信息。 下面显示了一些最常见的配置选项。

compilerArgs

[]

debuggable

true

includes

configurations.cppCompileVariant + library.publicHeaders + library.privateHeaders

macros

[:]

objectFileDir

layout.buildDirectory.dir("obj/main/$variant")

optimized

false 用于 debug 构建类型,否则为 true

positionIndependentCode

true 用于共享链接,否则为 false

source

library.cppSource

systemIncludes

派生自工具链

targetPlatform

派生自二进制文件的 TargetMachine

toolChain

根据目标机器自动选择

C++ 库插件为包含共享链接作为维度的库的每个变体添加一个 LinkSharedLibrary 实例 - 例如 linkDebuglinkRelease。 阅读 构建变体简介 以获取更多信息。 下面显示了一些最常见的配置选项。

debuggable

true

libs

configurations.nativeLinkVariant

linkedFile

layout.buildDirectory.dir("lib/main/$variant/libBaseName[.so|dylib]") (*nix) 或 layout.buildDirectory.dir("lib\main\$variant\baseName.dll") (Windows)

linkerArgs

[]

source

compileVariantCpp.objects

targetPlatform

派生自二进制文件的 TargetMachine

toolChain

根据目标机器自动选择

createVariant Task

C++ 库插件为包含静态链接作为维度的库的每个变体添加一个 CreateStaticLibrary 实例 - 例如 createDebugcreateRelease。 阅读 构建变体简介 以获取更多信息。 下面显示了一些最常见的配置选项。

outputFile

layout.buildDirectory.dir("lib/main/variant/libBaseName.a") (*nix) 或 layout.buildDirectory.dir("lib\main\variant\baseName.lib") (Windows)

source

compileVariantCpp.objects

staticLibArgs

[]

targetPlatform

派生自二进制文件的 TargetMachine

toolChain

根据目标机器自动选择