Crates.io | cargo-xcode |
lib.rs | cargo-xcode |
version | 1.11.0 |
source | src |
created_at | 2017-12-18 02:47:56.830016 |
updated_at | 2024-06-12 16:13:35.778815 |
description | Make Xcode project files from Cargo projects |
homepage | https://lib.rs/crates/cargo-xcode |
repository | https://gitlab.com/kornelski/cargo-xcode |
max_upload_size | |
id | 43487 |
size | 53,774 |
Generates Xcode project files from Cargo.toml
allowing use of Rust libraries in Mac and iOS applications without leaving Xcode.
It's better than just launching cargo build
from a script:
The generated Xcode project files are self-contained, and work without cargo-xcode
dependency. You can distribute the .xcodeproj
files and use them with just Rust and Xcode.
cargo install cargo-xcode
TL;DR: Run
cargo xcode
and use the generated project files as subprojects in your other Xcode projects.
This tool will generate Rust-aware project files for all binaries and C-compatible libraries in a Cargo workspace. Instead of modifying your Mac/iOS app's project file directly, take advantage of Xcode's ability to nest and combine multiple xcodeproj
files together. The generated Xcode projects are not meant for standalone use. They are supposed to be used only as subprojects of other regular app Xcode projects.
If you don't have an existing ObjC/Swift app project yet, create one in Xcode using any Cocoa app template you like. This will be called your "parent project" in later steps.
If your Rust project is a library, edit Cargo.toml
and add:
[lib]
crate-type = ["lib", "staticlib"] # cdylib is NOT recommended
Only Cargo libraries of type "staticlib"
or "cdylib"
are suitable, and staticlib
is much easier to work with (but keep the "lib"
crate type for compatibility with other Cargo libraries and tests). If you're not forced to deal with dynamic libraries, don't use them. Use static libraries whenever possible.
In the same directory as Cargo.toml
(or root of a Cargo workspace) run:
cargo xcode
This will generate <rust-project-name>.xcodeproj
. Don't open it yet!
Open your parent project (from step 1) in Xcode and add the <rust-crate-name>.xcodeproj
to the workspace (drag the file into the parent project's sidebar). You should see the dragged Rust-Xcode project embedded in your parent project. If the new Rust-Xcode project appears empty in the sidebar, close all Xcode windows and re-open only the parent project.
In your parent project's app's Build Phases, in Link Binary With Libraries phase, you can now add the Rust libraries from the workspace.
Real-world example of such usage.
You can configure some settings from within Xcode's target's Build Settings:
CARGO_XCODE_FEATURES
maps to --features
flag. cargo xcode --no-default-features
passes the same flag to cargo build
.RUSTUP_TOOLCHAIN
selects which toolchain to use (nightly
, 1.99.0
, stable
, empty string for default toolchain). See rustup toolchain add -h
. cargo xcode --nightly
picks the nightly.SDKROOT
) to iOS, DriverKit, etc. as needed.ADDITIONAL_SDKS
option, or run cargo xcode --platforms macosx
.You should almost always use static libraries (.a
). Dynamic libraries (.dylib
/cdylib
) are much harder to build, much harder to embed correctly, and add bloat app bundles from redundant copies of Rust's standard library and dead code. But if you're brave enough to to build a .dylib
anyway, for including in an application bundle, make sure to set DYLIB_INSTALL_NAME_BASE
in Xcode's settings to @executable_path/../Frameworks/
or whatever location you're going to copy the library to.
If you're putting a Rust a binary inside an app bundle, you may need to set SKIP_INSTALL=YES
or run cargo xcode --skip-install
.
Xcode supports reading config from text files, which is useful for sharing settings across multiple projects. You can specify these with --xcconfig debug.xcconfig --xcconfig release.xcconfig
.
Rust binaries are exported as command-line tools. This tool intentionally does not make app bundles. If you want to build a Mac GUI app, create one as ObjC or Swift project in Xcode and call Rust code via a Rust static library, or use Tauri.
AppleTV, Mac Catalyst, VisionOS, and some other rare platforms don't have pre-built rustup targets. cargo xcode
will try to use nightly toolchain and -Zbuild-std
feature to support these platforms. In case the auto-detection doesn't work:
RUSTUP_TOOLCHAIN
build setting to nightly
(or specific nightly version if you require).Cargo.toml
, and append -Zbuild-std
there.