// Copyright (C) 2024 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[cpp_application_plugin]]
= {cpp} Application

The {cpp} Application Plugin provides the tasks, configurations and conventions for a building {cpp} application.

[[sec:cpp_application_usage]]
== Usage

====
include::sample[dir="snippets/cpp/cppApplication/kotlin",files="build.gradle.kts[tags=apply-plugin]"]
include::sample[dir="snippets/cpp/cppApplication/groovy",files="build.gradle[tags=apply-plugin]"]
====

[[sec:cpp_application_build_variants]]
== Build variants

The {cpp} Application Plugin understands the following dimensions.
Read the <<building_cpp_projects.adoc#sec:introducing_build_variants-cpp,introduction to build variants>> for more information.

Build types - always either _debug_ or _release_::
The build type controls the debuggability as well as the optimization of the generated binaries.
- `debug` - Generate debug symbols and don’t optimized the binary
- `release` - Generate debug symbols and optimize, but extract the debug symbols from the binary

Target machines - defaults to the build host::
The target machine expresses which machines the application expects to run.
A target machine is identified by its operating system and architecture.
Gradle uses the target machine to decide which tool chain to choose based on availability on the host machine.

The target machine can be configured as follows:

====
include::sample[dir="snippets/cpp/cppApplication/kotlin",files="build.gradle.kts[tags=configure-target-machines]"]
include::sample[dir="snippets/cpp/cppApplication/groovy",files="build.gradle[tags=configure-target-machines]"]
====

[[sec:cpp_application_tasks]]
== Tasks

The following diagram shows the relationships between tasks added by this plugin.

.{cpp} Application Plugin default task graph
image::cpp-application-task-graph.png[]

[[sec:cpp_application_task_variants]]
=== Variant-dependent Tasks

The {cpp} Application Plugin creates tasks based on the variants of the application component.
Read the <<building_cpp_projects.adoc#sec:introducing_build_variants-cpp,introduction to build variants>> for more information.
The following diagram shows the relationship between variant-dependent tasks.

.{cpp} Application Plugin variant-dependent task graph
image::cpp-application-variant-task-graph.png[]

`compile__Variant__Cpp` (e.g. `compileDebugCpp` and `compileReleaseCpp`)  - link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html[CppCompile]::
Depends on: All tasks that contribute source files to the compilation
::
Compiles {cpp} source files using the selected compiler.

`link__Variant__` (e.g. `linkDebug` and `linkRelease`) - link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html[LinkExecutable]::
Depends on: All tasks which contribute to the link executable, including `link__Variant__` and `create__Variant__` tasks from projects that are resolved via project dependencies
::
Links executable from compiled object files using the selected linker.

`install__Variant__` (e.g. `installDebug` and `installRelease`) - link:{groovyDslPath}/org.gradle.nativeplatform.tasks.InstallExecutable.html[InstallExecutable]::
Depends on: `link__Variant__` and all tasks which contribute to the runtime of the executable, including `link__Variant__` tasks from projects that are resolved via project dependencies
::
Installs the executable and all of it's runtime dependencies for easy execution.

`assemble__Variant__` (e.g. `assembleDebug` and `assembleRelease`) - Task (lifecycle)::
Depends on: `link__Variant__`
::
Aggregates tasks that assemble the specific variant of this application.

[[sec:cpp_application_lifecycle_tasks]]
=== Lifecycle Tasks

The {cpp} Application Plugin attaches some of its tasks to the standard lifecycle tasks documented in the <<base_plugin.adoc#base_plugin,Base Plugin chapter>> - which the {cpp} Application Plugin applies automatically:

`assemble` - Task (lifecycle)::
Depends on: `linkDebug`
::
Aggregate task that assembles the debug variant of the application for the current host (if present) in the project.
This task is added by the <<base_plugin.adoc#base_plugin,Base Plugin>>.

`check` - Task (lifecycle)::
Aggregate task that performs verification tasks, such as running the tests.
Some plugins add their own verification task to `check`.
For example, the <<cpp_unit_test_plugin.adoc#cpp_unit_test_plugin,{cpp} Unit Test Plugin>> attaches a task to this lifecycle task to run tests.
This task is added by the <<base_plugin.adoc#base_plugin,Base Plugin>>.

`build` - Task (lifecycle)::
Depends on: `check`, `assemble`
::
Aggregate tasks that perform a full build of the project.
This task is added by the <<base_plugin.adoc#base_plugin,Base Plugin>>.

`clean` - Delete::
Deletes the build directory and everything in it, i.e. the path specified by the `layout.buildDirectory` project property.
This task is added by the <<base_plugin.adoc#base_plugin,Base Plugin>>.

[[sec:cpp_application_dependency_management]]
== Dependency management

Just like the tasks created by the {cpp} Application Plugin, multiple configurations are created based on the variants of the application component.
Read the <<building_cpp_projects.adoc#sec:introducing_build_variants-cpp,introduction to build variants>> for more information.
The following graph describes the configurations added by the {cpp} Application Plugin:

.{cpp} Application Plugin configurations
image::cpp-application-configurations.png[]

* The configurations in white are the ones a user should use to declare dependencies
* The configurations in pink, also known as consumable denoted by \(C), are the ones used when a component runs against the library
* The configurations in blue, also known as resolvable denoted by \(R), are internal to the component, for its own use

The following configurations are used to declare dependencies:

`implementation`::
Used for declaring implementation dependencies for all variants of the main component.
This is where you should declare dependencies of any variants.

`main__Variant__Implementation` (e.g. `mainDebugImplementation` and `mainReleaseImplementation`) extends `implementation`::
Used for declaring implementation dependencies for a specific variant of the main component.
This is where you should declare dependencies of the specific variant.

The following configurations are used by downstream consumers that depend on the application component:

`__variant__RuntimeElements` (e.g. `debugRuntimeElements` and `releaseRuntimeElements) extends `main__Variant__Implementation`::
Used for executing the application.
This configuration is meant to be used by consumers, to retrieve all the elements necessary to run the application.

The following configurations are used by the application itself:

`cppCompile__Variant__` (e.g. `cppCompileDebug` and `cppCompileRelease`) extends `main__Variant__Implementation`::
Used for compiling the application.
This configuration contains the compile include roots of the application and is therefore used when invoking the {cpp} compiler to compile it.

`nativeLink__Variant__` (e.g. `nativeLinkDebug` and `nativeLinkRelease`) extends `main__Variant__Implementation`::
Used for linking the application.
This configuration contains the libraries of the application and is therefore used when invoking the {cpp} linker to link it.

`nativeRuntime__Variant__` (e.g. `nativeRuntimeDebug` and `nativeRuntimeRelease`) extends `main__Variant__Implementation`::
Used for executing the application.
This configuration contains the runtime libraries of the application.

[[sec:cpp_application_conventions]]
== Conventions

The {cpp} Application Plugin adds conventions for sources and tasks, shown below.

[[sec:cpp_application_layout]]
=== Project layout

The {cpp} Application Plugin assumes the project layout shown below.
None of these directories need to exist or have anything in them.
The {cpp} Application Plugin will compile whatever it finds and ignore anything missing.

`src/main/cpp`::
{cpp} source with extension of `.cpp`, `.c++` or `.cc`

`src/main/headers`::
Headers - headers needed to compile the application

You <<building_cpp_projects.adoc#sec:custom_cpp_source_set_paths,configure the project layout>> by configuring the `source` and `privateHeaders` respectively on the `application` script block.

[[sec:cpp_application_compile_task]]
=== `compile__Variant__Cpp` Task

The {cpp} Application Plugin adds a link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html[CppCompile] instance for each variant of the application component to build (e.g. `compileDebugCpp` and `compileReleaseCpp`).
Read the <<building_cpp_projects.adoc#sec:introducing_build_variants-cpp,introduction to build variants>> for more information.
Some of the most common configuration options are shown below.

[horizontal]
link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:compilerArgs[compilerArgs]:: []

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:debuggable[debuggable]:: `true`

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:includes[includes]:: `configurations.cppCompile__Variant__` + `application.privateHeaders`

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:macros[macros]:: [:]

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:objectFileDir[objectFileDir]:: `layout.buildDirectory.dir("obj/main/__$variant__")`

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:optimized[optimized]:: `false` for debug build type or `true` otherwise

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:positionIndependentCode[positionIndependentCode]:: `false`

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:source[source]:: `application.cppSource`

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:systemIncludes[systemIncludes]:: derived from the tool chain

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:targetPlatform[targetPlatform]:: derived from the `TargetMachine` of the binary

link:{groovyDslPath}/org.gradle.language.cpp.tasks.CppCompile.html#org.gradle.language.cpp.tasks.CppCompile:toolChain[toolChain]:: <<building_cpp_projects.adoc#sec:cpp_supported_tool_chain,automatically selected based on target machine>>

[[sec:cpp_application_link_task]]
=== `link__Variant__` Task

The {cpp} Application Plugin adds a link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html[LinkExecutable] instance for each variant of the application — e.g. `linkDebug` and `linkRelease`.
Read the <<building_cpp_projects.adoc#sec:introducing_build_variants-cpp,introduction to build variants>> for more information.
Some of the most common configuration options are shown below.

[horizontal]
link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:debuggable[debuggable]:: `true`

link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:libs[libs]:: `configurations.nativeLink__Variant__`

link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:linkedFile[linkedFile]:: `layout.buildDirectory.dir("exe/main/__$variant__/baseName")` (*nix) or `layout.buildDirectory.dir("exe\main{backslash}__$variant__\baseName.exe")` (Windows)

link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:linkerArgs[linkerArgs]:: []

link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:source[source]:: `compile__Variant__Cpp.objects`

link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:targetPlatform[targetPlatform]:: derived from the `TargetMachine` of the binary

link:{groovyDslPath}/org.gradle.nativeplatform.tasks.LinkExecutable.html#org.gradle.nativeplatform.tasks.LinkExecutable:toolChain[toolChain]:: <<building_cpp_projects.adoc#sec:cpp_supported_tool_chain,automatically selected based on target machine>>

[[sec:cpp_application_install_task]]
=== `install__Variant__` Task

The {cpp} Application Plugin adds a link:{groovyDslPath}/org.gradle.nativeplatform.tasks.InstallExecutable.html[InstallExecutable] instance for each variant of the test component — e.g. `installDebug` and `installRelease`.
Read the <<building_cpp_projects.adoc#sec:introducing_build_variants-cpp,introduction to build variants>> for more information.
There is no need to configure any properties on the task.
