diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89830b7..6918d3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,25 @@ jobs: - name: Test run: swift test -v + linux-system-sqlite: + name: Linux (system SQLite) + runs-on: ubuntu-latest + container: swift:6.3.3 + env: + SWIFT_BUILD_SYSTEM_SQLITE: '1' + steps: + - uses: actions/checkout@v4 + - name: Install SQLite + run: | + apt-get update + apt-get install -y --no-install-recommends libsqlite3-dev pkg-config + - name: Swift version + run: swift --version + - name: Build + run: swift build -v + - name: Test + run: swift test -v + android: runs-on: ubuntu-latest steps: diff --git a/Package.swift b/Package.swift index 81e1f2d..d4da6da 100644 --- a/Package.swift +++ b/Package.swift @@ -6,10 +6,44 @@ import class Foundation.ProcessInfo // get environment variables let environment = ProcessInfo.processInfo.environment let dynamicLibrary = environment["SWIFT_BUILD_DYNAMIC_LIBRARY"] == "1" +let systemSQLite = environment["SWIFT_BUILD_SYSTEM_SQLITE"] == "1" // force building as dynamic library let libraryType: PackageDescription.Product.Library.LibraryType? = dynamicLibrary ? .dynamic : nil +// Linux uses the embedded SQLite build by default, like the other non-Darwin +// platforms. Set `SWIFT_BUILD_SYSTEM_SQLITE=1` to link the system SQLite +// (`libsqlite3-dev` / `sqlite-devel`) there instead. +let embeddedSQLitePlatforms: [Platform] = systemSQLite + ? [.android, .windows, .wasi, .openbsd] + : [.linux, .android, .windows, .wasi, .openbsd] + +var sqliteDependencies: [Target.Dependency] = [ + .product( + name: "SQLCipher", + package: "swift-sqlcipher", + condition: .when(platforms: embeddedSQLitePlatforms) + ) +] + +var sqliteTargets: [Target] = [] + +if systemSQLite { + sqliteDependencies.append( + .target(name: "CSQLite", condition: .when(platforms: [.linux])) + ) + sqliteTargets.append( + .systemLibrary( + name: "CSQLite", + pkgConfig: "sqlite3", + providers: [ + .apt(["libsqlite3-dev"]), + .yum(["sqlite-devel"]) + ] + ) + ) +} + let package = Package( name: "SQLite", products: [ @@ -21,26 +55,21 @@ let package = Package( ], dependencies: [ // Darwin platforms link the system SQLite3.framework; everywhere else - // has no system SQLite, so this package's embedded copy is used instead. + // uses this package's embedded copy, unless Linux opts into the system + // libsqlite3 with `SWIFT_BUILD_SYSTEM_SQLITE=1`. .package( url: "https://github.com/PureSwift/swift-sqlcipher", from: "0.1.0" ) ], - targets: [ + targets: sqliteTargets + [ .target( name: "SQLite", - dependencies: [ - .product( - name: "SQLCipher", - package: "swift-sqlcipher", - condition: .when(platforms: [.linux, .android, .windows, .wasi, .openbsd]) - ) - ], + dependencies: sqliteDependencies, swiftSettings: [ .define( "SQLITE_SWIFT_SQLCIPHER", - .when(platforms: [.linux, .android, .windows, .wasi, .openbsd]) + .when(platforms: embeddedSQLitePlatforms) ) ] ), diff --git a/README.md b/README.md index 33b9be8..30471e1 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,24 @@ DSL. - `Blob`, `Data`, `UUID`, and `Date` binding conversions - Cross-platform: uses the system `SQLite3` on Apple platforms and the embedded [swift-sqlcipher](https://github.com/PureSwift/swift-sqlcipher) build - everywhere else (Linux, Android, Windows, WASI, OpenBSD) + everywhere else (Linux, Android, Windows, WASI, OpenBSD), with Linux able to + link the system `libsqlite3` instead + +## System SQLite on Linux + +Linux uses the embedded SQLite build by default. To link the system SQLite +instead, install the development package and build with +`SWIFT_BUILD_SYSTEM_SQLITE=1`: + +```sh +apt-get install libsqlite3-dev pkg-config # Debian / Ubuntu +dnf install sqlite-devel pkgconf-pkg-config # Fedora / RHEL + +SWIFT_BUILD_SYSTEM_SQLITE=1 swift build +``` + +`pkg-config` is required in addition to the headers, since the system library +target resolves its flags through it. ## Installation diff --git a/Sources/CSQLite/module.modulemap b/Sources/CSQLite/module.modulemap new file mode 100644 index 0000000..0a291b5 --- /dev/null +++ b/Sources/CSQLite/module.modulemap @@ -0,0 +1,5 @@ +module CSQLite [system] { + header "shim.h" + link "sqlite3" + export * +} diff --git a/Sources/CSQLite/shim.h b/Sources/CSQLite/shim.h new file mode 100644 index 0000000..f52e1f0 --- /dev/null +++ b/Sources/CSQLite/shim.h @@ -0,0 +1 @@ +#include diff --git a/Sources/SQLite/AggregateFunction.swift b/Sources/SQLite/AggregateFunction.swift index 6eb79dc..bc81d94 100644 --- a/Sources/SQLite/AggregateFunction.swift +++ b/Sources/SQLite/AggregateFunction.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Backup.swift b/Sources/SQLite/Backup.swift index 64ba127..6578e8a 100644 --- a/Sources/SQLite/Backup.swift +++ b/Sources/SQLite/Backup.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Collation.swift b/Sources/SQLite/Collation.swift index 12e1aba..3277e67 100644 --- a/Sources/SQLite/Collation.swift +++ b/Sources/SQLite/Collation.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Connection.swift b/Sources/SQLite/Connection.swift index 6f23a40..b848c30 100644 --- a/Sources/SQLite/Connection.swift +++ b/Sources/SQLite/Connection.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Constants.swift b/Sources/SQLite/Constants.swift index baec0eb..31a5b3b 100644 --- a/Sources/SQLite/Constants.swift +++ b/Sources/SQLite/Constants.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Error.swift b/Sources/SQLite/Error.swift index 214c63d..6bc3c2d 100644 --- a/Sources/SQLite/Error.swift +++ b/Sources/SQLite/Error.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Function.swift b/Sources/SQLite/Function.swift index 7975a88..8a984fe 100644 --- a/Sources/SQLite/Function.swift +++ b/Sources/SQLite/Function.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/IncrementalBlob.swift b/Sources/SQLite/IncrementalBlob.swift index 727e1bc..f01e33c 100644 --- a/Sources/SQLite/IncrementalBlob.swift +++ b/Sources/SQLite/IncrementalBlob.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/PreparedStatement.swift b/Sources/SQLite/PreparedStatement.swift index 6abb236..2a9ac59 100644 --- a/Sources/SQLite/PreparedStatement.swift +++ b/Sources/SQLite/PreparedStatement.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Statement.swift b/Sources/SQLite/Statement.swift index 77dd89a..6813422 100644 --- a/Sources/SQLite/Statement.swift +++ b/Sources/SQLite/Statement.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/TypeAffinity.swift b/Sources/SQLite/TypeAffinity.swift index a664502..7abb69e 100644 --- a/Sources/SQLite/TypeAffinity.swift +++ b/Sources/SQLite/TypeAffinity.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/WAL.swift b/Sources/SQLite/WAL.swift index 05569c4..34d217f 100644 --- a/Sources/SQLite/WAL.swift +++ b/Sources/SQLite/WAL.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/WindowFunction.swift b/Sources/SQLite/WindowFunction.swift index 6619316..ed90010 100644 --- a/Sources/SQLite/WindowFunction.swift +++ b/Sources/SQLite/WindowFunction.swift @@ -10,7 +10,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import SwiftToolchainCSQLite +import CSQLite #else import SQLite3 #endif