diff --git a/Package.swift b/Package.swift new file mode 100644 index 000000000..c02ac8f1b --- /dev/null +++ b/Package.swift @@ -0,0 +1,61 @@ +// swift-tools-version: 5.6 +import PackageDescription + +let package = Package( + name: "SQLCipher", + products: [ + .library( + name: "sqlcipher", + targets: ["sqlcipher"]), + ], + dependencies: [], + targets: [ + .executableTarget( + name: "Amalgamation", + path: "SwiftPM/Amalgamation" + ), + .plugin( + name: "AmalgamationPlugin", + capability: .buildTool(), + dependencies: ["Amalgamation"], + path: "SwiftPM/AmalgamationPlugin" + ), + .target( + name: "sqlcipher", + path: "SwiftPM/sqlcipher", + cSettings: [ + .define("NDEBUG", to: nil), + .define("SQLITE_HAS_CODEC", to: nil), + .define("SQLITE_TEMP_STORE", to: "2"), + .define("SQLITE_SOUNDEX", to: nil), + .define("SQLITE_THREADSAFE", to: nil), + .define("SQLITE_ENABLE_RTREE", to: nil), + .define("SQLITE_ENABLE_STAT3", to: nil), + .define("SQLITE_ENABLE_STAT4", to: nil), + .define("SQLITE_ENABLE_COLUMN_METADATA", to: nil), + .define("SQLITE_ENABLE_MEMORY_MANAGEMENT", to: nil), + .define("SQLITE_ENABLE_LOAD_EXTENSION", to: nil), + .define("SQLITE_ENABLE_FTS4", to: nil), + .define("SQLITE_ENABLE_FTS4_UNICODE61", to: nil), + .define("SQLITE_ENABLE_FTS3_PARENTHESIS", to: nil), + .define("SQLITE_ENABLE_UNLOCK_NOTIFY", to: nil), + .define("SQLITE_ENABLE_JSON1", to: nil), + .define("SQLITE_ENABLE_FTS5", to: nil), + .define("SQLCIPHER_CRYPTO_CC", to: nil), + .define("HAVE_USLEEP", to: "1") + ], + swiftSettings: [ + .define("SQLITE_HAS_CODEC") + ] + ,linkerSettings: [ + .linkedFramework("Foundation"), + .linkedFramework("Security") + ], + plugins: [ + .plugin( + name: "AmalgamationPlugin" + ) + ] + ) + ] +) diff --git a/SwiftPM/Amalgamation/main.swift b/SwiftPM/Amalgamation/main.swift new file mode 100644 index 000000000..ce7c3a28a --- /dev/null +++ b/SwiftPM/Amalgamation/main.swift @@ -0,0 +1,49 @@ +import Foundation + +func exec(_ command: String) throws -> String { + let proc = Process() + let pipe = Pipe() + + proc.standardOutput = pipe + proc.standardError = pipe + proc.arguments = ["-c", command] + proc.launchPath = "/bin/zsh" + proc.launch() + proc.waitUntilExit() + + let output = pipe.fileHandleForReading.readDataToEndOfFile() + return String(data: output, encoding: .utf8)! +} + +let pluginWorkDir = CommandLine.arguments[1] +let outputDir = CommandLine.arguments[2] + +// clean out the working directory and copy the package source files there +var prep = [ + "rm -rf '\(pluginWorkDir)'", + "cp -R . '\(pluginWorkDir)'" +] + +try prep.forEach { cmd in + let out = try exec(cmd) + print ("\(cmd) returned \(out)") +} + +// change to working directory +FileManager.default.changeCurrentDirectoryPath(pluginWorkDir) +print(FileManager.default.currentDirectoryPath) + +// build the amalgamation and copy it to the output folder +var build = [ + "./configure --with-crypto-lib=none", + "make clean", + "make sqlite3.c", + "mkdir -p gen/include", + "cp sqlite3.c \(outputDir)", + "cp sqlite3.h \(outputDir)" +] + +try build.forEach { cmd in + let out = try exec(cmd) + print ("\(cmd) returned \(out)") +} diff --git a/SwiftPM/AmalgamationPlugin/plugin.swift b/SwiftPM/AmalgamationPlugin/plugin.swift new file mode 100644 index 000000000..0246de957 --- /dev/null +++ b/SwiftPM/AmalgamationPlugin/plugin.swift @@ -0,0 +1,20 @@ +// swift-tools-version: 5.6 +import Foundation +import PackagePlugin + +@main struct AmalgamationPlugin: BuildToolPlugin { + func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] { + let outputDir = context.pluginWorkDirectory.appending("gen") + let toolPath = try context.tool(named: "Amalgamation").path + print("outputFilesDirectory: \(outputDir) pluginWorkDir: \(context.pluginWorkDirectory) toolPath: \(toolPath)") + return [.buildCommand( + displayName: "Running Amalgamation", + executable: toolPath, + arguments: [context.pluginWorkDirectory.string, outputDir.string], + outputFiles: [ + outputDir.appending("sqlite3.c"), + outputDir.appending("sqlite3.h") + ] + )] + } +} diff --git a/SwiftPM/sqlcipher/empty.c b/SwiftPM/sqlcipher/empty.c new file mode 100644 index 000000000..d38a6fdc4 --- /dev/null +++ b/SwiftPM/sqlcipher/empty.c @@ -0,0 +1 @@ +/* intentionally left empty */ diff --git a/SwiftPM/sqlcipher/include/sqlcipher-Bridging-Header.h b/SwiftPM/sqlcipher/include/sqlcipher-Bridging-Header.h new file mode 100644 index 000000000..bc2ad0d3a --- /dev/null +++ b/SwiftPM/sqlcipher/include/sqlcipher-Bridging-Header.h @@ -0,0 +1,4 @@ +#ifndef sqlcipher_Bridging_Header_h +#define sqlcipher_Bridging_Header_h +#import "sqlite3.h" +#endif /* sqlcipher_Bridging_Header_h */ diff --git a/SwiftPM/sqlcipher/sqlcipher.modulemap b/SwiftPM/sqlcipher/sqlcipher.modulemap new file mode 100644 index 000000000..a7b937634 --- /dev/null +++ b/SwiftPM/sqlcipher/sqlcipher.modulemap @@ -0,0 +1,5 @@ +module sqlcipher { + header "include/sqlcipher-Bridging-Header.h" + link "sqlcipher" + export * +}