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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#### :rocket: New Feature

- Support Windows 11 on ARM by installing the x64 binaries, which Windows runs through its x64 emulation. https://github.com/rescript-lang/rescript/pull/8776
- Allow `$` in identifiers, e.g. `let count$ = signal(0)`. https://github.com/rescript-lang/rescript/pull/8791

#### :bug: Bug fix
Expand Down
18 changes: 7 additions & 11 deletions cli/common/bins.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@
// The lookup is synchronous so that tools.cjs, the CommonJS entry of
// `rescript/tools`, can load it; bins.js re-exports these values for ES modules.

const os = require("node:os");
const path = require("node:path");
const { getTarget } = require("./platform.cjs");
Comment thread
cknitt marked this conversation as resolved.

const minimumNodeVersion = "22.0.0";

const target = `${process.platform}-${process.arch}`;
const target = getTarget(process.platform, process.arch, os.release());

const supportedPlatforms = [
"darwin-arm64",
"darwin-x64",
"linux-arm64",
"linux-x64",
"win32-x64",
];

if (!supportedPlatforms.includes(target)) {
throw new Error(`Platform ${target} is not supported!`);
if (target === undefined) {
throw new Error(
`Platform ${process.platform}-${process.arch} is not supported!`,
);
}

const binPackageName = `@rescript/${target}`;
Expand Down
43 changes: 43 additions & 0 deletions cli/common/platform.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// @ts-check

// Maps the current platform to the platform package (@rescript/<target>) that
// provides its compiler binaries. Kept free of side effects so it can be tested.

const supportedTargets = [
"darwin-arm64",
"darwin-x64",
"linux-arm64",
"linux-x64",
"win32-x64",
];

// The first Windows 11 build. Windows 10 on ARM only emulates x86, not x64.
const firstWindows11Build = 22000;

/**
* @param {string} platform `process.platform`
* @param {string} arch `process.arch`
* @param {string} osRelease `os.release()`, e.g. "10.0.22631" on Windows 11
* @returns {string | undefined} the target, or undefined if unsupported
*/
function getTarget(platform, arch, osRelease) {
// Windows 11 on ARM runs the x64 toolchain through its x64 emulation.
const binaryArch =
platform === "win32" &&
arch === "arm64" &&
windowsBuild(osRelease) >= firstWindows11Build
? "x64"
: arch;
const target = `${platform}-${binaryArch}`;
return supportedTargets.includes(target) ? target : undefined;
}

/**
* @param {string} osRelease
*/
function windowsBuild(osRelease) {
const build = Number(osRelease.split(".")[2]);
return Number.isInteger(build) ? build : 0;
}

exports.getTarget = getTarget;
3 changes: 2 additions & 1 deletion packages/@rescript/win32-x64/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"win32"
],
"cpu": [
"x64"
"x64",
"arm64"
],
"files": [
"bin.js",
Expand Down
1 change: 1 addition & 0 deletions packages/artifacts.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"cli/bsc.js",
"cli/common/bins.cjs",
"cli/common/bins.js",
"cli/common/platform.cjs",
"cli/common/runtime.js",
"cli/common/tools.cjs",
"cli/common/tools.js",
Expand Down
1 change: 1 addition & 0 deletions scripts/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ if (mochaTest) {
"10000",
"tests/tests/src/**/*_test.mjs",
"tests/belt_tests/src/**/*_test.mjs",
"tests/cli_tests/*_test.mjs",
// jsx_preserve_test.mjs contains JSX, which Node cannot load; the
// file exists to pin the preserved-JSX output.
"--ignore",
Expand Down
33 changes: 33 additions & 0 deletions tests/cli_tests/platform_test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as assert from "node:assert/strict";
import { describe, it } from "mocha";
import { getTarget } from "../../cli/common/platform.cjs";

describe("getTarget", () => {
it("maps supported platforms to their own package", () => {
for (const [platform, arch] of [
["darwin", "arm64"],
["darwin", "x64"],
["linux", "arm64"],
["linux", "x64"],
["win32", "x64"],
]) {
assert.equal(getTarget(platform, arch, "10.0.0"), `${platform}-${arch}`);
}
});

it("uses the x64 package on Windows 11 on ARM", () => {
assert.equal(getTarget("win32", "arm64", "10.0.22000"), "win32-x64");
assert.equal(getTarget("win32", "arm64", "10.0.26100"), "win32-x64");
});

it("rejects Windows 10 on ARM, which cannot emulate x64", () => {
assert.equal(getTarget("win32", "arm64", "10.0.19045"), undefined);
assert.equal(getTarget("win32", "arm64", "unknown"), undefined);
});

it("rejects unsupported platforms", () => {
assert.equal(getTarget("win32", "ia32", "10.0.26100"), undefined);
assert.equal(getTarget("linux", "ia32", "6.0.0"), undefined);
assert.equal(getTarget("freebsd", "x64", "14.0"), undefined);
});
});
Loading