How can I add a dependent task to a task created by a C plugin?

I have successfully created a build script to produce a native executable using the C plugin. I am stuck, though, in my attempt to create a dependency on a task that produces a flex output file from a flex input file.

Here is what I believe to be the essential part of the build script. I’ve commented out my attempts to declare the dependency.

apply plugin: 'c'

model {
    components {
        test(NativeExecutableSpec) {
            sources {
                c {
                    source {
                        srcDir "."
                        include "*.c"

task compileLang (type: Exec) {
    commandLine 'flex', '-f', '-L', '-8', '-i', '-P', 'test', 'test.l'

//buildDependentsTestExecutable.dependsOn compileLang
//project.task('buildDependentsTestExecutable').dependsOn compileLang
//project.tasks.getByName('buildDependentsTestExecutable').dependsOn compileLang

Here are what I believe to be the relevant tasks configured when I execute ‘gradle tasks’:

Build tasks
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
clean - Deletes the build directory.
installTestExecutable - Installs a development image of executable 'test:executable'
testExecutable - Assembles executable 'test:executable'.

Build Dependents tasks
assembleDependentsTest - Assemble dependents of native executable 'test'.
assembleDependentsTestExecutable - Assemble dependents of executable 'test:executable'.
buildDependentsTest - Build dependents of native executable 'test'.
buildDependentsTestExecutable - Build dependents of executable 'test:executable'.

Can you describe how and what is not working?
Do you get an error when you try any of those attempts to add the dependent task?

When I uncomment the the first commented line

//buildDependentsTestExecutable.dependsOn compileLang

then I see this:

$ gradle build

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/jholt/gradle/build.gradle' line: 24

* What went wrong:
A problem occurred evaluating root project 'gradle'.
> Could not get unknown property 'buildDependentsTestExecutable' for root project 'gradle' of type org.gradle.api.Project.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at


When I uncomment the 2nd commented line

//project.task(‘buildDependentsTestExecutable’).dependsOn compileLang

then I see this (indicating that it never executed the dependent task because there’s no lex.test.c that was created and included in the compiling and linking)

$ gradle build

> Task :linkTestExecutable FAILED
Undefined symbols for architecture x86_64:
  "_testwrap", referenced from:
      _main in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':linkTestExecutable'.
> A build operation failed.
      Linker failed while linking test.
  See the complete log at: file:///Users/jholt/gradle/build/tmp/linkTestExecutable/output.txt
   > Linker failed while linking test.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at

2 actionable tasks: 1 executed, 1 up-to-date

When I uncommented the 3rd commented line

//project.tasks.getByName(‘buildDependentsTestExecutable’).dependsOn compileLang

then I get the same error that I got when I uncommented the 1st commented line.

Attached are the files in the directory. All you need to reproduce the critical part of my environment is gradle, a toolchain, and (913 Bytes)

Let me rephrase what I want.

I have a project with a main c program that calls a lexical analyzer that is stored in a .l file. That .l file has to be converted into a .c file before the compilation takes place. That means the model has to be evaluated as if its source file is the .l file but that it has to run a filter to produce the lex.test.c file before compilation starts.

And what I truly desire is something simple. I don’t want to have more than one build script as that would presumably increase the brittleness of the solution. I, in fact, already have a working solution that uses two build scripts and I hate it.

Thanks for the example! The task seems to be created at a later phase of the Gradle’s configuration phase. I suggest adding a listener on the tasks container and it worked for me on your example:

project.tasks.whenObjectAdded { Task t -> 
    println 'Task added: ' +
    if ('buildDependentsTestExecutable'.equals( {
        t.dependsOn compileLang

I’m not familiar with the ‘c’ plugin or with the model{} configuration, so my suggestion is based on the general familiarity I’ve with Gradle.

1 Like

“I’m not familiar”

Me too and I’m betting we are members of a high cardinality set.

Your suggestion works but I had to change the task name from ‘buildDependentsTestExecutable’ to ‘compileTestExecutableTestC’ before it worked fully.

I tested the incremental build nature (i.e., changing test.c or test.l) and subsequent builds do the expected things and skips tasks when I expect them to be up-to-date and it executes them when I expect them not to be up-to-date.

I missed methods returned by Project.getTasks (that returns a TaskContainer), that are inherited by org.gradle.api.DomainObjectCollection.

I got frustrated by an apparently lack of attention at this site and asked an SO question. If you post your answer at, then I’ll accept it and upvote it and you’ll get the bounty.