C++ Library Plugin 提供了构建 C++ 库的任务和约定。特别是,C++ 库提供的功能可以被消费者使用(即使用此插件或其他项目的项目,或者使用 C++ Application Plugin 的项目)。

用法

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

构建变体

C++ Library Plugin 理解以下维度。请阅读构建变体简介以获取更多信息。

构建类型 - 总是设置为 debugrelease

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

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

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

链接方式 - 默认为 shared

链接方式表示应该创建共享库还是静态库。库可以生成共享库、静态库或两者都生成。

链接方式可以按如下方式配置

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
    ]
}

任务

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

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

cpp shared library task graph
图 1. C++ Library Plugin 默认任务图

对于静态链接,图表变为如下所示

cpp static library task graph
图 2. C++ Library Plugin 仅静态库任务图

变体相关的任务

C++ Library Plugin 根据库组件的变体创建任务。请阅读构建变体简介以获取更多信息。下图显示了变体相关任务之间的关系。

cpp library variant task graph
图 3. C++ Library Plugin 变体相关任务图
取决于链接属性
compileVariantCpp (例如 compileDebugCppcompileReleaseCpp) - CppCompile

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

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

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

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

使用选定的归档器从编译后的目标文件创建静态库

assembleVariant (例如 assembleDebugassembleRelease) - 任务 (生命周期)

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

生命周期任务

C++ Library Plugin 将其部分任务附加到 Base Plugin 章中记录的标准生命周期任务——C++ Library Plugin 会自动应用 Base Plugin

assemble - 任务 (生命周期)

依赖于:当链接方式包含 shared 时依赖 linkDebug,否则依赖 createDebug。:: 聚合任务,组装项目当前主机(如果存在)的共享库调试变体(如果可用)。此任务由 Base Plugin 添加。

check - 任务 (生命周期)

聚合任务,执行验证任务,例如运行测试。一些插件将自己的验证任务添加到 check 任务。例如,C++ Unit Test Plugin 将其测试任务附加到此生命周期任务。此任务由 Base Plugin 添加。

build - 任务 (生命周期)

依赖于:check, assemble :: 聚合任务,执行项目的完整构建。此任务由 Base Plugin 添加。

clean - 删除

删除构建目录及其中的所有内容,即由 layout.buildDirectory 项目属性指定的路径。此任务由 Base Plugin 添加。

依赖管理

与 C++ Library Plugin 创建的任务类似,根据库组件的变体创建了多个配置。请阅读构建变体简介以获取更多信息。下图描述了 C++ Library Plugin 添加的配置

cpp library configurations
图 4. C++ Library Plugin 配置
  • 白色背景的配置是用户应该用于声明依赖的配置

  • 粉色背景的配置(也称为可消费配置,标记为 (C))是组件编译、链接或运行时使用的配置

  • 蓝色背景的配置(也称为可解析配置,标记为 (R))是组件内部使用的配置

以下配置用于声明依赖

api

用于声明 API 依赖(参见API vs implementation 部分)。您应在此处声明可传递导出给消费者用于编译和链接的依赖。

implementation 扩展 api

用于声明主组件所有变体的 implementation 依赖(参见API vs implementation 部分)。您应在此处声明纯粹内部使用且不应暴露给任何变体消费者的依赖。

mainVariantImplementation (例如 mainDebugImplementationmainReleaseImplementation) 扩展 implementation

用于声明主组件特定变体的 implementation 依赖(参见API vs implementation 部分)。您应在此处声明纯粹内部使用且不应暴露给此特定变体消费者的依赖。

消费者使用以下配置

cppApiElements 扩展 mainVariantImplementation

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

variantLinkElements (例如 debugLinkElementsreleaseLinkElements) 扩展 mainVariantImplementation

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

variantRuntimeElements (例如 debugRuntimeElementsreleaseRuntimeElements) 扩展 `mainVariantImplementation

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

该库自身使用以下配置

cppCompileVariant (例如 cppCompileDebugcppCompileRelease) 扩展 mainVariantImplementation

用于编译该库。此配置包含该库的编译包含根路径,因此在调用 C++ 编译器编译时使用。

nativeLinkVariant (例如 nativeLinkDebugnativeLinkRelease) 扩展 mainVariantImplementation

仅用于链接库(共享库)。此配置包含该库的库文件,因此在调用 C++ 链接器进行链接时使用。

nativeRuntimeVariant (例如 nativeRuntimeDebugnativeRuntimeRelease) 扩展 mainVariantImplementation

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

API 对比 implementation

该插件暴露了两个可用于声明依赖的配置: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++ Library Plugin 添加了源文件和任务的约定,如下所示。

项目布局

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

src/main/cpp

扩展名为 .cpp, .C++.cc 的 C++ 源文件

src/main/headers

私有头文件 - 编译库所需的头文件,但消费者不需要

src/main/public

公共头文件 - 编译库所需的头文件,并且消费者需要

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

compileVariantCpp 任务

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

compilerArgs

[]

debuggable

true

includes

configurations.cppCompileVariant + library.publicHeaders + library.privateHeaders

macros

[:]

objectFileDir

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

optimized

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

positionIndependentCode

共享链接为 true,否则为 false

source

library.cppSource

systemIncludes

源自工具链

targetPlatform

源自二进制文件的 TargetMachine

toolChain

根据目标机器自动选择

C++ Library Plugin 为包含共享链接作为维度的库的每个变体添加一个 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 任务

C++ Library Plugin 为包含静态链接作为维度的库的每个变体添加一个 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

根据目标机器自动选择