Automatic Swift bindings generation for rust-lightning
.
In order to use the automatically generated bindings, simply drag *.xcframework
file into an Xcode project.
The *.xcframework
files are either available on
the Releases page, or can be compiled
from scratch.
- A machine running macOS
- Xcode 13.2.1 or lower (this is because there is a bug with
cc
that prevents it from compiling for Mac Catalyst targets with clang 13) - Python3
- Rust
- GNU sed (optional, but will cut your compile times significantly!)
For Rust specifically, there are a couple additional requirements that can be installed once the Rust toolchain is set up:
rustup toolchain install nightly
rustup target add aarch64-apple-darwin aarch64-apple-ios x86_64-apple-ios
cargo install cbindgen
In order to generate these bindings from scratch, you will need to clone two dependency repositories:
rust-lightning, (a specific branch built for bindings compatibility):
git clone --branch 2022-07-109-java-bindings https://github.com/TheBlueMatt/rust-lightning /path/to/rust-lightning
git clone --branch v0.0.109.0 https://github.com/lightningdevkit/ldk-c-bindings /path/to/ldk-c-bindings
Take note of where you clone these directories, it's best you save the absolute path somewhere handy for the rest of the remaining steps.
Now, navigate to the ldk-c-bindings
directory and run the genbindings.sh
script:
pushd path/to/ldk-c-bindings
./genbindings.sh /path/to/rust-lightning true
popd
If using Docker
If you're using Docker to generate the Swift bindings, navigate (if you're not already there from the
previous step) to the ldk-c-bindings
directory and open the file located here:
/path/to/ldk-c-bindings/lightning-c-bindings/Cargo.toml
In that file, you will see four lines specifying the lightning
, lightning-persister
, lightning-invoice
, and
lightning-background-processor
dependencies. They will most likely show local paths to the rust-lightning
folder due to the previous genbindings.sh
step. As Docker won't have access to local paths,
replace those lines with the following:
lightning = { git = "https://github.com/thebluematt/rust-lightning", branch = "2022-07-109-java-bindings", default-features = false }
lightning-persister = { git = "https://github.com/thebluematt/rust-lightning", branch = "2022-07-109-java-bindings", default-features = false }
lightning-invoice = { git = "https://github.com/thebluematt/rust-lightning", branch = "2022-07-109-java-bindings", default-features = false }
lightning-background-processor = { git = "https://github.com/thebluematt/rust-lightning", branch = "2022-07-109-java-bindings", default-features = false }
lightning-rapid-gossip-sync = { git = "https://github.com/thebluematt/rust-lightning", branch = "2022-07-109-java-bindings", default-features = false }
You will note that the revision is unspecified and is currently just placeholder xxx
s. To obtain the revision,
just navigate to the just clone custom rust-lightning
directory and run:
cd /path/to/rust-lightning
git rev-parse HEAD
Take that commit hash and replace the xxx
instances with it.
To generate the Swift files, navigate to the ldk-swift
repository and run the following:
export LDK_SWIFT_GENERATOR_INPUT_HEADER_PATH="/path/to/ldk-c-bindings/lightning-c-bindings/include/lightning.h"
python3 ./
Now, the contents of ./ci/LDKSwift/Sources/LDKSwift/bindings
will have been completely regenerated.
To make sure the next two steps work correctly, you need to verify that you're using Xcode 13.2.1. If you have a later version, you can download the correct version from here: https://xcodereleases.com/
The direct download link is
You may be asked to log in to your Apple developer account.
After downloading the correct Xcode version and copying it to Applications, you might also need to run the following command with root privileges:
sudo xcode-select -s /Applications/Xcode\ 13.2.1.app/Contents/Developer/
To make sure the correct bindings files are referenced in the project, open ./xcode/LDKFramework/LDK.xcodeproj
.
In the sidebar, navigate to the LDK/bindings
group, and delete it by removing references.
Then, open a Finder window, and drag the bindings
folder (./ci/LDKSwift/Sources/LDKSwift/bindings
) into the same location in Xcode that you just deleted.
Finally, make sure you leave the "Copy items if needed" box unchecked, and pick at least LightningDevKit
as a target to add the references to. Depending on what you intend to do later on, it's easiest to simply add it to all the targets.
Navigate (cd
) to the ./src/scripts
folder, and run the following Python script:
python3 ./build_bulk_libldks.py /path/to/ldk-c-bindings
This command will take a while, but it will eventually produce a set of binaries for all the
platform/architecture combinations we're trying to support. Those binaries should adhere to the
./bindings/bin/release/<platform>/
folder pattern.
Each of those folders will contain an architectures
directory with subdirectories such as arm64
or x86_64
, as well as a libldk.a
file, which is the lipo
product of all the targeted
architectures.
With all the binaries generated, still in the ./src/scripts
directory, you just need to run one
last Python script to produce the framework:
python3 ./generate_xcframework.py /path/to/ldk-c-bindings
Once the script finishes running, you should see LightningDevKit.xcframework
in the
./bindings/bin/release
folder. Drag that into your project, and you're done!