-
-
Notifications
You must be signed in to change notification settings - Fork 795
SQLCipher (Official) Swift Package Manager Integration #1827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Conversation
… package trait is enabled - Package.swift -- Updates swift-tools-version to 6.1 to support traits -- Adds https://github.com/sqlcipher/SQLCipher.swift dependency -- Adds SQLCipher trait -- Adds SQLCipher dependency to GRDB target when SQLCipher trait is enabled -- Adds SQLCipherConfig library target to expose SQLCipher_config.h functions to swift with pass through to C variadic functions -- Adds SQLCipherConfig library depdency to GRDB target when SQLCipher trait is enabled -- Adds SQLCIPHER_HAS_CODEC swiftSettings/cSettings to GRDB target when SQLCipher trait is enabled -- Adds SQLCIPHER swiftSettings to GRDB target when SQLCipher trait is enabled -- Adds GRDBCIPHER_USE_ENCRYPTION to GRDBTests target when SQLCipher trait is enabled - Adjusts imports to check `#if SQLCIPHER` before `#if SWIFT_PACKAGE` - Adds Database+SQLCipher extension with SQLCipher operations, enabled by `#if SQLITE_HAS_CODEC` - Adds test_SPM_SQLCipher Makefile task and adds it as a dependent task of smokeTest Resolves groue#1772
… enabled (SQLCIPHER swiftSetting is set).
…bled - Removes SQLCipher related methods from Database as they are now moved to Database+SQLCipher - Adds SQLITE_DISABLE_SNAPSHOT swiftSetting to Package.swift when SQLCipher trait is enabled
…to test installing GRDB with SQLCipher trait - Adds test_install_SPM_SQLCipher Makefile task called as dependent task of test_install_SPM - Adjusts README.md SQLCipher example AppDependencies Package.swift to match GRDB platform versions
🥳 Thank you @R4N! I'm very happy we are converging. I'll review this great PR shortly! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm so very glad. Thank you @R4N, for your time, your work, and you very good ideas and improvements.
I have a few suggested changes and questions, but honestly we're very close to a successful merge :-)
- Removes exposing SQLCipherConfig shim package publicly in Package.swift - Calls dropAllDatabaseObjects from Database.erase() method when `#if SQLITE_HAS_CODEC` (SQLCipher enabled) - Adds `--traits SQLCipher` to swift build commands in test_SPM_SQLCipher Makefile task - Fixes formatting of XCODEBUILD commands in test_install_SPM_SQLCipher Makefile task - Removes setting SQLCIPHER swiftSetting in favor of using SQLCipher trait directly in import statements - Removes unneeded `#if SQLITE_VERSION_NUMBER >= 3029000` from SQLCipherConfig shim - Adjusts SQLCipher Information Accessors example code to use try variants in README.md - Adds details/summary to cipher_logging Example output in README.md - Adds cipherVersion display to sqlcipher SPM install test project - Removes references to Database+SQLCipher from GRDB.xcodeproj (only used for SPM) - Removes duplicate reference to AppDependencies in sqlcipher.xcodeproj (SQLCipher SPM example project)
…et/sqlcipher in README.md SQLCipher encryption section
…tion This is necessary for inheriting the SQLCipher passphrase. Also, update DatabaseConfigurationTests.testPrepareDatabase() so that it accurately counts the number of prepareDatabase invocations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! @R4N this is a great pull request :-)
I did not take the time to answer to this paragraph yet! Thank you very much! @R4N and @sjlombardo, you both have wonderfully found your way in this library. |
@R4N, Bad news. The test ( To reproduce, start from a clean stage (run You can also open This is a blocker 😬 [EDIT]
[EDIT] With Xcode 16.4,
Indeed the demo app is linked against SQLCipher: // prints "4.11.0 community"
let version = try String.fetchOne(db, sql: "PRAGMA cipher_version")
print(version) In summary, we have two blockers:
The first blocker is not due to this pull request. It was already there in #1826, where package traits were introduced. My personal focus is now to restore this basic functionality. Everything else is secondary (this pull request, #1825 and #1708). Unfortunately, we just can not go faster than Xcode. |
This seems like another scenario where importing packages within the Xcode UI doesn't play nice with package traits (even the default ones specified) yet. When I try running that make task using Xcode 26.x it complained about the missing module The issue seems to be that the default trait is not be getting setup properly so the dependency condition for GRDBSQLite isn't being met and hence not added: https://github.com/R4N/GRDB.swift/blob/4683362cf87e14a09ea13a581d2be694f6d5e614/Package.swift#L88 I had previously tested using GRDB with some of my modifications to include the SQLCipher trait both with the trait enabled (using the wrapper package) and without the trait enabled (both with the wrapper package and directly import using the Xcode UI which both worked prior). This was prior to the addition of the default GRDBSQLite trait. One immediate option that I see is removing the i.e. Remove the
And then always include
With these adjustments in place, I was able to successfully run
This configuration will:
I hope that Xcode will improve their support for adding swift Packages with traits in the near future (I'm surprised it's not already in Xcode 26!) When I ran This is why both One approach would be to update the swift-tools-version to 6.2, although that would require Xcode 26+ for consumers whereas 6.1 requires Xcode 16.4. |
I don't see how linking SQLCipher (or even a custom build of SQLite) with GRDB can be done reliably considering how dyld and swift currently works. |
To follow up on my previous comment with additional investigation results: Testing Proper Linking Without The Default Trait
When including GRDB directly in the Xcode UI (unable to set any traits on it)
When including GRDB in a wrapper package with no traits set and then consuming the wrapper package in Xcode UI
When including GRDB in a wrapper package with SQLCipher trait set and the consuming the wrapper package in Xcode UI
This output confirms:
Dependency scanning should omit the sqlite3 link when none of the source files depend on the module as outlined in this Apple documentation: https://developer.apple.com/documentation/xcode/building-your-project-with-explicit-module-dependencies When the SQLCipher trait is enabled, there is no
|
@R4N I agree wholeheartedly with point 1 & 2. If SQLCipher is built as a dylib Framework and is linked as a framework called Also, if GRDB links SQLite/SQLCipher statically as a private dependency this should also work (assuming there was no inline functions). Things get very hairy if any of your app's dependencies link in sqlite statically but also export those functions. We're experiencing that issue with a 3rd party vendor lib. I was just concerned that the efforts here might be potentially creating a similar issue. |
I'm following this conversation closely, and I appreciate that we're balancing between optimism and fair concerns. @R4N I admit I do not understand how removing the default trait can guarantee that GRDB+SQLCipher will be linked against SQLCipher when the package verbatim does not disable the GRDBSQLite target (which brings in the system SQLite3) with an SPM condition. I do appreciate that you did test the actual output with Please excuse this pile of questions, I'm just exploring the so many reasons it could turn wrong, and I'm trying to evaluate the risks. If what we're working with is a fragile pile of half-finished beta tools, and if tipping a GRDB toe there is bound to burst in my face, I'll seriously consider postponing our work to some future year, when Apple tooling is ready. The fact that Xcode 16.3/16.4 is able to link the demo app with SQLCipher, despite SQLCipher being guarded by traits, proves that traits are not reliable, and that the mere presence of SQLCipher in Package.swift can break apps that do not even know about SQLCipher. I mean, this is seriously concerning, right? @orj GRDB does inline calls to The GRDB module does not export ( |
Adds SQLCipher.swift Swift Package Manager integration when SQLCipher package trait is enabled
Changes
#if SQLITE_HAS_CODEC
Resolves #1772
Pull Request Checklist
development
branch.make smokeTest
terminal command runs without failure.Ongoing Support
The SQLCipher Team is committed to updating and supporting the official
SQLCipher.swift
Swift Package. We're happy to assist with any GitHub issues related to integration or troubleshooting usingGRDB.swift
withSQLCipher.swift
package dependency. Please feel free to raise an issue in the Official SQLCipher.swift repo