【gradle插件系列】C++库插件
文章目录
使用
要使用C++库插件,请在构建脚本中包含以下内容:
plugins {
id 'cpp-library'
}
C++库插件提供了构建C++库所需的任务和约定。特别地,C++库提供了可以被消费者(即使用此插件或C++应用程序插件的其他项目)使用的功能。
构建变体
C++库插件理解以下维度。有关更多信息,请阅读构建变体介绍。
-
构建类型:始终设置为debug和release
- debug:生成调试符号,并且不对二进制文件进行优化
- release:生成调试符号并进行优化,但从二进制文件中提取调试符号
-
链接方式:默认为shared
- 链接方式表示是创建共享库还是静态库。库可以产生共享库、静态库或两者。
可以通过以下方式配置链接方式:
library {
linkage = [Linkage.STATIC, Linkage.SHARED]
}
目标机器
目标机器表示应用程序期望运行的机器。目标机器由其操作系统和体系结构标识。Gradle根据主机上的可用性选择工具链时,使用目标机器来决定选择哪个工具链。
可以通过以下方式配置目标机器:
library {
targetMachines = [
machines.linux.x86_64,
machines.windows.x86, machines.windows.x86_64,
machines.macOS.x86_64
]
}
任务
下图显示了该插件添加的任务之间的关系。
请注意,C++库的默认链接方式是shared链接方式,如图所示。
使用静态链接时,图表变为以下形式:
变体相关任务
C++库插件基于库组件的变体创建任务。有关更多信息,请阅读构建变体介绍。下图显示了变体相关任务之间的关系。
根据链接方式属性的不同:
- compileVariantCpp(例如compileDebugCpp和compileReleaseCpp) - CppCompile
- 依赖于所有贡献源文件到编译中的任务 :: 使用选择的编译器编译C++源文件。
- linkVariant(例如linkDebug和linkRelease) - LinkSharedLibrary(共享链接方式)
- 依赖于所有贡献到链接库的任务,包括来自通过项目依赖解析的项目的linkVariant和createVariant任务 :: 使用选择的链接器从已编译的目标文件链接共享库。
- createVariant(例如createDebug和createRelease) - CreateStaticLibrary(静态链接方式)
- 使用选择的归档工具从已编译的目标文件创建静态库。
- assembleVariant(例如assembleDebug和assembleRelease) - Task(生命周期)
- 依赖于linkVariant(共享链接方式)或createVariant(静态链接方式) :: 聚合组装特定变体的所有任务。
生命周期任务
C++库插件将一些任务附加到Base插件文档中记录的标准生命周期任务上 - C++库插件会自动应用这些任务:
- assemble - Task(生命周期)
- 依赖于linkDebug(当链接方式包括共享链接时)或createDebug(否则) :: 聚合任务,为当前主机(如果存在)中的共享库的调试变体组装库。该任务由Base插件添加。
- check - Task(生命周期)
- 执行验证任务的聚合任务,例如运行测试。一些插件会将自己的验证任务添加到check中。例如,C++单元测试插件会将其测试任务附加到此生命周期任务。该任务由Base插件添加。
- build - Task(生命周期)
- 依赖于check、assemble :: 执行项目的完整构建的聚合任务。该任务由Base插件添加。
- clean - Delete
- 删除构建目录及其内容,即Project.getBuildDir()项目属性指定的路径。该任务由Base插件添加。
依赖管理
与C++库插件创建的任务一样,基于库组件的变体也创建了多个配置。有关更多信息,请阅读构建变体介绍。下图描述了C++库插件添加的配置:
白色配置是用户应该用于声明依赖项的配置;粉色配置(用©表示)是在编译、链接或运行时使用的配置;蓝色配置(用®表示)是组件内部使用的配置。
以下配置用于声明依赖项:
- api:用于声明API依赖项(参见API vs implementation部分)。在这里声明传递给消费者的依赖项,用于编译和链接。
- implementation扩展自api:用于声明主组件所有变体的实现依赖项(参见API vs implementation部分)。在这里声明纯粹为内部使用且不暴露给任何变体的消费者的依赖项。
- mainVariantImplementation(例如mainDebugImplementation和mainReleaseImplementation)扩展自implementation:用于声明主组件特定变体的实现依赖项(参见API vs implementation部分)。在这里声明纯粹为内部使用且不暴露给此特定变体的消费者的依赖项。
以下配置由消费者使用:
- cppApiElements扩展自mainVariantImplementation:用于编译针对库的代码。这个配置可用于消费者,以检索编译针对库所需的所有元素。
- variantLinkElements(例如debugLinkElements和releaseLinkElements)扩展自mainVariantImplementation:用于链接到库。这个配置可用于消费者,以检索链接到库所需的所有元素。
- variantRuntimeElements(例如debugRuntimeElements和releaseRuntimeElements)扩展自mainVariantImplementation:用于执行库。这个配置可用于消费者,以检索运行库所需的所有元素。
以下配置由库本身使用:
- cppCompileVariant(例如cppCompileDebug和cppCompileRelease)扩展自mainVariantImplementation:用于编译库。该配置包含库的编译包含根目录,并且在调用C++编译器进行编译时使用。
- nativeLinkVariant(例如nativeLinkDebug和nativeLinkRelease)扩展自mainVariantImplementation:用于链接库(仅适用于共享链接方式)。该配置包含库的库,并且在调用C++链接器进行链接时使用。
- nativeRuntimeVariant(例如nativeRuntimeDebug和nativeRuntimeRelease)扩展自mainVariantImplementation:用于执行库。该配置包含库的运行时库。
API vs implementation
该插件公开了两个配置,可以用来声明依赖项:api和implementation。api配置应该用于声明库API导出的依赖项,而implementation配置应该用于声明组件内部使用的依赖项。
例如:
library {
dependencies {
api "io.qt:core:5.1"
implementation "io.qt:network:5.1"
}
}
在api配置中出现的依赖项将传递给库的消费者,因此它们将出现在消费者的编译包含根目录和链接库中。而在implementation配置中找到的依赖项则不会传递给消费者,因此它们不会泄漏到消费者的编译包含根目录和链接库中。这带来了几个好处:
- 依赖项不会泄漏到消费者的编译包含根目录和链接库中,因此它们永远不会意外地依赖于传递依赖项
- 减少了编译时的时间,因为编译包含根目录和链接库减少了
- 当实现依赖项更改时,重新编译更少,因为不需要重新编译消费者
约定
C++库插件添加了源代码和任务的约定,如下所示。
项目布局
C++库插件假设以下项目布局。这些目录无需存在或包含任何内容。C++库插件将编译找到的所有内容,并忽略任何缺失的内容。
- src/main/cpp:C++源代码,扩展名为.cpp、.C++或.cc
- src/main/headers:私有头文件,用于编译库但不需要由消费者使用
- src/main/public:公共头文件,用于编译库并且消费者需要使用
您可以通过配置library脚本块上的source、privateHeaders和publicHeaders来配置项目布局。
compileVariantCpp任务
C++库插件为每个库组件的变体添加了CppCompile实例,以进行构建(例如compileDebugCpp和compileReleaseCpp)。有关更多信息,请阅读构建变体介绍。下面显示了一些常见的配置选项。
- compilerArgs:[]
- debuggable:true
- includes:configurations.cppCompileVariant + library.publicHeaders + library.privateHeaders
- macros:[:]
- objectFileDir:$buildDir/obj/main/variant
- optimized:对于debug构建类型为false,否则为true
- positionIndependentCode:对于共享链接方式为true,否则为false
- source:library.cppSource
- systemIncludes:根据工具链推导得出
- targetPlatform:根据二进制文件的TargetMachine推导得出
- toolChain:根据目标机器自动选择
linkVariant任务
C++库插件为每个包含共享链接方式作为维度的库的变体(例如linkDebug和linkRelease)添加了LinkSharedLibrary实例。有关更多信息,请阅读构建变体介绍。下面显示了一些常见的配置选项。
- debuggable:true
- libs:configurations.nativeLinkVariant
- linkedFile: b u i l d D i r / l i b / m a i n / v a r i a n t / l i b B a s e N a m e [ . s o ∣ d y l i b ] ( ∗ n i x )或 buildDir/lib/main/variant/libBaseName[.so|dylib](*nix)或 buildDir/lib/main/variant/libBaseName[.so∣dylib](∗nix)或buildDir\lib\main\variant\baseName.dll(Windows)
- linkerArgs:[]
- source:compileVariantCpp.objects
- targetPlatform:根据二进制文件的TargetMachine推导得出
- toolChain:根据目标机器自动选择
createVariant任务
C++库插件为每个包含静态链接方式作为维度的库的变体(例如createDebug和createRelease)添加了CreateStaticLibrary实例。有关更多信息,请阅读构建变体介绍。下面显示了一些常见的配置选项。
- outputFile: b u i l d D i r / l i b / m a i n / v a r i a n t / l i b B a s e N a m e . a ( ∗ n i x )或 buildDir/lib/main/variant/libBaseName.a(*nix)或 buildDir/lib/main/variant/libBaseName.a(∗nix)或buildDir\lib\main\variant\baseName.lib(Windows)
- source:compileVariantCpp.objects
- staticLibArgs:[]
- targetPlatform:根据二进制文件的TargetMachine推导得出
- toolChain:根据目标机器自动选择