diff --git a/recipes/motoko/README.md b/recipes/motoko/README.md index 0e883f1..195369f 100644 --- a/recipes/motoko/README.md +++ b/recipes/motoko/README.md @@ -1,6 +1,6 @@ # Motoko Recipe -Compile Motoko source code using the moc compiler to create IC canisters. +Compile Motoko source code using `mops build` to create IC canisters. ## Usage @@ -12,26 +12,34 @@ canisters: recipe: type: "@dfinity/motoko@" configuration: - main: src/main.mo shrink: true ``` -> Replace `` with a release version (e.g. `v4.0.0`). See [available versions](https://github.com/dfinity/icp-cli-recipes/releases?q=motoko&expanded=true). +> Replace `` with a release version (e.g. `v5.0.0`). See [available versions](https://github.com/dfinity/icp-cli-recipes/releases?q=motoko&expanded=true). + +The canister must also be defined in `mops.toml`. The key in the `[canisters]` section must match the canister name in `icp.yaml`: + +```toml +[toolchain] +moc = "1.8.2" + +[canisters] +backend = "src/main.mo" +``` + +Compiler flags, per-canister args, and the Candid file are all configured in `mops.toml`. See the [mops documentation](https://mops.one/docs) for the full `[canisters]` schema. ## Configuration Parameters | Parameter | Type | Required | Description | Default | |-----------|---------|----------|----------------------------------------------|---------| -| main | string | Yes | Path to the main Motoko source file | | -| args | string | No | Additional arguments to pass to moc compiler (e.g., `--incremental-gc`) | | -| candid | string | No | Path to a custom Candid interface file. If not provided, the interface is auto-generated by the Motoko compiler | (auto-generated) | | metadata | array | No | Array of key-value pairs for custom metadata | [] | | shrink | boolean | No | Remove unused functions and debug info to reduce file size | false | | compress | boolean | No | Gzip compress the WASM file | false | ## Prerequisites -- `mops` (Motoko package manager) - this recipe uses `mops toolchain` to manage the Motoko compiler +- `mops` (Motoko package manager) — manages the toolchain, dependencies, and canister build - `ic-wasm` (included with icp-cli installation) > **Note:** If you followed the [icp-cli installation guide](https://github.com/dfinity/icp-cli#installation), both `mops` and `ic-wasm` are already installed. @@ -45,42 +53,63 @@ If mops is not installed, see: ### Basic Example ```yaml +# icp.yaml canisters: - name: hello-world recipe: type: "@dfinity/motoko@" - configuration: - main: src/main.mo +``` + +```toml +# mops.toml +[toolchain] +moc = "1.8.2" + +[canisters] +hello-world = "src/main.mo" ``` ### Advanced Example ```yaml +# icp.yaml canisters: - - name: complex-backend + - name: backend recipe: type: "@dfinity/motoko@" configuration: - main: src/backend.mo - args: --incremental-gc shrink: true compress: true metadata: - name: "canister:type" value: "backend" - - name: "language:version" - value: "0.10.0" +``` + +```toml +# mops.toml +[toolchain] +moc = "1.8.2" + +[dependencies] +core = "2.5.0" + +[moc] +args = ["--default-persistent-actors"] + +[canisters.backend] +main = "src/main.mo" +candid = "backend.did" ``` ## Build Process When this recipe is executed: -1. Checks if `mops` is installed (used for Motoko toolchain management) -2. Compiles the specified Motoko entry file using `moc` via `mops toolchain` -3. Handles Candid interface: auto-generates from Motoko source, or uses the provided `candid` file -4. Injects compiler version metadata ("moc:version") -5. Injects template type metadata ("template:type" = "motoko") +1. Checks if `mops` and `ic-wasm` are installed +2. Runs `mops build ` which compiles the canister using the toolchain, dependencies, and compiler flags defined in `mops.toml` +3. Copies the built WASM to the icp-cli output path +4. Injects compiler version metadata (`moc:version`) +5. Injects template type metadata (`template:type` = `motoko`) 6. Injects any custom metadata specified in the configuration 7. Optionally removes unused functions if `shrink` is enabled 8. Optionally gzip compresses the WASM file if `compress` is enabled @@ -95,31 +124,35 @@ my-project/ │ ├── main.mo # Entry point │ ├── types.mo # Type definitions │ └── utils.mo # Utility functions -├── .vessel/ # Package manager dependencies -└── icp.yaml # Build configuration +├── mops.toml # Toolchain, dependencies, canister config +└── icp.yaml # Build configuration ``` -## Common Issues +## Migrating from v4 + +The `main`, `candid`, and `args` recipe parameters have been removed. Move them to `mops.toml`: -### Issue 1 +| Before (`icp.yaml`) | After (`mops.toml`) | +|-----------------------------|--------------------------------------------| +| `main: src/main.mo` | `[canisters.backend] main = "src/main.mo"` | +| `candid: backend.did` | `[canisters.backend] candid = "backend.did"` | +| `args: --incremental-gc` | `[canisters.backend] args = ["--incremental-gc"]` | -**Problem**: `moc not found` error -**Solution**: Install the Motoko compiler following the instructions at +The canister name in `icp.yaml` is used automatically — no additional recipe configuration is needed. -### Issue 2 +## Common Issues -**Problem**: Compilation errors in Motoko code -**Solution**: Check your Motoko syntax and ensure all imports are correctly resolved +### "No Motoko canisters found in mops.toml configuration" -### Issue 3 +The `[canisters]` section is missing from `mops.toml`, or the canister name does not match the `name` parameter in `icp.yaml`. Ensure the key in `[canisters]` exactly matches the `name` value in the recipe configuration. -**Problem**: Entry file not found -**Solution**: Verify the entry path is correct relative to your project root and the file exists +### "moc not found" error -### Issue 4 +Install the Motoko compiler via mops: run `mops install` in your project directory. The toolchain version is set in `mops.toml` under `[toolchain]`. -**Problem**: Missing dependencies -**Solution**: Ensure all imported modules are available or install them using vessel package manager +### Compilation errors + +Check your Motoko syntax and ensure all imports resolve. Run `mops check` for detailed diagnostics. ## Related Recipes @@ -127,8 +160,6 @@ my-project/ - [Pre-built Recipe](../prebuilt/README.md) - For using pre-compiled WASM files - [Asset Canister Recipe](../asset-canister/README.md) - For frontend assets canister -Use this recipe when developing IC canisters in Motoko, the native language for the Internet Computer. - ## Release History See the [release history](https://github.com/dfinity/icp-cli-recipes/releases?q=motoko&expanded=true) for changelogs, version updates, and breaking changes. diff --git a/recipes/motoko/recipe.hbs b/recipes/motoko/recipe.hbs index 9508fac..77ef5ed 100644 --- a/recipes/motoko/recipe.hbs +++ b/recipes/motoko/recipe.hbs @@ -1,7 +1,4 @@ -{{! A recipe for building a Motoko canister }} -{{! `main: string` Motoko file which contains the main actor }} -{{! `args: string` Additional arguments to pass to the moc compiler }} -{{! `candid: string` Optional, the path to the Candid interface file }} +{{! A recipe for building a Motoko canister using `mops build` }} {{! `shrink: boolean` Optimizes the wasm with ic-wasm }} {{! `compress: boolean` determines whether the wasm should be gzipped }} {{! `metadata: [name: string, value: string]`: An array of name/value pairs that get injected into the wasm metadata section }} @@ -19,7 +16,8 @@ build: - type: script commands: - - sh -c '$(mops toolchain bin moc) "{{ main }}" {{#if args}}{{ args }} {{/if}}{{#if candid}}--omit-metadata{{else}}--public-metadata{{/if}} candid:service $(mops sources) -o "$ICP_WASM_OUTPUT_PATH"' + - mops build "{{ _.canister.name }}" --output .mops/.build + - cp ".mops/.build/{{ _.canister.name }}.wasm" "$ICP_WASM_OUTPUT_PATH" - type: script commands: @@ -28,9 +26,6 @@ build: - type: script commands: - ic-wasm "$ICP_WASM_OUTPUT_PATH" -o "${ICP_WASM_OUTPUT_PATH}" metadata "template:type" -d "motoko" --keep-name-section - {{#if candid}} - - ic-wasm "$ICP_WASM_OUTPUT_PATH" -o "${ICP_WASM_OUTPUT_PATH}" metadata "candid:service" -f '{{ candid }}' -v public --keep-name-section - {{/if}} {{#if metadata}} {{#each metadata}} - ic-wasm "$ICP_WASM_OUTPUT_PATH" -o "${ICP_WASM_OUTPUT_PATH}" metadata "{{ name }}" -d "{{ value }}" --keep-name-section