Skip to content

Commit e11dc0a

Browse files
authored
Merge pull request #1 from powersync-ja/feat/powersync-core-rust-extension-wasm
PowerSync core rust extension wasm
2 parents 7bdca77 + e53d1bd commit e11dc0a

File tree

9 files changed

+157
-8
lines changed

9 files changed

+157
-8
lines changed

.github/actions/build-wasm/action.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: "Build SQLite3 WASM"
2+
description: "Build SQLite3 WASM on macOS"
3+
runs:
4+
using: "composite"
5+
steps:
6+
- uses: actions/checkout@v3
7+
with:
8+
submodules: recursive
9+
- name: Setup Homebrew
10+
id: set-up-homebrew
11+
uses: Homebrew/actions/setup-homebrew@master
12+
- name: Install Flutter
13+
uses: subosito/flutter-action@v2
14+
with:
15+
flutter-version: "3.x"
16+
channel: "stable"
17+
- name: Setup macOS
18+
shell: bash
19+
run: |
20+
brew install cmake
21+
brew install llvm
22+
brew install binaryen
23+
curl -sL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/libclang_rt.builtins-wasm32-wasi-22.0.tar.gz | \
24+
tar x -zf - -C /opt/homebrew/opt/llvm/lib/clang/18*
25+
curl -sS -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sysroot-22.0.tar.gz | \
26+
sudo tar x -zf - -C /opt
27+
- name: Install Rust Nightly
28+
uses: dtolnay/rust-toolchain@stable
29+
with:
30+
toolchain: nightly-2024-05-18
31+
components: rust-src
32+
- name: Set environment variable
33+
shell: bash
34+
run: |
35+
echo "/opt/homebrew/opt/llvm/bin" >> $GITHUB_PATH
36+
- name: Flutter pub get
37+
working-directory: sqlite3
38+
shell: bash
39+
run: |
40+
flutter pub get
41+
- name: Compile sqlite3.wasm on macOS
42+
if: runner.os == 'macOS'
43+
working-directory: sqlite3
44+
shell: bash
45+
run: |
46+
cmake -Dwasi_sysroot=/opt/wasi-sysroot -Dclang=/opt/homebrew/opt/llvm/bin/clang -S assets/wasm -B .dart_tool/sqlite3_build --toolchain toolchain.cmake
47+
cmake --build .dart_tool/sqlite3_build/ -t output -j

.github/workflows/release.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Build and upload SQLite3 WASM
2+
3+
on:
4+
push:
5+
tags:
6+
- "v[0-9]+.[0-9]+.[0-9]+"
7+
8+
jobs:
9+
compile_sqlite3_wasm:
10+
strategy:
11+
matrix:
12+
os: [macos-latest]
13+
14+
name: Compile sqlite3 wasm for ${{ matrix.os }}
15+
runs-on: ${{ matrix.os }}
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
- name: Build wasm
20+
uses: ./.github/actions/build-wasm
21+
- name: Upload sqlite3 binary
22+
uses: svenstaro/upload-release-action@v2
23+
with:
24+
repo_token: ${{ secrets.GITHUB_TOKEN }}
25+
overwrite: true
26+
file: sqlite3/.dart_tool/sqlite3_build/sqlite3.wasm
27+
asset_name: sqlite3.wasm
28+
body: "SQLite3 WASM binary"
29+
tag: ${{ github.ref_name }}
30+
- name: Upload sqlite3 debug binary
31+
uses: svenstaro/upload-release-action@v2
32+
with:
33+
repo_token: ${{ secrets.GITHUB_TOKEN }}
34+
overwrite: true
35+
file: sqlite3/.dart_tool/sqlite3_build/sqlite3.debug.wasm
36+
asset_name: sqlite3.debug.wasm
37+
tag: ${{ github.ref_name }}

.github/workflows/test.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Build SQLite3 WASM
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
7+
jobs:
8+
compile_sqlite3_wasm:
9+
strategy:
10+
matrix:
11+
os: [macos-latest]
12+
13+
name: Compile sqlite3 wasm for ${{ matrix.os }}
14+
runs-on: ${{ matrix.os }}
15+
16+
steps:
17+
- uses: actions/checkout@v3
18+
- name: Build wasm
19+
uses: ./.github/actions/build-wasm

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,4 @@ lib/generated_plugin_registrant.dart
9999
# End of https://www.toptal.com/developers/gitignore/api/flutter,dart
100100

101101
*.wasm
102+
.DS_Store

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "sqlite3/powersync-sqlite-core"]
2+
path = sqlite3/powersync-sqlite-core
3+
url = [email protected]:powersync-ja/powersync-sqlite-core.git

sqlite3/assets/wasm/CMakeLists.txt

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,42 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
99
# We can't really ask users to use a cmake that recent, so there's this if here.
1010
FetchContent_Declare(
1111
sqlite3
12-
# NOTE: When changing this, also update `test/wasm/sqlite3_test.dart`
13-
URL https://sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
12+
URL https://sqlite.org/2023/sqlite-autoconf-3440000.tar.gz
1413
DOWNLOAD_EXTRACT_TIMESTAMP NEW
1514
)
1615
else()
1716
FetchContent_Declare(
1817
sqlite3
19-
# NOTE: When changing this, also update `test/wasm/sqlite3_test.dart`
20-
URL https://sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
18+
URL https://sqlite.org/2023/sqlite-autoconf-3440000.tar.gz
2119
)
2220
endif()
2321

2422
FetchContent_MakeAvailable(sqlite3)
2523

2624
set(wasm_visibility "__attribute__((visibility(\"default\")))")
2725

26+
get_filename_component(RS_LIB_DIR "${CMAKE_BINARY_DIR}/../../powersync-sqlite-core/" ABSOLUTE)
27+
set(RS_LIB "powersync")
28+
set(RS_WASM_TGT "wasm32-wasi")
29+
set(RS_WASM_TGT_DIR "${RS_LIB_DIR}/target/${RS_WASM_TGT}")
30+
31+
set(RS_RELEASE_OUT "${RS_WASM_TGT_DIR}/wasm/")
32+
set(RS_RELEASE_OUT_DEPS "${RS_WASM_TGT_DIR}/wasm/deps")
33+
set(RS_RELEASE_EXTENSION_OUT "${RS_RELEASE_OUT}/powersync-extension.o")
34+
set(RS_DEBUG_BC "${RS_WASM_TGT_DIR}/debug/deps/${RS_LIB}.bc")
35+
set(RS_BUILD_COMMAND "cargo build -p powersync_loadable --profile wasm --no-default-features --features \"powersync_core/static powersync_core/omit_load_extension sqlite_nostd/static sqlite_nostd/omit_load_extension\" -Z build-std=panic_abort,core,alloc --target ${RS_WASM_TGT}")
36+
37+
file(GLOB BYTECODE_FILES "${RS_WASM_TGT_DIR}/wasm/deps/*.bc")
38+
file(GLOB OBJ_FILES "${RS_WASM_TGT_DIR}/wasm/deps/*.o" CONFIGURE_DEPENDS "*.o")
39+
2840
macro(base_sqlite3_target name)
2941
add_executable(${name}
3042
"${sqlite3_SOURCE_DIR}/sqlite3.c"
3143
os_web.c
3244
helpers.c
3345
)
3446

47+
target_link_libraries(${name} ${RS_RELEASE_EXTENSION_OUT})
3548
target_link_options(${name} PRIVATE -nostartfiles -Wl,--import-memory -Wl,--no-entry -Wl,--export-dynamic)
3649
target_include_directories(${name} PRIVATE "${PROJECT_SOURCE_DIR}/")
3750
target_include_directories(${name} PRIVATE ${sqlite3_SOURCE_DIR})
@@ -42,6 +55,24 @@ macro(base_sqlite3_target name)
4255
set_property(TARGET ${name} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
4356
endmacro()
4457

58+
# Script to use llc to get object code from bytecode
59+
set(objectcode_script "${CMAKE_CURRENT_BINARY_DIR}/loop_objectcode_script.sh")
60+
file(WRITE ${objectcode_script}
61+
"cd ${RS_RELEASE_OUT_DEPS}\n"
62+
"for filename in *.bc; do llc -march=wasm32 -filetype=obj $filename -o $filename.o; done\n"
63+
"wasm-ld -relocatable *.o -o ../powersync-extension.o"
64+
)
65+
66+
add_custom_target(
67+
powersync_core_bytecode
68+
COMMAND ${CMAKE_COMMAND} -E env
69+
"RUSTFLAGS=--emit=llvm-bc -C linker=true"
70+
cargo build -p powersync_loadable --profile wasm --no-default-features --features \"powersync_core/static powersync_core/omit_load_extension sqlite_nostd/static sqlite_nostd/omit_load_extension\" -Z build-std=panic_abort,core,alloc --target ${RS_WASM_TGT}
71+
WORKING_DIRECTORY ${RS_LIB_DIR}
72+
# Converts bytecode to wasm object files
73+
COMMAND sh ${objectcode_script}
74+
)
75+
4576
base_sqlite3_target(sqlite3_debug)
4677
file(DOWNLOAD https://raw.githubusercontent.com/sqlite/sqlite/master/src/test_vfstrace.c "${CMAKE_BINARY_DIR}/vfstrace.c")
4778
target_sources(sqlite3_debug PRIVATE "${CMAKE_BINARY_DIR}/vfstrace.c")
@@ -58,7 +89,10 @@ add_custom_command(TARGET sqlite3_opt POST_BUILD
5889
COMMAND wasm-opt ${CMAKE_CURRENT_BINARY_DIR}/sqlite3.dce.wasm -O4 -o ${CMAKE_CURRENT_BINARY_DIR}/sqlite3.wasm
5990
)
6091
92+
add_dependencies(sqlite3_opt powersync_core_bytecode)
93+
add_dependencies(sqlite3_debug powersync_core_bytecode)
94+
6195
add_custom_target(output)
62-
add_custom_command(TARGET output COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/sqlite3.wasm ${PROJECT_SOURCE_DIR}/../../example/web/sqlite3.wasm)
96+
add_custom_command(TARGET output COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/sqlite3.wasm ${PROJECT_SOURCE_DIR}/../../example/web/sqlite3.wasm DEPENDS)
6397
add_custom_command(TARGET output COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/sqlite3.debug.wasm ${PROJECT_SOURCE_DIR}/../../example/web/sqlite3.debug.wasm)
64-
add_dependencies(output sqlite3_debug sqlite3_opt)
98+
add_dependencies(output sqlite3_debug sqlite3_opt powersync_core_bytecode)

sqlite3/assets/wasm/os_web.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#include "bridge.h"
66
#include "sqlite3.h"
77

8-
int sqlite3_os_init(void) { return SQLITE_OK; }
8+
extern int __rust_no_alloc_shim_is_unstable = 0;
9+
extern int sqlite3_powersync_init(sqlite3 *db, char **pzErrMsg,
10+
const sqlite3_api_routines *pApi);
11+
12+
int sqlite3_os_init(void) {
13+
sqlite3_auto_extension((void (*)(void)) & sqlite3_powersync_init);
14+
return SQLITE_OK;
15+
}
916

1017
int sqlite3_os_end(void) { return SQLITE_OK; }

sqlite3/assets/wasm/sqlite_cfg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
// Disable things we don't need
4444
#define SQLITE_OMIT_DEPRECATED
4545
#define SQLITE_OMIT_PROGRESS_CALLBACK
46-
#define SQLITE_OMIT_AUTHORIZATION
46+
// #define SQLITE_OMIT_AUTHORIZATION // This breaks the powersync-core build
4747
#define SQLITE_UNTESTABLE
4848
#define SQLITE_OMIT_COMPILEOPTION_DIAGS
4949
#define SQLITE_OMIT_LOAD_EXTENSION

sqlite3/powersync-sqlite-core

Submodule powersync-sqlite-core added at 955e93f

0 commit comments

Comments
 (0)