Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ kotlin {
optIn("kotlinx.cinterop.ExperimentalForeignApi")
optIn("kotlin.time.ExperimentalTime")
optIn("kotlin.experimental.ExperimentalObjCRefinement")
optIn("com.powersync.PowerSyncInternal")
}
}

Expand Down
12 changes: 12 additions & 0 deletions common/src/commonMain/kotlin/com/powersync/PowerSyncInternal.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.powersync

@RequiresOptIn(message = "This API should not be used outside of PowerSync SDK packages")
@Retention(AnnotationRetention.BINARY)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.CONSTRUCTOR,
AnnotationTarget.PROPERTY,
AnnotationTarget.VALUE_PARAMETER,
)
public annotation class PowerSyncInternal
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import com.powersync.db.runWrapped
@Throws(PowerSyncException::class)
public actual fun resolvePowerSyncLoadableExtensionPath(): String? = runWrapped { powersyncExtension }

private val powersyncExtension: String by lazy { extractLib("powersync") }
private val powersyncExtension: String by lazy { extractLib(BuildConfig::class,"powersync") }
8 changes: 4 additions & 4 deletions common/src/jvmMain/kotlin/com/powersync/ExtractLib.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package com.powersync

import java.io.File
import java.util.UUID
import kotlin.reflect.KClass

private class R

internal fun extractLib(fileName: String): String {
@PowerSyncInternal
public fun extractLib(reference: KClass<*>, fileName: String): String {
val os = System.getProperty("os.name").lowercase()
val (prefix, extension) =
when {
Expand Down Expand Up @@ -34,7 +34,7 @@ internal fun extractLib(fileName: String): String {

val resourcePath = "/$prefix${fileName}_$arch.$extension"

(R::class.java.getResourceAsStream(resourcePath) ?: error("Resource $resourcePath not found")).use { input ->
(reference.java.getResourceAsStream(resourcePath) ?: error("Resource $resourcePath not found")).use { input ->
file.outputStream().use { output -> input.copyTo(output) }
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ compose = "1.8.2" # This is for the multiplatform compose
androidCompose = "2025.08.00"
compose-preview = "1.9.0"
compose-lifecycle = "2.9.2"
androidxSqlite = "2.6.0"
androidxSqlite = "2.6.1"
androidxSplashscreen = "1.0.1"
room = "2.8.0"
sqldelight = "2.1.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,7 @@ abstract class ClangCompile : DefaultTask() {

@get:Input
val xcodeInstallation: Provider<String>
get() =
providers
.exec {
executable("xcode-select")
args("-p")
}.standardOutput.asText
get() = resolveXcode(providers)

@TaskAction
fun run() {
Expand Down Expand Up @@ -95,15 +90,7 @@ abstract class ClangCompile : DefaultTask() {
"--compile",
"-I${include.get().asFile.absolutePath}",
inputFile.get().asFile.absolutePath,
"-DHAVE_GETHOSTUUID=0",
"-DSQLITE_ENABLE_DBSTAT_VTAB",
"-DSQLITE_ENABLE_FTS5",
"-DSQLITE_ENABLE_RTREE",
// Used by GRDB
"-DSQLITE_ENABLE_SNAPSHOT",
// Used for GRDB update hook like functionality
"-DSQLITE_ENABLE_SESSION",
"-DSQLITE_ENABLE_PREUPDATE_HOOK",
*sqlite3ClangOptions,
//
"-O3",
"-o",
Expand All @@ -126,5 +113,26 @@ abstract class ClangCompile : DefaultTask() {
const val TVOS_SIMULATOR_SDK =
"Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk"
const val MACOS_SDK = "Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/"

val sqlite3ClangOptions = arrayOf(
// Note: Keep in sync with sqlite3multiplecipers/src/jni/CMakeLists.txt
"-DHAVE_GETHOSTUUID=0",
"-DSQLITE_ENABLE_DBSTAT_VTAB",
"-DSQLITE_ENABLE_FTS5",
"-DSQLITE_ENABLE_RTREE",
// Used by GRDB
"-DSQLITE_ENABLE_SNAPSHOT",
// Used for GRDB update hook like functionality
"-DSQLITE_ENABLE_SESSION",
"-DSQLITE_ENABLE_PREUPDATE_HOOK",
)

fun resolveXcode(factory: ProviderFactory): Provider<String> {
return factory
.exec {
executable("xcode-select")
args("-p")
}.standardOutput.asText
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ abstract class UnzipSqlite: Copy() {
@get:OutputDirectory
abstract val destination: DirectoryProperty

fun unzipSqlite(src: FileTree, dir: Provider<Directory>) {
fun unzipSqlite(src: FileTree, dir: Provider<Directory>, filter: String? = "*/sqlite3.*") {
from(
src.matching {
include("*/sqlite3.*")
filter?.let { include(it) }
exclude {
it.isDirectory
}
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ include(":core")
include(":core-tests-android")
include(":integrations:room")
include(":static-sqlite-driver")
include(":sqlite3multipleciphers")

include(":integrations:sqldelight")
include(":integrations:sqldelight-test-database")
Expand Down
22 changes: 22 additions & 0 deletions sqlite3multipleciphers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Building

Please note that the build currently only runs on macOS.
We use cross-compilation to be able to compile for Windows and Linux.

For Linux, we use a Docker container to build the extension. To run the build,
first build that image:

```shell
docker build -t powersync_kotlin_sqlite3mc_build_helper --load src/jni
```

To compile for Windows, we use [llvm-mingw](https://github.com/mstorsjo/llvm-mingw),
which needs to be downloaded.

With all dependencies ready, run the Gradle task:

```shell
./gradlew sqlite3multipleciphers:jniCompile -PllvmMingw='.../Downloads/llvm-mingw-20251104-ucrt-macos-universal'
```

This outputs binaries to `build/jni-build/`.
Loading
Loading