This guide demonstrates how to use Gradle’s Build Init plugin to produce a C++ application that follows Gradle conventions.

What you’ll need

Check the user manual

Gradle comes with a built-in plugin called the Build Init plugin. It is documented in the Gradle User Manual. The plugin provides a task, called init, that generates the project. The plugin also uses the (also built-in) wrapper task to create a Gradle wrapper script, gradlew.

Setup

The first step is to create a folder for the new project and change directory into it.

$ mkdir building-cpp-applications
$ cd building-cpp-applications

Run the init task

From inside the new project directory, run the init task and select cpp-application project type when prompted. For the other questions, press enter to use the default values.

$ gradle init

Select type of project to generate:
  1: basic
  2: cpp-application
  3: cpp-library
  4: groovy-application
  5: groovy-library
  6: java-application
  7: java-library
  8: kotlin-application
  9: kotlin-library
  10: scala-library
Enter selection (default: basic) [1..10] 2

Select build script DSL:
  1: groovy
  2: kotlin
Enter selection (default: groovy) [1..2]

Project name (default: building-cpp-applications):

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

If you prefer the Kotlin DSL, you can select kotlin for the build script DSL.

The init task runs the wrapper task first, which generates the gradlew and gradlew.bat wrapper scripts. Then it creates the new project with the following structure:

├── build.gradle
├── gradle    (1)
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── cpp      (2)
    │   │   └── app.cpp
    │   └── headers  (3)
    │       └── app.h
    └── test         (4)
        └── cpp
            └── app_test.cpp
├── build.gradle.kts
├── gradle    (1)
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
└── src
    ├── main
    │   ├── cpp      (2)
    │   │   └── app.cpp
    │   └── headers  (3)
    │       └── app.h
    └── test         (4)
        └── cpp
            └── app_test.cpp
1 Generated folder for wrapper files
2 Default C++ source folder
3 Default C++ header folder
4 Default C++ test folder
The Gradle source layout convention can be customize to fit any source layout. See customizing C++ source section of the C++ chapter in User Manual as well as the custom source layout sample for a demonstration.

Review the generated project files

The settings.gradle file is heavily commented, but has only one active line:

settings.gradle
/*
 * This file was generated by the Gradle 'init' task.
 *
 * The settings file is used to specify which projects to include in your build.
 *
 * Detailed information about configuring a multi-project build in Gradle can be found
 * in the user manual at https://docs.gradle.org/5.3/userguide/multi_project_builds.html
 */

rootProject.name = 'building-cpp-applications'
settings.gradle.kts
/*
 * This file was generated by the Gradle 'init' task.
 *
 * The settings file is used to specify which projects to include in your build.
 *
 * Detailed information about configuring a multi-project build in Gradle can be found
 * in the user manual at https://docs.gradle.org/5.3/userguide/multi_project_builds.html
 */

rootProject.name = "building-cpp-applications"

This sets the name of the root project to "building-cpp-applications", which overrides the default behavior of naming the project after the directory it’s in.

The generated build.gradle file also has many comments. The active portion is reproduced here:

build.gradle
/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample CPP project to get you started.
 */

plugins {
    // Apply the cpp-application plugin to add support for building CPP applications
    id 'cpp-application'

    // Apply the cpp-unit-test plugin to add support for building and running CPP test applications
    id 'cpp-unit-test'
}

// Set the target operating system and architecture for this application
application {
    targetMachines.add(machines.macOS.x86_64)
}
build.gradle.kts
/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample CPP project to get you started.
 */

plugins {
    // Apply the cpp-application plugin to add support for building CPP applications
    `cpp-application`

    // Apply the cpp-unit-test plugin to add support for building and running CPP test applications
    `cpp-unit-test`
}

// Set the target operating system and architecture for this application
application {
    targetMachines.add(machines.macOS.x86_64)
}

The build file adds the cpp-application and cpp-unit-test plugins:

  • The cpp-application plugin automatically generates application component configurable via application extension DSL.

  • The cpp-unit-test plugin automatically generates a executable component that depends on the application. It also adds a new verification task. The verification tasks are check tasks that assemble and test a binary. The unit test component configurable via the unitTest extension DSL.

The file src/main/cpp/app.cpp is shown here:

src/main/cpp/app.cpp
/*
 * This C++ source file was generated by the Gradle 'init' task.
 */

#include <iostream>
#include <stdlib.h>
#include "app.h"

std::string building_cpp_applications::Greeter::greeting() {
    return std::string("Hello, World!");
}

int main () {
    building_cpp_applications::Greeter greeter;
    std::cout << greeter.greeting() << std::endl;
    return 0;
}

The exported header, src/main/headers/app.h is shown here:

src/main/headers/app.h
/*
 * This C++ source file was generated by the Gradle 'init' task.
 */
#ifndef APP_H
#define APP_H

#include <string>

namespace building_cpp_applications {
    class Greeter {
        public:
        std::string greeting();
    };
}

#endif

The test application, src/test/cpp/app_test.cpp is shown next:

src/test/cpp/app_test.cpp
/*
 * This C++ source file was generated by the Gradle 'init' task.
 */

#include "app.h"
#include <cassert>

int main() {
    building_cpp_applications::Greeter greeter;
    assert(greeter.greeting().compare("Hello, World!") == 0);
    return 0;
}

The generated test file has a single test using the standard library assert function. The test instantiates the Greeter class, invokes the greeting() method, and checks that the returned value is equals to the expected string.

The cpp-unit-test plugin can also be used to test your application binaries using Google Test as demonstrated in the simple library sample.

Execute the build

To build the project, run the build task. You can use the regular gradle command, but when a project includes a wrapper script, it is considered good form to use it instead.

$ ./gradlew build
> Task :compileTestCpp
> Task :compileDebugCpp
> Task :relocateMainForTest
> Task :linkDebug
> Task :installDebug
> Task :assemble
> Task :linkTest
> Task :installTest
> Task :runTest
> Task :test
> Task :check
> Task :build

BUILD SUCCESSFUL
8 actionable tasks: 8 executed
The first time you run the wrapper script, gradlew, there may be a delay while that version of gradle is downloaded and stored locally in your ~/.gradle/wrapper/dists folder.

The build task compiles the C++ sources, link the object files, and runs the tests.

Dependencies to other projects isn’t covered in this guide. To learn more about that subject, have a look at the transitive dependency sample for a demonstration.
Gradle integrate with several IDEs: Visual Studio, Xcode and Clion. To learn more, have a look at their respective linked documentation to configure those IDE integration in your project.

Application package

As part of the the build process, Gradle package the main and test application for distribution on other system. The installDebug and installTest task copies the executable and generate a shell script for executing the application. The following listing shows the content of the build/install folder:

├── main
│   └── debug
│       ├── building-cpp-applications      (1)
│       └── lib
│           └── building-cpp-applications  (2)
└── test
    ├── building-cpp-applicationsTest      (1)
    └── lib
        └── building-cpp-applicationsTest  (3)
1 The script for executing the application variant
2 The main executable binary (debug variant)
3 The test executable binary
When a build has dependencies, every dependent shared libraries are also copied into the installation folder. The shell scripts then properly configure the library path so the package can be relocated. Have a look at the transitive dependency sample for a demonstration.

Run the application

Look inside the build folder and you will notice the appearance of a exe folder. By convention Gradle will place all applications in subfolders named according to the component name. In this case you will find your assembled executable in build/exe/main/debug and it will be called building-cpp-applications (or building-cpp-applications.exe under Windows).

Now run your newly built executable.

$ ./build/exe/main/debug/building-cpp-applications
Hello, World!

Summary

You have created an C++ application with unit tests. In doing so, you saw:

  • How to generate a C++ application

  • How the generate build file and sample C++ files are structured

  • How to run the build with it’s tests

  • How to execute the application from the command line

Next Steps

Help improve this guide

Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to gradle-guides/building-cpp-applications and we’ll get back to you.