plugins { id 'com.android.library' id 'org.jetbrains.kotlin.android' id "de.undercouch.download" } Properties properties = new Properties() if (rootProject.file("local.properties").exists()) { properties.load(rootProject.file("local.properties").newDataInputStream()) } ext["keyId"] = properties.getProperty("signing.keyId", System.getenv('SIGNING_KEY_ID')) ext["password"] = properties.getProperty("signing.password", System.getenv('SIGNING_PASSWORD')) ext["key"] = properties.getProperty("signing.key", System.getenv('SIGNING_KEY')) ext["ossrhUsername"] = properties.getProperty("ossrhUsername", System.getenv('OSSRH_USERNAME')) ext["ossrhPassword"] = properties.getProperty("ossrhPassword", System.getenv('OSSRH_PASSWORD')) ext["sonatypeStagingProfileId"] = properties.getProperty("sonatypeStagingProfileId", System.getenv('SONATYPE_STAGING_PROFILE_ID')) ext { set("GROUP_ID", "org.kiwix") set("ARTIFACT_ID", "libkiwix") set("VERSION", "2.2.4") } // Replace these versions with the latest available versions of libkiwix and libzim ext.libkiwix_version = "14.0.0-1" ext.libzim_version = "9.2.3-2" apply from: 'publish.gradle' android { compileSdk 34 namespace = "kiwix.org.kiwixlib" defaultConfig { minSdk 24 targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags '' arguments "-DANDROID_STL=c++_shared", "-DBUILD_DIR=${buildDir}" } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } externalNativeBuild { cmake { path file('src/main/cpp/CMakeLists.txt') version '3.18.1' } } buildFeatures { viewBinding true } ndkVersion '21.4.7075529' // Enabled the lint to avoid potential errors. lintOptions { abortOnError true checkAllWarnings = true warningsAsErrors true disable("GradleDependency", "UnknownNullness", "OldTargetApi") } } dependencies { implementation 'com.getkeepsafe.relinker:relinker:1.4.5' implementation 'androidx.core:core-ktx:1.7.0' } ext.libkiwix_base_url = 'https://download.kiwix.org/release/libkiwix/' ext.libzim_base_url = 'https://download.openzim.org/release/libzim/' tasks.register('downloadLibzimSoAndHeaderFiles', Download) { src([ libzim_base_url + 'libzim_android-arm-' + libzim_version + '.tar.gz', libzim_base_url + 'libzim_android-arm64-' + libzim_version + '.tar.gz', libzim_base_url + 'libzim_android-x86-' + libzim_version + '.tar.gz', libzim_base_url + 'libzim_android-x86_64-' + libzim_version + '.tar.gz', libzim_base_url + 'libzim_linux-x86_64-' + libzim_version + '.tar.gz' ]) dest buildDir overwrite true } tasks.register('unzipLibzim', Copy) { mustRunAfter downloadLibzimSoAndHeaderFiles // unzip android arm from tarTree(buildDir.path + "/libzim_android-arm-" + libzim_version + ".tar.gz") into buildDir // unzip android arm64 from tarTree(buildDir.path + "/libzim_android-arm64-" + libzim_version + ".tar.gz") into buildDir // unzip android x86 from tarTree(buildDir.path + "/libzim_android-x86-" + libzim_version + ".tar.gz") into buildDir // unzip android x86_64 from tarTree(buildDir.path + "/libzim_android-x86_64-" + libzim_version + ".tar.gz") into buildDir // unzip linux x86_64 from tarTree(buildDir.path + "/libzim_linux-x86_64-" + libzim_version + ".tar.gz") into buildDir } tasks.register('renameLibzimFolders') { removeVersionFromFolderName(buildDir.path, "libzim_", libzim_version) } tasks.register('copyLibzimHeaderAndSoFiles', Copy) { copy { // copying header file from buildDir.path + "/libzim_android-arm/include/" into buildDir.path + "/include/libzim/" } copy { // copying android_arm so file from buildDir.path + "/libzim_android-arm/lib/arm-linux-androideabi/" into buildDir.path + "/jniLibs/armeabi-v7a/libzim/" } copy { // copying android_arm64 so file from buildDir.path + "/libzim_android-arm64/lib/aarch64-linux-android/" into buildDir.path + "/jniLibs/arm64-v8a/libzim/" } copy { // copying android_x86 so file from buildDir.path + "/libzim_android-x86/lib/i686-linux-android/" into buildDir.path + "/jniLibs/x86/libzim/" } copy { // copying android_x86_64 so file from buildDir.path + "/libzim_android-x86_64/lib/x86_64-linux-android/" into buildDir.path + "/jniLibs/x86_64/libzim/" } copy { // copying linux_x86_64 so file from buildDir.path + "/libzim_linux-x86_64/lib/x86_64-linux-gnu/libzim.so." + getActualLibraryVersion(libzim_version) into buildDir.path } } tasks.register('renameLibzimSoFile', Copy) { if (libzim_version != null) { def finalLibzimVersion = getActualLibraryVersion(libzim_version) def sourceFile = file(buildDir.path + "/libzim.so." + finalLibzimVersion) if (project.gradle.startParameter.taskNames.contains("renameLibzimSoFile") && !sourceFile.exists()) { throw new RuntimeException("Rename Libzim so file task failed, File not found: ${sourceFile}") } from(buildDir.path) include "libzim.so." + finalLibzimVersion destinationDir file(buildDir.path) rename "libzim.so." + finalLibzimVersion, "libzim.so" } } tasks.register('downloadLibkiwixSoAndHeaderFiles', Download) { src([ libkiwix_base_url + 'libkiwix_android-arm-' + libkiwix_version + '.tar.gz', libkiwix_base_url + 'libkiwix_android-arm64-' + libkiwix_version + '.tar.gz', libkiwix_base_url + 'libkiwix_android-x86-' + libkiwix_version + '.tar.gz', libkiwix_base_url + 'libkiwix_android-x86_64-' + libkiwix_version + '.tar.gz', libkiwix_base_url + 'libkiwix_linux-x86_64-' + libkiwix_version + '.tar.gz' ]) dest buildDir overwrite true } tasks.register('renameLibkiwixFolders') { removeVersionFromFolderName(buildDir.path, "libkiwix_", libkiwix_version) } static void removeVersionFromFolderName(String path, String startWith, String version) { File directory = new File(path) if (directory.exists() && directory.isDirectory()) { Arrays.stream(directory.listFiles()) .filter(folder -> folder.isDirectory() && folder.getName().startsWith(startWith)) .forEach(file -> { String newName = file.getName().replace("-" + version, "") File newFile = new File(directory, newName) file.renameTo(newFile) }) } } tasks.register('unzipLibkiwix', Copy) { mustRunAfter downloadLibkiwixSoAndHeaderFiles // unzip android arm from tarTree(buildDir.path + "/libkiwix_android-arm-" + libkiwix_version + ".tar.gz") into buildDir // unzip android arm64 from tarTree(buildDir.path + "/libkiwix_android-arm64-" + libkiwix_version + ".tar.gz") into buildDir // unzip android x86 from tarTree(buildDir.path + "/libkiwix_android-x86-" + libkiwix_version + ".tar.gz") into buildDir // unzip android x86_64 from tarTree(buildDir.path + "/libkiwix_android-x86_64-" + libkiwix_version + ".tar.gz") into buildDir // unzip linux x86_64 from tarTree(buildDir.path + "/libkiwix_linux-x86_64-" + libkiwix_version + ".tar.gz") into buildDir } tasks.register('copyLibkiwixHeaderAndSoFiles', Copy) { copy { // copying header file from buildDir.path + "/libkiwix_android-arm/include/kiwix/" into buildDir.path + "/include/libkiwix/" } copy { // copying android_arm so file from buildDir.path + "/libkiwix_android-arm/lib/arm-linux-androideabi/" into buildDir.path + "/jniLibs/armeabi-v7a/libkiwix/" } copy { // copying android_arm64 so file from buildDir.path + "/libkiwix_android-arm64/lib/aarch64-linux-android/" into buildDir.path + "/jniLibs/arm64-v8a/libkiwix/" } copy { // copying android_x86 so file from buildDir.path + "/libkiwix_android-x86/lib/i686-linux-android/" into buildDir.path + "/jniLibs/x86/libkiwix/" } copy { // copying android_x86_64 so file from buildDir.path + "/libkiwix_android-x86_64/lib/x86_64-linux-android/" into buildDir.path + "/jniLibs/x86_64/libkiwix/" } copy { // copying linux_x86_64 so file from buildDir.path + "/libkiwix_linux-x86_64/lib/x86_64-linux-gnu/libkiwix.so." + getActualLibraryVersion(libkiwix_version) into buildDir.path } } tasks.register('renameLibkiwixSoFile', Copy) { if (libkiwix_version != null) { def finalLibkiwixVersion = getActualLibraryVersion(libkiwix_version) def sourceFile = file(buildDir.path + "/libkiwix.so." + finalLibkiwixVersion) if (project.gradle.startParameter.taskNames.contains("renameLibkiwixSoFile") && !sourceFile.exists()) { throw new RuntimeException("Rename Libkiwix so file task failed, File not found: ${sourceFile}") } from(buildDir.path) include "libkiwix.so." + finalLibkiwixVersion destinationDir file(buildDir.path) rename "libkiwix.so." + finalLibkiwixVersion, "libkiwix.so" } } // Extracting the library version before the "-" // see https://github.com/kiwix/java-libkiwix/pull/79 for more details static String getActualLibraryVersion(String libraryVersion) { // Find the index of the first occurrence of "-" Integer dashIndex = libraryVersion.indexOf('-') // Get the substring before the first "-" return dashIndex != -1 ? libraryVersion.substring(0, dashIndex) : libraryVersion } tasks.register('testSourceJar', Jar) { from android.sourceSets.test.java.srcDirs archiveBaseName = 'test-sources' } tasks.register('compileTestFile', JavaCompile) { dependsOn testSourceJar source = file('src/test') destinationDirectory = file("$buildDir") classpath = files("src/test/junit-4.13.jar", "src/test/hamcrest-core-1.4.jar", "build/libs/test-sources-${VERSION}.jar") } tasks.register('runTests', JavaExec) { workingDir("$projectDir/src/test/") dependsOn compileTestFile classpath = files("$buildDir", 'src/test/java/', 'src/test/junit-4.13.jar', 'src/test/hamcrest-core-1.3.jar') mainClass = 'org.junit.runner.JUnitCore' args = ['test'] jvmArgs = [ '-Djava.library.path=' + buildDir.path, '-javaagent:jacoco-0.8.7/lib/jacocoagent.jar=destfile=../../build/jacoco/jacoco.exec' ] } tasks.register('createCodeCoverageReport', JavaExec) { workingDir "${projectDir}/src/test/" dependsOn runTests classpath = files('src/test/', 'src/test/java/', 'src/test/junit-4.13.jar', 'src/test/hamcrest-core-1.3.jar', 'src/test/jacoco-0.8.7/lib/*') mainClass = 'org.jacoco.cli.internal.Main' args = [ 'report', '../../build/jacoco/jacoco.exec', '--classfiles', 'java/org/kiwix', '--classfiles', '../../build/org/kiwix', '--html', '../../build/coverage-report', '--xml', '../../build/coverage.xml' ] } tasks.register('checkCurrentJavaVersion') { if (JavaVersion.current() != JavaVersion.VERSION_17) { throw new RuntimeException("This build must be run with java 17. your current java version is ${JavaVersion.current()}") } } tasks.register('buildHeaders', Exec) { workingDir "${projectDir}/src/main/java/org/kiwix/" commandLine 'bash', '-c', "javac -h ${buildDir}/include/javah_generated/ -d ${projectDir}/src/test/java/ ${getLibzimFiles()} ${getLibkiwixFiles()}" } String getLibkiwixFiles() { return "${projectDir}/src/main/java/org/kiwix/libkiwix/Book.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/Bookmark.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/BookmarkMigrationResult.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/Filter.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/JNIICU.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/Illustration.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/JNIKiwixException.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/Library.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/Manager.java " + "${projectDir}/src/main/java/org/kiwix/libkiwix/Server.java" } String getLibzimFiles() { return "${projectDir}/src/main/java/org/kiwix/libzim/Archive.java " + "${projectDir}/src/main/java/org/kiwix/libzim/Blob.java " + "${projectDir}/src/main/java/org/kiwix/libzim/DirectAccessInfo.java " + "${projectDir}/src/main/java/org/kiwix/libzim/EntryIterator.java " + "${projectDir}/src/main/java/org/kiwix/libzim/Entry.java " + "${projectDir}/src/main/java/org/kiwix/libzim/Item.java " + "${projectDir}/src/main/java/org/kiwix/libzim/Query.java " + "${projectDir}/src/main/java/org/kiwix/libzim/Searcher.java " + "${projectDir}/src/main/java/org/kiwix/libzim/SearchIterator.java " + "${projectDir}/src/main/java/org/kiwix/libzim/Search.java " + "${projectDir}/src/main/java/org/kiwix/libzim/SuggestionItem.java " + "${projectDir}/src/main/java/org/kiwix/libzim/SuggestionIterator.java " + "${projectDir}/src/main/java/org/kiwix/libzim/SuggestionSearcher.java " + "${projectDir}/src/main/java/org/kiwix/libzim/SuggestionSearch.java " + "${projectDir}/src/main/java/org/kiwix/libzim/ZimFileFormatException.java " + "${projectDir}/src/main/java/org/kiwix/libzim/EntryNotFoundException.java " + "${projectDir}/src/main/java/org/kiwix/libzim/FdInput.java" } tasks.register('buildLinuxBinding', Exec) { workingDir "${projectDir}/src/main/cpp/" commandLine 'bash', '-c', "cmake . -B ${buildDir} && make -C ${buildDir}" } build.dependsOn buildLinuxBinding