Skip to content

Latest commit

 

History

History
174 lines (128 loc) · 5.89 KB

File metadata and controls

174 lines (128 loc) · 5.89 KB

Rust Recipe

Build Rust canisters using Cargo with WASM target for the Internet Computer.

Usage

Example of how to reference this recipe in an icp.yaml file:

canisters:
  - name: my-canister
    recipe:
      type: "@dfinity/rust@<version>"
      configuration:
        shrink: true

By convention the canister name in icp.yaml should match the [package] name in Cargo.toml. If they differ, use the optional package parameter to specify the Cargo package name explicitly.

Replace <version> with a release version (e.g. v3.0.0). See available versions.

Configuration Parameters

Parameter Type Required Description Default
package string No Cargo package name to build. Defaults to the canister name in icp.yaml (canister name)
locked boolean No Use exact dependency versions from Cargo.lock (passes --locked to Cargo) false
candid string No Path to a custom Candid interface file. If not provided, the interface is auto-extracted from the WASM using candid-extractor (auto-extracted)
metadata array No Custom wasm metadata entries. Each takes name, value, and an optional visibility of public or private (omitted means private) []
shrink boolean No Remove unused functions and debug info to reduce file size false
compress boolean No Gzip compress the WASM file false

Prerequisites

  • Rust toolchain with wasm32-unknown-unknown target
  • ic-wasm (included with icp-cli installation)
  • candid-extractor (only required if not providing a custom candid file)

Note: If you followed the icp-cli installation guide, ic-wasm is already installed. You only need to install candid-extractor if you want auto-extraction of Candid interfaces.

Additional Installation

# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown

# Install candid-extractor (only needed if not providing candid file)
cargo install candid-extractor

Examples

Basic Example

canisters:
  - name: hello-rust
    recipe:
      type: "@dfinity/rust@<version>"

Advanced Example

canisters:
  - name: app-backend
    recipe:
      type: "@dfinity/rust@<version>"
      configuration:
        shrink: true
        compress: true
        metadata:
          - name: "crate:version"
            value: "1.0.0"
          - name: "build:profile"
            value: "release"
          - name: "build:commit"
            value: "a1b2c3d"
            visibility: public

Workspace Example

Use package when the Cargo package name differs from the canister name (e.g. in a workspace):

canisters:
  - name: backend
    recipe:
      type: "@dfinity/rust@<version>"
      configuration:
        package: my-project-backend

Build Process

When this recipe is executed:

  1. Runs cargo build with the specified package for the wasm32-unknown-unknown target in release mode (with --locked if enabled)
  2. Moves the resulting WASM file from the Cargo target directory to the output location
  3. Handles package name conversion (hyphens to underscores for the WASM filename)
  4. Injects Cargo version metadata ("cargo:version")
  5. Injects template type metadata ("template:type" = "rust")
  6. Injects Candid interface: uses the provided candid file, or auto-extracts it from the WASM using candid-extractor
  7. Injects any custom metadata specified in the configuration
  8. Optionally removes unused functions if shrink is enabled
  9. Optionally gzip compresses the WASM file if compress is enabled

Project Structure

A typical Rust canister project structure:

my-project/
├── Cargo.toml           # Package configuration
├── src/
│   ├── lib.rs          # Main canister code
│   └── types.rs        # Type definitions
├── Cargo.lock          # Dependency lock file
└── icp.yaml           # Build configuration

Cargo.toml Example

[package]
name = "my-canister"
version = "1.0.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
ic-cdk = "0.10"
ic-cdk-macros = "0.10"
candid = "0.10"
serde = { version = "1.0", features = ["derive"] }

Common Issues

Issue 1

Problem: wasm32-unknown-unknown target not installed Solution: Run rustup target add wasm32-unknown-unknown to install the WASM target

Issue 2

Problem: Package not found during build Solution: By default the canister name in icp.yaml is used as the Cargo package name. If they differ, set the package parameter explicitly to match the [package] name in Cargo.toml

Issue 3

Problem: Compilation errors Solution: Run cargo check locally to identify and fix Rust compilation issues

Issue 4

Problem: WASM file not found after build Solution: Check that your Cargo.toml has crate-type = ["cdylib"] in the [lib] section

Related Recipes

Use this recipe when developing IC canisters in Rust, which provides performance benefits and access to the rich Rust ecosystem.

Release History

See the release history for changelogs, version updates, and breaking changes.