diff --git a/.cargo/config.toml b/.cargo/config.toml index caa816c..abb061f 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,3 @@ - # Previously we added this to rustflags for all linux builds: # "-C", "link-arg=-lgcc_eh" # It was to fix this error when loading the loadable extension: @@ -86,3 +85,18 @@ rustflags = [ rustflags = [ "-C", "link-arg=-Wl,-soname,libpowersync.so", ] + +[target.aarch64-apple-watchos] +rustflags = [ + "-C", "link-arg=-mwatchos-version-min=9.0", +] + +[target.aarch64-apple-watchos-sim] +rustflags = [ + "-C", "link-arg=-mwatchsimulator-version-min=9.0", +] + +[target.x86_64-apple-watchos-sim] +rustflags = [ + "-C", "link-arg=-mwatchos-version-min=9.0", +] diff --git a/.gitignore b/.gitignore index 5fee65f..f7f55d4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ target/ *.tar.gz *.tar.xz *.zip +.build diff --git a/Cargo.lock b/Cargo.lock index 303b7ec..4c08108 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,6 +273,14 @@ dependencies = [ "sqlite_nostd", ] +[[package]] +name = "powersync_static" +version = "0.4.0" +dependencies = [ + "powersync_core", + "sqlite_nostd", +] + [[package]] name = "prettyplease" version = "0.2.32" diff --git a/Cargo.toml b/Cargo.toml index a802bd4..e0baca7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,3 +38,4 @@ repository = "https://github.com/powersync-ja/powersync-sqlite-core" [workspace.dependencies] sqlite_nostd = { path="./sqlite-rs-embedded/sqlite_nostd" } + diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..498c829 --- /dev/null +++ b/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 5.7 + +// NOTE! This is never released, we're only using this to support local builds builds for the +// Swift SDK. +import PackageDescription +let packageName = "PowerSyncSQLiteCore" + +let package = Package( + name: packageName, + platforms: [ + .iOS(.v13), + .macOS(.v10_15), + .watchOS(.v9) + ], + products: [ + .library( + name: packageName, + targets: [packageName]), + ], + targets: [ + .binaryTarget( + name: packageName, + path: "powersync-sqlite-core.xcframework" + ) + ] +) diff --git a/crates/static/Cargo.toml b/crates/static/Cargo.toml new file mode 100644 index 0000000..cc7e0f3 --- /dev/null +++ b/crates/static/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "powersync_static" +edition.workspace = true +version.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +authors.workspace = true +keywords.workspace = true + +[lib] +name = "powersync" +crate-type = ["staticlib"] + +[dependencies] +sqlite_nostd = { workspace=true } + +[dependencies.powersync_core] +path = "../core" +default-features = false +features = [] + +[features] +default = ["powersync_core/static", "powersync_core/omit_load_extension", "sqlite_nostd/omit_load_extension"] diff --git a/crates/static/README.md b/crates/static/README.md new file mode 100644 index 0000000..07aefdd --- /dev/null +++ b/crates/static/README.md @@ -0,0 +1 @@ +Builds the core extension as a static library, exposing the `powersync_init_static` function to load it. diff --git a/crates/static/src/lib.rs b/crates/static/src/lib.rs new file mode 100644 index 0000000..9e5a9de --- /dev/null +++ b/crates/static/src/lib.rs @@ -0,0 +1,31 @@ +#![no_std] +#![feature(vec_into_raw_parts)] +#![feature(core_intrinsics)] +#![allow(internal_features)] +#![feature(lang_items)] + +extern crate alloc; + +// Defines sqlite3_powersync_init +#[allow(unused_imports)] +use powersync_core; + +// Use the SQLite allocator, allowing us to freely transfer memory between SQLite and Rust. +#[cfg(not(test))] +use sqlite_nostd::SQLite3Allocator; + +#[cfg(not(test))] +#[global_allocator] +static ALLOCATOR: SQLite3Allocator = SQLite3Allocator {}; + +// Custom Panic handler for WASM and other no_std builds +#[cfg(not(test))] +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + core::intrinsics::abort() +} + +#[cfg(not(target_family = "wasm"))] +#[cfg(not(test))] +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} diff --git a/powersync-sqlite-core.podspec b/powersync-sqlite-core.podspec index 27040b5..5075a6c 100644 --- a/powersync-sqlite-core.podspec +++ b/powersync-sqlite-core.podspec @@ -13,7 +13,7 @@ PowerSync extension for SQLite. s.source = { :http => "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v#{s.version}/powersync-sqlite-core.xcframework.zip" } s.vendored_frameworks = 'powersync-sqlite-core.xcframework' - s.ios.deployment_target = '11.0' s.osx.deployment_target = '10.13' + s.watchos.deployment_target = '9.0' end diff --git a/tool/build_xcframework.sh b/tool/build_xcframework.sh index 37619a7..d377f9d 100755 --- a/tool/build_xcframework.sh +++ b/tool/build_xcframework.sh @@ -3,12 +3,48 @@ set -e # Adapted from https://github.com/vlcn-io/cr-sqlite/blob/main/core/all-ios-loadable.sh - BUILD_DIR=./build -DIST_PACKAGE_DIR=./dist +TARGETS=( + # iOS and simulator + aarch64-apple-ios + aarch64-apple-ios-sim + x86_64-apple-ios -function createXcframework() { - plist=$(cat << EOF + # macOS + aarch64-apple-darwin + x86_64-apple-darwin + + # watchOS and simulator + aarch64-apple-watchos + aarch64-apple-watchos-sim + x86_64-apple-watchos-sim + arm64_32-apple-watchos +) +VERSION=0.4.0 + +function generatePlist() { + min_os_version=0 + additional_keys="" + # We support versions 11.0 or later for iOS and macOS. For watchOS, we need 9.0 or later. + case $1 in + *"watchos"*) + additional_keys=$(cat <CFBundleSupportedPlatforms + + WatchOS + + UIDeviceFamily + + 4 + +EOF + ) + min_os_version="9.0";; + *) + min_os_version="11.0";; + esac + + cat < @@ -26,18 +62,25 @@ function createXcframework() { CFBundleSignature ???? MinimumOSVersion - 11.0 + $min_os_version CFBundleVersion - 0.4.0 + $VERSION CFBundleShortVersionString - 0.4.0 + $VERSION +$additional_keys EOF -) +} + +function createXcframework() { + ios_plist=$(generatePlist "ios") + macos_plist=$(generatePlist "macos") + watchos_plist=$(generatePlist "watchos") + echo "===================== create ios device framework =====================" mkdir -p "${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework" - echo "${plist}" > "${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework/Info.plist" + echo "${ios_plist}" > "${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework/Info.plist" cp -f "./target/aarch64-apple-ios/release_apple/libpowersync.dylib" "${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework/powersync-sqlite-core" install_name_tool -id "@rpath/powersync-sqlite-core.framework/powersync-sqlite-core" "${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework/powersync-sqlite-core" # Generate dSYM for iOS Device @@ -45,7 +88,7 @@ EOF echo "===================== create ios simulator framework =====================" mkdir -p "${BUILD_DIR}/ios-arm64_x86_64-simulator/powersync-sqlite-core.framework" - echo "${plist}" > "${BUILD_DIR}/ios-arm64_x86_64-simulator/powersync-sqlite-core.framework/Info.plist" + echo "${ios_plist}" > "${BUILD_DIR}/ios-arm64_x86_64-simulator/powersync-sqlite-core.framework/Info.plist" lipo ./target/aarch64-apple-ios-sim/release_apple/libpowersync.dylib ./target/x86_64-apple-ios/release_apple/libpowersync.dylib -create -output "${BUILD_DIR}/ios-arm64_x86_64-simulator/powersync-sqlite-core.framework/powersync-sqlite-core" install_name_tool -id "@rpath/powersync-sqlite-core.framework/powersync-sqlite-core" "${BUILD_DIR}/ios-arm64_x86_64-simulator/powersync-sqlite-core.framework/powersync-sqlite-core" # Generate dSYM for iOS Simulator @@ -53,7 +96,7 @@ EOF echo "===================== create macos framework =====================" mkdir -p "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/A/Resources" - echo "${plist}" > "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/A/Resources/Info.plist" + echo "${ios_plist}" > "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/A/Resources/Info.plist" lipo ./target/x86_64-apple-darwin/release_apple/libpowersync.dylib ./target/aarch64-apple-darwin/release_apple/libpowersync.dylib -create -output "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/A/powersync-sqlite-core" install_name_tool -id "@rpath/powersync-sqlite-core.framework/powersync-sqlite-core" "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/A/powersync-sqlite-core" ln -sf A "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/Current" @@ -62,9 +105,27 @@ EOF # Generate dSYM for macOS dsymutil "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework/Versions/A/powersync-sqlite-core" -o "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework.dSYM" + echo "===================== create watchos device framework =====================" + mkdir -p "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework/Versions/A/Resources" + echo "${watchos_plist}" > "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework/Versions/A/Resources/Info.plist" + lipo ./target/aarch64-apple-watchos/release_apple/libpowersync.a ./target/arm64_32-apple-watchos/release_apple/libpowersync.a -create -output "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework/Versions/A/powersync-sqlite-core" + # install_name_tool isn't necessary, we use a statically-linked library + ln -sf A "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework/Versions/Current" + ln -sf Versions/Current/powersync-sqlite-core "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework/powersync-sqlite-core" + ln -sf Versions/Current/Resources "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework/Resources" + + echo "===================== create watchos simulator framework =====================" + mkdir -p "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework/Versions/A/Resources" + echo "${watchos_plist}" > "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework/Versions/A/Resources/Info.plist" + lipo ./target/aarch64-apple-watchos-sim/release_apple/libpowersync.a ./target/x86_64-apple-watchos-sim/release_apple/libpowersync.a -create -output "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework/Versions/A/powersync-sqlite-core" + # install_name_tool isn't necessary, we use a statically-linked library + ln -sf A "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework/Versions/Current" + ln -sf Versions/Current/powersync-sqlite-core "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework/powersync-sqlite-core" + ln -sf Versions/Current/Resources "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework/Resources" + echo "===================== create xcframework =====================" rm -rf "${BUILD_DIR}/powersync-sqlite-core.xcframework" - # "-debug-symbols" requires the absolute path + xcodebuild -create-xcframework \ -framework "${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework" \ -debug-symbols "$(pwd -P)/${BUILD_DIR}/ios-arm64/powersync-sqlite-core.framework.dSYM" \ @@ -72,7 +133,9 @@ EOF -debug-symbols "$(pwd -P)/${BUILD_DIR}/ios-arm64_x86_64-simulator/powersync-sqlite-core.framework.dSYM" \ -framework "${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework" \ -debug-symbols "$(pwd -P)/${BUILD_DIR}/macos-arm64_x86_64/powersync-sqlite-core.framework.dSYM" \ - -output "${BUILD_DIR}/powersync-sqlite-core.xcframework" \ + -framework "${BUILD_DIR}/watchos-arm64_arm64_32_armv7k/powersync-sqlite-core.framework" \ + -framework "${BUILD_DIR}/watchos-arm64_x86_64-simulator/powersync-sqlite-core.framework" \ + -output "${BUILD_DIR}/powersync-sqlite-core.xcframework" cp -Rf "${BUILD_DIR}/powersync-sqlite-core.xcframework" "powersync-sqlite-core.xcframework" zip -r --symlinks powersync-sqlite-core.xcframework.zip powersync-sqlite-core.xcframework LICENSE README.md @@ -84,13 +147,18 @@ EOF rm -rf powersync-sqlite-core.xcframework -# iOS -cargo build -p powersync_loadable --profile release_apple --target aarch64-apple-ios -Zbuild-std -# Simulator -cargo build -p powersync_loadable --profile release_apple --target aarch64-apple-ios-sim -Zbuild-std -cargo build -p powersync_loadable --profile release_apple --target x86_64-apple-ios -Zbuild-std -# macOS -cargo build -p powersync_loadable --profile release_apple --target aarch64-apple-darwin -Zbuild-std -cargo build -p powersync_loadable --profile release_apple --target x86_64-apple-darwin -Zbuild-std +for TARGET in ${TARGETS[@]}; do + echo "Building PowerSync loadable extension for $TARGET" + + if [[ $TARGET == *"watchos"* ]]; then + cargo build \ + -p powersync_static \ + --profile release_apple \ + --target $TARGET \ + -Zbuild-std + else + cargo build -p powersync_loadable --profile release_apple --target $TARGET -Zbuild-std + fi +done createXcframework