Make genbindings.sh only build one of java/wasm, test wasm in CI
authorMatt Corallo <git@bluematt.me>
Wed, 5 Jan 2022 06:32:04 +0000 (06:32 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 7 Jan 2022 07:17:59 +0000 (07:17 +0000)
.github/workflows/build.yml
genbindings.sh
ts/test/browser.mjs [new file with mode: 0644]
ts/test/index.html
ts/test/node.mjs [new file with mode: 0644]
ts/test/test.mjs [deleted file]
ts/test/tests.mjs [new file with mode: 0644]

index f1f72c68c270221d770c4613a4c66850ae81edc4..334e106d287dae4e8d0f02d4854fecf5a449e35e 100644 (file)
@@ -3,21 +3,24 @@ name: Continuous Integration Checks
 on: [push, pull_request]
 
 jobs:
 on: [push, pull_request]
 
 jobs:
-  check_bindings:
+  wasm_bindings:
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
-    # Ubuntu's version of rustc uses its own LLVM instead of being a real native package.
-    # This leaves us with an incompatible LLVM version when linking. Instead, use a real OS.
-    container: debian:bullseye
-    env:
-      TOOLCHAIN: stable
+    # Ubuntu's version of clang doesn't support....anything that should work.
+    # Ubuntu is an utter trash OS and should generally never be used for anything.
+    # We also require at least rustc 1.51 (ie https://github.com/rust-lang/rust/pull/79998),
+    # so we use debian testing
+    container: debian:bookworm
     strategy:
       fail-fast: false
     steps:
     strategy:
       fail-fast: false
     steps:
-      - name: Install native Rust toolchain, Valgrind, and build utilitis
+      - name: Install build utilities and test that clang can build for wasm
         run: |
           apt-get update
           apt-get -y dist-upgrade
         run: |
           apt-get update
           apt-get -y dist-upgrade
-          apt-get -y install cargo libstd-rust-dev-wasm32 valgrind lld git g++ clang openjdk-11-jdk maven faketime zip unzip llvm curl
+          apt-get -y install cargo libstd-rust-dev-wasm32 lld git g++ clang curl node-typescript npm python3
+          echo "int main() {}" > genbindings_wasm_test_file.c
+          clang -nostdlib -o /dev/null --target=wasm32-wasi -Wl,--no-entry genbindings_wasm_test_file.c
+          rm genbindings_wasm_test_file.c
       - name: Checkout source code
         uses: actions/checkout@v2
         with:
       - name: Checkout source code
         uses: actions/checkout@v2
         with:
@@ -36,21 +39,75 @@ jobs:
           git clone https://github.com/lightningdevkit/ldk-c-bindings
           cd ldk-c-bindings
           git checkout 0.0.104
           git clone https://github.com/lightningdevkit/ldk-c-bindings
           cd ldk-c-bindings
           git checkout 0.0.104
-      - name: Rebuild C bindings without STD for WASM
+      - name: Rebuild C bindings without STD
         run: |
           cd ldk-c-bindings
           ./genbindings.sh ../rust-lightning false
         run: |
           cd ldk-c-bindings
           ./genbindings.sh ../rust-lightning false
-          mv lightning-c-bindings/target/wasm32-wasi ./
+      - name: Build and Test TS Bindings for Node
+        run: |
+          # We need FinalizationRegistry and top-level await support, which requires node 14.6/8,
+          # however Debian ships with Node 12
+          # Thus, we install the binary nodejs from nodejs.org and test with that.
+          curl https://nodejs.org/dist/v16.13.1/node-v16.13.1-linux-x64.tar.xz > nodejs.tar.xz
+          tar xvvf nodejs.tar.xz
+          export PATH=$(echo node-*/bin):$PATH
+          ./genbindings.sh ./ldk-c-bindings/ wasm false false
+      - name: Build and Test TS Bindings for Web
+        run: |
+          export PATH=$(echo node-*/bin):$PATH
+          ./genbindings.sh ./ldk-c-bindings/ wasm false true
+          export HOME=/root/ # Github actions is apparently broken
+          npm i -D playwright
+          # npx playwright install-deps is broken so we do it manually, see https://github.com/microsoft/playwright/issues/11165
+          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
+          mkdir -p $HOME/.cache/ms-playwright # `playwright install` is too dumb to create this for us
+          chmod -R 777 $HOME/
+          npx playwright install
+          export PATH=$(echo node-*/bin):$PATH
+          python3 -m http.server &
+          node ts/test/browser.mjs
+      - name: Check latest TS files are in git
+        run: |
+          git diff --exit-code
+
+  java_bindings:
+    runs-on: ubuntu-latest
+    # Ubuntu's version of rustc uses its own LLVM instead of being a real native package.
+    # This leaves us with an incompatible LLVM version when linking. Instead, use a real OS.
+    container: debian:bullseye
+    strategy:
+      fail-fast: false
+    steps:
+      - name: Install native Rust toolchain, Valgrind, and build utilitis
+        run: |
+          apt-get update
+          apt-get -y dist-upgrade
+          apt-get -y install cargo valgrind lld git g++ clang openjdk-11-jdk maven faketime zip unzip llvm curl
+      - name: Checkout source code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Install cbindgen
+        run: cargo install --force cbindgen
+      - name: Checkout Rust-Lightning and LDK-C-Bindings git
+        run: |
+          git config --global user.email "ldk-ci@example.com"
+          git config --global user.name "LDK CI"
+          # Note this is a different endpoint, as we need one non-upstream commit!
+          git clone https://git.bitcoin.ninja/rust-lightning
+          cd rust-lightning
+          git checkout origin/2021-03-java-bindings-base
           cd ..
           cd ..
+          git clone https://github.com/lightningdevkit/ldk-c-bindings
+          cd ldk-c-bindings
+          git checkout 0.0.104
       - name: Rebuild C bindings, and check the sample app builds + links
         run: |
           cd ldk-c-bindings
           # Reset the Cargo.toml file so that git describe doesn't think we're "-dirty"
           git checkout lightning-c-bindings/Cargo.toml
           ./genbindings.sh ../rust-lightning true
       - name: Rebuild C bindings, and check the sample app builds + links
         run: |
           cd ldk-c-bindings
           # Reset the Cargo.toml file so that git describe doesn't think we're "-dirty"
           git checkout lightning-c-bindings/Cargo.toml
           ./genbindings.sh ../rust-lightning true
-          mv wasm32-wasi lightning-c-bindings/target/
-          cd ..
-      - name: Build Java/TS Debug Bindings
+      - name: Build Java Debug Bindings
         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
       - name: Run Java Tests against Debug Bindings
         run: |
         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
       - name: Run Java Tests against Debug Bindings
         run: |
@@ -72,7 +129,7 @@ jobs:
           cd ../..
           mkdir -p src/main/resources/
           cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/liblightningjni_MacOSX-"* src/main/resources/
           cd ../..
           mkdir -p src/main/resources/
           cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/liblightningjni_MacOSX-"* src/main/resources/
-      - name: Build Java/TS Release Bindings
+      - name: Build Java Release Bindings
         run: |
           export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
           ./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
         run: |
           export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
           ./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:
     runs-on: ubuntu-latest
     # Frankly, I'm not really sure why debian and ubuntu differ in the results here, they really shouldn't
     container: debian:bullseye
     runs-on: ubuntu-latest
     # Frankly, I'm not really sure why debian and ubuntu differ in the results here, they really shouldn't
     container: debian:bullseye
-    env:
-      TOOLCHAIN: stable
     strategy:
       fail-fast: false
     steps:
     strategy:
       fail-fast: false
     steps:
@@ -211,8 +266,6 @@ jobs:
           - platform: macos-11
       fail-fast: false
     runs-on: ${{ matrix.platform }}
           - platform: macos-11
       fail-fast: false
     runs-on: ${{ matrix.platform }}
-    env:
-      TOOLCHAIN: stable
     steps:
       - name: Install other Rust platforms
         run: rustup target install aarch64-apple-darwin
     steps:
       - name: Install other Rust platforms
         run: rustup target install aarch64-apple-darwin
@@ -272,22 +325,18 @@ jobs:
           cd ../..
           mkdir -p src/main/resources/
           cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/liblightningjni_Linux-"* src/main/resources/
           cd ../..
           mkdir -p src/main/resources/
           cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/liblightningjni_Linux-"* src/main/resources/
-      - name: Build Java/TS Release Bindings
+      - name: Build Java Release Bindings
         run: |
           export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
           export JAVA_HOME=`pwd`/jdk-16.0.1.jdk/Contents/Home
           export PATH=$JAVA_HOME/bin:$PATH
         run: |
           export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
           export JAVA_HOME=`pwd`/jdk-16.0.1.jdk/Contents/Home
           export PATH=$JAVA_HOME/bin:$PATH
-          # genbindings.sh always fails as there is no wasm32-wasi library
-          # available, so instead we check that the expected JNI library
-          # is created.
           export PATH=`pwd`/clang+llvm-13.0.0-x86_64-apple-darwin/bin:$PATH
           export PATH=`pwd`/clang+llvm-13.0.0-x86_64-apple-darwin/bin:$PATH
-          ./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false || echo
-          cat src/main/resources/liblightningjni_MacOSX-x86_64.nativelib > /dev/null
+          ./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false
           if [ "${{ matrix.platform }}" = "macos-11" ]; then
             export CC="clang --target=aarch64-apple-darwin"
             export LDK_TARGET=aarch64-apple-darwin
             export LDK_TARGET_CPU=apple-a14
           if [ "${{ matrix.platform }}" = "macos-11" ]; then
             export CC="clang --target=aarch64-apple-darwin"
             export LDK_TARGET=aarch64-apple-darwin
             export LDK_TARGET_CPU=apple-a14
-            ./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false || echo
+            ./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false
             cat src/main/resources/liblightningjni_MacOSX-aarch64.nativelib > /dev/null
           fi
       - name: Fetch Maven 3.8.4
             cat src/main/resources/liblightningjni_MacOSX-aarch64.nativelib > /dev/null
           fi
       - name: Fetch Maven 3.8.4
index a378a1e154eaadfda05cb08ecf9a5b4a220e4394..6c7f6501210dd816317a58b0150488c48680b791 100755 (executable)
@@ -1,18 +1,18 @@
 #!/bin/bash
 usage() {
 #!/bin/bash
 usage() {
-       echo "USAGE: path/to/ldk-c-bindings \"JNI_CFLAGS\" debug android web"
+       echo "USAGE: path/to/ldk-c-bindings [wasm|\"JNI_CFLAGS\"] debug android_web"
        echo "For JNI_CFLAGS you probably want -I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/"
        echo "For JNI_CFLAGS you probably want -I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/"
+       echo "If JNI_CFLAGS is instead set to wasm, we build for wasm/TypeScript instead of Java"
        echo "debug should either be true, false, or leaks"
        echo "debug of leaks turns on leak tracking on an optimized release bianry"
        echo "debug should either be true, false, or leaks"
        echo "debug of leaks turns on leak tracking on an optimized release bianry"
-       echo "android should either be true or false"
-       echo "web should either be true or false"
+       echo "android_web should either be true or false and indicates if we build for android (Java) or web (WASM)"
        exit 1
 }
 [ "$1" = "" ] && usage
 [ "$3" != "true" -a "$3" != "false" -a "$3" != "leaks" ] && usage
 [ "$4" != "true" -a "$4" != "false" ] && usage
        exit 1
 }
 [ "$1" = "" ] && usage
 [ "$3" != "true" -a "$3" != "false" -a "$3" != "leaks" ] && usage
 [ "$4" != "true" -a "$4" != "false" ] && usage
-[ "$5" != "true" -a "$5" != "false" ] && usage
 
 
+set -e
 set -x
 
 if [ "$CC" != "" ]; then
 set -x
 
 if [ "$CC" != "" ]; then
@@ -22,201 +22,211 @@ else
        COMMON_COMPILE="clang -std=c11 -Wall -Wextra -Wno-unused-parameter -Wno-ignored-qualifiers -Wno-unused-function -Wno-nullability-completeness -Wno-pointer-sign -Wdate-time -ffile-prefix-map=$(pwd)="
 fi
 
        COMMON_COMPILE="clang -std=c11 -Wall -Wextra -Wno-unused-parameter -Wno-ignored-qualifiers -Wno-unused-function -Wno-nullability-completeness -Wno-pointer-sign -Wdate-time -ffile-prefix-map=$(pwd)="
 fi
 
-TARGET_STRING="$LDK_TARGET"
-if [ "$TARGET_STRING" = "" ]; then
-       # We assume clang-style $CC --version here, but worst-case we just get an empty suffix
-       TARGET_STRING="$($CC --version | grep Target | awk '{ print $2 }')"
-fi
-case "$TARGET_STRING" in
-       "x86_64-pc-linux"*)
-               LDK_TARGET_SUFFIX="_Linux-amd64"
-               LDK_JAR_TARGET=true
-               ;;
-       "x86_64-apple-darwin"*)
-               LDK_TARGET_SUFFIX="_MacOSX-x86_64"
-               LDK_JAR_TARGET=true
-               ;;
-       "aarch64-apple-darwin"*)
-               LDK_TARGET_SUFFIX="_MacOSX-aarch64"
-               LDK_JAR_TARGET=true
-               ;;
-       *)
-               LDK_TARGET_SUFFIX="_${TARGET_STRING}"
-esac
-if [ "$LDK_TARGET_CPU" = "" ]; then
-       LDK_TARGET_CPU="sandybridge"
-fi
-
-set -e
-
-if [ "$LDK_GARBAGECOLLECTED_GIT_OVERRIDE" = "" ]; then
-       export LDK_GARBAGECOLLECTED_GIT_OVERRIDE=$(git describe --tag --dirty)
-fi
-if [ "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:0:1}" != "v" ]; then
-       echo "Version tag should start with a v" > /dev/stderr
-       exit 1
+DEBUG_ARG="$3"
+if [ "$3" = "leaks" ]; then
+       DEBUG_ARG="true"
 fi
 
 cp "$1/lightning-c-bindings/include/lightning.h" ./
 if [ "$(rustc --version --verbose | grep "host:")" = "host: x86_64-apple-darwin" ]; then
        # OSX sed is for some reason not compatible with GNU sed
        sed -i '' "s/TransactionOutputs/C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ/g" ./lightning.h
 fi
 
 cp "$1/lightning-c-bindings/include/lightning.h" ./
 if [ "$(rustc --version --verbose | grep "host:")" = "host: x86_64-apple-darwin" ]; then
        # OSX sed is for some reason not compatible with GNU sed
        sed -i '' "s/TransactionOutputs/C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ/g" ./lightning.h
-       sed -i '' "s/^    <version>.*<\/version>/    <version>${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:1:100}<\/version>/g" pom.xml
 else
        sed -i "s/TransactionOutputs/C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ/g" ./lightning.h
 else
        sed -i "s/TransactionOutputs/C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ/g" ./lightning.h
-       sed -i "s/^    <version>.*<\/version>/    <version>${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:1:100}<\/version>/g" pom.xml
 fi
 
 fi
 
-echo "Creating Java bindings..."
-mkdir -p src/main/java/org/ldk/{enums,structs}
-rm -f src/main/java/org/ldk/{enums,structs}/*.java
-rm -f src/main/jni/*.h
-DEBUG_ARG="$3"
-if [ "$3" = "leaks" ]; then
-       DEBUG_ARG="true"
-fi
-if [ "$4" = "true" ]; then
-       ./genbindings.py "./lightning.h" src/main/java/org/ldk/impl src/main/java/org/ldk src/main/jni/ $DEBUG_ARG android $4
-else
-       ./genbindings.py "./lightning.h" src/main/java/org/ldk/impl src/main/java/org/ldk src/main/jni/ $DEBUG_ARG java $4
-fi
-rm -f src/main/jni/bindings.c
-if [ "$3" = "true" ]; then
-       echo "#define LDK_DEBUG_BUILD" > src/main/jni/bindings.c
-elif [ "$3" = "leaks" ]; then
-       # For leak checking we use release libldk which doesn't expose
-       # __unmangle_inner_ptr, but the C code expects to be able to call it.
-       echo "#define __unmangle_inner_ptr(a) (a)" > src/main/jni/bindings.c
-fi
-echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" >> src/main/jni/bindings.c
-echo "#define CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free CVec_TransactionOutputsZ_free" >> src/main/jni/bindings.c
-cat src/main/jni/bindings.c.body >> src/main/jni/bindings.c
-javac -h src/main/jni src/main/java/org/ldk/enums/*.java src/main/java/org/ldk/impl/*.java
-rm src/main/java/org/ldk/enums/*.class src/main/java/org/ldk/impl/bindings*.class
+if [ "$2" != "wasm" ]; then
+       TARGET_STRING="$LDK_TARGET"
+       if [ "$TARGET_STRING" = "" ]; then
+               # We assume clang-style $CC --version here, but worst-case we just get an empty suffix
+               TARGET_STRING="$($CC --version | grep Target | awk '{ print $2 }')"
+       fi
+       case "$TARGET_STRING" in
+               "x86_64-pc-linux"*)
+                       LDK_TARGET_SUFFIX="_Linux-amd64"
+                       LDK_JAR_TARGET=true
+                       ;;
+               "x86_64-apple-darwin"*)
+                       LDK_TARGET_SUFFIX="_MacOSX-x86_64"
+                       LDK_JAR_TARGET=true
+                       ;;
+               "aarch64-apple-darwin"*)
+                       LDK_TARGET_SUFFIX="_MacOSX-aarch64"
+                       LDK_JAR_TARGET=true
+                       ;;
+               *)
+                       LDK_TARGET_SUFFIX="_${TARGET_STRING}"
+       esac
+       if [ "$LDK_TARGET_CPU" = "" ]; then
+               LDK_TARGET_CPU="sandybridge"
+       fi
 
 
-IS_MAC=false
-[ "$($CC --version | grep apple-darwin)" != "" ] && IS_MAC=true
-IS_APPLE_CLANG=false
-[ "$($CC --version | grep "Apple clang version")" != "" ] && IS_APPLE_CLANG=true
+       if [ "$LDK_GARBAGECOLLECTED_GIT_OVERRIDE" = "" ]; then
+               export LDK_GARBAGECOLLECTED_GIT_OVERRIDE=$(git describe --tag --dirty)
+       fi
+       if [ "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:0:1}" != "v" ]; then
+               echo "Version tag should start with a v" > /dev/stderr
+               exit 1
+       fi
 
 
-echo "Building Java bindings..."
-COMPILE="$COMMON_COMPILE -mcpu=$LDK_TARGET_CPU -Isrc/main/jni -pthread -ldl -shared -fPIC"
-[ "$IS_MAC" = "false" ] && COMPILE="$COMPILE -Wl,--no-undefined"
-[ "$IS_MAC" = "true" ] && COMPILE="$COMPILE -mmacosx-version-min=10.9"
-[ "$IS_MAC" = "true" -a "$IS_APPLE_CLANG" = "false" ] && COMPILE="$COMPILE -fuse-ld=lld"
-[ "$IS_MAC" = "true" -a "$IS_APPLE_CLANG" = "false" ] && echo "WARNING: Need at least upstream clang 13!"
-[ "$IS_MAC" = "false" -a "$3" != "false" ] && COMPILE="$COMPILE -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,malloc -Wl,-wrap,free"
-if [ "$3" = "true" ]; then
-       $COMPILE -o liblightningjni_debug$LDK_TARGET_SUFFIX.so -g -fsanitize=address -shared-libasan -rdynamic -I"$1"/lightning-c-bindings/include/ $2 src/main/jni/bindings.c "$1"/lightning-c-bindings/target/$LDK_TARGET/debug/libldk.a -lm
-else
-       LDK_LIB="$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a
-       if [ "$IS_MAC" = "false" -a "$4" = "false" ]; then
-               COMPILE="$COMPILE -Wl,--version-script=libcode.version -fuse-ld=lld"
-               # __cxa_thread_atexit_impl is used to more effeciently cleanup per-thread local storage by rust libstd.
-               # However, it is not available on glibc versions 2.17 or earlier, and rust libstd has a null-check and
-               # fallback in case it is missing.
-               # Because it is weak-linked on the rust side, we should be able to simply define it
-               # explicitly, forcing rust to use the fallback. However, for some reason involving ancient
-               # dark magic and haunted code segments, overriding the weak symbol only impacts sites which
-               # *call* the symbol in question, not sites which *compare with* the symbol in question.
-               # This means that the NULL check in rust's libstd will always think the function is
-               # callable while the function which is called ends up being NULL (leading to a jmp to the
-               # zero page and a quick SEGFAULT).
-               # This issue persists not only with directly providing a symbol, but also ld.lld's -wrap
-               # and --defsym arguments.
-               # In smaller programs, it appears to be possible to work around this with -Bsymbolic and
-               # -nostdlib, however when applied the full-sized JNI library here it no longer works.
-               # After exhausting nearly every flag documented in lld, the only reliable method appears
-               # to be editing the LDK binary. Luckily, LLVM's tooling makes this rather easy as we can
-               # disassemble it into very readable code, edit it, and then reassemble it.
-               # Note that if we do so we don't have to bother overriding the actual call, LLVM should
-               # optimize it away, which also provides a good check that there isn't anything actually
-               # relying on it elsewhere.
-               [ ! -f "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a ] && exit 1
-               if [ "$(ar t "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a | grep -v "\.o$" || echo)" != "" ]; then
-                       echo "Archive contained non-object files!"
-                       exit 1
-               fi
-               if [ "$(ar t "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a | grep ldk.ldk.*-cgu.*.rcgu.o | wc -l)" != "1" ]; then
-                       echo "Archive contained more than one LDK object file"
-                       exit 1
-               fi
-               mkdir -p tmp
-               rm -f tmp/*
-               ar x --output=tmp "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a
-               pushd tmp
-               llvm-dis ldk.ldk.*-cgu.*.rcgu.o
-               sed -i 's/br i1 icmp eq (i8\* @__cxa_thread_atexit_impl, i8\* null)/br i1 icmp eq (i8* null, i8* null)/g' ldk.ldk.*-cgu.*.rcgu.o.ll
-               llvm-as ldk.ldk.*-cgu.*.rcgu.o.ll -o ./libldk.bc
-               ar q libldk.a *.o
-               popd
-               LDK_LIB="tmp/libldk.bc tmp/libldk.a"
+       if [ "$(rustc --version --verbose | grep "host:")" = "host: x86_64-apple-darwin" ]; then
+               # OSX sed is for some reason not compatible with GNU sed
+               sed -i '' "s/^    <version>.*<\/version>/    <version>${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:1:100}<\/version>/g" pom.xml
+       else
+               sed -i "s/^    <version>.*<\/version>/    <version>${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:1:100}<\/version>/g" pom.xml
        fi
        fi
-       $COMPILE -o liblightningjni_release$LDK_TARGET_SUFFIX.so -flto -O3 -I"$1"/lightning-c-bindings/include/ $2 src/main/jni/bindings.c $LDK_LIB
-       if [ "$IS_MAC" = "false" -a "$4" = "false" ]; then
-               GLIBC_SYMBS="$(objdump -T liblightningjni_release$LDK_TARGET_SUFFIX.so | grep GLIBC_ | grep -v "GLIBC_2\.2\." | grep -v "GLIBC_2\.3\(\.\| \)" | grep -v "GLIBC_2.\(14\|17\) " || echo)"
-               if [ "$GLIBC_SYMBS" != "" ]; then
-                       echo "Unexpected glibc version dependency! Some users need glibc 2.17 support, symbols for newer glibcs cannot be included."
-                       echo "$GLIBC_SYMBS"
-                       exit 1
-               fi
-               REALLOC_ARRAY_SYMBS="$(objdump -T liblightningjni_release$LDK_TARGET_SUFFIX.so | grep reallocarray || echo)"
-               if [ "$REALLOC_ARRAY_SYMBS" != "" ]; then
-                       echo "Unexpected reallocarray dependency!"
-                       exit 1
-               fi
+
+       echo "Creating Java bindings..."
+       mkdir -p src/main/java/org/ldk/{enums,structs}
+       rm -f src/main/java/org/ldk/{enums,structs}/*.java
+       rm -f src/main/jni/*.h
+       if [ "$4" = "true" ]; then
+               ./genbindings.py "./lightning.h" src/main/java/org/ldk/impl src/main/java/org/ldk src/main/jni/ $DEBUG_ARG android $4
+       else
+               ./genbindings.py "./lightning.h" src/main/java/org/ldk/impl src/main/java/org/ldk src/main/jni/ $DEBUG_ARG java $4
        fi
        fi
-       if [ "$LDK_JAR_TARGET" = "true" ]; then
-               # Copy to JNI native directory for inclusion in JARs
-               mkdir -p src/main/resources/
-               cp liblightningjni_release$LDK_TARGET_SUFFIX.so src/main/resources/liblightningjni$LDK_TARGET_SUFFIX.nativelib
+       rm -f src/main/jni/bindings.c
+       if [ "$3" = "true" ]; then
+               echo "#define LDK_DEBUG_BUILD" > src/main/jni/bindings.c
+       elif [ "$3" = "leaks" ]; then
+               # For leak checking we use release libldk which doesn't expose
+               # __unmangle_inner_ptr, but the C code expects to be able to call it.
+               echo "#define __unmangle_inner_ptr(a) (a)" > src/main/jni/bindings.c
        fi
        fi
-fi
+       echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" >> src/main/jni/bindings.c
+       echo "#define CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free CVec_TransactionOutputsZ_free" >> src/main/jni/bindings.c
+       cat src/main/jni/bindings.c.body >> src/main/jni/bindings.c
+       javac -h src/main/jni src/main/java/org/ldk/enums/*.java src/main/java/org/ldk/impl/*.java
+       rm src/main/java/org/ldk/enums/*.class src/main/java/org/ldk/impl/bindings*.class
 
 
-echo "Creating TS bindings..."
-mkdir -p ts/{enums,structs}
-rm -f ts/{enums,structs,}/*.{mjs,mts}
-if [ "$5" = "true" ]; then
-       ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript node
-else
-       ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript browser
-fi
-rm -f ts/bindings.c
-if [ "$3" = "true" ]; then
-       echo "#define LDK_DEBUG_BUILD" > ts/bindings.c
-elif [ "$3" = "leaks" ]; then
-       # For leak checking we use release libldk which doesn't expose
-       # __unmangle_inner_ptr, but the C code expects to be able to call it.
-       echo "#define __unmangle_inner_ptr(a) (a)" > ts/bindings.c
-fi
-echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" >> ts/bindings.c
-echo "#define CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free CVec_TransactionOutputsZ_free" >> ts/bindings.c
-cat ts/bindings.c.body >> ts/bindings.c
+       IS_MAC=false
+       [ "$($CC --version | grep apple-darwin)" != "" ] && IS_MAC=true
+       IS_APPLE_CLANG=false
+       [ "$($CC --version | grep "Apple clang version")" != "" ] && IS_APPLE_CLANG=true
 
 
-echo "Building TS bindings..."
-COMPILE="$COMMON_COMPILE -flto -Wl,--no-entry -Wl,--export-dynamic -Wl,-allow-undefined -nostdlib --target=wasm32-wasi"
-# We only need malloc and assert/abort, but for now just use WASI for those:
-#EXTRA_LINK=/usr/lib/wasm32-wasi/libc.a
-EXTRA_LINK=
-[ "$3" != "false" ] && COMPILE="$COMPILE -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,reallocarray -Wl,-wrap,malloc -Wl,-wrap,free"
-if [ "$3" = "true" ]; then
-       $COMPILE -o liblightningjs_debug.wasm -g -I"$1"/lightning-c-bindings/include/ ts/bindings.c "$1"/lightning-c-bindings/target/wasm32-wasi/debug/libldk.a $EXTRA_LINK
+       echo "Building Java bindings..."
+       COMPILE="$COMMON_COMPILE -mcpu=$LDK_TARGET_CPU -Isrc/main/jni -pthread -ldl -shared -fPIC"
+       [ "$IS_MAC" = "false" ] && COMPILE="$COMPILE -Wl,--no-undefined"
+       [ "$IS_MAC" = "true" ] && COMPILE="$COMPILE -mmacosx-version-min=10.9"
+       [ "$IS_MAC" = "true" -a "$IS_APPLE_CLANG" = "false" ] && COMPILE="$COMPILE -fuse-ld=lld"
+       [ "$IS_MAC" = "true" -a "$IS_APPLE_CLANG" = "false" ] && echo "WARNING: Need at least upstream clang 13!"
+       [ "$IS_MAC" = "false" -a "$3" != "false" ] && COMPILE="$COMPILE -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,malloc -Wl,-wrap,free"
+       if [ "$3" = "true" ]; then
+               $COMPILE -o liblightningjni_debug$LDK_TARGET_SUFFIX.so -g -fsanitize=address -shared-libasan -rdynamic -I"$1"/lightning-c-bindings/include/ $2 src/main/jni/bindings.c "$1"/lightning-c-bindings/target/$LDK_TARGET/debug/libldk.a -lm
+       else
+               LDK_LIB="$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a
+               if [ "$IS_MAC" = "false" -a "$4" = "false" ]; then
+                       COMPILE="$COMPILE -Wl,--version-script=libcode.version -fuse-ld=lld"
+                       # __cxa_thread_atexit_impl is used to more effeciently cleanup per-thread local storage by rust libstd.
+                       # However, it is not available on glibc versions 2.17 or earlier, and rust libstd has a null-check and
+                       # fallback in case it is missing.
+                       # Because it is weak-linked on the rust side, we should be able to simply define it
+                       # explicitly, forcing rust to use the fallback. However, for some reason involving ancient
+                       # dark magic and haunted code segments, overriding the weak symbol only impacts sites which
+                       # *call* the symbol in question, not sites which *compare with* the symbol in question.
+                       # This means that the NULL check in rust's libstd will always think the function is
+                       # callable while the function which is called ends up being NULL (leading to a jmp to the
+                       # zero page and a quick SEGFAULT).
+                       # This issue persists not only with directly providing a symbol, but also ld.lld's -wrap
+                       # and --defsym arguments.
+                       # In smaller programs, it appears to be possible to work around this with -Bsymbolic and
+                       # -nostdlib, however when applied the full-sized JNI library here it no longer works.
+                       # After exhausting nearly every flag documented in lld, the only reliable method appears
+                       # to be editing the LDK binary. Luckily, LLVM's tooling makes this rather easy as we can
+                       # disassemble it into very readable code, edit it, and then reassemble it.
+                       # Note that if we do so we don't have to bother overriding the actual call, LLVM should
+                       # optimize it away, which also provides a good check that there isn't anything actually
+                       # relying on it elsewhere.
+                       [ ! -f "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a ] && exit 1
+                       if [ "$(ar t "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a | grep -v "\.o$" || echo)" != "" ]; then
+                               echo "Archive contained non-object files!"
+                               exit 1
+                       fi
+                       if [ "$(ar t "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a | grep ldk.ldk.*-cgu.*.rcgu.o | wc -l)" != "1" ]; then
+                               echo "Archive contained more than one LDK object file"
+                               exit 1
+                       fi
+                       mkdir -p tmp
+                       rm -f tmp/*
+                       ar x --output=tmp "$1"/lightning-c-bindings/target/$LDK_TARGET/release/libldk.a
+                       pushd tmp
+                       llvm-dis ldk.ldk.*-cgu.*.rcgu.o
+                       sed -i 's/br i1 icmp eq (i8\* @__cxa_thread_atexit_impl, i8\* null)/br i1 icmp eq (i8* null, i8* null)/g' ldk.ldk.*-cgu.*.rcgu.o.ll
+                       llvm-as ldk.ldk.*-cgu.*.rcgu.o.ll -o ./libldk.bc
+                       ar q libldk.a *.o
+                       popd
+                       LDK_LIB="tmp/libldk.bc tmp/libldk.a"
+               fi
+               $COMPILE -o liblightningjni_release$LDK_TARGET_SUFFIX.so -flto -O3 -I"$1"/lightning-c-bindings/include/ $2 src/main/jni/bindings.c $LDK_LIB
+               if [ "$IS_MAC" = "false" -a "$4" = "false" ]; then
+                       GLIBC_SYMBS="$(objdump -T liblightningjni_release$LDK_TARGET_SUFFIX.so | grep GLIBC_ | grep -v "GLIBC_2\.2\." | grep -v "GLIBC_2\.3\(\.\| \)" | grep -v "GLIBC_2.\(14\|17\) " || echo)"
+                       if [ "$GLIBC_SYMBS" != "" ]; then
+                               echo "Unexpected glibc version dependency! Some users need glibc 2.17 support, symbols for newer glibcs cannot be included."
+                               echo "$GLIBC_SYMBS"
+                               exit 1
+                       fi
+                       REALLOC_ARRAY_SYMBS="$(objdump -T liblightningjni_release$LDK_TARGET_SUFFIX.so | grep reallocarray || echo)"
+                       if [ "$REALLOC_ARRAY_SYMBS" != "" ]; then
+                               echo "Unexpected reallocarray dependency!"
+                               exit 1
+                       fi
+               fi
+               if [ "$LDK_JAR_TARGET" = "true" ]; then
+                       # Copy to JNI native directory for inclusion in JARs
+                       mkdir -p src/main/resources/
+                       cp liblightningjni_release$LDK_TARGET_SUFFIX.so src/main/resources/liblightningjni$LDK_TARGET_SUFFIX.nativelib
+               fi
+       fi
 else
 else
-       $COMPILE -o liblightningjs_release.wasm -s -Os -I"$1"/lightning-c-bindings/include/ ts/bindings.c "$1"/lightning-c-bindings/target/wasm32-wasi/release/libldk.a $EXTRA_LINK
-fi
+       echo "Creating TS bindings..."
+       mkdir -p ts/{enums,structs}
+       rm -f ts/{enums,structs,}/*.{mjs,mts}
+       if [ "$4" = "false" ]; then
+               ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript node
+       else
+               ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript browser
+       fi
+       rm -f ts/bindings.c
+       if [ "$3" = "true" ]; then
+               echo "#define LDK_DEBUG_BUILD" > ts/bindings.c
+       elif [ "$3" = "leaks" ]; then
+               # For leak checking we use release libldk which doesn't expose
+               # __unmangle_inner_ptr, but the C code expects to be able to call it.
+               echo "#define __unmangle_inner_ptr(a) (a)" > ts/bindings.c
+       fi
+       echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" >> ts/bindings.c
+       echo "#define CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free CVec_TransactionOutputsZ_free" >> ts/bindings.c
+       cat ts/bindings.c.body >> ts/bindings.c
 
 
-if [ -x "$(which tsc)" ]; then
-       cd ts
-rm -r structs # TODO: Make the human-types compile
-       if [ "$5" = "false" ]; then
-               tsc
+       echo "Building TS bindings..."
+       COMPILE="$COMMON_COMPILE -flto -Wl,--no-entry -Wl,--export-dynamic -Wl,-allow-undefined -nostdlib --target=wasm32-wasi"
+       # We only need malloc and assert/abort, but for now just use WASI for those:
+       #EXTRA_LINK=/usr/lib/wasm32-wasi/libc.a
+       EXTRA_LINK=
+       [ "$3" != "false" ] && COMPILE="$COMPILE -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,reallocarray -Wl,-wrap,malloc -Wl,-wrap,free"
+       if [ "$3" = "true" ]; then
+               WASM_FILE=liblightningjs_debug.wasm
+               $COMPILE -o liblightningjs_debug.wasm -g -I"$1"/lightning-c-bindings/include/ ts/bindings.c "$1"/lightning-c-bindings/target/wasm32-wasi/debug/libldk.a $EXTRA_LINK
        else
        else
-               tsc --types node --typeRoots .
-               cd ..
-               if [ -x "$(which node)" ]; then
-                       NODE_V="$(node --version)"
-                       if [ "${NODE_V:1:2}" -gt 14 ]; then
-                               node ts/test/
+               WASM_FILE=liblightningjs_release.wasm
+               $COMPILE -o liblightningjs_release.wasm -s -Os -I"$1"/lightning-c-bindings/include/ ts/bindings.c "$1"/lightning-c-bindings/target/wasm32-wasi/release/libldk.a $EXTRA_LINK
+       fi
+
+       if [ -x "$(which tsc)" ]; then
+               cd ts
+       rm -r structs # TODO: Make the human-types compile
+               if [ "$4" = "true" ]; then
+                       tsc
+               else
+                       tsc --types node --typeRoots .
+                       cd ..
+                       if [ -x "$(which node)" ]; then
+                               NODE_V="$(node --version)"
+                               if [ "${NODE_V:1:2}" -gt 14 ]; then
+                                       rm -f liblightningjs.wasm
+                                       ln -s $WASM_FILE liblightningjs.wasm
+                                       node ts/test/node.mjs
+                               fi
                        fi
                fi
        fi
                        fi
                fi
        fi
diff --git a/ts/test/browser.mjs b/ts/test/browser.mjs
new file mode 100644 (file)
index 0000000..fecaa3e
--- /dev/null
@@ -0,0 +1,15 @@
+import { chromium, firefox, webkit } from 'playwright';
+import { strict as assert } from 'assert';
+
+for (const browserType of [chromium, firefox]) { // We'd like to test webkit, but playwright doesn't support it on Debian (?!)
+       const browser = await browserType.launch();
+       const context = await browser.newContext();
+       const page = await context.newPage();
+       await page.goto('http://localhost:8000/ts/test/index.html');
+       const ret = await page.evaluate(() => {
+               return test_runner('../../liblightningjs.wasm');
+       });
+       assert(ret);
+
+       await browser.close();
+}
index 3b0ba69f49d4fe1d53fa24267919b46e4d945c4d..a100395426218af4753a7872263b6997c33a3fc3 100644 (file)
@@ -1,9 +1,14 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
-<!-- add.html -->
 <html>
 <head></head>
 <body>
 <html>
 <head></head>
 <body>
-<script type="module" src="test.mjs">
+<script type="text/javascript">
+       var test_runner;
+</script>
+<script type="module">
+       import { run_tests } from './tests.mjs';
+       run_tests('../../liblightningjs.wasm');
+       test_runner = run_tests;
 </script>
 </body>
 </html>
 </script>
 </body>
 </html>
diff --git a/ts/test/node.mjs b/ts/test/node.mjs
new file mode 100644 (file)
index 0000000..dfabe66
--- /dev/null
@@ -0,0 +1,4 @@
+import { run_tests } from "./tests.mjs";
+import { strict as assert } from 'assert';
+const res = await run_tests('./liblightningjs.wasm');
+assert(res);
diff --git a/ts/test/test.mjs b/ts/test/test.mjs
deleted file mode 100644 (file)
index 1bcf0f1..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as ldk from "../bindings.mjs";
-async function run_tests() {
-       await ldk.initializeWasm("../../liblightningjs.wasm");
-       const result = ldk.CResult_boolLightningErrorZ_ok(true);
-       console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
-       console.assert(ldk.CResult_boolLightningErrorZ_get_ok(result));
-       ldk.CResult_boolLightningErrorZ_free(result);
-       console.assert(ldk.CResult_boolLightningErrorZ_ok(false) == result); // malloc doesn't need to guarantee this, but currently does
-       console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
-       console.assert(!ldk.CResult_boolLightningErrorZ_get_ok(result));
-       ldk.CResult_boolLightningErrorZ_free(result);
-
-       /*var pk_arr = [];
-       for (var i = 0; i < 33; i++) { pk_arr[i] = 42; }
-       const pk_bytes = encodeUint8Array(pk_arr);
-       const pk_res = wasm.TS_CResult_PublicKeyErrorZ_ok(pk_bytes);
-       console.assert(wasm.TS_CResult_PublicKeyErrorZ_is_ok(pk_res));
-       const pk_res_bytes = wasm.TS_LDKCResult_PublicKeyErrorZ_get_ok(pk_res);
-       wasm.TS_CResult_PublicKeyErrorZ_free(pk_res);*/
-
-       console.log("pass");
-}
-
-run_tests();
diff --git a/ts/test/tests.mjs b/ts/test/tests.mjs
new file mode 100644 (file)
index 0000000..96e50ec
--- /dev/null
@@ -0,0 +1,24 @@
+import * as ldk from "../bindings.mjs";
+
+export async function run_tests(wasm_path) {
+       await ldk.initializeWasm(wasm_path);
+       const result = ldk.CResult_boolLightningErrorZ_ok(true);
+       console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
+       console.assert(ldk.CResult_boolLightningErrorZ_get_ok(result));
+       ldk.CResult_boolLightningErrorZ_free(result);
+       console.assert(ldk.CResult_boolLightningErrorZ_ok(false) == result); // malloc doesn't need to guarantee this, but currently does
+       console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
+       console.assert(!ldk.CResult_boolLightningErrorZ_get_ok(result));
+       ldk.CResult_boolLightningErrorZ_free(result);
+
+       /*var pk_arr = [];
+       for (var i = 0; i < 33; i++) { pk_arr[i] = 42; }
+       const pk_bytes = encodeUint8Array(pk_arr);
+       const pk_res = wasm.TS_CResult_PublicKeyErrorZ_ok(pk_bytes);
+       console.assert(wasm.TS_CResult_PublicKeyErrorZ_is_ok(pk_res));
+       const pk_res_bytes = wasm.TS_LDKCResult_PublicKeyErrorZ_get_ok(pk_res);
+       wasm.TS_CResult_PublicKeyErrorZ_free(pk_res);*/
+
+       console.log("pass");
+       return true;
+}