diff --git a/.cargo/config.toml b/.cargo/config.toml index abb061f6..87890bb2 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -17,22 +17,25 @@ # 173K, loading works # Conclusion: -lgcc_eh has no effect when using -Z build-std. -[target.x86_64-unknown-linux-gnu] +[target.'cfg(target_os = "linux")'] rustflags = [ "-C", "link-arg=-lgcc_eh", ] +[target.x86_64-unknown-linux-gnu] +linker = "x86_64-linux-gnu-gcc" + [target.i686-unknown-linux-gnu] -rustflags = [ - "-C", "link-arg=-lgcc_eh", -] +linker = "i686-linux-gnu-gcc" [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" -rustflags = [ - "-C", "link-arg=-lgcc_eh", -] +[target.armv7-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabihf-gcc" + +[target.riscv64gc-unknown-linux-gnu] +linker = "riscv64-linux-gnu-gcc" # For iOS and macOS, we need to specify the minimum/target version. # This must match the versions in the podspec file. diff --git a/.github/actions/android/action.yml b/.github/actions/android/action.yml index f973471c..0147576a 100644 --- a/.github/actions/android/action.yml +++ b/.github/actions/android/action.yml @@ -56,7 +56,7 @@ runs: uses: actions/upload-artifact@v4 with: name: android-library - retention-days: 1 + retention-days: 14 compression-level: 0 # We're uploading a zip, no need to compress again path: android/build/distributions/powersync_android.zip if-no-files-found: error diff --git a/.github/actions/linux/action.yml b/.github/actions/linux/action.yml new file mode 100644 index 00000000..d1bbfbc2 --- /dev/null +++ b/.github/actions/linux/action.yml @@ -0,0 +1,37 @@ +name: "Build Linux libraries" +description: "Create artifact for Linux libraries" + +runs: + using: "composite" + steps: + - name: Install Rust Nightly + uses: dtolnay/rust-toolchain@stable + with: + toolchain: nightly-2025-04-15 + components: rust-src + targets: aarch64-unknown-linux-gnu,x86_64-unknown-linux-gnu,i686-unknown-linux-gnu,riscv64gc-unknown-linux-gnu,armv7-unknown-linux-gnueabihf + + - name: Install cross-compiling GCC + shell: bash + run: | + sudo apt install -y gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu gcc-arm-linux-gnueabihf gcc-i686-linux-gnu + + - name: Build binaries + shell: bash + run: | + ./tool/build_linux.sh x64 + ./tool/build_linux.sh aarch64 + ./tool/build_linux.sh x86 + ./tool/build_linux.sh armv7 + ./tool/build_linux.sh riscv64gc + + - uses: actions/upload-artifact@v4 + with: + name: linux-library + retention-days: 14 + path: | + libpowersync_x64.so + libpowersync_x86.so + libpowersync_aarch64.so + libpowersync_armv7.so + libpowersync_riscv64gc.so diff --git a/.github/actions/macos/action.yml b/.github/actions/macos/action.yml new file mode 100644 index 00000000..e304e37a --- /dev/null +++ b/.github/actions/macos/action.yml @@ -0,0 +1,26 @@ +name: "Build macoS libraries" +description: "Create artifact for macOS libraries" + +runs: + using: "composite" + steps: + - name: Install Rust Nightly + uses: dtolnay/rust-toolchain@stable + with: + toolchain: nightly-2025-04-15 + components: rust-src + targets: x86_64-apple-darwin,aarch64-apple-darwin + + - name: Build binaries + shell: bash + run: | + ./tool/build_macos.sh x64 + ./tool/build_macos.sh aarch64 + + - uses: actions/upload-artifact@v4 + with: + name: macos-library + retention-days: 14 + path: | + libpowersync_x64.dylib + libpowersync_aarch64.dylib diff --git a/.github/actions/wasm/action.yml b/.github/actions/wasm/action.yml new file mode 100644 index 00000000..723bf3aa --- /dev/null +++ b/.github/actions/wasm/action.yml @@ -0,0 +1,29 @@ +name: "Build wasm libraries" +description: "Create artifact for wasm libraries" + +runs: + using: "composite" + steps: + - name: Install Rust Nightly + uses: dtolnay/rust-toolchain@stable + with: + toolchain: nightly-2025-04-15 + components: rust-src + + - name: Setup emsdk + uses: mymindstorm/setup-emsdk@v14 + with: + version: 4.0.10 + + - name: Build WASM + shell: bash + run: ./tool/build_wasm.sh + + - uses: actions/upload-artifact@v4 + with: + name: wasm-library + retention-days: 14 + path: | + libpowersync-async.wasm + libpowersync.wasm + libpowersync-wasm.a diff --git a/.github/actions/windows/action.yml b/.github/actions/windows/action.yml new file mode 100644 index 00000000..46d55c28 --- /dev/null +++ b/.github/actions/windows/action.yml @@ -0,0 +1,28 @@ +name: "Build Windows libraries" +description: "Create artifact for Windows libraries" + +runs: + using: "composite" + steps: + - name: Install Rust Nightly + uses: dtolnay/rust-toolchain@stable + with: + toolchain: nightly-2025-04-15 + components: rust-src + targets: x86_64-pc-windows-msvc,aarch64-pc-windows-msvc,i686-pc-windows-msvc + + - name: Build binaries + shell: bash + run: | + ./tool/build_windows.sh x64 + ./tool/build_windows.sh aarch64 + ./tool/build_windows.sh x86 + + - uses: actions/upload-artifact@v4 + with: + name: windows-library + retention-days: 14 + path: | + powersync_x64.dll + powersync_aarch64.dll + powersync_x86.dll diff --git a/.github/actions/xcframework/action.yml b/.github/actions/xcframework/action.yml new file mode 100644 index 00000000..5e4c498d --- /dev/null +++ b/.github/actions/xcframework/action.yml @@ -0,0 +1,45 @@ +name: "Build xcframework" +description: "Create artifact with XCFramework for apple targets" + +runs: + using: "composite" + steps: + - name: Setup + shell: bash + run: | + rustup toolchain install nightly-2025-04-15-aarch64-apple-darwin + rustup component add rust-src --toolchain nightly-2025-04-15-aarch64-apple-darwin + rustup target add \ + x86_64-apple-darwin \ + aarch64-apple-darwin \ + aarch64-apple-ios \ + aarch64-apple-ios-sim \ + x86_64-apple-ios + + - name: setup-cocoapods + uses: maxim-lobanov/setup-cocoapods@v1 + with: + version: 1.16.2 + + - name: Set up XCode + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: latest-stable + + - name: Build iOS & macOS xcframework + shell: bash + run: | + ./tool/build_xcframework.sh + + - name: Lint pod + shell: bash + run: | + pod lib lint + + - uses: actions/upload-artifact@v4 + with: + name: xcframework + retention-days: 14 + compression: 0 # We're uploading a zip archive, no need to compress agan + path: | + powersync-sqlite-core.xcframework.zip diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml deleted file mode 100644 index 12ca5ce2..00000000 --- a/.github/workflows/android.yml +++ /dev/null @@ -1,17 +0,0 @@ -on: - push: - pull_request: -name: "android" -jobs: - build: - name: Building Android - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Build Android - uses: ./.github/actions/android - with: - sign-publication: '0' diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml deleted file mode 100644 index 4c6057ee..00000000 --- a/.github/workflows/ios.yml +++ /dev/null @@ -1,37 +0,0 @@ -on: - push: - pull_request: -name: "ios" -jobs: - build: - name: Building iOS - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: macos-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Setup - run: | - rustup toolchain install nightly-2025-04-15-aarch64-apple-darwin - rustup component add rust-src --toolchain nightly-2025-04-15-aarch64-apple-darwin - rustup target add \ - x86_64-apple-darwin \ - aarch64-apple-darwin \ - aarch64-apple-ios \ - aarch64-apple-ios-sim \ - x86_64-apple-ios - - - name: setup-cocoapods - uses: maxim-lobanov/setup-cocoapods@v1 - with: - version: 1.16.2 - - - name: Build iOS & macOS xcframework - run: | - ./tool/build_xcframework.sh - - - name: Lint pod - run: | - pod lib lint diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 0e8d7cb9..00000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,40 +0,0 @@ -on: - push: - pull_request: -name: "linux" -jobs: - build_x86_64: - name: Building Linux x86_64 - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binaries - run: ./tool/build_linux.sh x64 - - build_aarch64: - name: Building Linux aarch64 - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: ubuntu-arm64 - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binaries - run: ./tool/build_linux.sh aarch64 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml deleted file mode 100644 index a59e0cda..00000000 --- a/.github/workflows/macos.yml +++ /dev/null @@ -1,40 +0,0 @@ -on: - push: - pull_request: -name: "macos" -jobs: - build_macOS_aarch64: - name: Building macOS aarch64 - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: macos-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binary - run: ./tool/build_macos.sh aarch64 - - build_macOS_x64: - name: Building macOS x64 - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: macos-14 - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binary - run: ./tool/build_macos.sh x64 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7c583505..d14ea5e4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,8 +28,42 @@ jobs: body="Release $tag" gh release create --draft "$tag" --title "$tag" --notes "$body" - build_android: - name: Build Android + libs_linux: + name: Building Linux libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build Android + uses: ./.github/actions/linux + + libs_macos: + name: Building macOS libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build macOS + uses: ./.github/actions/macos + + libs_windows: + name: Building Windows libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build Windows + uses: ./.github/actions/windows + + libs_android: + name: Building Android libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -41,12 +75,35 @@ jobs: gpg-key: ${{ secrets.GPG_PRIVATE_KEY }} gpg-password: ${{ secrets.GPG_PASSWORD }} + libs_wasm: + name: Basic WASM build + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Build wasm + uses: ./.github/actions/wasm + + libs_xcframework: + name: Build XCFramework + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build XCFramework + uses: ./.github/actions/xcframework + publish_android: permissions: contents: read packages: write name: Publish Android - needs: [ draft_release, build_android ] + needs: [ draft_release, libs_android ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -64,32 +121,17 @@ jobs: publish_ios_pod_and_spm_package: name: Publish iOS - needs: [ draft_release ] + needs: [ draft_release, libs_xcframework ] runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: true - - name: Setup - run: | - rustup toolchain install nightly-2025-04-15-aarch64-apple-darwin - rustup component add rust-src --toolchain nightly-2025-04-15-aarch64-apple-darwin - rustup target add \ - x86_64-apple-darwin \ - aarch64-apple-darwin \ - aarch64-apple-ios \ - aarch64-apple-ios-sim \ - x86_64-apple-ios - - - name: setup-cocoapods - uses: maxim-lobanov/setup-cocoapods@v1 + - name: Download libs + uses: actions/download-artifact@v5 with: - version: 1.16.2 - - - name: Build iOS & macOS xcframework - run: | - ./tool/build_xcframework.sh + name: xcframework - name: Lint pod run: | @@ -130,153 +172,54 @@ jobs: "fileName": "${{ steps.fileName.outputs.fileName }}" } - publish_linux_x86_64: - name: Publish Linux x86_64 - needs: [ draft_release ] + publish_desktop: + name: Publish Desktop libraries + needs: [ draft_release, libs_linux, libs_macos, libs_windows ] runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binaries - run: ./tool/build_linux.sh x64 - - name: Upload binary - uses: ./.github/actions/upload - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - file-name: libpowersync_x64.so - tag: ${{ needs.draft_release.outputs.tag }} - - publish_linux_aarch64: - name: Publish Linux aarch64 - needs: [ draft_release ] - runs-on: ubuntu-arm64 steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binaries - run: ./tool/build_linux.sh aarch64 - - - name: Upload binary - uses: ./.github/actions/upload - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - file-name: libpowersync_aarch64.so - tag: ${{ needs.draft_release.outputs.tag }} - - publish_windows_x64: - name: Publish Windows x64 - needs: [ draft_release ] - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binary - run: bash tool/build_windows.sh x64 - - - name: Upload binary - uses: ./.github/actions/upload - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - file-name: powersync_x64.dll - tag: ${{ needs.draft_release.outputs.tag }} - - publish_macOS_aarch64: - name: Publish macOS aarch64 - needs: [ draft_release ] - runs-on: macos-latest - steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: true - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable + - name: Download libs + uses: actions/download-artifact@v5 with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binary - run: ./tool/build_macos.sh aarch64 - - - name: Upload binary - uses: ./.github/actions/upload + name: linux-library + path: dart/assets + - name: Download libs + uses: actions/download-artifact@v5 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - file-name: libpowersync_aarch64.dylib - tag: ${{ needs.draft_release.outputs.tag }} - - publish_macOS_x64: - name: Publish macOS x64 - needs: [ draft_release ] - runs-on: macos-14 - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable + name: macos-library + path: dart/assets + - name: Download libs + uses: actions/download-artifact@v5 with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binary - run: ./tool/build_macos.sh x64 + name: windows-library + path: dart/assets - name: Upload binary - uses: ./.github/actions/upload - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - file-name: libpowersync_x64.dylib - tag: ${{ needs.draft_release.outputs.tag }} + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + run: | + gh release upload "${{ needs.draft_release.outputs.tag }}" *.dll + gh release upload "${{ needs.draft_release.outputs.tag }}" *.dylib + gh release upload "${{ needs.draft_release.outputs.tag }}" *.so publish_wasm: name: Publish WASM builds - needs: [ draft_release ] + needs: [ draft_release, libs_wasm ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: true - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable + - name: Download wasm bundle + uses: actions/download-artifact@v5 with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Setup emsdk - uses: mymindstorm/setup-emsdk@v14 - with: - version: 4.0.10 - - - name: Build WASM - run: ./tool/build_wasm.sh + name: wasm-library - name: Upload libpowersync.wasm uses: ./.github/actions/upload @@ -308,11 +251,7 @@ jobs: - draft_release - publish_android - publish_ios_pod_and_spm_package - - publish_linux_x86_64 - - publish_linux_aarch64 - - publish_windows_x64 - - publish_macOS_aarch64 - - publish_macOS_x64 + - publish_desktop - publish_wasm steps: - name: Create issue diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 45c313b4..718c3312 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,20 +4,87 @@ on: name: "tests" jobs: - build: - name: Testing on ${{ matrix.os }} + libs_linux: + name: Building Linux libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build Linux libraries + uses: ./.github/actions/linux + + libs_macos: + name: Building macOS libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build macOS + uses: ./.github/actions/macos + + libs_windows: + name: Building Windows libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build Windows + uses: ./.github/actions/windows + + libs_android: + name: Building Android libraries + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build Android + uses: ./.github/actions/android + with: + sign-publication: '0' + + libs_wasm: + name: Basic WASM build + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Build wasm + uses: ./.github/actions/wasm + + libs_xcframework: + name: Build XCFramework + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build XCFramework + uses: ./.github/actions/xcframework + + rust_unit_tests: + name: Rust unit tests on ${{ matrix.os }} if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-24.04, macos-latest] - steps: - uses: actions/checkout@v4 with: submodules: true - - uses: dart-lang/setup-dart@v1 - name: Ubuntu setup if: matrix.os == 'ubuntu-24.04' @@ -55,11 +122,28 @@ jobs: run: | ./target/release/sqlite3 ":memory:" ".load ./target/release/libpowersync" "select powersync_rs_version()" + build: + name: Testing on ${{ matrix.os }} + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + runs-on: ${{ matrix.os }} + needs: [libs_linux, libs_macos, libs_windows] + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, ubuntu-arm64, macos-latest, windows-latest, windows-11-arm] + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - uses: dart-lang/setup-dart@v1 + - uses: actions/cache@v4 id: sqlite_build with: path: dart/.dart_tool/sqlite3/ - key: ${{ runner.os }}-${{ hashFiles('dart/tool/') }} + key: ${{ matrix.os }}-${{ hashFiles('dart/tool/') }} - name: Setup Dart tests working-directory: dart @@ -68,6 +152,28 @@ jobs: dart run tool/download_sqlite3.dart dart analyze + - name: Download libs + uses: actions/download-artifact@v5 + with: + name: linux-library + path: dart/assets + - name: Download libs + uses: actions/download-artifact@v5 + with: + name: macos-library + path: dart/assets + - name: Download libs + uses: actions/download-artifact@v5 + with: + name: windows-library + path: dart/assets + + - name: View downloaded artifacts + if: runner.os == 'Linux' + working-directory: dart + run: | + ls -al assets/ + - name: Dart tests on Linux if: runner.os == 'Linux' working-directory: dart @@ -82,3 +188,27 @@ jobs: run: | CORE_TEST_SQLITE=.dart_tool/sqlite3/latest/libsqlite3.dylib dart test -P skip_slow CORE_TEST_SQLITE=.dart_tool/sqlite3/minimum/libsqlite3.dylib dart test -P skip_slow + + valgrind: + name: Testing with Valgrind on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + strategy: + matrix: + include: + - os: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Install valgrind + run: sudo apt update && sudo apt install -y valgrind + + - name: Install Cargo Valgrind + run: | + cargo install cargo-valgrind + + - name: Test Core + run: | + cargo valgrind test -p powersync_core --features loadable_extension diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml deleted file mode 100644 index d780142d..00000000 --- a/.github/workflows/valgrind.yml +++ /dev/null @@ -1,28 +0,0 @@ -on: - push: - pull_request: -name: "valgrind" -jobs: - build: - name: Testing with Valgrind on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - strategy: - matrix: - include: - - os: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install valgrind - run: sudo apt update && sudo apt install -y valgrind - - - name: Install Cargo Valgrind - run: | - cargo install cargo-valgrind - - - name: Test Core - run: | - cargo valgrind test -p powersync_core --features loadable_extension diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml deleted file mode 100644 index 0e9cb647..00000000 --- a/.github/workflows/wasm.yml +++ /dev/null @@ -1,27 +0,0 @@ -on: - push: - pull_request: -name: "wasm" -jobs: - build_wasm: - name: Basic WASM build - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Setup emsdk - uses: mymindstorm/setup-emsdk@v14 - with: - version: 4.0.10 - - - name: Build WASM - run: ./tool/build_wasm.sh diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index 5ac33a3d..00000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,22 +0,0 @@ -on: - push: - pull_request: -name: "windows" -jobs: - build_windows: - name: Building Windows - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-04-15 - components: rust-src - - - name: Build binary - run: ./tool/build_windows.sh x64 diff --git a/dart/pubspec.lock b/dart/pubspec.lock index c15dc216..f1e15419 100644 --- a/dart/pubspec.lock +++ b/dart/pubspec.lock @@ -17,6 +17,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.5.6" + archive: + dependency: "direct dev" + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.dev" + source: hosted + version: "4.0.7" args: dependency: transitive description: @@ -153,6 +161,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + http: + dependency: "direct dev" + description: + name: http + sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 + url: "https://pub.dev" + source: hosted + version: "1.5.0" http_multi_server: dependency: transitive description: @@ -265,6 +281,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" power_extensions: dependency: transitive description: diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index aa361af1..12a25c8a 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -17,3 +17,5 @@ dev_dependencies: convert: ^3.1.2 meta: ^1.16.0 path: ^1.9.1 + http: ^1.5.0 + archive: ^4.0.7 diff --git a/dart/test/utils/native_test_utils.dart b/dart/test/utils/native_test_utils.dart index 36db4a56..db38b8f5 100644 --- a/dart/test/utils/native_test_utils.dart +++ b/dart/test/utils/native_test_utils.dart @@ -8,7 +8,7 @@ import 'package:path/path.dart' as p; const defaultSqlitePath = 'libsqlite3.so.0'; -const libPath = '../target/debug'; +const cargoDebugPath = '../target/debug'; var didLoadExtension = false; void applyOpenOverride() { @@ -44,16 +44,45 @@ CommonDatabase openTestDatabase( void loadExtension() { applyOpenOverride(); - var lib = DynamicLibrary.open(getLibraryForPlatform(path: libPath)); + // Using an absolute path is required for macOS, where Dart can't dlopen + // relative paths due to being a "hardened program". + var lib = + DynamicLibrary.open(p.normalize(p.absolute(resolvePowerSyncLibrary()))); var extension = SqliteExtension.inLibrary(lib, 'sqlite3_powersync_init'); sqlite3.ensureExtensionLoaded(extension); didLoadExtension = true; } -String getLibraryForPlatform({String? path = "."}) { - // Using an absolute path is required for macOS, where Dart can't dlopen - // relative paths due to being a "hardened program". - return p.normalize(p.absolute(switch (Abi.current()) { +String resolvePowerSyncLibrary() { + if (Directory('assets').existsSync()) { + // For the CI tests, we download prebuilt artifacts from an earlier step + // into assets. Use that. + const prefix = 'assets'; + + return p.join( + prefix, + switch (Abi.current()) { + Abi.macosX64 => 'libpowersync_x64.dylib', + Abi.macosArm64 => 'libpowersync_aarch64.dylib', + Abi.windowsX64 => 'powersync_x64.dll', + Abi.windowsArm64 => 'powersync_aarch64.dll', + Abi.linuxX64 => 'libpowersync_x64.so', + Abi.linuxArm => 'libpowersync_armv7.so', + Abi.linuxArm64 => 'libpowersync_aarch64.so', + Abi.linuxRiscv64 => 'libpowersync_riscv64gc.so', + _ => throw ArgumentError( + 'Unsupported processor architecture "${Abi.current()}". ' + 'Please open an issue on GitHub to request it.', + ) + }); + } else { + // Otherwise, use a local build from ../target/debug/. + return _getLibraryForPlatform(); + } +} + +String _getLibraryForPlatform({String? path = cargoDebugPath}) { + return switch (Abi.current()) { Abi.androidArm || Abi.androidArm64 || Abi.androidX64 => @@ -70,5 +99,5 @@ String getLibraryForPlatform({String? path = "."}) { 'Unsupported processor architecture "${Abi.current()}". ' 'Please open an issue on GitHub to request it.', ) - })); + }; } diff --git a/dart/tool/download_sqlite3.dart b/dart/tool/download_sqlite3.dart index a5b3c94d..3215fd12 100644 --- a/dart/tool/download_sqlite3.dart +++ b/dart/tool/download_sqlite3.dart @@ -1,6 +1,9 @@ +import 'dart:ffi'; import 'dart:io'; +import 'package:archive/archive_io.dart'; import 'package:path/path.dart' as p; +import 'package:http/http.dart'; typedef SqliteVersion = ({String version, String year}); @@ -21,6 +24,12 @@ Future main(List args) async { extension on SqliteVersion { String get autoconfUrl => 'https://sqlite.org/$year/sqlite-autoconf-$version.tar.gz'; + + String get windowsArm64Url => + 'https://sqlite.org/$year/sqlite-dll-win-arm64-$version.zip'; + + String get windowsX64Url => + 'https://sqlite.org/$year/sqlite-dll-win-x64-$version.zip'; } Future _downloadAndCompile(String name, SqliteVersion version, @@ -52,6 +61,40 @@ Future _downloadAndCompile(String name, SqliteVersion version, await Directory.systemTemp.createTemp('powersync-core-compile-sqlite3'); final temporaryDirPath = temporaryDir.path; + // Compiling on Windows is ugly because we need users to have Visual Studio + // installed and all those tools activated in the current shell. + // Much easier to just download precompiled builds. + if (Platform.isWindows) { + final windowsUri = Abi.current() == Abi.windowsX64 + ? version.windowsX64Url + : version.windowsArm64Url; + final sqlite3Zip = p.join(temporaryDirPath, 'sqlite3.zip'); + final client = Client(); + final response = await client + .send(Request('GET', Uri.parse(windowsUri))..followRedirects = true); + if (response.statusCode != 200) { + print( + 'Could not download $windowsUri, status code ${response.statusCode}'); + exit(1); + } + await response.stream.pipe(File(sqlite3Zip).openWrite()); + + final inputStream = InputFileStream(sqlite3Zip); + final archive = ZipDecoder().decodeStream(inputStream); + + for (final file in archive.files) { + if (file.isFile && file.name == 'sqlite3.dll') { + final outputStream = OutputFileStream(p.join(target, 'sqlite3.dll')); + + file.writeContent(outputStream); + outputStream.close(); + } + } + + await File(p.join(target, 'version')).writeAsString(version.version); + exit(0); + } + await _run('curl -L ${version.autoconfUrl} --output sqlite.tar.gz', workingDirectory: temporaryDirPath); await _run('tar zxvf sqlite.tar.gz', workingDirectory: temporaryDirPath); diff --git a/tool/build_linux.sh b/tool/build_linux.sh index ed19841e..f5aad702 100755 --- a/tool/build_linux.sh +++ b/tool/build_linux.sh @@ -1,10 +1,29 @@ #!/bin/sh set -e -if [ "$1" = "x64" ]; then - cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target x86_64-unknown-linux-gnu - mv "target/x86_64-unknown-linux-gnu/release/libpowersync.so" "libpowersync_x64.so" -else - cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target aarch64-unknown-linux-gnu - mv "target/aarch64-unknown-linux-gnu/release/libpowersync.so" "libpowersync_aarch64.so" -fi +case "$1" in + x64) + cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target x86_64-unknown-linux-gnu + mv "target/x86_64-unknown-linux-gnu/release/libpowersync.so" "libpowersync_x64.so" + ;; + x86) + cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target i686-unknown-linux-gnu + mv "target/i686-unknown-linux-gnu/release/libpowersync.so" "libpowersync_x86.so" + ;; + aarch64) + cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target aarch64-unknown-linux-gnu + mv "target/aarch64-unknown-linux-gnu/release/libpowersync.so" "libpowersync_aarch64.so" + ;; + armv7) + cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target armv7-unknown-linux-gnueabihf + mv "target/armv7-unknown-linux-gnueabihf/release/libpowersync.so" "libpowersync_armv7.so" + ;; + riscv64gc) + cargo build -p powersync_loadable -Z build-std=panic_abort,core,alloc --release --target riscv64gc-unknown-linux-gnu + mv "target/riscv64gc-unknown-linux-gnu/release/libpowersync.so" "libpowersync_riscv64gc.so" + ;; + *) + echo "Unknown architecture" + exit 1; + ;; +esac diff --git a/tool/build_windows.sh b/tool/build_windows.sh index fd943252..e4469ebc 100755 --- a/tool/build_windows.sh +++ b/tool/build_windows.sh @@ -1,11 +1,21 @@ #!/bin/sh set -e -if [ "$1" = "x64" ]; then - cargo build -Z build-std=panic_abort,core,alloc -p powersync_loadable --release --target x86_64-pc-windows-msvc - mv "target/x86_64-pc-windows-msvc/release/powersync.dll" "powersync_x64.dll" -else - #Note: aarch64-pc-windows-msvc has not been tested. - cargo build -Z build-std=panic_abort,core,alloc -p powersync_loadable --release --target aarch64-pc-windows-msvc - mv "target/aarch64-pc-windows-msvc/release/powersync.dll" "powersync_aarch64.dll" -fi \ No newline at end of file +case "$1" in + x64) + cargo build -Z build-std=panic_abort,core,alloc -p powersync_loadable --release --target x86_64-pc-windows-msvc + mv "target/x86_64-pc-windows-msvc/release/powersync.dll" "powersync_x64.dll" + ;; + x86) + cargo build -Z build-std=panic_abort,core,alloc -p powersync_loadable --release --target i686-pc-windows-msvc + mv "target/i686-pc-windows-msvc/release/powersync.dll" "powersync_x86.dll" + ;; + aarch64) + cargo build -Z build-std=panic_abort,core,alloc -p powersync_loadable --release --target aarch64-pc-windows-msvc + mv "target/aarch64-pc-windows-msvc/release/powersync.dll" "powersync_aarch64.dll" + ;; + *) + echo "Unknown architecture" + exit 1 + ;; +esac