Package Configuration#

moon uses a package file to identify and describe a package. The legacy format is moon.pkg.json, and the new format is moon.pkg. For full JSON schema, please check moon's repository.

moon.pkg.json のサポートは非推奨です。新しいプロジェクトでは moon.pkg を使ってください。既存の JSON 設定は、以下の説明に従って moon fmt で移行できます。

New format (moon.pkg)#

The new format is a concise DSL. You can generate or reformat it from an existing moon.pkg.json with:

moon -C <module_dir> fmt

Example:

import {
  "moonbit-community/language/packages/virtual",
}

pkgtype(kind: "executable")

options(
  overrides: [ "moonbit-community/language/packages/implement" ],
)

In moon.pkg, dependencies are declared in an import { ... } block. Use @alias to set a custom alias:

import {
  "moonbit-community/language/packages/pkgA",
  "moonbit-community/language/packages/pkgC" @c,
  "moonbitlang/core/builtin",
}

Most fields from moon.pkg.json can be represented in an options(...) block. Stable declarations such as formatter and pkgtype have dedicated top-level forms. Legacy keys that contain - must be quoted when they are used inside options.

options(
  "virtual": { "has-default": true },
)

The moon.pkg format allows comments //....

Full syntax of moon.pkg is as follows:

moon_pkg ::= statement*
statement ::= import | assign | apply

import ::= "import" "{" (import_item ",")* import_item? "}" import_kind?
import_item ::= STRING ("@" PKG_NAME)?
import_kind ::= "for" STRING

assign ::= LIDENT "=" expr

apply ::= LIDENT "(" (argument ",")* argument? ")"
argument ::= LIDENT ":" expr | STRING ":" expr  

expr ::= array | object | apply | STRING | INT | "true" | "false"
array ::= "[" (expr ",")* expr? "]"
object ::= "{" (field ",")* field? "}"

Name#

The package name is not configurable; it is determined by the directory name of the package.

フォーマッタ#

formatter フィールドは、このパッケージに対する moon fmt の設定を行います。現在は、フォーマッタがスキップするファイル名の一覧である ignore をサポートしています。

これは、生成ファイルや、意図的に別の形式のままにしておきたいファイルに便利です。pre-build で生成されたファイルはすでに自動でスキップされるため、formatter.ignore は主に追加で除外したいファイルのために使います。

formatter(ignore: ["generated.mbt", "snapshot.mbt"])
{
  "formatter": {
    "ignore": ["generated.mbt", "snapshot.mbt"]
  }
}

Package type#

Use one pkgtype declaration to specify what a package builds. For example, an executable package uses:

pkgtype(kind: "executable")

The available kinds are library, executable, and foreign_library. library is the default. executable replaces the legacy options("is-main": true), while foreign_library replaces the legacy options(link: true). These kinds are alternatives and must not be declared together.

In a foreign-library package, #export_name assigns a stable symbol name to a public, non-generic function in generated Wasm, JavaScript, or C output:

#export_name("attr_add")
pub fn add_by_attr(n : Int) -> Int {
  n + 42
}

MoonBit currently requires export names to be valid C symbol identifiers and unique within the package, regardless of the selected backend.

警告

Known compiler issue: #export_name currently applies its C-symbol-identifier restriction to every backend. WebAssembly export names are UTF-8 strings and are not limited to C identifiers.

The attribute cannot be used on generic functions or functions with optional arguments. Prefer #export_name over backend-specific exports link configuration for new exports.

Export declarations are scoped to the package that produces the artifact. An attribute or exports configuration in a dependency applies when that dependency is built as its own artifact, but it does not add symbols to a downstream package's artifact. Define and export a wrapper in the exporting package to expose dependency functionality.

注釈

native バックエンドは現在、foreign_library パッケージをリンク可能なライブラリアーティファクトとしてエクスポートできません。これには .dll.so などの共有ライブラリも含まれます。

is-main(非推奨)#

is-main フィールドは非推奨です。既存のパッケージファイルとの互換性のため引き続き使用できますが、新規または移行後の moon.pkg では pkgtype(kind: "executable") を使用してください。次の旧形式の宣言は、この pkgtype 宣言と同等です。

The output of the linking process depends on the backend. When this field is set to true:

  • For the Wasm and wasm-gc backends, a standalone WebAssembly module will be generated.

  • For the js backend, a standalone JavaScript file will be generated.

options(
  "is-main": true,
)
{
  "is-main": true
}

Importing dependencies#

Import#

The import field is used to specify other packages that a package depends on.

For example, the following imports pkgA and pkgC, aliasing pkgC to c. User can write @c to access definitions from pkgC.

import {
  "moonbit-community/language/packages/pkgA",
  "moonbit-community/language/packages/pkgC" @c,
  "moonbitlang/core/builtin",
}
{
    "import": [
        "moonbit-community/language/packages/pkgA",
        {
            "path": "moonbit-community/language/packages/pkgC",
            "alias": "c"
        },
        "moonbitlang/core/builtin"
    ]
}

Most core packages are not special here: if you use @json, @test, or other ordinary core aliases, add the corresponding moonbitlang/core/... package to import to avoid core_package_not_imported warnings.

prelude is the exception. It is available by default, so the names it exposes do not need an explicit package import.

Test import#

The test import is used to specify other packages that the black-box test package of this package depends on, with the same format as import.

import {
  "path/to/package1",
  "path/to/package2" @pkg2,
} for "test"
{
  "test-import": {
    "path/to/package1",
    {
      "path": "path/to/package2",
      "alias": "pkg2"
    }
  }
}

The test-import-all field is used to specify whether all public definitions from the package being tested should be imported (true) by default.

White-box test import#

The white-box test import is used to specify other packages that the white-box test package of this package depends on, with the same format as import.

import {
  "path/to/package1",
  "path/to/package2" @pkg2,
} for "wbtest"
{
  "wbtest-import": {
    "path/to/package1",
    {
      "path": "path/to/package2",
      "alias": "pkg2"
    }
  }
}

最大同時テスト数#

max-concurrent-tests フィールドは、moon test がこのパッケージを実行するときに、このパッケージのテストを同時に実行できる数を制限します。

同じパッケージ内のテストがポート、一時ファイル、または同時実行すべきでないその他の外部リソースを共有する場合に便利です。

options(
  "max-concurrent-tests": 2,
)
{
  "max-concurrent-tests": 2
}

Conditional Compilation#

The smallest unit of conditional compilation is a file.

In a conditional compilation expression, three logical operators are supported: and, or, and not, where the or operator can be omitted.

For example, ["or", "wasm", "wasm-gc"] can be simplified to ["wasm", "wasm-gc"].

Conditions in the expression can be categorized into backends and optimization levels:

  • Backend conditions: "wasm", "wasm-gc", and "js"

  • Optimization level conditions: "debug" and "release"

Conditional expressions support nesting.

If a file is not listed in "targets", it will be compiled under all conditions by default.

Example:

options(
  targets: {
    "only_js.mbt": ["js"],
    "only_wasm.mbt": ["wasm"],
    "only_wasm_gc.mbt": ["wasm-gc"],
    "all_wasm.mbt": ["wasm", "wasm-gc"],
    "not_js.mbt": ["not", "js"],
    "only_debug.mbt": ["debug"],
    "js_and_release.mbt": ["and", ["js"], ["release"]],
    "js_only_test.mbt": ["js"],
    "js_or_wasm.mbt": ["js", "wasm"],
    "wasm_release_or_js_debug.mbt": ["or", ["and", "wasm", "release"], ["and", "js", "debug"]]
  }
)
{
  "targets": {
    "only_js.mbt": ["js"],
    "only_wasm.mbt": ["wasm"],
    "only_wasm_gc.mbt": ["wasm-gc"],
    "all_wasm.mbt": ["wasm", "wasm-gc"],
    "not_js.mbt": ["not", "js"],
    "only_debug.mbt": ["debug"],
    "js_and_release.mbt": ["and", ["js"], ["release"]],
    "js_only_test.mbt": ["js"],
    "js_or_wasm.mbt": ["js", "wasm"],
    "wasm_release_or_js_debug.mbt": ["or", ["and", "wasm", "release"], ["and", "js", "debug"]]
  }
}

Supported Targets#

supported_targets フィールドは、パッケージが対応する予定のバックエンドを宣言します。値には配列ではなく、ターゲット集合式を使います:

supported_targets = "js"
{
  "supported-targets": "js"
}

Examples:

  • js for a single backend

  • +js+wasm-gc for an explicit set of backends

  • +all-js for all backends except js

Legacy array syntax is still accepted for compatibility:

supported_targets = ["js", "native"]
{
  "supported-targets": ["js", "native"]
}

This is package metadata, not a conditional compilation rule:

  • supported_targets を使って、パッケージが対応するバックエンド集合を宣言する

  • use targets to include or exclude individual files for different backends

  • use preferred_target in moon.mod to choose the default backend for commands such as moon check, moon run, and moon build

モジュールとパッケージの両方で supported_targets を宣言した場合、有効なバックエンド集合は両方の宣言の積集合になります。

Command behavior follows the selected backend:

  • moon check, moon build, moon test, and moon bench keep only packages that support the selected backend

  • moon run requires the selected package to support the selected backend

  • moon info skips unsupported selected packages with a warning

  • moon bundle skips package targets that do not support the selected backend

After root selection, Moon also checks reachable required dependencies. If a required dependency does not support the selected backend, the command fails with a normal user-facing error.

Notes:

  • supported_targets を省略すると、すべてのバックエンドがサポート対象になる

  • --target all expands to wasm, wasm-gc, js, and native, but not llvm

  • llvmsupported_targets の有効な値である

  • legacy array syntax is deprecated, but still accepted for compatibility

A common setup is:

  • native 専用パッケージには supported_targets = "native" を設定する

  • set preferred_target = "native" in moon.mod

  • use targets only when some files inside the package differ by backend

ネイティブスタブファイル#

native-stub フィールドは、native ビルド向けにこのパッケージと一緒にコンパイルすべき C スタブソースファイルを列挙します。

これは、FFI ドキュメントにある extern "C" 宣言 と組み合わせて使われることが多く、その場合スタブファイルは、MoonBit で直接書くより C で書く方が容易なラッパー関数やアダプタコードを提供します。

パスはパッケージディレクトリからの相対パスです。

options(
  "native-stub": [ "stub.c", "helpers.c" ],
)
{
  "native-stub": ["stub.c", "helpers.c"]
}

rule と dev_build#

rule は再利用可能なコマンドを宣言し、dev_build は具体的な入力ファイルと出力ファイルに rule を適用します。これらの事前ビルドステップは、moon checkmoon buildmoon test などの開発用コマンドの前に実行されます。

この仕組みは、パッケージ作者がパッケージ開発中に使用することを想定しています。そのパッケージが下流ユーザーの依存関係として使われる場合、セキュリティ上の理由から、これらの事前ビルドステップは実行されません。そのため、依存関係がビルド中に任意のコマンドを実行することはありません。生成された出力ファイルをリポジトリにコミットし、下流ユーザーがそれらを直接使ってビルドできるようにしてください。

rule(name: "...", command: "...") は再利用可能なコマンドテンプレートを宣言します。name フィールドはその rule を識別し、command はシェルコマンド文字列です。コマンドは $input$output を参照できます。これらは、その rule を使用する dev_build エントリから提供されます。パッケージは複数の rule エントリを宣言できます。

dev_build(rule: "...", input: "...", output: "...") は事前ビルドステップを宣言します。これは rule を選択し、その rule のコマンドを展開するときに使用する入力パスと出力パスを提供します。パッケージは複数の dev_build エントリを宣言できます。

Pre-build commands run with the module root as their working directory. Input, output, and other pre-build paths are resolved relative to that module root.

rule は、同じ moon.pkg 内のパッケージレベル rule として宣言することも、moon.mod 内のモジュールレベル rule として宣言することもできます。パッケージレベル rule は、同じ moon.pkg 内の dev_build エントリからのみ参照できます。モジュールレベル rule は、モジュール内のすべてのパッケージの dev_build エントリから参照できます。rule 名を解決するとき、moon はまず同じ moon.pkg 内のパッケージレベル rule を探し、次に moon.mod 内のモジュールレベル rule を探します。

rule(name: "copy", command: "cat $input > $output")
dev_build(rule: "copy", input: "a.txt", output: "a.mbt")

moon.pkg.json では rule エントリと dev_build エントリはサポートされていません。代わりに、非推奨の pre-build 設定を使用してください:

{
  "pre-build": [
    {
      "input": "a.txt",
      "output": "a.mbt",
      "command": "cat $input > $output"
    }
  ]
}

この例では、moon check などの開発用コマンドを実行すると、パッケージがチェックされる前に a.txt の内容が a.mbt にコピーされます。

Warnings List#

警告リストは警告を無効化または有効化します。有効な警告でコマンドを失敗させるには、--deny-warn を使います。警告リストは 1 つ以上の警告名で構成される文字列で、各警告名の先頭に記号を付けます:

  • - to disable the warning

  • + to enable the warning

For example, in the following configuration, -unused_value disables the unused functions and variables warning.

warnings = "-unused_value"
{
  "warn-list": "-unused_value"
}

If multiple warnings need to be disabled, they can be directly connected and combined.

warnings = "-unused_value-unreachable_code"
{
  "warn-list": "-unused_value-unreachable_code"
}

If it is necessary to activate certain warnings that were originally prohibited, use the plus sign.

warnings = "+unused_optional_argument"
{
  "warn-list": "+unused_optional_argument"
}

古い設定では、警告をエラーに昇格させるために @ 接頭辞を使っていることがあります。この接頭辞は互換性のためにのみ引き続き受け入れられますが、新しい設定では使用しないでください。警告でビルドを失敗させる場合は、moon check --deny-warn (および他の CI コマンドの同等のフラグ)を使います。

warnings では警告番号も使用できます。以下の出力で、mnemonic は警告リストで使う記号名、id は同じ警告の数値形式です。

moonc check -warn-help の現在の出力は次のとおりです:

Available warnings:
mnemonic                   description                                                     id state
unused_value               Unused variable or function.                                     1 warn
unused_value               Unused variable.                                                 2 warn
unused_type_declaration    Unused type declaration.                                         3 warn
missing_priv               Unused abstract type.                                            4 warn
unused_type_variable       Unused type variable.                                            5 warn
unused_constructor         Unused constructor.                                              6 warn
unused_field               Unused field or constructor argument.                            7 warn
redundant_modifier         Redundant modifier.                                              8 warn
struct_never_constructed   Struct never constructed.                                        9 warn
unused_pattern             Unused pattern.                                                 10 warn
partial_match              Partial pattern matching.                                       11 error
unreachable_code           Unreachable code.                                               12 warn
unresolved_type_variable   Unresolved type variable.                                       13 warn
alert or alert_<category>  All alerts or alerts with specific category.                    14 warn
unused_mut                 Unused mutability.                                              15 error
parser_inconsistency       Parser inconsistency check.                                     16 warn
ambiguous_loop_argument    Ambiguous usage of loop argument.                               17 warn
useless_loop               Useless loop expression.                                        18 warn
deprecated                 Deprecated API usage.                                           20 warn
missing_pattern_arguments  Some arguments of constructor are omitted in pattern.           21 warn
ambiguous_block            Ambiguous block.                                                22 warn
unused_try                 Useless try expression.                                         23 warn
unused_error_type          Useless error type.                                             24 warn
test_unqualified_package   Using implicitly imported API in test.                          25 off
unused_catch_all           Useless catch all.                                              26 warn
deprecated_syntax          Deprecated syntax.                                              27 warn
todo                       Todo                                                            28 warn
unused_package             Unused package.                                                 29 warn
missing_package_alias      Empty package alias.                                            30 warn
unused_optional_argument   Optional argument never supplied.                               31 off
unused_default_value       Default value of optional argument never used.                  32 off
text_segment_excceed       Text segment exceed the line or column limits.                  33 warn
implicit_use_builtin       Implicit use of definitions from `moonbitlang/core/builtin`.    34 warn
reserved_keyword           Reserved keyword.                                               35 warn
block_label_shadowing      Block label shadows another label.                              36 warn
unused_block_label         Unused block label.                                             37 warn
missing_invariant          For-loop is missing an invariant.                               38 off
missing_reasoning          For-loop is missing a proof_reasoning.                          39 off
multiline_string_escape    Deprecated escape sequence in multiline string.                 40 error
missing_rest_mark          Missing `..` in map pattern.                                    41 warn
invalid_attribute          Invalid attribute.                                              42 warn
unused_attribute           Unused attribute.                                               43 warn
invalid_inline_wasm        Invalid inline-wasm.                                            44 error
unused_rest_mark           Useless `..` in pattern                                         46 warn
missing_definition         Unused pub definition because it does not exist in mbti file.   49 warn
method_shadowing           Local method shadows upstream method                            50 warn
ambiguous_precedence       Ambiguous operator precedence                                   51 warn
unused_loop_variable       Loop variable not updated in loop                               52 warn
unused_trait_bound         Unused trait bound                                              53 warn
ambiguous_range_direction  Ambiguous looping direction for range e1..=e2                   54 off
unannotated_ffi            Unannotated FFI param type                                      55 error
missing_pattern_field      Missing field in struct pattern                                 56 warn
missing_pattern_payload    Constructor pattern expect payload                              57 warn
unaligned_byte_access      Unaligned byte access in bits pattern                           59 warn
unused_struct_update       Unused struct update                                            60 warn
duplicate_test             Duplicate test name                                             61 warn
invalid_cascade            Calling method with non-unit return type via `..`               62 warn
syntax_lint                Syntax lint warning                                             63 warn
unannotated_toplevel_array Unannotated toplevel array                                      64 warn
prefer_readonly_array      Suggest ReadOnlyArray for read-only array literal               65 off
prefer_fixed_array         Suggest FixedArray for mutated array literal                    66 off
unused_async               Useless `async` annotation                                      67 warn
declaration_unimplemented  Declaration is unimplemented                                    68 warn
declaration_implemented    Declaration is already implemented                              69 off
deprecated_for_in_method   using `iterator()` method for `for .. in` loop.                 70 off
core_package_not_imported  Packages in `moonbitlang/core` need to be explicitly imported.  71 warn
unqualified_local_using    unqualified local using                                         72 off
unnecessary_annotation     unnecessary type annotation                                     73 off
missing_doc                Missing documentation for public definition                     74 off
unnecessary_view_op        Unnecessary `[:]` view operator                                 75 off
result_error_return        Using `Result[T, E]` where `E` is an error type.                78 off
implicit_impl_as_method    `impl` implicitly promoted as method                            79 off
regex_match_missing_before Missing `before` binding in `regex match`.                      80 warn
regex_match_missing_after  Missing `after` binding in `regex match`.                       81 warn
ambiguous_braces           Ambiguous `{}` braces.                                          82 warn
type_param_method          Calling method of type parameter in a deprecated way.           83 warn
unqualified_record         Struct literal in a `let` binding without a type prefix.        84 off
unlabelled_break_in_labelled_loop Unlabelled `break` directly inside a labelled loop.             85 warn
unlabelled_continue_in_labelled_loop Unlabelled `continue` directly inside a labelled loop.          86 warn
guard_inexhaustive         `guard` condition is not exhaustive and may panic.              87 warn
guard_redundant_bang       Redundant `!` on an exhaustive `guard`.                         88 warn
guard_redundant_else       Redundant `else` on an exhaustive `guard`.                      89 warn
unused_lexcase             `lexmatch`/`lexscan` branch that can never be selected because other branches takes precedence or its pattern matches nothing.  90 warn
unused_errdefer            unused `errdefer` statement                                     91 warn
fragile_catch_all          fragile `catch` handler that can be converted to `defer` or `errdefer`  92 warn
all                        all warnings
state: warn = enabled, error = promoted to error, off = disabled
note: default alert exceptions: alert_unsafe=off

注釈

moonc check -warn-help を使うと、プリセットされたコンパイラ警告の一覧を確認できます。

Alert Warning#

Alerts are special warnings that indicate the usage of API marked with #internal attribute.

すべての alert には API 作者が定めたカテゴリがあります。alert_<category> という警告名で特定カテゴリを有効または無効にでき、alert を使えばすべての alert 警告をまとめて制御できます。

例えば、次の設定は unsafe カテゴリ以外のすべての alert 警告を有効にします。CI で有効な警告を致命的エラーとして扱うには、moon checkmoon test、または同等のコマンドに --deny-warn を追加してください。

warnings = "+alert-alert_unsafe"
{
  "warn-list": "+alert-alert_unsafe"
}

Virtual Package#

A virtual package serves as an interface of a package that can be replaced by actual implementations.

Declarations#

The virtual field is used to declare the current package as a virtual package.

For example, the following declares a virtual package with default implementation:

options(
  virtual: {
    "has-default": true,
  },
)
{
  "virtual": {
    "has-default": true
  }
}

Implementations#

The implement field is used to declare the virtual package to be implemented by the current package.

For example, the following implements a virtual package:

options(
  implement: "moonbitlang/core/abort",
)
{
  "implement": "moonbitlang/core/abort"
}

Overriding implementations#

The overrides field is used to provide the implementations that fulfills an imported virtual package.

For example, the following overrides the default implementation of the builtin abort package with another package:

options(
  overrides: [ "moonbitlang/dummy_abort/abort_show_msg" ],
)
{
  "overrides": ["moonbitlang/dummy_abort/abort_show_msg"]
}