171 lines
5.6 KiB
Groovy
171 lines
5.6 KiB
Groovy
// QNN Dependencies Preparation
|
|
// This gradle file handles downloading and preparing QNN dependencies
|
|
|
|
// QNN configuration
|
|
ext {
|
|
// QNN download settings
|
|
QNN_LIBS_URL = 'http://meta.alicdn.com/data/mnn/libs/qnn_inc_libs_2_37.zip'
|
|
}
|
|
|
|
def qnnZipName = 'qnn_inc_libs.zip'
|
|
def qnnZipFile = new File(buildDir, qnnZipName)
|
|
def qnnTmpDir = new File(buildDir, 'qnn_tmp')
|
|
|
|
task prepareQnnDeps {
|
|
group = 'build setup'
|
|
description = 'Download and extract QNN include/lib into source/backend/qnn/3rdParty when BUILD_QNN is enabled.'
|
|
onlyIf {
|
|
project.ext.has('BUILD_QNN') && project.ext.BUILD_QNN
|
|
}
|
|
|
|
// Define inputs and outputs for incremental build
|
|
inputs.property("qnn_libs_url", { QNN_LIBS_URL })
|
|
inputs.property("build_qnn", { project.ext.has('BUILD_QNN') && project.ext.BUILD_QNN })
|
|
outputs.dir(new File(project.rootDir, '../../source/backend/qnn/3rdParty'))
|
|
outputs.dir(new File(buildDir, 'native-packed/native/libs'))
|
|
|
|
doLast {
|
|
println "BUILD_QNN is ON. Preparing QNN dependencies..."
|
|
|
|
def url = QNN_LIBS_URL
|
|
println "Downloading QNN dependencies from ${url}"
|
|
|
|
if (!qnnZipFile.exists()) {
|
|
println "Downloading ${qnnZipName} ..."
|
|
qnnZipFile.parentFile.mkdirs()
|
|
|
|
try {
|
|
new java.net.URL(url).withInputStream { inputStream ->
|
|
qnnZipFile.withOutputStream { outputStream ->
|
|
outputStream << inputStream
|
|
}
|
|
}
|
|
println "Downloaded to: ${qnnZipFile.absolutePath}"
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Failed to download QNN dependencies from ${url}. Error: ${e.message}")
|
|
}
|
|
} else {
|
|
println "Using cached zip: ${qnnZipFile.absolutePath}"
|
|
}
|
|
|
|
// Clean temp dir and unpack
|
|
project.delete(qnnTmpDir)
|
|
qnnTmpDir.mkdirs()
|
|
copy {
|
|
from zipTree(qnnZipFile)
|
|
into qnnTmpDir
|
|
}
|
|
|
|
// Find the extracted QNN directory
|
|
def extractedQnnDir = findQnnDirectory(qnnTmpDir)
|
|
if (extractedQnnDir == null) {
|
|
throw new RuntimeException("Failed to find QNN directory structure in ${qnnZipFile.name}")
|
|
}
|
|
|
|
copyQnnFiles(extractedQnnDir)
|
|
}
|
|
}
|
|
|
|
def findQnnDirectory(File searchDir) {
|
|
// Mirror the shell script's approach: find the 'include' directory
|
|
// anywhere in the hierarchy, then use its parent as the QNN root.
|
|
// This is more reliable than requiring both include and lib to be present
|
|
// at the same level.
|
|
|
|
def foundIncludeDir = null
|
|
|
|
searchDir.eachDirRecurse { dir ->
|
|
if (foundIncludeDir == null && dir.name == 'include') {
|
|
foundIncludeDir = dir
|
|
}
|
|
}
|
|
|
|
if (foundIncludeDir != null) {
|
|
return foundIncludeDir.parentFile
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
def copyQnnFiles(File sourceDir) {
|
|
// Resolve destination directories
|
|
def qnnRoot = new File(project.rootDir, '../../source/backend/qnn/3rdParty')
|
|
def includeDir = new File(qnnRoot, 'include')
|
|
def libDir = new File(qnnRoot, 'lib')
|
|
|
|
includeDir.mkdirs()
|
|
libDir.mkdirs()
|
|
|
|
// Copy include files
|
|
def sourceInclude = new File(sourceDir, 'include')
|
|
if (sourceInclude.exists()) {
|
|
copy {
|
|
from sourceInclude
|
|
into includeDir
|
|
}
|
|
println "QNN includes copied to: ${includeDir.absolutePath}"
|
|
} else {
|
|
throw new RuntimeException("Include directory not found in ${sourceDir.absolutePath}")
|
|
}
|
|
|
|
// Copy library files - try both jniLibs and lib directories
|
|
def sourceLibs = new File(sourceDir, 'jniLibs')
|
|
if (!sourceLibs.exists()) {
|
|
sourceLibs = new File(sourceDir, 'lib')
|
|
}
|
|
|
|
if (sourceLibs.exists()) {
|
|
copy {
|
|
from sourceLibs
|
|
into libDir
|
|
}
|
|
println "QNN libs copied to: ${libDir.absolutePath}"
|
|
|
|
// Also copy QNN .so files to native-packed for AAR packaging
|
|
copyQnnLibsToNativePacked(sourceLibs)
|
|
} else {
|
|
println "Warning: No lib/jniLibs directory found in ${sourceDir.absolutePath}"
|
|
}
|
|
|
|
println "QNN dependencies preparation completed successfully."
|
|
}
|
|
|
|
def copyQnnLibsToNativePacked(File sourceLibsDir) {
|
|
// Create native-packed directory structure for QNN .so files
|
|
def nativePackedLibsDir = new File(buildDir, 'native-packed/native/libs')
|
|
nativePackedLibsDir.mkdirs()
|
|
|
|
println "Copying QNN .so files to native-packed for AAR packaging..."
|
|
|
|
// Copy all .so files from QNN libs to native-packed
|
|
sourceLibsDir.eachFileRecurse { file ->
|
|
if (file.name.endsWith('.so')) {
|
|
// Determine the ABI directory (arm64-v8a, armeabi-v7a, etc.)
|
|
def relativePath = sourceLibsDir.toPath().relativize(file.toPath())
|
|
def targetFile = new File(nativePackedLibsDir, relativePath.toString())
|
|
|
|
// Create parent directories if they don't exist
|
|
targetFile.parentFile.mkdirs()
|
|
|
|
// Copy the .so file
|
|
copy {
|
|
from file
|
|
into targetFile.parentFile
|
|
}
|
|
|
|
println "Copied QNN lib: ${file.name} -> ${targetFile.absolutePath}"
|
|
}
|
|
}
|
|
|
|
println "QNN .so files copied to native-packed directory"
|
|
}
|
|
|
|
// Ensure preparation runs before compilation when enabled
|
|
if (project.ext.has('BUILD_QNN') && project.ext.BUILD_QNN) {
|
|
afterEvaluate {
|
|
if (tasks.findByName('preBuild')) {
|
|
preBuild.dependsOn prepareQnnDeps
|
|
}
|
|
}
|
|
}
|