Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ Building a programming language is a long journey. It took Rust 9 years and Go 5
- OCaml 4.14.2
- [OPAM](https://opam.ocaml.org/)

### Toolchain versions

This repository currently targets the following upstream snapshots:

- [`moon`](https://github.com/moonbitlang/moon) @ `f1ae8e97e4c020c078f0f728987a1001ab8cc5ef` (2025‑01‑26)
- [`core`](https://github.com/moonbitlang/core) @ `f69968c1802a315d3f7baa30238c9c67fe5ccd61` (2025‑02‑07)

The pinned commits are encoded in `flake.nix` / `flake.lock`. If you update either project, make sure the compiler still type‑checks `core` with `nix build .#test-core`.

### Build

Build with following scripts:
Expand All @@ -39,6 +48,29 @@ dune build -p moonbit-lang

You would also need to build the core library, as instructed in the following section.

### Build with Nix

If you prefer a reproducible environment, install [Nix](https://nixos.org/download.html) and use the provided flake:

```bash
# Drop into a shell with dune/ocaml/etc.
nix develop

# Build the compiler binary
nix build

# Build the pinned core library with the current moon/moonc pair
nix build .#test-core
```

The last command produces a result symlink that contains:

- `bin/` — the toolchain binaries (`moon`, `moonc`)
- `logs/build-log.txt` — the core build transcript (if generated)
- `core/target/` — the compiled core artifacts

These builds use the exact moon/core commits listed above; no extra manual setup is required.

### Usage

MoonBit's core library is typically installed in `~/.moon/lib/core/`. In following commands, we use `$core` to denote the path. You can choose your target between `riscv` and `wasm-gc`, which we denote by `$target`. Currently, `riscv` will only produce a `.ssa` file for static single assignment IR, and does not proceed to generate assembly.
Expand All @@ -52,16 +84,19 @@ We use `$dest` to represent target files, which might be `.wat` or `.wasm`, but
To set up the environment, execute these commands (you only need to do it once):

```bash
# Remove currently installed MoonBit version
# Remove any previously installed MoonBit core
rm -rf $core

# Install the latest version of core library
# Fetch the pinned core revision
git clone https://github.com/moonbitlang/core.git $core
(cd $core && git checkout f69968c1802a315d3f7baa30238c9c67fe5ccd61)

# Compile the core library
moon bundle --source-dir $core
```

Ensure the `moon` binary you use to run these commands matches commit `f1ae8e97e4c020c078f0f728987a1001ab8cc5ef` (see the “Toolchain versions” section above). The recommended way is to use the `nix build` output from this repository.

We strongly recommend that you build the core library yourself via the commands above. The pre-built binaries are not always compatible with this compiler, as MoonBit is still under development.

You should verify that now there is a folder called `wasm-gc` under `$core/target`.
Expand Down Expand Up @@ -150,4 +185,3 @@ In the past two years, our team worked hard to improve MoonBit and its toolchain
We are grateful for the support of the community.
Special thanks to Jane Street for their excellent PPX libraries,
for this repo has used some of their [PPX functions](./src/hash.c).

39 changes: 35 additions & 4 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
- [OPAM](https://opam.ocaml.org/)


### 工具链版本

本仓库当前固定依赖以下上游提交:

- [`moon`](https://github.com/moonbitlang/moon):`f1ae8e97e4c020c078f0f728987a1001ab8cc5ef`(2025‑01‑26)
- [`core`](https://github.com/moonbitlang/core):`f69968c1802a315d3f7baa30238c9c67fe5ccd61`(2025‑02‑07)

这些提交被写入 `flake.nix` / `flake.lock`。如需更新,请确保运行 `nix build .#test-core` 验证当前 `moonc` 与新的 core 是否仍兼容。

### 构建

使用下列脚本构建:
Expand All @@ -38,7 +47,30 @@ opam install -y dune
dune build -p moonbit-lang
```

### 使用
### 使用 Nix 构建

如果希望拥有可复现的环境,可以安装 [Nix](https://nixos.org/download.html),并使用项目自带的 flake:

```bash
# 进入包含所有构建依赖的开发环境(dune、ocaml 等)
nix develop

# 构建 moonc 与配套的 moon 二进制
nix build

# 使用固定的 moon/core 组合构建标准库
nix build .#test-core
```

最后一条命令会生成一个 `result` 符号链接,内容包括:

- `bin/`:`moon`、`moonc` 以及内部工具;
- `logs/build-log.txt`:如果存在,保存 core 的构建日志;
- `core/target/`:编译好的 core 产物。

以上命令全部采用上述固定的 moon/core 提交,无需手动准备其他依赖。

### 手动使用

MoonBit 的核心库一般安装在 `~/.moon/lib/core` 下。在下面的命令中,我们会用 `$core` 表示核心库的安装路径。你可以选择 `riscv` 或 `wasm-gc` 作为编译目标,我们用 `$target` 表示这两者之一。值得注意的是,目前 `riscv` 只会产生 SSA 文件,而不会产生汇编代码。

Expand All @@ -56,13 +88,13 @@ rm -rf $core

# 安装指定的版本
git clone https://github.com/moonbitlang/core.git $core
git checkout 4660d8b
(cd $core && git checkout f69968c1802a315d3f7baa30238c9c67fe5ccd61)

# 编译
moon bundle --source-dir $core
```

我们强烈建议使用上面的命令重新编译一次标准库。已经构建好的二进制文件可能和这个编译器不兼容。
请确保运行上述命令时使用的 `moon` 二进制对应 `f1ae8e97e4c020c078f0f728987a1001ab8cc5ef`,推荐直接使用本仓库 `nix build` 的产物。我们强烈建议使用上面的命令重新编译一次标准库。已经构建好的二进制文件可能和这个编译器不兼容。

执行完成后,你应当能在 `$core/target/` 下发现文件夹 `wasm-gc`。

Expand Down Expand Up @@ -147,4 +179,3 @@ MoonBit 采用 MoonBit Public License,一个放宽的 SSPL (Server Side Public

我们十分感谢社区对我们的支持。
特别感谢 Jane Street 的优秀的 PPX 库,这个仓库使用了一些他们的 [PPX 函数](./src/hash.c)。

36 changes: 36 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 147 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,30 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
moon-repo = {
url = "github:moonbitlang/moon/f1ae8e97e4c020c078f0f728987a1001ab8cc5ef";
flake = false;
};
core-repo = {
url = "github:moonbitlang/core/f69968c1802a315d3f7baa30238c9c67fe5ccd61";
flake = false;
};
};

outputs = { self, nixpkgs, flake-utils }:
outputs = { self, nixpkgs, flake-utils, moon-repo, core-repo }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};

# Download rusty_v8 prebuilt library
rusty-v8-lib = pkgs.fetchurl {
url = "https://github.com/denoland/rusty_v8/releases/download/v0.106.0/librusty_v8_release_x86_64-unknown-linux-gnu.a.gz";
sha256 = "sha256-jLYl/CJp2Z+Ut6qZlh6u+CtR8KN+ToNTB+72QnVbIKM=";
};
in
{
packages.default = pkgs.stdenv.mkDerivation rec {
packages = {
default = pkgs.stdenv.mkDerivation rec {
pname = "moonbit-hybrid";
version = "latest-moon-plctlab-moonc";

Expand Down Expand Up @@ -93,6 +108,136 @@
};
};

# Build moon from specific commit
moon-custom = pkgs.rustPlatform.buildRustPackage {
pname = "moon";
version = "47b2c5a0";

src = moon-repo;

cargoLock = {
lockFile = "${moon-repo}/Cargo.lock";
outputHashes = {
"n2-0.1.5" = "sha256-HAA0S8TjcWuIljgixWaLvMK4RFaE3YPPlp7CKkboCH4=";
};
};

nativeBuildInputs = with pkgs; [ pkg-config perl python3 ];
buildInputs = with pkgs; [ openssl ];

# Skip tests to speed up build
doCheck = false;

# Provide the predownloaded rusty_v8 library
RUSTY_V8_ARCHIVE = "${rusty-v8-lib}";

meta = with pkgs.lib; {
description = "Moon build system";
homepage = "https://www.moonbitlang.com";
license = licenses.asl20;
};
};

# Build moonc from current repo
moonc-custom = pkgs.stdenv.mkDerivation {
pname = "moonc";
version = "local";

src = ./.;

nativeBuildInputs = with pkgs; [
dune_3
ocaml
pkg-config
libffi
gmp
];

buildPhase = ''
dune build --root .
'';

installPhase = ''
mkdir -p $out/bin
cp _build/install/default/bin/moonc $out/bin/
chmod +x $out/bin/moonc
'';
};

# Combine moon-custom and moonc-custom to build core
test-core = pkgs.stdenv.mkDerivation rec {
pname = "moonbit-test-core";
version = "moon-47b2c5a0-core-39c5f6ee";

src = core-repo;

nativeBuildInputs = [ self.packages.${system}.moon-custom self.packages.${system}.moonc-custom ];

buildPhase = ''
runHook preBuild

# Create moon toolchain directory with custom moonc
mkdir -p moon-toolchain/bin
cp ${self.packages.${system}.moon-custom}/bin/moon moon-toolchain/bin/
cp ${self.packages.${system}.moonc-custom}/bin/moonc moon-toolchain/bin/
chmod +x moon-toolchain/bin/moon
chmod +x moon-toolchain/bin/moonc

# Copy core to writable location
cp -r ${core-repo} core-test
chmod -R u+w core-test
cd core-test

# Set up environment for moon to use writable directories
export HOME=$(pwd)/moon-home
export MOON_HOME=$(pwd)/moon-home
mkdir -p $HOME/.moon

# Build core with custom toolchain
echo "Building core library with moon (f2f5ab3f) and local moonc..."
export PATH=$(pwd)/../moon-toolchain/bin:$PATH
moon bundle 2>&1 | tee ../build-log.txt || echo "Build completed with errors"

runHook postBuild
'';

installPhase = ''
runHook preInstall

# Navigate back to build root (buildPhase ended in core-test subdirectory)
cd ..

mkdir -p $out/bin
mkdir -p $out/logs
mkdir -p $out/core

# Install moon toolchain
if [ -d moon-toolchain/bin ]; then
cp -r moon-toolchain/bin/. $out/bin/
fi

# Install build log
if [ -f build-log.txt ]; then
cp build-log.txt $out/logs/
fi

# Install core artifacts if they exist
if [ -d "core-test/target" ]; then
cp -r core-test/target $out/core/
fi

runHook postInstall
'';

meta = with pkgs.lib; {
description = "MoonBit moon (47b2c5a0, 2025-04-18) with local moonc, testing core (39c5f6ee, 2025-04-18)";
homepage = "https://www.moonbitlang.com";
license = licenses.asl20;
platforms = platforms.linux;
};
};
};

devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
ocaml
Expand Down