Skip to content

Instantly share code, notes, and snippets.

@surpher
Last active April 25, 2024 12:30
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save surpher/bbf88e191e9d1f01ab2e2bbb85f9b528 to your computer and use it in GitHub Desktop.
Save surpher/bbf88e191e9d1f01ab2e2bbb85f9b528 to your computer and use it in GitHub Desktop.
Building binaries from Rust to iOS/macOS (PactSwift specific)

Dealing with Rust to build PactSwiftMockServer

Example of an automated script that does most of this: https://github.com/surpher/PactSwiftMockServer/blob/fb8148866bb05f49a0b1dcaae66c67bad1e7eca7/Support/build_rust_dependencies

Install Rust

curl https://sh.rustup.rs -sSf | sh

List available architecture targets

rustup target list

Add arch targets

rustup target add aarch64-apple-ios aarch64-apple-darwin x86_64-apple-ios x86_64-apple-darwin

# While arm64-apple-ios-sim is still in Tier 3:
rustup component add rust-src --toolchain nightly-x86_64-apple-darwin 

Install other toolchains

rustup toolchain install nightly

more: https://doc.rust-lang.org/edition-guide/rust-2018/rustup-for-managing-rust-versions.html

Install more tools to help with the build

cargo-lipo - a tool for building universal iOS binaries, cbindgen - a tool for generating C headers from rust

cargo install cargo-lipo
cargo install cbindgen

Generate the header file

cd pact-reference/rust/pact_mock_server_ffi
cbindgen src/lib.rs -l c > pact_mock_server.h
cp pact_mock_server.h ../PactSwift/Sources/Headers/pact_mock_server.h

Define the type of binary

cd pact-reference/rust/pact_mock_server_ffi
nano Cargo.toml

Set the following:

[lib]
name = "pact_mock_server"
crate-type = ["staticlib", "cdylib"]

Cross compiling

https://github.com/japaric/rust-cross

Build binaries

Universal iOS (arm64 mobile device + x86_64 simulator)

cargo lipo --release
cp ../target/universal/release/libpact_mock_server.a /path/to/PactSwift/Resources/iOS/lipact_mock_server.a

iOS Simulator x86_64

cargo build --target=x86_64-apple-ios --release
cp ../target/x86_64-apple-ios/release/libpact_mock_server.a /path/to/PactSwift/Resources/iOS/lipact_mock_server.a

iOS Simulator arm64

cargo +nightly build -Z build-std --target aarch64-apple-ios-sim --release
cp ../target/arm64-apple-ios-sim/release/libpact_mock_server.a /path/to/PactSwift/Resources/arm64iOSsim/libpact_mock_server.a

macOS x86_64

cargo build --targget=x86_64-apple-darwin --release
cp ../target/x86_64-apple-darwin/release/libpact_mock_server.a /path/to/PactSwift/Resources/macOS-x86_64/lipact_mock_server.a

macOS arm64

cargo build --target=aarch64-apple-darwin --release
cp ../target/arm64-apple-darwin/release/libpact_mock_server.a /path/to/PactSwift/Resources/macOS-arm64/lipact_mock_server.a

Mac Catalyst

https://nadim.computer/posts/2022-02-11-maccatalyst.html

List architectures in .a file

lipo -info libpact_mock_server.a

Extract one of the architectures from a fat library using the lipo command:

lipo libfoo.a -thin arm64 -output libfoo-arm64.a

Use -thin and not -extract the latter, still outputs a fat file, one which happens to only contain a single architecture.

Combine multiple architectures into one fat library

lipo -create foo-arm64.a foo-x86_64.a -output foo.a

For a fat lib, start by having cargo build the Rust code separately for each architecture. use lipo to combine the outputs into a fat binary.

iOS on M1

cargo +nightly build -Z build-std --target aarch64-apple-ios-sim

On Linux

curll --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
apt-get install protobuf-compiler

https://blog.mozilla.org/data/2021/04/16/this-week-in-glean-rustc-ios-and-an-m1/

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment