Skip to content

Commit a937ced

Browse files
authored
Merge pull request #72 from TheBlueMatt/main
Get TypeScript compiling warning-free and properly test wasm loading+calling in CI
2 parents 52476c3 + dbac7c5 commit a937ced

File tree

356 files changed

+58277
-89637
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

356 files changed

+58277
-89637
lines changed

.github/workflows/build.yml

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,24 @@ name: Continuous Integration Checks
33
on: [push, pull_request]
44

55
jobs:
6-
check_bindings:
6+
wasm_bindings:
77
runs-on: ubuntu-latest
8-
# Ubuntu's version of rustc uses its own LLVM instead of being a real native package.
9-
# This leaves us with an incompatible LLVM version when linking. Instead, use a real OS.
10-
container: debian:bullseye
11-
env:
12-
TOOLCHAIN: stable
8+
# Ubuntu's version of clang doesn't support....anything that should work.
9+
# Ubuntu is an utter trash OS and should generally never be used for anything.
10+
# We also require at least rustc 1.51 (ie https://github.com/rust-lang/rust/pull/79998),
11+
# so we use debian testing
12+
container: debian:bookworm
1313
strategy:
1414
fail-fast: false
1515
steps:
16-
- name: Install native Rust toolchain, Valgrind, and build utilitis
16+
- name: Install build utilities and test that clang can build for wasm
1717
run: |
1818
apt-get update
1919
apt-get -y dist-upgrade
20-
apt-get -y install cargo libstd-rust-dev-wasm32 valgrind lld git g++ clang openjdk-11-jdk maven faketime zip unzip llvm curl
20+
apt-get -y install cargo libstd-rust-dev-wasm32 lld git g++ clang curl node-typescript npm python3
21+
echo "int main() {}" > genbindings_wasm_test_file.c
22+
clang -nostdlib -o /dev/null --target=wasm32-wasi -Wl,--no-entry genbindings_wasm_test_file.c
23+
rm genbindings_wasm_test_file.c
2124
- name: Checkout source code
2225
uses: actions/checkout@v2
2326
with:
@@ -36,21 +39,75 @@ jobs:
3639
git clone https://github.com/lightningdevkit/ldk-c-bindings
3740
cd ldk-c-bindings
3841
git checkout 0.0.104
39-
- name: Rebuild C bindings without STD for WASM
42+
- name: Rebuild C bindings without STD
4043
run: |
4144
cd ldk-c-bindings
4245
./genbindings.sh ../rust-lightning false
43-
mv lightning-c-bindings/target/wasm32-wasi ./
46+
- name: Build and Test TS Bindings for Node
47+
run: |
48+
# We need FinalizationRegistry and top-level await support, which requires node 14.6/8,
49+
# however Debian ships with Node 12
50+
# Thus, we install the binary nodejs from nodejs.org and test with that.
51+
curl https://nodejs.org/dist/v16.13.1/node-v16.13.1-linux-x64.tar.xz > nodejs.tar.xz
52+
tar xvvf nodejs.tar.xz
53+
export PATH=$(echo node-*/bin):$PATH
54+
./genbindings.sh ./ldk-c-bindings/ wasm false false
55+
- name: Build and Test TS Bindings for Web
56+
run: |
57+
export PATH=$(echo node-*/bin):$PATH
58+
./genbindings.sh ./ldk-c-bindings/ wasm false true
59+
export HOME=/root/ # Github actions is apparently broken
60+
npm i -D playwright
61+
# npx playwright install-deps is broken so we do it manually, see https://github.com/microsoft/playwright/issues/11165
62+
apt-get install -y --no-install-recommends fonts-liberation libenchant-2-2 libicu67 libjpeg62-turbo libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libcairo2 libcups2 libdbus-1-3 libdrm2 libegl1 libgbm1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libxshmfence1 xvfb fonts-noto-color-emoji fonts-unifont libfontconfig libfreetype6 xfonts-scalable fonts-ipafont-gothic fonts-wqy-zenhei fonts-tlwg-loma-otf ffmpeg libcairo-gobject2 libdbus-glib-1-2 libfontconfig1 libgdk-pixbuf2.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libxcb-shm0 libxcursor1 libxi6 libxrender1 libxt6 gstreamer1.0-libav gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good libepoxy0 libevdev2 libgl1 libgles2 libgstreamer-gl1.0-0 libgstreamer1.0-0 libharfbuzz-icu0 libharfbuzz0b libhyphen0 libnotify4 libopenjp2-7 libopus0 libpng16-16 libsecret-1-0 libsoup2.4-1 libwayland-client0 libwayland-egl1 libwayland-server0 libwebp6 libwebpdemux2 libwoff1 libxkbcommon0 libxml2 libxslt1.1
63+
mkdir -p $HOME/.cache/ms-playwright # `playwright install` is too dumb to create this for us
64+
chmod -R 777 $HOME/
65+
npx playwright install
66+
export PATH=$(echo node-*/bin):$PATH
67+
python3 -m http.server &
68+
node ts/test/browser.mjs
69+
- name: Check latest TS files are in git
70+
run: |
71+
git diff --exit-code
72+
73+
java_bindings:
74+
runs-on: ubuntu-latest
75+
# Ubuntu's version of rustc uses its own LLVM instead of being a real native package.
76+
# This leaves us with an incompatible LLVM version when linking. Instead, use a real OS.
77+
container: debian:bullseye
78+
strategy:
79+
fail-fast: false
80+
steps:
81+
- name: Install native Rust toolchain, Valgrind, and build utilitis
82+
run: |
83+
apt-get update
84+
apt-get -y dist-upgrade
85+
apt-get -y install cargo valgrind lld git g++ clang openjdk-11-jdk maven faketime zip unzip llvm curl
86+
- name: Checkout source code
87+
uses: actions/checkout@v2
88+
with:
89+
fetch-depth: 0
90+
- name: Install cbindgen
91+
run: cargo install --force cbindgen
92+
- name: Checkout Rust-Lightning and LDK-C-Bindings git
93+
run: |
94+
git config --global user.email "[email protected]"
95+
git config --global user.name "LDK CI"
96+
# Note this is a different endpoint, as we need one non-upstream commit!
97+
git clone https://git.bitcoin.ninja/rust-lightning
98+
cd rust-lightning
99+
git checkout origin/2021-03-java-bindings-base
44100
cd ..
101+
git clone https://github.com/lightningdevkit/ldk-c-bindings
102+
cd ldk-c-bindings
103+
git checkout 0.0.104
45104
- name: Rebuild C bindings, and check the sample app builds + links
46105
run: |
47106
cd ldk-c-bindings
48107
# Reset the Cargo.toml file so that git describe doesn't think we're "-dirty"
49108
git checkout lightning-c-bindings/Cargo.toml
50109
./genbindings.sh ../rust-lightning true
51-
mv wasm32-wasi lightning-c-bindings/target/
52-
cd ..
53-
- name: Build Java/TS Debug Bindings
110+
- name: Build Java Debug Bindings
54111
run: ./genbindings.sh ./ldk-c-bindings/ "-I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/" true false
55112
- name: Run Java Tests against Debug Bindings
56113
run: |
@@ -72,7 +129,7 @@ jobs:
72129
cd ../..
73130
mkdir -p src/main/resources/
74131
cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/liblightningjni_MacOSX-"* src/main/resources/
75-
- name: Build Java/TS Release Bindings
132+
- name: Build Java Release Bindings
76133
run: |
77134
export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
78135
./genbindings.sh ./ldk-c-bindings/ "-I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/" false false
@@ -116,8 +173,6 @@ jobs:
116173
runs-on: ubuntu-latest
117174
# Frankly, I'm not really sure why debian and ubuntu differ in the results here, they really shouldn't
118175
container: debian:bullseye
119-
env:
120-
TOOLCHAIN: stable
121176
strategy:
122177
fail-fast: false
123178
steps:
@@ -211,8 +266,6 @@ jobs:
211266
- platform: macos-11
212267
fail-fast: false
213268
runs-on: ${{ matrix.platform }}
214-
env:
215-
TOOLCHAIN: stable
216269
steps:
217270
- name: Install other Rust platforms
218271
run: rustup target install aarch64-apple-darwin
@@ -272,22 +325,18 @@ jobs:
272325
cd ../..
273326
mkdir -p src/main/resources/
274327
cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/liblightningjni_Linux-"* src/main/resources/
275-
- name: Build Java/TS Release Bindings
328+
- name: Build Java Release Bindings
276329
run: |
277330
export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
278331
export JAVA_HOME=`pwd`/jdk-16.0.1.jdk/Contents/Home
279332
export PATH=$JAVA_HOME/bin:$PATH
280-
# genbindings.sh always fails as there is no wasm32-wasi library
281-
# available, so instead we check that the expected JNI library
282-
# is created.
283333
export PATH=`pwd`/clang+llvm-13.0.0-x86_64-apple-darwin/bin:$PATH
284-
./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false || echo
285-
cat src/main/resources/liblightningjni_MacOSX-x86_64.nativelib > /dev/null
334+
./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false
286335
if [ "${{ matrix.platform }}" = "macos-11" ]; then
287336
export CC="clang --target=aarch64-apple-darwin"
288337
export LDK_TARGET=aarch64-apple-darwin
289338
export LDK_TARGET_CPU=apple-a14
290-
./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false || echo
339+
./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false
291340
cat src/main/resources/liblightningjni_MacOSX-aarch64.nativelib > /dev/null
292341
fi
293342
- name: Fetch Maven 3.8.4

genbindings.py

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -700,17 +700,10 @@ def map_result(struct_name, res_ty, err_ty):
700700
if not err_map.is_native_primitive and (err_map.rust_obj.replace("LDK", "") + "_clone" not in clone_fns):
701701
can_clone = False
702702

703-
out_java.write("\tpublic static native " + res_map.java_ty + " " + struct_name + "_get_ok(long arg);\n")
704-
write_c(consts.c_fn_ty_pfx + res_map.c_ty + " " + consts.c_fn_name_define_pfx(struct_name + "_get_ok", True) + consts.ptr_c_ty + " arg) {\n")
705-
write_c("\t" + struct_name + " *val = (" + struct_name + "*)(arg & ~1);\n")
706-
write_c("\tCHECK(val->result_ok);\n\t")
703+
create_getter(struct_name, res_ty, "ok", ("*", "->contents.result"), ("", "->result_ok"))
704+
create_getter(struct_name, err_ty, "err", ("*", "->contents.err"), ("!", "->result_ok"))
705+
707706
out_java_struct.write("\tpublic static final class " + human_ty + "_OK extends " + human_ty + " {\n")
708-
if res_map.ret_conv is not None:
709-
write_c(res_map.ret_conv[0].replace("\n", "\n\t") + "(*val->contents.result)")
710-
write_c(res_map.ret_conv[1].replace("\n", "\n\t") + "\n\treturn " + res_map.ret_conv_name)
711-
else:
712-
write_c("return *val->contents.result")
713-
write_c(";\n}\n")
714707

715708
if res_map.java_hu_ty != "void":
716709
out_java_struct.write("\t\tpublic final " + res_map.java_hu_ty + " res;\n")
@@ -719,42 +712,60 @@ def map_result(struct_name, res_ty, err_ty):
719712
if res_map.java_hu_ty == "void":
720713
pass
721714
elif res_map.to_hu_conv is not None:
722-
out_java_struct.write("\t\t\t" + res_map.java_ty + " res = bindings." + struct_name + "_get_ok(ptr);\n")
715+
out_java_struct.write("\t\t\t" + res_map.java_ty + " res = bindings." + struct_name.replace("LDK", "") + "_get_ok(ptr);\n")
723716
out_java_struct.write("\t\t\t" + res_map.to_hu_conv.replace("\n", "\n\t\t\t"))
724717
out_java_struct.write("\n\t\t\tthis.res = " + res_map.to_hu_conv_name + ";\n")
725718
else:
726-
out_java_struct.write("\t\t\tthis.res = bindings." + struct_name + "_get_ok(ptr);\n")
719+
out_java_struct.write("\t\t\tthis.res = bindings." + struct_name.replace("LDK", "") + "_get_ok(ptr);\n")
727720
out_java_struct.write("\t\t}\n")
728721
out_java_struct.write("\t}\n\n")
729722

730-
out_java.write("\tpublic static native " + err_map.java_ty + " " + struct_name + "_get_err(long arg);\n")
731-
write_c(consts.c_fn_ty_pfx + err_map.c_ty + " " + consts.c_fn_name_define_pfx(struct_name + "_get_err", True) + consts.ptr_c_ty + " arg) {\n")
732-
write_c("\t" + struct_name + " *val = (" + struct_name + "*)(arg & ~1);\n")
733-
write_c("\tCHECK(!val->result_ok);\n\t")
734723
out_java_struct.write("\tpublic static final class " + human_ty + "_Err extends " + human_ty + " {\n")
735-
if err_map.ret_conv is not None:
736-
write_c(err_map.ret_conv[0].replace("\n", "\n\t") + "(*val->contents.err)")
737-
write_c(err_map.ret_conv[1].replace("\n", "\n\t") + "\n\treturn " + err_map.ret_conv_name)
738-
else:
739-
write_c("return *val->contents.err")
740-
write_c(";\n}\n")
741-
742724
if err_map.java_hu_ty != "void":
743725
out_java_struct.write("\t\tpublic final " + err_map.java_hu_ty + " err;\n")
744726
out_java_struct.write("\t\tprivate " + human_ty + "_Err(Object _dummy, long ptr) {\n")
745727
out_java_struct.write("\t\t\tsuper(_dummy, ptr);\n")
746728
if err_map.java_hu_ty == "void":
747729
pass
748730
elif err_map.to_hu_conv is not None:
749-
out_java_struct.write("\t\t\t" + err_map.java_ty + " err = bindings." + struct_name + "_get_err(ptr);\n")
731+
out_java_struct.write("\t\t\t" + err_map.java_ty + " err = bindings." + struct_name.replace("LDK", "") + "_get_err(ptr);\n")
750732
out_java_struct.write("\t\t\t" + err_map.to_hu_conv.replace("\n", "\n\t\t\t"))
751733
out_java_struct.write("\n\t\t\tthis.err = " + err_map.to_hu_conv_name + ";\n")
752734
else:
753-
out_java_struct.write("\t\t\tthis.err = bindings." + struct_name + "_get_err(ptr);\n")
735+
out_java_struct.write("\t\t\tthis.err = bindings." + struct_name.replace("LDK", "") + "_get_err(ptr);\n")
754736
out_java_struct.write("\t\t}\n")
755737

756738
out_java_struct.write("\t}\n\n")
757739

740+
def create_getter(struct_name, field_decl, field_name, accessor, check_sfx):
741+
field_ty = java_c_types(field_decl + " " + field_name, None)
742+
ptr_fn_defn = field_decl + " *" + struct_name.replace("LDK", "") + "_get_" + field_name + "(" + struct_name + " *NONNULL_PTR owner)"
743+
owned_fn_defn = field_decl + " " + struct_name.replace("LDK", "") + "_get_" + field_name + "(" + struct_name + " *NONNULL_PTR owner)"
744+
745+
holds_ref = False
746+
if field_ty.rust_obj is not None and field_ty.rust_obj.replace("LDK", "") + "_clone" in clone_fns:
747+
fn_defn = owned_fn_defn
748+
write_c("static inline " + fn_defn + "{\n")
749+
if check_sfx is not None:
750+
write_c("CHECK(" + check_sfx[0] + "owner" + check_sfx[1] + ");\n")
751+
write_c("\treturn " + field_ty.rust_obj.replace("LDK", "") + "_clone(&" + accessor[0] + "owner" + accessor[1] + ");\n")
752+
elif field_ty.arr_len is not None or field_ty.is_native_primitive or field_ty.rust_obj in unitary_enums:
753+
fn_defn = owned_fn_defn
754+
write_c("static inline " + fn_defn + "{\n")
755+
if check_sfx is not None:
756+
write_c("CHECK(" + check_sfx[0] + "owner" + check_sfx[1] + ");\n")
757+
write_c("\treturn " + accessor[0] + "owner" + accessor[1] + ";\n")
758+
else:
759+
fn_defn = ptr_fn_defn
760+
write_c("static inline " + fn_defn + "{\n")
761+
if check_sfx is not None:
762+
write_c("CHECK(" + check_sfx[0] + "owner" + check_sfx[1] + ");\n")
763+
write_c("\treturn &" + accessor[0] + "owner" + accessor[1] + ";\n")
764+
holds_ref = True
765+
write_c("}\n")
766+
dummy_line = fn_defn + ";\n"
767+
map_fn_with_ref_option(dummy_line, reg_fn_regex.match(dummy_line), None, None, "", holds_ref)
768+
758769
def map_tuple(struct_name, field_lines):
759770
human_ty = struct_name.replace("LDKC2Tuple", "TwoTuple").replace("LDKC3Tuple", "ThreeTuple")
760771
with open(f"{sys.argv[3]}/structs/{human_ty}{consts.file_ext}", "w") as out_java_struct:
@@ -770,27 +781,7 @@ def map_tuple(struct_name, field_lines):
770781
if idx != 0 and idx < len(field_lines) - 2:
771782
field_name = chr(ord('a') + idx - 1)
772783
assert line.endswith(" " + field_name + ";")
773-
field_ty = java_c_types(line[:-1], None)
774-
ptr_fn_defn = line[:-3].strip() + " *" + struct_name.replace("LDK", "") + "_get_" + field_name + "(" + struct_name + " *NONNULL_PTR tuple)"
775-
owned_fn_defn = line[:-3].strip() + " " + struct_name.replace("LDK", "") + "_get_" + field_name + "(" + struct_name + " *NONNULL_PTR tuple)"
776-
777-
holds_ref = False
778-
if field_ty.rust_obj is not None and field_ty.rust_obj.replace("LDK", "") + "_clone" in clone_fns:
779-
fn_defn = owned_fn_defn
780-
write_c("static inline " + fn_defn + "{\n")
781-
write_c("\treturn " + field_ty.rust_obj.replace("LDK", "") + "_clone(&tuple->" + field_name + ");\n")
782-
elif field_ty.arr_len is not None or field_ty.is_native_primitive:
783-
fn_defn = owned_fn_defn
784-
write_c("static inline " + fn_defn + "{\n")
785-
write_c("\treturn tuple->" + field_name + ";\n")
786-
else:
787-
fn_defn = ptr_fn_defn
788-
write_c("static inline " + fn_defn + "{\n")
789-
write_c("\treturn &tuple->" + field_name + ";\n")
790-
holds_ref = True
791-
write_c("}\n")
792-
dummy_line = fn_defn + ";\n"
793-
map_fn_with_ref_option(dummy_line, reg_fn_regex.match(dummy_line), None, None, "", holds_ref)
784+
create_getter(struct_name, line[:-3].strip(), field_name, ("", "->" + field_name), None)
794785

795786
out_java.write(consts.bindings_header)
796787
with open(f"{sys.argv[2]}/version{consts.file_ext}", "w") as out_java_version:

0 commit comments

Comments
 (0)