# Set path to include our rustc wrapper as well as cbindgen
export LDK_RUSTC_PATH="$(which rustc)"
-PATH="$(pwd)/deterministic-build-wrappers:$PATH:~/.cargo/bin"
+export RUSTC="$(pwd)/deterministic-build-wrappers/rustc"
+PATH="$PATH:~/.cargo/bin"
# Set up CFLAGS and RUSTFLAGS vars appropriately for building libsecp256k1 and demo apps...
BASE_CFLAGS="" # CFLAGS for libsecp256k1
# Now cd to lightning-c-bindings, build the generated bindings, and call cbindgen to build a C header file
cd lightning-c-bindings
-cargo build
+RUSTFLAGS="$RUSTFLAGS --cfg=test_mod_pointers" cargo build
if [ "$CFLAGS_aarch64_apple_darwin" != "" ]; then
RUSTFLAGS="$BASE_RUSTFLAGS -C target-cpu=apple-a14" cargo build --target aarch64-apple-darwin
fi
# stdlib.h doesn't exist in clang's wasm sysroot, and cbindgen
# doesn't actually use it anyway, so drop the import.
- sed -i '' 's/#include <stdlib.h>/#include <ldk_rust_types.h>/g' include/lightning.h
+ sed -i '' 's/#include <stdlib.h>/#include "ldk_rust_types.h"/g' include/lightning.h
else
sed -i 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
# stdlib.h doesn't exist in clang's wasm sysroot, and cbindgen
# doesn't actually use it anyway, so drop the import.
- sed -i 's/#include <stdlib.h>/#include <ldk_rust_types.h>/g' include/lightning.h
+ sed -i 's/#include <stdlib.h>/#include "ldk_rust_types.h"/g' include/lightning.h
fi
+# Build C++ class methods which call trait methods
+set +x # Echoing every command is very verbose here
+OLD_IFS="$IFS"
+export IFS=''
+echo '#include <string.h>' > include/lightningpp_new.hpp
+echo 'namespace LDK {' >> include/lightningpp_new.hpp
+echo '// Forward declarations' >> include/lightningpp_new.hpp
+cat include/lightningpp.hpp | sed -n 's/class \(.*\) {/class \1;/p' >> include/lightningpp_new.hpp
+echo '' >> include/lightningpp_new.hpp
+
+DECLS=""
+while read LINE; do
+ case "$LINE" in
+ "#include <string.h>")
+ # We already printed this above.
+ ;;
+ "namespace LDK {")
+ # We already printed this above.
+ ;;
+ "}")
+ # We'll print this at the end
+ ;;
+ "XXX"*)
+ STRUCT_NAME="$(echo "$LINE" | awk '{ print $2 }')"
+ METHOD_NAME="$(echo "$LINE" | awk '{ print $3 }')"
+ STRUCT_CONTENTS="$(cat include/lightning.h | sed -n -e "/struct LDK$STRUCT_NAME/{:s" -e "/\} LDK$STRUCT_NAME;/!{N" -e "b s" -e "}" -e p -e "}")"
+ METHOD="$(echo "$STRUCT_CONTENTS" | grep "(\*$METHOD_NAME)")"
+ if [ "$METHOD" = "" ]; then
+ echo "Unable to find method declaration for $LINE"
+ exit 1
+ fi
+ RETVAL="$(echo "$METHOD" | sed 's/[ ]*\([A-Za-z0-9 _]*\)(\*\(.*\)).*/\1/' | sed 's/^struct LDK/LDK::/g' | tr -d ' ')"
+ [ "$RETVAL" = "LDK::SecretKey" ] && RETVAL="LDKSecretKey"
+ [ "$RETVAL" = "LDK::PublicKey" ] && RETVAL="LDKPublicKey"
+ [ "$RETVAL" = "LDK::ThirtyTwoBytes" ] && RETVAL="LDKThirtyTwoBytes"
+ PARAMS="$(echo "$METHOD" | sed 's/.*(\*.*)(\(const \)*void \*this_arg\(, \)*\(.*\));/\3/')"
+
+ echo -e "\tinline $RETVAL $METHOD_NAME($PARAMS);" >> include/lightningpp_new.hpp
+ DECLS="$DECLS"$'\n'"inline $RETVAL $STRUCT_NAME::$METHOD_NAME($PARAMS) {"
+
+ DECLS="$DECLS"$'\n'$'\t'
+ [ "$RETVAL" != "void" ] && DECLS="$DECLS$RETVAL ret = "
+ DECLS="$DECLS(self.$METHOD_NAME)(self.this_arg"
+
+ IFS=','; for PARAM in $PARAMS; do
+ DECLS="$DECLS, "
+ DECLS="$DECLS$(echo $PARAM | sed 's/.* (*\**\([a-zA-Z0-9_]*\)\()[\[0-9\]*]\)*/\1/')"
+ done
+ IFS=''
+
+ DECLS="$DECLS);"
+ [ "$RETVAL" != "void" ] && DECLS="$DECLS"$'\n'$'\t'"return ret;"
+ DECLS="$DECLS"$'\n'"}"
+ ;;
+ *)
+ echo "$LINE" >> include/lightningpp_new.hpp
+ esac
+done < include/lightningpp.hpp
+echo "$DECLS" >> include/lightningpp_new.hpp
+echo "}" >> include/lightningpp_new.hpp
+export IFS="$OLD_IFS"
+set -x
+mv include/lightningpp_new.hpp include/lightningpp.hpp
+
# Finally, sanity-check the generated C and C++ bindings with demo apps:
# Naively run the C demo app:
gcc $LOCAL_CFLAGS -Wall -g -pthread demo.c target/debug/libldk.a -ldl
# Finally, run the C++ demo app with our native networking library
# in valgrind to test memory model correctness and lack of leaks.
-gcc $LOCAL_CFLAGS -std=c99 -Wall -g -pthread -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
+gcc $LOCAL_CFLAGS -fPIC -std=c99 -Wall -g -pthread -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
g++ $LOCAL_CFLAGS -std=c++11 -Wall -g -pthread -DREAL_NET -I../ldk-net ldk_net.o demo.cpp target/debug/libldk.a -ldl
if [ -x "`which valgrind`" ]; then
valgrind --error-exitcode=4 --memcheck:leak-check=full --show-leak-kinds=all ./a.out
echo "WARNING: Can't use memory sanitizer on non-Linux, non-x86 platforms"
fi
-RUSTC_LLVM_V=$(rustc --version --verbose | grep "LLVM version" | awk '{ print substr($3, 0, 4); }')
+RUSTC_LLVM_V=$(rustc --version --verbose | grep "LLVM version" | awk '{ print substr($3, 0, 2); }')
if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
# Apple is special, as always, and their versions of clang aren't
echo "Apple clang isn't compatible with upstream clang, install upstream clang"
CLANG_LLVM_V="0"
else
- CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 4); }')
+ CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 2); }')
if [ -x "$(which ld64.lld)" ]; then
- LLD_LLVM_V="$(ld64.lld --version | awk '{ print substr($2, 0, 4); }')"
+ LLD_LLVM_V="$(ld64.lld --version | awk '{ print substr($2, 0, 2); }')"
fi
fi
else
- CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 4); }')
+ CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 2); }')
if [ -x "$(which ld.lld)" ]; then
- LLD_LLVM_V="$(ld.lld --version | awk '{ print substr($2, 0, 4); }')"
+ LLD_LLVM_V="$(ld.lld --version | awk '{ print substr($2, 0, 2); }')"
fi
fi
fi
if [ "$LLD_LLVM_V" != "$RUSTC_LLVM_V" ]; then
LLD="$(which lld-$RUSTC_LLVM_V || echo lld)"
- LLD_LLVM_V="$(ld.$LLD --version | awk '{ print substr($2, 0, 4); }')"
+ LLD_LLVM_V="$(ld.$LLD --version | awk '{ print substr($2, 0, 2); }')"
if [ "$LLD_LLVM_V" != "$RUSTC_LLVM_V" ]; then
echo "Could not find a workable version of lld, not using cross-language LTO"
unset LLD
if [ "$CFLAGS_aarch64_apple_darwin" != "" ]; then
RUSTFLAGS="$BASE_RUSTFLAGS -C target-cpu=apple-a14" RUSTC_BOOTSTRAP=1 cargo rustc --target aarch64-apple-darwin -v -- -Zsanitizer=address -Cforce-frame-pointers=yes || ( mv Cargo.toml.bk Cargo.toml; exit 1)
fi
- RUSTC_BOOTSTRAP=1 cargo rustc -v -- -Zsanitizer=address -Cforce-frame-pointers=yes || ( mv Cargo.toml.bk Cargo.toml; exit 1)
+ RUSTFLAGS="$RUSTFLAGS --cfg=test_mod_pointers" RUSTC_BOOTSTRAP=1 cargo rustc -v -- -Zsanitizer=address -Cforce-frame-pointers=yes || ( mv Cargo.toml.bk Cargo.toml; exit 1)
mv Cargo.toml.bk Cargo.toml
# First the C demo app...
ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out >/dev/null
# ...then the C++ demo app with the ldk_net network implementation
- $CLANG $LOCAL_CFLAGS -fsanitize=address -g -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
+ $CLANG $LOCAL_CFLAGS -fPIC -fsanitize=address -g -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
$CLANGPP $LOCAL_CFLAGS -std=c++11 -fsanitize=address -g -DREAL_NET -I../ldk-net ldk_net.o demo.cpp target/debug/libldk.a -ldl
ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out >/dev/null
else
rm genbindings_wasm_test_file.c
fi
+EXTRA_TARGETS=( $LDK_C_BINDINGS_EXTRA_TARGETS )
+EXTRA_CCS=( $LDK_C_BINDINGS_EXTRA_TARGET_CCS )
+
+if [ ${#EXTRA_TARGETS[@]} != ${#EXTRA_CCS[@]} ]; then
+ echo "LDK_C_BINDINGS_EXTRA_TARGETS and LDK_C_BINDINGS_EXTRA_TARGET_CCS didn't have the same number of elements!"
+ exit 1
+fi
+
+for IDX in ${!EXTRA_TARGETS[@]}; do
+ EXTRA_ENV_TARGET=$(echo "${EXTRA_TARGETS[$IDX]}" | sed 's/-/_/g')
+ export CFLAGS_$EXTRA_ENV_TARGET="$BASE_CFLAGS"
+ export CC_$EXTRA_ENV_TARGET=${EXTRA_CCS[$IDX]}
+ RUSTFLAGS="$BASE_RUSTFLAGS -C linker=${EXTRA_CCS[$IDX]}" CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release --target "${EXTRA_TARGETS[$IDX]}" -- -C lto
+done
+
if [ "$CFLAGS_aarch64_apple_darwin" != "" ]; then
RUSTFLAGS="$BASE_RUSTFLAGS -C target-cpu=apple-a14" CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release --target aarch64-apple-darwin -- -C lto
fi