# Chapter 47. C++ Support

The Gradle C++ support is in very early stages of development. Please be aware that the DSL and other configuration may change in later Gradle versions.

The C++ plugins add support for building software comprised of C++ source code, and managing the process of building “native” software in general. While many excellent build tools exist for this space of software development, Gradle brings the dependency management practices more traditionally found in the JVM development space to C++ developers.

The following platforms are supported:

Operating System | Compiler | Notes
Linux | GCC | Tested with GCC 4.6.1 on Ubuntu 11.10
Mac OS X | GCC | Tested with XCode 4.2.1 on OS X 10.7
Windows | Visual C++ | Tested with Windows 7 and Visual C++ 2010
Windows | MinGW | Tested with Windows 7 and MinGW 4.6.2. Note: G++ support is currently broken under cygwin

Currently, there is no direct support for creating multiple variants of the same binary (e.g. 32 bit vs. 64 bit) and there is no direct support for cross platform source configuration (à la autoconf) at this time. Support for different compiler chains, managing multiple variants and cross platform source configuration will be added over time, making Gradle a fully capable build tool for C++ (and other “native” language) projects.

## 47.1. Usage

The build scripts DSLs, model elements and tasks used to manage C++ projects are added by the `cpp` plugin. However, it is typically more convenient to use either the `cpp-lib` or `cpp-exe` plugins that sit on top of the `cpp` plugin to preconfigure the project to build either a shared library or executable binary respectively.

Example 47.1. Using the 'cpp-exe' plugin

`build.gradle`

    apply plugin: "cpp-exe"

Example 47.2. Using the 'cpp-lib' plugin

`build.gradle`

    apply plugin: "cpp-lib"

The `cpp-exe` plugin configures the project to build a single executable (at ``$buildDir`/binaries/`$project.name``) and the `cpp-lib` plugin configures the project to build a single shared library (at ``$buildDir`/binaries/lib`$project.name`.so`).

## 47.2. Source code locations

Both plugins configure the project to look for `.cpp` and `.c` source files in `src/main/cpp` and use the `src/main/headers` directory as a header include root. For a library, the header files in `src/main/headers` are considered the “public” or “exported” headers. Header files that should not be exported (but are used internally) should be placed inside the `src/main/cpp` directory (though be aware that such header files should always be referenced in a manner relative to the file including them).

The `cpp` plugin is also very flexible in where it looks for source and header files, aand you can configure the above conventions to look however you like.

## 47.3. Compiling

For both the `cpp-lib` and `cpp-exe` plugins, you can run `gradle compileMain` to compile and link the binary.

### 47.3.1. Compiling on UNIX

The UNIX C++ support is currently based on the `g++` tool which must be installed and on the `PATH` for the Gradle process.

### 47.3.2. Compiling on Windows

The Windows C++ support can use either the MinGW `g++` or the Microsoft Visual C++ `cl` tool, either of which must be installed and on the `PATH` for the Gradle process. Gradle searches first for Microsoft Visual C++, and then MinGW.

## 47.4. Configuring the compiler

Arbitrary arguments can be provided to the compiler by using the following syntax:

Example 47.3. Supplying arbitrary args to the compiler

`build.gradle`

    executables {
        main {
            spec {
                args "-fno-access-control", "-fconserve-space"
            }
        }
    }

The above example applies to the `cpp-exe` plugin, to supply arguments for the `cpp-lib` plugin replace “`executables`” with “`libraries`”.

## 47.5. Working with shared libraries

The C++ plugin provides an `installMain` task, which creates a development install of the executable, along with the shared libraries it requires. This allows you to run the executable without needing to install the shared libraries in their final locations.

## 47.6. Dependencies

Dependencies for C++ projects are binary libraries that export header files. The header files are used during compilation, with the compiled binary dependency being used during the linking.

### 47.6.1. External Dependencies

External dependencies (i.e. from a repository, not a subproject) must be specified using the following syntax:

Example 47.4. Declaring dependencies

`build.gradle`

    cpp {
        sourceSets {
            main {
                dependency group: "some-org", name: "some-lib", version: "1.0"
            }
        }
    }

Each dependency must be specified with the `dependency` method as above and must be declared as part of the source set. The `group`, `name` and `version` arguments must be supplied.

For each declared dependency, two actual dependencies are created. One with the classifier “`headers`” and extension “`zip`” which is a zip file of the exported headers, and another with the classifier “`so`” and extension “`so`” which is the compiled library binary to link against (which is supplied as a direct input to the g++ link operation).

### 47.6.2. Project Dependencies

The notation for project dependencies is slightly different.

Example 47.5. Declaring project dependencies

`build.gradle`

    project(":lib") {
        apply plugin: "cpp-lib"
    }

    project(":exe") {
        apply plugin: "cpp-exe"
        cpp {
            sourceSets {
                main {
                    libs << project(":lib").libraries.main
                }
            }
        }
    }

## 47.7. Publishing

The `cpp-exe` and `cpp-lib` plugins configure their respective output binaries to be publishable as part of the `archives` configuration. To publish, simply configure the `uploadArchives` task as per usual.

Example 47.6. Uploading exe or lib

`build.gradle`

    group = "some-org"
    archivesBaseName = "some-lib"
    version = 1.0

    uploadArchives {
        repositories {
            mavenDeployer {
                repository(url: uri("${buildDir}/repo"))
            }
        }
    }

The `cpp-exe` plugin publishes a single artifact with extension “`exe`”. The `cpp-lib` plugin publishes two artifacts; one with classifier “`headers`” and extension “`zip`”, and one with classifier “`so`” and extension “`so`” (which is the format used when consuming dependencies).

Currently, there is no support for publishing the dependencies of artifacts in POM or Ivy files. Future versions will support this.