What you’ll build

This guide demonstrates how to create a minimalist C executable using Gradle’s c plugin.

What you’ll need

Layout

The first step is to create a folder for the new project and add a Gradle Wrapper to the project.

$ mkdir c-executable
$ cd c-executable
$ gradle wrapper (1)

:wrapper

BUILD SUCCESSFUL
1 This allows a version of Gradle to be locked to a project and henceforth you can use ./gradlew instead of gradle.

Create a minimalist build.gradle file with the following content:

build.gradle
apply plugin : 'c' (1)

model { (2)
    components {
        main(NativeExecutableSpec)  (3) (4)
    }
}
1 C projects are enabled via the c plugin
2 All native build definitions are done within a model block.
3 A native executable component is defined by a name - main in this case. This will determine the default location of source code, as well as the final name of the executable.
4 An executable is specified by using NativeExecutableSpec.

If you run

$ ./gradlew tasks

you will see in the output that Gradle has added a number of tasks

installMainExecutable - Installs a development image of executable 'main:executable'
mainExecutable - Assembles executable 'main:executable'.

Build Dependents tasks
----------------------
assembleDependentsMain - Assemble dependents of native executable 'main'.
assembleDependentsMainExecutable - Assemble dependents of executable 'main:executable'.
buildDependentsMain - Build dependents of native executable 'main'.
buildDependentsMainExecutable - Build dependents of executable 'main:executable'.

Note the use of Main in the task names which are a direct deriviative of the component being called main.

Add source code

By convention, C projects in Gradle will follow a more contemporary layout. This can be troublesome for you if you are used to building C code with build tools that do not use a convention-over-configuration approach. Rest assured that Gradle is very configurable in this regard and should you need to migrate a C project to Gradle you can consult the C sources section of the User Guide.

In the build.gradle you have previsouly defined the executable component to be called main. By convention, this will means that Gradle will look in src/main/c for source files and non-exported header files. Create this folder

$ mkdir -p src/main/c

and place a main.c an a greeting.h within.

src/main/c/main.c
#include <stdio.h>  (1)
#include "greeting.h" (2)

int main(int argc, char** argv) {
    printf( "%s\n", GREETING_STRING);
    return 0;
}
1 The standard C headers wil be located via the compiler toolchain that Gradle uses
2 Non-exported headers will be searched for relative to the specified C source folders. (In this case src/main/c).
src/main/c/greeting.h
#ifndef GRADLE_GUIDE_EXAMPLE_GREETING_H__
#define GRADLE_GUIDE_EXAMPLE_GREETING_H__

#define GREETING_STRING "Hello, World"

#endif

Build your project

To build your project you can simply do ./gradlew build as per usual, but if you specifically want to build the executable, run the task that Gradle has created for you:

$ ./gradlew mainExecutable

:compileMainExecutableMainC (1)
:linkMainExecutable (2)
:mainExecutable

BUILD SUCCESSFUL
1 To keep things tidy on the console, Gradle does not display compiler output. If you need to ever diagnose a compilation issue, the output from the compiler is stored in build/tmp/compileMainExecutableMainC/output.txt.
2 In a similar fashion the output from the linker is written to build/tmp/linkMainExecutable/output.txt

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

Now run your newly built executable.

$ ./build/exe/main/main

Hello World

Congratulations! You have just built a C executable with Gradle.

Summary

You have created an C project that can be used as a foundation for something more substantial. In the process you saw:

  • How to create a build script for C executables.

  • Where to add source code by convention.

  • How to build the executable without building the full project.

Next Steps

  • Testing using CUnit or GoogleTest is supported. Gradle will respectively create a matching CUnitTestSuiteSpec or GoogleTestTestSuiteSpec component for the executable you have defined in this guide. See the CUnit support and GoogleTest support sections in the User Guide for more details.

  • As there is no 'standard' way of creating documentation for C projects, the c plugin does not offer a task to generate documentation. If you do use the popular Doxygen tool for documenting C code, you may want to have a look at the Doxygen plugin for Gradle

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-c-executables and we’ll get back to you.