Build improvements with UniFFI library mode
Bumped UniFFI to 0.28.2 Added a tool to run uniffi-bindgen in library mode. It can input either a specific library path or the megazord crate name. Use that simplify several build scripts -- especially the generate docs ones. The best part of this is that we no longer have to maintain hand-written modulemaps, which makes adding a new component harder than it needs to be. Split out the uniffi-bindgen commands from `build-xcframework.sh`. This way you can run them standalone and see the results, even if you don't have XCode setup. One change is that automation/swift-components-docs/generate-swift-project.sh now uses `megazord_ios` rather than `megazord`. I think this should result in slightly more accurate docs, since historically some components in the Android megazord aren't in the iOS one (Although, I think they match at the present).
This commit is contained in:
Родитель
581f5d2866
Коммит
eb1f268654
|
@ -1,6 +1,7 @@
|
|||
[alias]
|
||||
regen-protobufs = ["run", "--bin", "protobuf-gen", "tools/protobuf_files.toml"]
|
||||
uniffi-bindgen = ["run", "--package", "embedded-uniffi-bindgen", "--"]
|
||||
uniffi-bindgen-library-mode = ["run", "--package", "uniffi-bindgen-library-mode", "--"]
|
||||
dev-install = ["install", "asdev"]
|
||||
verify_env = ["asdev", "verify_env"]
|
||||
fxa = ["run", "-p", "examples-fxa-client", "--"]
|
||||
|
|
|
@ -4805,12 +4805,13 @@ checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
|||
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31bff6daf87277a9014bcdefbc2842b0553392919d1096843c5aad899ca4588"
|
||||
checksum = "51ce6280c581045879e11b400bae14686a819df22b97171215d15549efa04ddb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"clap 4.2.2",
|
||||
"uniffi_bindgen",
|
||||
"uniffi_build",
|
||||
|
@ -4818,11 +4819,23 @@ dependencies = [
|
|||
"uniffi_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi-bindgen-library-mode"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"clap 4.2.2",
|
||||
"uniffi",
|
||||
"uniffi_bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96061d7e01b185aa405f7c9b134741ab3e50cc6796a47d6fd8ab9a5364b5feed"
|
||||
checksum = "5e9f25730c9db2e878521d606f54e921edb719cdd94d735e7f97705d6796d024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
|
@ -4838,15 +4851,14 @@ dependencies = [
|
|||
"textwrap 0.16.1",
|
||||
"toml",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"uniffi_udl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6b86f9b221046af0c533eafe09ece04e2f1ded04ccdc9bba0ec09aec1c52bd"
|
||||
checksum = "88dba57ac699bd8ec53d6a352c8dd0e479b33f698c5659831bb1e4ce468c07bd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
|
@ -4855,9 +4867,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_checksum_derive"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fcfa22f55829d3aaa7acfb1c5150224188fe0f27c59a8a3eddcaa24d1ffbe58"
|
||||
checksum = "d2c801f0f05b06df456a2da4c41b9c2c4fdccc6b9916643c6c67275c4c9e4d07"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
|
@ -4865,13 +4877,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_core"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3210d57d6ab6065ab47a2898dacdb7c606fd6a4156196831fa3bf82e34ac58a6"
|
||||
checksum = "61049e4db6212d0ede80982adf0e1d6fa224e6118387324c5cfbe3083dfb2252"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"camino",
|
||||
"log",
|
||||
"once_cell",
|
||||
"paste",
|
||||
|
@ -4880,9 +4891,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b58691741080935437dc862122e68d7414432a11824ac1137868de46181a0bd2"
|
||||
checksum = "b40fd2249e0c5dcbd2bfa3c263db1ec981f7273dca7f4132bf06a272359a586c"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
|
@ -4898,9 +4909,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7663eacdbd9fbf4a88907ddcfe2e6fa85838eb6dc2418a7d91eebb3786f8e20b"
|
||||
checksum = "c9ad57039b4fafdbf77428d74fff40e0908e5a1731e023c19cfe538f6d4a8ed6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
@ -4910,9 +4921,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_testing"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f922465f7566f25f8fe766920205fdfa9a3fcdc209c6bfb7557f0b5bf45b04dd"
|
||||
checksum = "21fa171d4d258dc51bbd01893cc9608c1b62273d2f9ea55fb64f639e77824567"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
|
@ -4923,9 +4934,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_udl"
|
||||
version = "0.28.0"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cef408229a3a407fafa4c36dc4f6ece78a6fb258ab28d2b64bddd49c8cb680f6"
|
||||
checksum = "f52299e247419e7e2934bef2f94d7cccb0e6566f3248b1d48b160d8f369a2668"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"textwrap 0.16.1",
|
||||
|
|
|
@ -50,6 +50,7 @@ members = [
|
|||
"tools/protobuf-gen",
|
||||
"tools/embedded-uniffi-bindgen",
|
||||
"tools/start-bindings",
|
||||
"tools/uniffi-bindgen-library-mode",
|
||||
"automation/swift-components-docs",
|
||||
|
||||
"examples/*/",
|
||||
|
@ -122,6 +123,7 @@ default-members = [
|
|||
# "testing/sync-test",
|
||||
"tools/protobuf-gen",
|
||||
"tools/embedded-uniffi-bindgen",
|
||||
"tools/uniffi-bindgen-library-mode",
|
||||
"examples/*/",
|
||||
"testing/separated/*/",
|
||||
]
|
||||
|
@ -129,7 +131,8 @@ default-members = [
|
|||
[workspace.dependencies]
|
||||
rusqlite = "0.31.0"
|
||||
libsqlite3-sys = "0.28.0"
|
||||
uniffi = "0.28.0"
|
||||
uniffi = "0.28.2"
|
||||
uniffi_bindgen = "0.28.2"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "s"
|
||||
|
|
|
@ -14,20 +14,10 @@ CARGO="$HOME/.cargo/bin/cargo"
|
|||
# Set the documentation directory
|
||||
KOTLIN_DIR="$WORKING_DIR/src/main/kotlin"
|
||||
|
||||
# Build the Rust crate using Cargo
|
||||
echo "Building the Rust crate..."
|
||||
$CARGO build -p megazord --release
|
||||
|
||||
# Define the path to the generated Rust library
|
||||
LIBRARY_FILE="$REPO_ROOT/target/release/libmegazord.so"
|
||||
if [[ ! -f "$LIBRARY_FILE" ]]; then
|
||||
echo "Error: Rust library not found at $LIBRARY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate Kotlin bindings, headers, and module map using uniffi-bindgen
|
||||
# Generate Kotlin bindings to use as the documentation source
|
||||
echo "Generating Kotlin bindings with uniffi-bindgen..."
|
||||
$CARGO uniffi-bindgen generate --library "$LIBRARY_FILE" --language kotlin --out-dir "$KOTLIN_DIR"
|
||||
|
||||
$CARGO uniffi-bindgen-library-mode -m megazord kotlin "$KOTLIN_DIR"
|
||||
|
||||
# Generate documentation with increased memory
|
||||
(cd "$WORKING_DIR" && "$REPO_ROOT/gradlew" --max-workers=2 dokkaHtml -Dorg.gradle.vfs.watch=false)
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Define the module name and path to the include directory
|
||||
MODULE_NAME="MozillaRustComponents"
|
||||
INCLUDE_DIR="Sources/SwiftComponents/include"
|
||||
MODULEMAP_FILE="$INCLUDE_DIR/module.modulemap"
|
||||
|
||||
# Start creating the module map
|
||||
echo "module $MODULE_NAME {" > "$MODULEMAP_FILE"
|
||||
|
||||
# Find all .h files in the include directory and add them to the module map
|
||||
for header in "$INCLUDE_DIR"/*.h; do
|
||||
echo " header \"$(basename "$header")\"" >> "$MODULEMAP_FILE"
|
||||
done
|
||||
|
||||
# Add export statement to the end of the module map
|
||||
echo " export *" >> "$MODULEMAP_FILE"
|
||||
echo "}" >> "$MODULEMAP_FILE"
|
||||
|
||||
# Confirm module.modulemap was created
|
||||
echo "module.modulemap generated at: $MODULEMAP_FILE"
|
|
@ -8,7 +8,6 @@ set -euo pipefail
|
|||
|
||||
FRAMEWORK_NAME="SwiftComponents"
|
||||
THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
REPO_ROOT="$( dirname "$( dirname "$THIS_DIR" )" )"
|
||||
WORKING_DIR="$THIS_DIR"
|
||||
CARGO="$HOME/.cargo/bin/cargo"
|
||||
|
||||
|
@ -17,39 +16,10 @@ INCLUDE_DIR="$WORKING_DIR/Sources/$FRAMEWORK_NAME/include"
|
|||
SWIFT_DIR="$WORKING_DIR/Sources/$FRAMEWORK_NAME"
|
||||
mkdir -p "$INCLUDE_DIR"
|
||||
|
||||
# Build the Rust crate using Cargo
|
||||
echo "Building the Rust crate..."
|
||||
$CARGO build -p megazord_ios --release
|
||||
|
||||
# Define the path to the generated Rust library
|
||||
LIBRARY_FILE="$REPO_ROOT/target/release/libmegazord_ios.a"
|
||||
if [[ ! -f "$LIBRARY_FILE" ]]; then
|
||||
echo "Error: Rust library not found at $LIBRARY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate Swift bindings, headers, and module map using uniffi-bindgen
|
||||
echo "Generating Swift bindings with uniffi-bindgen..."
|
||||
$CARGO uniffi-bindgen generate --library "$LIBRARY_FILE" --language swift --out-dir "$SWIFT_DIR"
|
||||
|
||||
# Move generated header files to the include directory
|
||||
echo "Moving header files to include directory..."
|
||||
mv "$SWIFT_DIR"/*.h "$INCLUDE_DIR" || {
|
||||
echo "Error: Failed to move header files."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Remove any old modulemaps
|
||||
echo "Cleaning up old module maps..."
|
||||
rm -f "$SWIFT_DIR"/*.modulemap
|
||||
|
||||
# Generate a new module map
|
||||
echo "Generating module map..."
|
||||
if [[ ! -f "$WORKING_DIR/generate-modulemap.sh" ]]; then
|
||||
echo "Error: generate-modulemap.sh script not found."
|
||||
exit 1
|
||||
fi
|
||||
"$WORKING_DIR/generate-modulemap.sh"
|
||||
# Generate Swift bindings, headers, and module map to use as the documentation source
|
||||
echo "Generating Swift bindings"
|
||||
$CARGO uniffi-bindgen-library-mode -m megazord_ios swift --swift-sources "$SWIFT_DIR"
|
||||
$CARGO uniffi-bindgen-library-mode -m megazord_ios swift --headers --modulemap --modulemap-filename module.modulemap "$INCLUDE_DIR"
|
||||
|
||||
# Success message
|
||||
echo "Successfully generated Swift bindings, headers, and module map."
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.autofill"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "autofillFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.crashtest"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "crashtestFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.fxaclient"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "fxa_clientFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.logins"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "loginsFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -13,7 +13,6 @@ from_custom = "{}.toString()"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "nimbusFFI"
|
||||
generate_module_map = false
|
||||
|
||||
[bindings.python]
|
||||
# This can be commented out, and the `--library` argument of `bindgen-uniffi` should be used instead.
|
||||
|
|
|
@ -6,4 +6,3 @@ package_name = "mozilla.appservices.places.uniffi"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "placesFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -13,5 +13,4 @@ from_custom = "{}.toString()"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "remote_settingsFFI"
|
||||
generate_module_map = false
|
||||
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.errorsupport"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "errorFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.rust_log_forwarder"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "rustlogforwarderFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.sync15"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "sync15FFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.syncmanager"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "syncmanagerFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -4,4 +4,3 @@ package_name = "mozilla.appservices.remotetabs"
|
|||
[bindings.swift]
|
||||
ffi_module_name = "MozillaRustComponents"
|
||||
ffi_module_filename = "tabsFFI"
|
||||
generate_module_map = false
|
||||
|
|
|
@ -133,7 +133,6 @@ rm -rf "$XCFRAMEWORK_ROOT"
|
|||
COMMON="$XCFRAMEWORK_ROOT/common/$FRAMEWORK_NAME.framework"
|
||||
|
||||
mkdir -p "$COMMON/Modules"
|
||||
cp "$WORKING_DIR/module.modulemap" "$COMMON/Modules/"
|
||||
|
||||
cp "$WORKING_DIR/DEPENDENCIES.md" "$COMMON/DEPENDENCIES.md"
|
||||
|
||||
|
@ -147,17 +146,8 @@ UNIFFI_BINDGEN_LIBRARY="$TARGET_DIR/aarch64-apple-ios/$BUILD_PROFILE/$LIB_NAME"
|
|||
cp "$WORKING_DIR/$FRAMEWORK_NAME.h" "$COMMON/Headers"
|
||||
cp "$REPO_ROOT/components/viaduct/ios/RustViaductFFI.h" "$COMMON/Headers"
|
||||
|
||||
# Next, move the generated headers.
|
||||
#
|
||||
# TODO: https://github.com/mozilla/uniffi-rs/issues/1060
|
||||
#
|
||||
# It would be neat if there was a single UniFFI command that would generate headers-only, but for
|
||||
# now we generate both the `.h` and `.swift` files, then delete the `.swift`. Bleh.
|
||||
|
||||
$CARGO uniffi-bindgen generate --library "$UNIFFI_BINDGEN_LIBRARY" -l swift -o "$COMMON/Headers"
|
||||
rm -rf "$COMMON"/Headers/*.swift
|
||||
|
||||
|
||||
# Next, generate files with uniffi-bindgen
|
||||
"$THIS_DIR/generate-files.sh" "$UNIFFI_BINDGEN_LIBRARY" "$COMMON"
|
||||
|
||||
# Flesh out the framework for each architecture based on the common files.
|
||||
# It's a little fiddly, because we apparently need to put all the simulator targets
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
framework module MozillaRustComponents {
|
||||
umbrella header "MozillaRustComponents.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
if [[ $# -ne 2 ]] ; then
|
||||
echo "USAGE megazords/ios-rust/generate-files.sh [UNIFFI_BINDGEN_LIBRARY] [COMMON]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
UNIFFI_BINDGEN_LIBRARY=$1
|
||||
COMMON=$2
|
||||
|
||||
# Helper to run the cargo build command in a controlled environment.
|
||||
# It's important that we don't let environment variables from the user's default
|
||||
# desktop build environment leak into the iOS build, otherwise it might e.g.
|
||||
# link against the desktop build of NSS.
|
||||
CARGO="$HOME/.cargo/bin/cargo"
|
||||
|
||||
# Run uniffi-bindgen-library-mode to generate the files.
|
||||
#
|
||||
# We can't use the `-m` flag because UNIFFI_BINDGEN_LIBRARY is cross-compiled, which our
|
||||
# uniffi-bindgen-library-mode tool can't handle yet.
|
||||
"$CARGO" uniffi-bindgen-library-mode -l "$UNIFFI_BINDGEN_LIBRARY" swift --headers "$COMMON/Headers"
|
||||
"$CARGO" uniffi-bindgen-library-mode -l "$UNIFFI_BINDGEN_LIBRARY" swift --modulemap "$COMMON/Modules" --xcframework --modulemap-filename module.modulemap
|
|
@ -1,6 +0,0 @@
|
|||
framework module MozillaRustComponents {
|
||||
umbrella header "MozillaRustComponents.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
|
@ -143,21 +143,16 @@ def generate_uniffi_bindings(args):
|
|||
# Generate sources for Focus
|
||||
generate_uniffi_bindings_for_target(focus_out_dir, "megazord_focus")
|
||||
|
||||
def generate_uniffi_bindings_for_target(out_dir, library_name):
|
||||
log(f"generating sources for {library_name}")
|
||||
# Use a megazord library that was built for the XCFramework. Pick an arbitrary target, since
|
||||
# the target doesn't affect the UniFFI bindings.
|
||||
lib_path = f'target/aarch64-apple-ios/release/lib{library_name}.a'
|
||||
|
||||
cmdline = ['generate', '--library', lib_path, '-l', 'swift', '-o', out_dir]
|
||||
run_uniffi_bindgen(cmdline)
|
||||
|
||||
def run_uniffi_bindgen(bindgen_args):
|
||||
all_args = [
|
||||
'cargo', 'run', '-p', 'embedded-uniffi-bindgen',
|
||||
]
|
||||
all_args.extend(bindgen_args)
|
||||
subprocess.check_call(all_args, cwd=ROOT_DIR)
|
||||
def generate_uniffi_bindings_for_target(out_dir, megazord):
|
||||
log(f"generating sources for {megazord}")
|
||||
# We can't use the `-m` flag here because the megazord library was cross-compiled and the
|
||||
# `uniffi-bindgen-library-mode` tool can't handle that yet. Instead, send one of the library
|
||||
# paths using the `-l` flag. Pick an arbitrary target, since the it doesn't affect the UniFFI
|
||||
# bindings.
|
||||
lib_path = f'target/aarch64-apple-ios/release/lib{megazord}.a'
|
||||
subprocess.check_call([
|
||||
'cargo', 'uniffi-bindgen-library-mode', '-l', lib_path, "swift", out_dir
|
||||
])
|
||||
|
||||
def copy_source_dirs(args):
|
||||
out_dir = args.out_dir / 'all'
|
||||
|
|
|
@ -89,17 +89,20 @@ def _build_shared_library(megazord, target, dist_dir):
|
|||
'cargo', 'build', '--manifest-path', f'{SRC_ROOT}/megazords/{megazord}/Cargo.toml', '--release', '--target', target,
|
||||
], env=env, cwd=SRC_ROOT)
|
||||
|
||||
# Move the .so file to the dist_directory
|
||||
shutil.move(SRC_ROOT / 'target' / target / 'release' / filename, dist_dir / filename)
|
||||
|
||||
# This is only temporary, until cirrus uses pre-built binaries.
|
||||
_patch_uniffi_tomls()
|
||||
|
||||
# Generate the Python FFI. We do this with `--library` so we don't have to specify the UDL or the uniffi.toml file.
|
||||
library_path = SRC_ROOT / 'target' / target / 'release' / filename
|
||||
|
||||
# Generate the Python FFI. We do this with `uniffi-bindgen-library-mode` so we don't have to specify the UDL or the uniffi.toml file.
|
||||
# Use the `-l` flag rather than `-m` since we want to specify a particular target.
|
||||
subprocess.check_call([
|
||||
'cargo', 'uniffi-bindgen', 'generate', '--library', dist_dir / filename, '--language', 'python', '--out-dir', dist_dir,
|
||||
'cargo', 'uniffi-bindgen-library-mode', '-l', library_path.as_posix(), 'python', dist_dir
|
||||
], env=env, cwd=SRC_ROOT)
|
||||
|
||||
# Move the .so file to the dist_directory
|
||||
shutil.move(SRC_ROOT / 'target' / target / 'release' / filename, dist_dir / filename)
|
||||
|
||||
return filename
|
||||
|
||||
def _patch_uniffi_tomls():
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "uniffi-bindgen-library-mode"
|
||||
version = "0.1.0"
|
||||
authors = ["The Firefox Sync Developers <sync-team@mozilla.com>"]
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
uniffi = { workspace = true, features = ["cli"] }
|
||||
uniffi_bindgen = { workspace = true }
|
||||
clap = "4"
|
||||
cargo_metadata = "0.15"
|
||||
camino = "1"
|
||||
anyhow = "1"
|
|
@ -0,0 +1,202 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::{
|
||||
env::consts::{DLL_PREFIX, DLL_SUFFIX},
|
||||
fmt, process,
|
||||
};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use uniffi_bindgen::bindings::{generate_swift_bindings, SwiftBindingsOptions};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
struct Cli {
|
||||
#[command(flatten)]
|
||||
megazord: MegazordArg,
|
||||
#[command(subcommand)]
|
||||
command: Command,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
#[group(required = true, multiple = false)]
|
||||
struct MegazordArg {
|
||||
/// Name of the megazord to use
|
||||
#[arg(short, long, value_parser=["megazord", "megazord_ios", "megazord_focus", "cirrus", "nimbus-experimenter"])]
|
||||
megazord: Option<String>,
|
||||
|
||||
/// Path to a library file
|
||||
#[arg(short, long)]
|
||||
library: Option<Utf8PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
Kotlin {
|
||||
out_dir: Utf8PathBuf,
|
||||
},
|
||||
Swift {
|
||||
out_dir: Utf8PathBuf,
|
||||
/// Generate swift files
|
||||
#[arg(long)]
|
||||
swift_sources: bool,
|
||||
/// Generate header files
|
||||
#[arg(long)]
|
||||
headers: bool,
|
||||
/// Generate modulemap
|
||||
#[arg(long)]
|
||||
modulemap: bool,
|
||||
// Generate an xcframework-compatible modulemap
|
||||
#[arg(long)]
|
||||
xcframework: bool,
|
||||
/// module name for the generated modulemap
|
||||
#[arg(long)]
|
||||
module_name: Option<String>,
|
||||
/// filename for the generate modulemap
|
||||
#[arg(long)]
|
||||
modulemap_filename: Option<String>,
|
||||
},
|
||||
Python {
|
||||
out_dir: Utf8PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
enum Language {
|
||||
Kotlin,
|
||||
Swift,
|
||||
Python,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let Err(e) = run_uniffi_bindgen(Cli::parse()) {
|
||||
eprintln!("{e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_uniffi_bindgen(cli: Cli) -> Result<()> {
|
||||
let metadata = cargo_metadata::MetadataCommand::new()
|
||||
.exec()
|
||||
.expect("error running cargo metadata");
|
||||
let megazord = Megazord::new(
|
||||
&cli.megazord,
|
||||
cli.command.language(),
|
||||
&metadata.workspace_root,
|
||||
)?;
|
||||
let config_supplier = uniffi::CargoMetadataConfigSupplier::from(metadata);
|
||||
|
||||
match cli.command {
|
||||
Command::Kotlin { out_dir } => {
|
||||
uniffi::generate_bindings_library_mode(
|
||||
&megazord.library_path,
|
||||
None,
|
||||
&uniffi::KotlinBindingGenerator,
|
||||
&config_supplier,
|
||||
None,
|
||||
&out_dir,
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
Command::Swift {
|
||||
out_dir,
|
||||
mut swift_sources,
|
||||
mut headers,
|
||||
mut modulemap,
|
||||
xcframework,
|
||||
module_name,
|
||||
modulemap_filename,
|
||||
} => {
|
||||
let module_name = module_name.unwrap_or_else(|| "MozillaRustComponents".to_owned());
|
||||
// If no generate kinds were specified, generate them all
|
||||
if !(swift_sources || headers || modulemap) {
|
||||
swift_sources = true;
|
||||
headers = true;
|
||||
modulemap = true;
|
||||
}
|
||||
|
||||
generate_swift_bindings(SwiftBindingsOptions {
|
||||
out_dir,
|
||||
generate_swift_sources: swift_sources,
|
||||
generate_headers: headers,
|
||||
generate_modulemap: modulemap,
|
||||
library_path: megazord.library_path,
|
||||
xcframework,
|
||||
module_name: Some(module_name),
|
||||
modulemap_filename,
|
||||
metadata_no_deps: false,
|
||||
})?;
|
||||
}
|
||||
Command::Python { out_dir } => {
|
||||
uniffi::generate_bindings_library_mode(
|
||||
&megazord.library_path,
|
||||
None,
|
||||
&uniffi::PythonBindingGenerator,
|
||||
&config_supplier,
|
||||
None,
|
||||
&out_dir,
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct Megazord {
|
||||
library_path: Utf8PathBuf,
|
||||
}
|
||||
|
||||
impl Megazord {
|
||||
fn new(arg: &MegazordArg, language: Language, workspace_root: &Utf8Path) -> Result<Self> {
|
||||
if let Some(crate_name) = &arg.megazord {
|
||||
// Build the megazord
|
||||
process::Command::new("cargo")
|
||||
.args(["build", "--release", "-p", crate_name])
|
||||
.spawn()?
|
||||
.wait()?;
|
||||
|
||||
let filename = match language {
|
||||
// Swift uses static libs
|
||||
Language::Swift => format!("lib{}.a", crate_name.replace('-', "_")),
|
||||
// Everything else uses dynamic libraries
|
||||
_ => format!(
|
||||
"{}{}{}",
|
||||
DLL_PREFIX,
|
||||
crate_name.replace('-', "_"),
|
||||
DLL_SUFFIX
|
||||
),
|
||||
};
|
||||
let library_path = workspace_root.join("target").join("release").join(filename);
|
||||
Ok(Self { library_path })
|
||||
} else if let Some(library_path) = &arg.library {
|
||||
Ok(Self {
|
||||
library_path: library_path.clone(),
|
||||
})
|
||||
} else {
|
||||
bail!("Neither megazord nor library specified")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Language {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let name = match self {
|
||||
Self::Swift => "swift",
|
||||
Self::Kotlin => "kotlin",
|
||||
Self::Python => "python",
|
||||
};
|
||||
write!(f, "{}", name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Command {
|
||||
fn language(&self) -> Language {
|
||||
match self {
|
||||
Self::Kotlin { .. } => Language::Kotlin,
|
||||
Self::Swift { .. } => Language::Swift,
|
||||
Self::Python { .. } => Language::Python,
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче