Link to Android's atomic lib in bundled SQLite
Fix Bundled SQLite loading for devices with older ARM architecture by linking to Android's atomic library instead of relying on Clang's extension (c_atomic) or GCC's built-ins as used in sqlite3.c.
Also add support for passing linker args to androidx's native compilation infra.
See also discussion in https://sqlite.org/forum/forumpost/792d76a592608d8f
Bug: 341639198
Test: Locally tested via BundledSQLiteDriverTest in a Nexus 5 on API 23
Change-Id: Ia818b7c4f1a990a1b5e35f4c7a3c89694aee0503
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/clang/ClangSharedLibraryTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/clang/ClangSharedLibraryTask.kt
index 9d74715e1..ff2bfee 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/clang/ClangSharedLibraryTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/clang/ClangSharedLibraryTask.kt
@@ -20,6 +20,7 @@
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.services.ServiceReference
import org.gradle.api.tasks.CacheableTask
@@ -81,6 +82,9 @@
@get:InputFiles
@get:PathSensitive(PathSensitivity.NAME_ONLY)
abstract val linkedObjects: ConfigurableFileCollection
+
+ /** List of arguments that will be passed into linker when creating a shared library. */
+ @get:Input abstract val linkerArgs: ListProperty<String>
}
private abstract class ClangSharedLibraryWorker : WorkAction<ClangSharedLibraryWorker.Params> {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/clang/KonanBuildService.kt b/buildSrc/private/src/main/kotlin/androidx/build/clang/KonanBuildService.kt
index 972fb9c..20d562b 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/clang/KonanBuildService.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/clang/KonanBuildService.kt
@@ -128,9 +128,12 @@
// Specify max-page-size to align ELF regions to 16kb
val linkerFlags =
- if (parameters.konanTarget.get().asKonanTarget.family == Family.ANDROID) {
- listOf("-z", "max-page-size=16384")
- } else emptyList()
+ parameters.linkerArgs.get() +
+ if (parameters.konanTarget.get().asKonanTarget.family == Family.ANDROID) {
+ listOf("-z", "max-page-size=16384")
+ } else {
+ emptyList()
+ }
val objectFiles = parameters.objectFiles.regularFilePaths()
val linkedObjectFiles = parameters.linkedObjects.regularFilePaths()
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/clang/MultiTargetNativeCompilation.kt b/buildSrc/private/src/main/kotlin/androidx/build/clang/MultiTargetNativeCompilation.kt
index ca56db8..9d2557e 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/clang/MultiTargetNativeCompilation.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/clang/MultiTargetNativeCompilation.kt
@@ -167,11 +167,17 @@
val sources = project.objects.fileCollection()
val freeArgs = project.objects.listProperty<String>()
val linkedObjects = project.objects.fileCollection()
+ val linkerArgs = project.objects.listProperty<String>()
val compileTask =
createCompileTask(serializableKonanTarget, includes, sources, freeArgs)
val archiveTask = createArchiveTask(serializableKonanTarget, compileTask)
val sharedLibTask =
- createSharedLibraryTask(serializableKonanTarget, compileTask, linkedObjects)
+ createSharedLibraryTask(
+ serializableKonanTarget,
+ compileTask,
+ linkedObjects,
+ linkerArgs
+ )
return NativeTargetCompilation(
project = project,
konanTarget = serializableKonanTarget.asKonanTarget,
@@ -181,6 +187,7 @@
sources = sources,
includes = includes,
linkedObjects = linkedObjects,
+ linkerArgs = linkerArgs,
freeArgs = freeArgs
)
}
@@ -243,6 +250,7 @@
serializableKonanTarget: SerializableKonanTarget,
compileTask: TaskProvider<ClangCompileTask>,
linkedObjects: ConfigurableFileCollection,
+ linkerArgs: ListProperty<String>
): TaskProvider<ClangSharedLibraryTask> {
val archiveTaskName =
taskPrefix.appendCapitalized("createSharedLibrary", serializableKonanTarget.name)
@@ -267,6 +275,7 @@
clang.konanTarget.set(serializableKonanTarget)
clang.objectFiles.from(compileTask.map { it.clangParameters.output })
clang.linkedObjects.from(linkedObjects)
+ clang.linkerArgs.addAll(linkerArgs)
}
}
return archiveTask
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/clang/NativeTargetCompilation.kt b/buildSrc/private/src/main/kotlin/androidx/build/clang/NativeTargetCompilation.kt
index 72d1032..625e681 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/clang/NativeTargetCompilation.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/clang/NativeTargetCompilation.kt
@@ -39,6 +39,7 @@
* @param includes List of include directories containing .h files for the compilation.
* @param linkedObjects List of object files that should be dynamically linked in the final shared
* object output.
+ * @param linkerArgs Arguments that will be passed into linker when creating a shared library.
* @param freeArgs Arguments that will be passed into clang for compilation.
*/
class NativeTargetCompilation
@@ -52,6 +53,8 @@
val includes: ConfigurableFileCollection,
val linkedObjects: ConfigurableFileCollection,
@Suppress("unused") // used via build.gradle
+ val linkerArgs: ListProperty<String>,
+ @Suppress("unused") // used via build.gradle
val freeArgs: ListProperty<String>
) : Named {
override fun getName(): String = konanTarget.name
diff --git a/sqlite/sqlite-bundled/build.gradle b/sqlite/sqlite-bundled/build.gradle
index 3169138..baeb12a 100644
--- a/sqlite/sqlite-bundled/build.gradle
+++ b/sqlite/sqlite-bundled/build.gradle
@@ -159,6 +159,10 @@
)
// statically include the output of SQLite compilation
nativeCompilation.include(sqliteCompilation)
+ if (nativeCompilation.konanTarget.family == Family.ANDROID) {
+ // b/341639198: Link to Android's Atomic lib, important for older ARM devices
+ nativeCompilation.linkerArgs.add("-latomic")
+ }
if (nativeCompilation.konanTarget.family == Family.OSX) {
// KT-57848
nativeCompilation.freeArgs.addAll("-Dat_quick_exit=atexit", "-Dquick_exit=exit")