ORIG_PWD="$(pwd)"
cd "$1"
LIGHTNING_PATH="$(pwd)"
+LIGHTNING_GIT="$(git describe --tag --dirty)"
cd "$ORIG_PWD"
# Generate (and reasonably test) C bindings
mv lightning-c-bindings/src/c_types/mod.rs ./
mv lightning-c-bindings/src/bitcoin ./
+# Before we try to sed the Cargo.toml, generate version define tags
+# (ignoring any files that we're about to generate)
+
+git checkout lightning-c-bindings/src
+git checkout lightning-c-bindings/include
+BINDINGS_GIT="$(git describe --tag --dirty)"
+echo -e "#ifndef _LDK_HEADER_VER" > lightning-c-bindings/include/ldk_ver.h
+echo -e "static inline int _ldk_strncmp(const char *s1, const char *s2, uint64_t n) {" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\tif (n && *s1 != *s2) return 1;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\twhile (n && *s1 != 0 && *s2 != 0) {" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t\ts1++; s2++; n--;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t\tif (n && *s1 != *s2) return 1;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t}" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\treturn 0;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "}" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "#define _LDK_HEADER_VER \"$LIGHTNING_GIT\"" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "#define _LDK_C_BINDINGS_HEADER_VER \"$BINDINGS_GIT\"" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "static inline const char* check_get_ldk_version() {" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\tLDKStr bin_ver = _ldk_get_compiled_version();" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\tif (_ldk_strncmp(_LDK_HEADER_VER, (const char*)bin_ver.chars, bin_ver.len) != 0) {" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t// Version mismatch, we don't know what we're running!" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t\treturn 0;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t}" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\treturn _LDK_HEADER_VER;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "}" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "static inline const char* check_get_ldk_bindings_version() {" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\tLDKStr bin_ver = _ldk_c_bindings_get_compiled_version();" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\tif (_ldk_strncmp(_LDK_C_BINDINGS_HEADER_VER, (const char*)bin_ver.chars, bin_ver.len) != 0) {" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t// Version mismatch, we don't know what we're running!" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t\treturn 0;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\t}" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "\treturn _LDK_C_BINDINGS_HEADER_VER;" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "}" >> lightning-c-bindings/include/ldk_ver.h
+echo -e "#endif /* _LDK_HEADER_VER */" >> lightning-c-bindings/include/ldk_ver.h
+
rm -rf lightning-c-bindings/src
mkdir -p lightning-c-bindings/src/{c_types,lightning}
# Finally, run the c-bindings-gen binary, building fresh bindings.
OUT="$(pwd)/lightning-c-bindings/src"
OUT_TEMPL="$(pwd)/lightning-c-bindings/src/c_types/derived.rs"
-OUT_F="$(pwd)/lightning-c-bindings/include/rust_types.h"
+OUT_F="$(pwd)/lightning-c-bindings/include/ldk_rust_types.h"
OUT_CPP="$(pwd)/lightning-c-bindings/include/lightningpp.hpp"
BIN="$(pwd)/c-bindings-gen/target/release/c-bindings-gen"
if [ "$2" = "true" ]; then
add_crate lightning lightning --features=allow_wallclock_use ', features = ["allow_wallclock_use"]'
add_crate "lightning-persister" "lightning_persister"
+ add_crate "lightning-background-processor" "lightning_background_processor"
else
add_crate lightning lightning
drop_crate "lightning-persister"
+ drop_crate "lightning-background-processor"
fi
add_crate "lightning-invoice" "lightning_invoice"
cat /tmp/crate-source.txt | RUST_BACKTRACE=1 "$BIN" "$OUT/" "$OUT_TEMPL" "$OUT_F" "$OUT_CPP"
+echo -e '#[no_mangle]' >> lightning-c-bindings/src/version.rs
+echo -e 'pub extern "C" fn _ldk_get_compiled_version() -> crate::c_types::Str {' >> lightning-c-bindings/src/version.rs
+echo -e '\t"'"$LIGHTNING_GIT"'".into()' >> lightning-c-bindings/src/version.rs
+echo -e '}' >> lightning-c-bindings/src/version.rs
+echo -e '#[no_mangle]' >> lightning-c-bindings/src/version.rs
+echo -e 'pub extern "C" fn _ldk_c_bindings_get_compiled_version() -> crate::c_types::Str {' >> lightning-c-bindings/src/version.rs
+echo -e '\t"'"$BINDINGS_GIT"'".into()' >> lightning-c-bindings/src/version.rs
+echo -e '}' >> lightning-c-bindings/src/version.rs
+
# Set path to include our rustc wrapper as well as cbindgen
PATH="$(pwd)/deterministic-build-wrappers:$PATH:~/.cargo/bin"
# Now cd to lightning-c-bindings, build the generated bindings, and call cbindgen to build a C header file
# 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>//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>//g' include/lightning.h
+ sed -i 's/#include <stdlib.h>/#include <ldk_rust_types.h>/g' include/lightning.h
fi
# Finally, sanity-check the generated C and C++ bindings with demo apps:
-LOCAL_CFLAGS="-Wall -Wno-nullability-completeness -pthread"
+LOCAL_CFLAGS="-Wall -Wno-nullability-completeness -pthread -Iinclude/"
# Naively run the C demo app:
gcc $LOCAL_CFLAGS -Wall -g -pthread demo.c target/debug/libldk.a -ldl
CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C lto
clang++ $LOCAL_CFLAGS -std=c++11 -flto -O2 demo.cpp target/release/libldk.a -ldl
+strip ./a.out
+echo "C++ Bin size and runtime with only RL (LTO) optimized:"
+ls -lha a.out
+time ./a.out > /dev/null
+
if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then
# If we can use cross-language LTO, use it for building C dependencies (i.e. libsecp256k1) as well
export CC="$CLANG"
- export CFLAGS_wasm32_wasi="-target wasm32 -flto"
+ # The cc-rs crate tries to force -fdata-sections and -ffunction-sections on, which
+ # breaks -fembed-bitcode, so we turn off cc-rs' default flags and specify exactly
+ # what we want here.
+ export CFLAGS="$CFLAGS -fPIC -fembed-bitcode"
+ export CRATE_CC_NO_DEFAULTS=true
fi
if [ "$2" = "false" -a "$(rustc --print target-list | grep wasm32-wasi)" != "" ]; then
# Test to see if clang supports wasm32 as a target (which is needed to build rust-secp256k1)
echo "int main() {}" > genbindings_wasm_test_file.c
- clang -nostdlib -o /dev/null --target=wasm32-wasi -Wl,--no-entry genbindings_wasm_test_file.c > /dev/null 2>&1 &&
- # And if it does, build a WASM binary without capturing errors
- cargo rustc -v --target=wasm32-wasi -- -C embed-bitcode=yes &&
- CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release --target=wasm32-wasi -- -C opt-level=s -C linker-plugin-lto -C lto ||
- echo "Cannot build WASM lib as clang does not seem to support the wasm32-wasi target"
+ if clang -nostdlib -o /dev/null --target=wasm32-wasi -Wl,--no-entry genbindings_wasm_test_file.c > /dev/null 2>&1; then
+ # And if it does, build a WASM binary without capturing errors
+ export CFLAGS_wasm32_wasi="-target wasm32"
+ cargo rustc -v --target=wasm32-wasi
+ export CFLAGS_wasm32_wasi="-target wasm32 -Os"
+ CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release --target=wasm32-wasi -- -C embed-bitcode=yes -C opt-level=s -C linker-plugin-lto -C lto
+ else
+ echo "Cannot build WASM lib as clang does not seem to support the wasm32-wasi target"
+ fi
rm genbindings_wasm_test_file.c
fi
-strip ./a.out
-echo "C++ Bin size and runtime with only RL (LTO) optimized:"
-ls -lha a.out
-time ./a.out > /dev/null
-
if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then
# Finally, test cross-language LTO. Note that this will fail if rustc and clang++
# build against different versions of LLVM (eg when rustc is installed via rustup
# or Ubuntu packages). This should work fine on Distros which do more involved
# packaging than simply shipping the rustup binaries (eg Debian should Just Work
# here).
- # The cc-rs crate tries to force -fdata-sections and -ffunction-sections on, which
- # breaks -fembed-bitcode, so we turn off cc-rs' default flags and specify exactly
- # what we want here.
- export CFLAGS="$CFLAGS -O3 -fPIC -fembed-bitcode"
- export CRATE_CC_NO_DEFAULTS=true
+ export CFLAGS="$CFLAGS -O3"
# Rust doesn't recognize CFLAGS changes, so we need to clean build artifacts
cargo clean --release
CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld