Gradle task ordering issue in Android Studio
Asked Answered
F

3

9

I am using Android Studio 2.2 Beta 3 and my test project uses CMake to build a hybrid C++ and Java app. The JNI interface is generated by SWIG. This means that I would want to generate the SWIG wrappers before the externalNativeBuild and JavaCompile gradle tasks; ie my CMakeLists.txt specifies the cpp wrapper file generated by SWIG and my java code imports the java wrapper files generated by SWIG.

To ensure SWIG is run and generates the necessary wrapper files before any tasks, I specifies the following in my app/build.gradle file

project.afterEvaluate {
    preBuild.dependsOn("runSwig")
}

When I run from the commandline using the command

./gradlew assembleDebug

I do not face any issues and as expected my task "runSwig" runs before any of the other tasks

:app:runSwig
:app:preBuild
:app:preDebugBuild
<blah blah more tasks>
:app:externalNativeBuildDebug

But issue is when the project is first opened in Android Studio, it looks like the external native build gets invoked before runSwig and I get the error

CMake Error at CMakeLists.txt:79 (add_library):
  Cannot find source file:

    ../../../wrap.cxx

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx

FAILURE: Build failed with an exception.

The error does not go away till I either assemble using command line OR, remove the wrap.cxx file from my CMakeLists.txt and re-add it after swig gets run successfully at-least once.

Foeticide answered 31/8, 2016 at 22:58 Comment(0)
B
2

Yeah, this is because Android Studio IDE need get the files to display in IDE before compile: expose different behavior between command line and IDE build. In here I hack to download the needed repo earlier than anything else, so Android Studio will not complain. But it is not pretty... and long android studio start up time...

Baccalaureate answered 13/10, 2016 at 6:45 Comment(0)
A
4

I've run into this same problem with the order of the build in Android Studio 3 (and 2.3 I guess).

I don't know if this is a traditionally valid solution, but it -seems- to work in my Android/SWIG/NDK example (here: https://github.com/sureshjoshi/android-ndk-swig-example)

I added this into my Gradle file, so that CMake is called before the build fails out on missing files. CMake calls SWIG to auto-generate my Java files and place them appropriately.

project.afterEvaluate {
    javaPreCompileDebug.dependsOn externalNativeBuildDebug
}

I probably also need a

javaPreCompileRelease.dependsOn externalNativeBuildRelease

or something similar... Just haven't tested it yet.

Stemmed from this issue: https://github.com/sureshjoshi/android-ndk-swig-example/issues/8

Anzio answered 15/11, 2017 at 9:3 Comment(0)
B
2

Yeah, this is because Android Studio IDE need get the files to display in IDE before compile: expose different behavior between command line and IDE build. In here I hack to download the needed repo earlier than anything else, so Android Studio will not complain. But it is not pretty... and long android studio start up time...

Baccalaureate answered 13/10, 2016 at 6:45 Comment(0)
O
0

Problem: for some reasons, adding build.gradle custom task to run SWIG generation in 'preBuild' task prevent of CMakeList.txt compiling.

Previous answer SJoshi helps me a lot. I have build.gradle.kts for module, code below is working:

    tasks.register("make-swig-script-executable", Exec::class) {
        description = "Make swig-generate script executable"
        commandLine = "chmod +x swig/run_shig.sh".split(" ")
    }

    tasks.register("swig-generate", Exec::class) {
        dependsOn("make-swig-script-executable")
        description = "Generating JNI files by swig"
        commandLine = "swig/run_shig.sh".split(" ")
    }

    tasks.withType(JavaCompile::class) {
        dependsOn("swig-generate")
    }

    project.afterEvaluate {
        task("javaPreCompileDebug").dependsOn("externalNativeBuildDebug")
    }

I had lines below in my code and its NOT WORKING:

//same tasks swig-generate and make-swig-script-executable
//but different "trigger event" (on preBuild)

tasks.matching { it.name == "preBuild" }.all {
    dependsOn("swig-generate")
}
Ofilia answered 2/9, 2021 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.