Доступ к значению sdk.dir в build.gradle после оценки проекта
У меня есть пользовательская задача в моем файле build.gradle, который преобразует байт-коды в файлы классов, прежде чем получить dex'd, который выглядит так:
task droidcook(type: JavaExec) {
main 'org.tsg.android.asm.Main'
}
afterEvaluate { project ->
android.applicationVariants.each { variant ->
variant.javaCompile.doLast {
project.tasks.droidcook.configure {
classpath variant.javaCompile.classpath
classpath "build/classes/" + variant.dirName
classpath sdk.dir + "/platforms/android-19/android.jar"
classpath "compile-libs/droidcook.jar"
args "build/classes/" + variant.dirName
args "com.example"
// args "-debug"
// args "-asmifier"
}
project.tasks.droidcook.execute()
}
}
}
Проблема с вышесказанным - это строка classpath sdk.dir + ...
, где sdk.dir
не оценивается соответствующим образом. Чтобы получить эту работу, мне в настоящее время нужно жестко закодировать путь к android.jar
.
Бонусные баллы, если вы можете ответить с соответствующим значением, чтобы заменить android-19
на доступ к платформе android.jar
на основе конфигурации проекта.: D
Ответы
Ответ 1
Я не вижу опубликованного API, чтобы выставлять файл sdk.dir в ваш файл сборки, поэтому я просто скрепил код https://android.googlesource.com/platform/tools/build/+/d69964104aed4cfae5052028b5c5e57580441ae8/gradle/src/main/groovy/com/android/build/gradle/internal/Sdk.groovy, чтобы прочитать его вручную. Что касается замены android-19, если я читаю android.compileSdkVersion, я получаю эту точную строку. Я не уверен, что это тоже опубликованный API, поэтому он может быть изменен и поврежден в будущих версиях плагина Android Gradle.
Сказав это, это работает для меня:
afterEvaluate {
def rootDir = project.rootDir
def localProperties = new File(rootDir, "local.properties")
if (localProperties.exists()) {
Properties properties = new Properties()
localProperties.withInputStream { instr ->
properties.load(instr)
}
def sdkDir = properties.getProperty('sdk.dir')
def androidJarPath = sdkDir + "/platforms/" + android.compileSdkVersion + "/android.jar"
print androidJarPath + "\n"
}
}
Если нет local.properties, этот код будет терпеть неудачу. Если вам это интересно, вы можете скопировать больше кода из Sdk.groovy, чтобы подражать его поведению, пытаясь найти разумное значение по умолчанию.
Ответ 2
Там гораздо более простой способ, хотя он не документирован, поэтому он, вероятно, официально не поддерживается.
println "${android.getSdkDirectory().getAbsolutePath()}"
Как ни странно, этот метод доступен только для некоторых версий плагина gradle. Он не доступен в фиксации, связанной выше Скоттом. Если вышеуказанный код не работает, попробуйте следующее:
println "${android.plugin.getSdkFolder().getAbsolutePath()}"
Для полноты здесь также можно получить переменную ndk.dir
:
println "${android.plugin.getNdkFolder().getAbsolutePath()}"
Ответ 3
Как и для андроида gradle плагин v2.1.2, это то, что я использую в своем gradle script:
android.ndkDirectory.path
android.sdkDirectory.path
Например, для явного запуска ndk-build
:
task ndkBuild(type: Exec) {
commandLine android.ndkDirectory.path+'/ndk-build', '-C', file('src/main').absolutePath
}
Ответ 4
Использование:
String androidJar = android.getBootClasspath()[0]
Предполагая, что вы используете SDK 21, это установит '< path-to-SDK > /platforms/android-21/android.jar' в переменную androidJar (выбор версии SDK выполняется автоматически).
Следующим шагом, очевидно, будет замена "classpath sdk.dir..." и т.д. с помощью
classpath androidJar