Skip to content

Commit

Permalink
[User Guide] Make Tutorial section self-contained and self-explanatory (
Browse files Browse the repository at this point in the history
  • Loading branch information
mhammond authored May 3, 2024
1 parent b79ede9 commit 139a024
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 35 deletions.
8 changes: 6 additions & 2 deletions docs/manual/src/tutorial/Prerequisites.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Prerequisites

This tutorial builds on our [`arithmetic`](https://github.com/mozilla/uniffi-rs/tree/main/examples/arithmetic) and (creatively-named) [`arithmetic-procmacro`](https://github.com/mozilla/uniffi-rs/tree/main/examples/arithmetic-procmacro) examples, which will be useful when we've omitted things.

Here we will be creating a `math` library - so we assume a `cargo new --lib math` environment.

## Add `uniffi` as a dependency and build-dependency

In your crate's `Cargo.toml` add:
Expand All @@ -16,11 +20,11 @@ UniFFI has not reached version `1.0` yet. Versions are typically specified as `

## Build your crate as a cdylib

Ensure your crate builds as a `cdylib` by adding
Ensure your crate builds as a `cdylib` so looks something like
```toml
[lib]
crate-type = ["cdylib"]
name = "<library name>"
name = "math" # This is our crate name in this tutorial
```
to your crate's `Cargo.toml`.

Expand Down
28 changes: 8 additions & 20 deletions docs/manual/src/tutorial/Rust_scaffolding.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
# Rust scaffolding

## Rust scaffolding code
As already noted UniFFI supports two methods of interface definitions: UDL files and proc macros.

Now we generate some Rust helper code to make the `add` method available to foreign-language bindings.
If you use proc macros you can skip the next section, but if you use UDL files, you need to generate Rust "scaffolding" - code to implement what's described in the UDL.

First, add `uniffi` to your crate as both a dependency and build-dependency. Enable the `build` feature for the build-dependencies. This adds the runtime support code that powers UniFFI and build-time support for generating the Rust scaffolding code.

```toml
[dependencies]
uniffi = "0.XX.0"

[build-dependencies]
uniffi = { version = "0.XX.0", features = ["build"] }
```

As noted in [Describing the interface](udl_file.md), UniFFI currently supports two methods of interface definitions: UDL files and proc macros.
If you are using only proc macros, you can skip some boilerplate in your crate setup as well.

### Setup for crates using UDL
## Rust scaffolding code for UDL

Crates using UDL need a `build.rs` file next to `Cargo.toml`. This uses `uniffi` to generate the Rust scaffolding code.

Expand All @@ -27,25 +14,26 @@ fn main() {
}
```

It will generate `<namespace>.uniffi.rs` under your `target` directory.

Lastly, we include the generated scaffolding code in our `lib.rs` using this handy macro:

```rust
uniffi::include_scaffolding!("math");
```

**Note:** The file name is always `<namespace>.uniffi.rs`.

### Setup for crates using only proc macros

If you are only using proc macros, you can skip `build.rs` entirely!
All you need to do is add this to the top of `lib.rs`
NOTE: This function takes an optional parameter, the [`namespace`](../udl/namespace.md) used by the component.
If not specified, the crate name will be used as the namespace.

```rust
uniffi::setup_scaffolding!();
```

NOTE: This function takes an optional parameter, the [`namespace`](../udl/namespace.md) used by the component.
If not specified, the crate name will be used as the namespace.

**⚠ Warning ⚠** Do not call both `uniffi::setup_scaffolding!()` and `uniffi::include_scaffolding!!()` in the same crate.

### Libraries that depend on UniFFI components
Expand Down
29 changes: 17 additions & 12 deletions docs/manual/src/tutorial/foreign_language_bindings.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Foreign-language bindings

As stated in the [Overview](../Overview.md), this library and tutorial does not cover *how* to ship a Rust library on mobile, but how to generate bindings for it, so this section will only cover that.
By now you have setup your crate and `cargo build` has successfully created your library.

As stated in the [Overview](../Overview.md), UniFFI does not help shipping a Rust library on mobile, only how to generate bindings for it.

## Creating the bindgen binary

Expand Down Expand Up @@ -38,19 +40,20 @@ creating a binary for each crate that uses UniFFI. You can avoid this by creati

Then your can run `uniffi-bindgen` from any create in your project using `cargo run -p uniffi-bindgen [args]`

## Running uniffi-bindgen using a library file (RECOMMENDED)
## Running uniffi-bindgen using a library file

Use `generate --library` to generate foreign bindings by using a cdylib file built for your library.
This flag was added in UniFFI 0.24 and can be more convenient than specifying the UDL file -- especially when multiple UniFFI-ed crates are built together in one library.
The plan is to make library mode the default in a future UniFFI version, and it is highly recommended to specify the flag for now (because some features simply don't work otherwise).
This can be more convenient than specifying the UDL file -- especially when multiple UniFFI-ed crates are built together in one library.
This should be used where possible - some "external type" features don't work otherwise.

Taking `example/arithmetic` as an example, you can generate the bindings with:
In our example, we generate the bindings with:
```
cargo build --release
cargo run --bin uniffi-bindgen generate --library target/release/libarithmetical.so --language kotlin --out-dir out
cargo run --bin uniffi-bindgen generate --library target/release/libmath.so --language kotlin --out-dir out
```
(maybe `.dylib`, good luck with `.dll`!)

Then check out the `out` directory.
Then look in the `out` directory.

When using library mode, if multiple crates get built into the library that use UniFFI, all will have bindings generated for them.

Expand All @@ -63,23 +66,25 @@ Library mode comes with some extra requirements:

## Running uniffi-bindgen with a single UDL file

As noted above, library mode is encouraged - building from a single UDL is not recommended.

Use the `generate` command to generate bindings by specifying a UDL file.

### Kotlin

From the `example/arithmetic` directory, run:
From the example directory, run:
```
cargo run --bin uniffi-bindgen generate src/arithmetic.udl --language kotlin
cargo run --bin uniffi-bindgen generate src/math.udl --language kotlin
```
then have a look at `src/uniffi/arithmetic/arithmetic.kt`
then have a look at `src/uniffi/math/math.kt`

### Swift

Run
```
cargo run --bin uniffi-bindgen generate src/arithmetic.udl --language swift
cargo run --bin uniffi-bindgen generate src/math.udl --language swift
```
then check out `src/arithmetic.swift`
then check out `src/math.swift`

Note that these commands could be integrated as part of your gradle/Xcode build process.

Expand Down
3 changes: 2 additions & 1 deletion docs/manual/src/tutorial/udl_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace math {

Here you can note multiple things:

- The `namespace` directive: it will be the name of your Kotlin/Swift package. It **must** be present in any udl file, even if there ain't any exposed function (e.g. `namespace foo {}`).
- The `namespace` directive: it will be the name of your Kotlin/Swift package. It **must** be present in any udl file, even if there ain't any exposed functions (e.g. `namespace foo {}`).
It will typically your crate name.
- The `add` function is in the `namespace` block. That's because on the Rust side it is a top-level _function_, we will see later how to to handle _methods_.
- Rust's `u32` is also UDL's `u32`, but it is not always true! See the [Built-in Types](../udl/builtin_types.md) chapter for more information on mapping types between Rust and UDL.

Expand Down

0 comments on commit 139a024

Please sign in to comment.