作为使用NDK的Android应用程序的一部分,我需要将一些常量从C / C ++世界导出到Java中。出于显而易见的原因,我宁愿自动化。我使用Android Studio并支持NDK。
如何在应用程序构建时由Gradle运行的shell脚本动态生成一些.java
文件?理想情况下,此.java
文件将位于某个构建中介目录中,并且不必位于应用程序源目录中。
作为示例,shell脚本将生成此Java源:
public enum Type {
FOO,
BAR
}
来自这个C ++源代码:
enum class Type {
FOO,
BAR
}
此处参考Gradle文件的简化版本我将从Android Studio开始:
apply plugin: 'com.android.model.application'
model {
compileOptions.with {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "..."
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 23
}
defaultConfig.multiDexEnabled = true
}
android.ndk {
platformVersion = "18"
moduleName = "jni"
...
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
ndk.with {
CFlags.add("-Werror")
cppFlags.add("-Werror")
}
}
}
android.productFlavors {
create("arm7") {
ndk.abiFilters.add("armeabi-v7a")
}
}
}
repositories {
...
}
dependencies {
...
}
apply plugin: 'com.google.gms.google-services'
答案 0 :(得分:0)
您可以将生成的文件写入$buildDir/generatedJava
,然后将该目录添加为源文件夹。然后使任务javaCompile
取决于生成源的任务。这样的东西可以在build.gradle
def outputJavaFile = new File("$buildDir.absolutePath/generatedJava", 'MyEnum.java')
task generateSources(type: Exec) {
def source = $/
package com.example;
public enum Something {
One,
Two
}
/$
if (!outputJavaFile.parentFile.exists()) {
outputJavaFile.parentFile.mkdirs()
}
outputJavaFile.withWriter {
it << source
}
}
compileJava.dependsOn outputJavaFile
sourceSets {
main {
java {
srcDirs 'src/main/java', outputJavaFile.absolutePath
}
}
}
// if the goal is to generate the source from a script then just call the script
// inside the Exec closure
task shellScriptToGenerateSources(type: Exec) {
commandLine 'myShellScript.sh'
}
// then make compileJava depend on the task that runs the script
compileJava.dependsOn shellScriptToGenerateSources
编辑:要将相同的逻辑应用于更新的build.gradle
文件,可能看起来像这样
apply plugin: 'com.android.model.application'
// define an output folder for our generated .java files
def GENERATED_JAVA_OUTPUT = "$buildDir/generatedJava"
// if the goal is to generate the source from a script then just call the script
// inside the Exec closure
task shellScriptToGenerateSources(type: Exec) {
commandLine 'myShellScript.sh'
}
// then make compileJava depend on the task that runs the script
compileJava.dependsOn shellScriptToGenerateSources
model {
compileOptions.with {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "..."
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 23
}
defaultConfig.multiDexEnabled = true
}
android.ndk {
platformVersion = "18"
moduleName = "jni"
...
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
ndk.with {
CFlags.add("-Werror")
cppFlags.add("-Werror")
}
}
}
android.productFlavors {
create("arm7") {
ndk.abiFilters.add("armeabi-v7a")
}
}
// let android know that our java sources shoudl also consider the generated java for the compiler
android.sourceSet {
main {
java {
srcDir(GENERATED_JAVA_OUTPUT)
}
}
}
}
repositories {
...
}
dependencies {
...
}
apply plugin: 'com.google.gms.google-services'