# How to reference a native library task for adding dependencies, input files, etc

**URL:** <https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472>\
**Category:** Old Forum Archive\
**Created:** [January 19, 2015, 6:27pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472 "2015-01-19T18:27:00Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 19, 2015, 6:27pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/1 "2015-01-19T18:27:00Z")

</div>

When declaring a C++ binary library I also need to compile it against my Fortran library, which is not supported by Gradle. So I wrote a quick and dirty Fortran compile task with proper inputs/outputs. Now I need to make the C++ library depend on my fortran compile task but there is no C++ library task!

To be clear, the task exists, but it doesn’t exist until some later stage in the build process. This is not a problem for Java tasks created by the Java plugin - they exist early in the build process and can have dependencies and input files added - but this does seem to be a problem for native tasks created by native plugins like ‘cpp’.

How can I add dependencies and input files to my native tasks?

Here’s my Gradle script

```gradle
apply plugin: 'cpp'
  libraries {
    ibnativetest {}
}
  sources {
    ibnativetest {
        cpp {
            // Necessary because Gradle will compile _ALL_ files including Vim
            // hidden swap files (e.g., '.ibnativetest.cpp.swp')
            source {
                include '**/*.cpp'
            }
        }
    }
}
  task compileIBNativeTestFortran() {
    ext.objName = 'ib_native_test.o'
    ext.outputDir = file("$buildDir/fortran/ibnativetest")
    ext.src = file("src/ibnativetest/f95/ib_native_test.f95")
    ext.obj = file("$outputDir/$objName")
    outputs.dir outputDir
    outputs.file obj
    inputs.file src
    doLast {
        outputDir.exists() || outputDir.mkdirs()
        exec {
            workingDir outputDir
            commandLine 'gfortran', '-o', objName, '-c', src
        }
    }
}
  //*
def linkIbnativetestTask = tasks.getByName('linkIbnativetestSharedLibrary')
linkIbnativetestTask.dependsOn compileIBNativeTestFortran
linkIbnativetestTask.inputs.file compileIBNativeTestFortran.obj
//*/
  libraries {
    'ibnativetest-jni' {
        binaries.all {
            if ( toolChain in GccCompatibleToolChain ) {
                linker.args "-L$ibiGccLibPath", '-lgfortran',
                    compileIBNativeTestFortran.obj.toString()
            }
            if ( toolChain in VisualCpp ) {
                println "---- need to configure for Visual CPP!! ----"
            }
        }
    }
}

```

Here’s the relevant output:

> Task with name ‘linkIbnativetestSharedLibrary’ not found in project ‘:numerical\_toolkit’.

---

<div class="post-metadata">

**Author:** ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)\
**Post date:** [January 20, 2015, 2:11am UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/2 "2015-01-20T02:11:00Z")

</div>

You are correct, these tasks are created during a later stage of the configuration phase. In general, to reference these tasks, you need only nest your configuration inside a ‘model {…}’ block. Take a look at the [release notes](http://www.gradle.org/docs/2.2/release-notes#publishing-plugins-and-native-language-support-plugins-changes) for Gradle 2.2 for more info.

model {

tasks.linkIbnativetestTask {

dependsOn ‘compileIBNativeTestFortran’

}

}

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 20, 2015, 8:33pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/3 "2015-01-20T20:33:00Z")

</div>

This doesn’t work. Details below in my next comment.

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 20, 2015, 8:39pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/4 "2015-01-20T20:39:00Z")

</div>

I added this code per your suggestion:

```gradle
model {
    tasks.linkIbnativetestStaticLibrary {
        dependsOn compileIBNativeTestFortran
    }
}

```

The ‘linkIbnativetesStaticLibrary’ is of course the native library task defined by the ‘cpp’ plugin. The ‘compileIBNativeTestFortran’ is my task to compile F95 code.

The error I get is this:

```
* What went wrong: A problem occurred configuring project ':numerical_toolkit'. > The following model rules are unbound:

model.tasks.linkIbnativetestStaticLibrary

  Mutable:

 - tasks.linkIbnativetestStaticLibrary (java.lang.Object)
```

In fact, if I remove the ‘dependsOn’ line I still get this error.

---

<div class="post-metadata">

**Author:** ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)\
**Post date:** [January 20, 2015, 11:01pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/5 "2015-01-20T23:01:00Z")

</div>

Try this ( **do not** put in ‘model {…}’ block).

binaries.withType(StaticLibraryBinarySpec) {

binary.tasks.link.dependsOn compileIBNativeTestFortran

}

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 22, 2015, 2:40pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/6 "2015-01-22T14:40:00Z")

</div>

Right away, I’m guessing ‘binary’ should be ‘it’ or there should be a ‘binary -\>’ immediately after the open curly brace.

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 22, 2015, 2:47pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/7 "2015-01-22T14:47:00Z")

</div>

Thanks Mark!

You’re previous comment led me to a solution that works. Here is my solution:

```gradle
binaries.withType(SharedLibraryBinarySpec) {
    if (it.name == 'odrpack95-jniSharedLibrary') {
        it.tasks[0].dependsOn compileOdrSlimWrapFortran
        it.tasks[0].inputs.file compileOdrSlimWrapFortran.obj
    }
    if (it.name == 'ibnativetest-jniSharedLibrary') {
        it.tasks[0].dependsOn compileIBNativeTestFortran
        it.tasks[0].inputs.file compileIBNativeTestFortran.obj
    }
}

```

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 22, 2015, 2:48pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/8 "2015-01-22T14:48:00Z")

</div>

Also, there doesn’t seem to be a ‘link’ property on the ‘tasks’ object. I will use ‘tasks[0]’ instead… which isn’t the same and I can imagine would easily break in the future, but it works for now.

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 22, 2015, 2:52pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/9 "2015-01-22T14:52:00Z")

</div>

For anyone else reading these comments you’ll probably notice the switch between ‘shared’ and ‘static’ as well as my sometimes added ‘-jni’ suffix. Please pretend all those differences don’t exist 🙂 the examples are part of a larger build system where there are both shared and static libraries and most also have a JNI binary compiled after the library is compiled. I apologize for not being extra careful in keeping things consistent in the examples, and I hope you find the question and answers here useful.

---

<div class="post-metadata">

**Author:** ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)\
**Post date:** [January 22, 2015, 4:54pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/10 "2015-01-22T16:54:00Z")

</div>

You are correct, the ‘link’ property is only available on ‘NativeBinarySpec’ and it should be referencing ‘it’. This is a bit of a bastardized version of an integration test I found.

---

<div class="post-metadata">

**Author:** ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)\
**Post date:** [January 22, 2015, 4:58pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/11 "2015-01-22T16:58:00Z")

</div>

Jason, glad you got it working. I’d be a little uncomfortable referencing the task by index (unless I suppose there is only one). I’m not sure that ordering is deterministic or won’t change over time. I realize the task name is derived, perhaps something like ‘tasks.withType()’ would work and be a little less brittle.

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 22, 2015, 10:32pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/12 "2015-01-22T22:32:00Z")

</div>

I _am_ uneasy referencing the task by index! I didn’t think to use ‘withType’, I’ll try that.

---

<div class="post-metadata">

**Author:** ![Jason\_Zwolak](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@Jason\_Zwolak](https://discuss.gradle.org/u/Jason_Zwolak)\
**Post date:** [January 22, 2015, 10:38pm UTC](https://discuss.gradle.org/t/how-to-reference-a-native-library-task-for-adding-dependencies-input-files-etc/7472/13 "2015-01-22T22:38:00Z")

</div>

I’m continuing to revise my solution and I want the revisions to be here for future readers (and I may be a future reader! Hello future self 🙂

This revision doesn’t rely on the index of the task and names the 'it’s so there is less confusion with the nested lambdas.

```gradle
binaries.withType(SharedLibraryBinarySpec) { binary ->
    if (binary.name == 'odrpack95-jniSharedLibrary') {
        binary.tasks.withType(LinkSharedLibrary) { task ->
            task.dependsOn compileOdrSlimWrapFortran
            task.inputs.file compileOdrSlimWrapFortran.obj
        }
    }
    if (binary.name == 'ibnativetest-jniSharedLibrary') {
        binary.tasks.withType(LinkSharedLibrary) { task ->
            task.dependsOn compileIBNativeTestFortran
            task.inputs.file compileIBNativeTestFortran.obj
        }
    }
}

```
