我使用Android Studio 2.2 Beta 3,我的测试项目使用CMake来构建一个混合c++和Java应用程序。JNI接口是由SWIG生成的。这意味着我想要在externalNativeBuild和javaccompile gradle任务之前生成SWIG包装器;例如,我的CMakeLists.txt指定SWIG生成的cpp包装文件,我的java代码导入SWIG生成的java包装文件。
为了确保SWIG运行并在任何任务之前生成必要的包装器文件,我在我的app/build中指定了以下内容。gradle文件
project.afterEvaluate {
preBuild.dependsOn("runSwig")
}
当我使用命令
从命令行运行时./gradlew assembleDebug
我没有遇到任何问题,正如预期的那样,我的任务"runSwig"在任何其他任务之前运行
:app:runSwig
:app:preBuild
:app:preDebugBuild
<blah blah more tasks>
:app:externalNativeBuildDebug
但问题是当项目首次在Android Studio中打开时,看起来外部本地构建在runSwig之前被调用,我得到错误
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.
错误不会消失,直到我使用命令行或删除换行。从我的CMakeLists.txt中的cxx文件,并在swig成功运行至少一次后重新添加它。
我在Android Studio 3(和2.3)的构建顺序上遇到了同样的问题。
我不知道这是不是一个传统的有效的解决方案,但它-似乎-工作在我的Android/SWIG/NDK的例子(这里:https://github.com/sureshjoshi/android-ndk-swig-example)
我将此添加到我的Gradle文件中,以便在构建失败之前调用CMake。CMake调用SWIG来自动生成我的Java文件,并将它们适当地放置。
project.afterEvaluate {
javaPreCompileDebug.dependsOn externalNativeBuildDebug
}
我可能还需要一个
javaPreCompileRelease.dependsOn externalNativeBuildRelease
或类似的东西…只是还没测试过。
源于此问题:https://github.com/sureshjoshi/android-ndk-swig-example/issues/8
是的,这是因为Android Studio IDE需要在编译之前在IDE中显示文件:暴露命令行和IDE构建之间的不同行为。在这里,我试图比其他任何事情都更早地下载所需的repo,所以Android Studio不会抱怨。但它并不漂亮……android studio启动时间长…
问题:由于某些原因,添加构建。gradle自定义任务,在'preBuild'任务中运行SWIG生成,以防止编译CMakeList.txt。
上一个答案SJoshi帮了我很多。我有build.gradle.kts模块,下面的代码正在工作:
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")
}
我的代码中有下面几行,它的不工作:
//same tasks swig-generate and make-swig-script-executable
//but different "trigger event" (on preBuild)
tasks.matching { it.name == "preBuild" }.all {
dependsOn("swig-generate")
}