Skip to content

Cross-compilation from macOS to Linux on arm64 broken on >=22 #181

Open

Description

@Niek

What version of pkg are you using?

6.9.0

What version of Node.js are you using?

24.10.0

What operating system are you using?

macOS 26

What CPU architecture are you using?

arm64

What Node versions, OSs and CPU architectures are you building for?

node22-linux-arm64

Describe the Bug

I can no longer cross-compile binaries from macOS (arm64) to Linux (arm64) - I'm sure this worked fine before. The binary builds fine, but when running exits without any message.

Expected Behavior

Cross-compilation used to work fine

To Reproduce

❯ cat hello.js
console.log('Hello World')
❯ npx -y @yao-pkg/pkg hello.js -t node22-linux-arm64 -o hello
> pkg@6.9.0
❯ ls -lha hello
-rwxr-xr-x@ 1 niek  staff    65M Oct 16 14:33 hello
❯ docker run --rm -it -v $(pwd):/mnt ubuntu:latest /mnt/hello

The issue is the same with node24-linux-arm64 or node24-linuxstatic-arm64.

However, node20-linux-arm64 still seems to work fine.

Activity

  1. robertsLando commented on Oct 16, 2025

    @robertsLando
    Member

    Please show me package.json content and also share pkg command output with --debug flag. Then run the result package with DEBUG_PKG=2 env var and share the run output as well

    cc @faulpeltz

  2. faulpeltz commented on Oct 16, 2025

    @faulpeltz

    Cross compilation from and to macOS (without --public) doesnt work since Node 22 and I wasn't able to fix this in the latest Node 24 changes...
    Basically the code cache generated is not compatible between many OS/arch combinations because the V8 readonly heap snapshots are no longer the same - in Node 20 and earlier this works fine

  3. Niek commented on Oct 16, 2025

    @Niek
    Author

    There is no package.json, see the reproducible script in a fresh dir.

    ❯ npx -y @yao-pkg/pkg hello.js -t node22-linux-arm64 -o hello --debug
    > pkg@6.9.0
    > [debug] Bytecode of /Users/niek/test/hello.js is added to queue.
    > [debug] Stat info of /Users/niek/test/hello.js is added to queue.
    > [debug] Directory /Users/niek/test is added to queue.
    > [debug] Stat info of /Users/niek/test is added to queue.
    > [debug] Directory /Users/niek is added to queue.
    > [debug] Stat info of /Users/niek is added to queue.
    > [debug] Directory /Users is added to queue.
    > [debug] Stat info of /Users is added to queue.
    > [debug] Directory / is added to queue.
    > [debug] Stat info of / is added to queue.
    > [debug] Deleting record file: /
    > [debug] Deleting record file: /Users
    > [debug] The file was included as bytecode (no sources)
      /Users/niek/test/hello.js
    > [debug] The file was included as bytecode (no sources)
      /Users/niek/test/hello.js
    > [debug] files & folders deduped =
      hello.js
    > [debug] The directory files list was included (1 item)
      /Users/niek/test
    > [debug] The directory files list was included (1 item)
      /Users/niek/test
    > [debug] files & folders deduped =
      test
    > [debug] The directory files list was included (1 item)
      /Users/niek
    > [debug] The directory files list was included (1 item)
      /Users/niek
    > [debug] Targets:
      [
      {
        "nodeRange": "node22",
        "platform": "linux",
        "arch": "arm64",
        "output": "/Users/niek/test/hello",
        "forceBuild": false,
        "fabricator": {
          "nodeRange": "node22",
          "platform": "macos",
          "arch": "arm64",
          "binaryPath": "/Users/niek/.pkg-cache/v3.5/fetched-v22.20.0-macos-arm64-signed"
        },
        "binaryPath": "/Users/niek/.pkg-cache/v3.5/fetched-v22.20.0-linux-arm64"
      }
    ]
    ❯ docker run --rm -it -v $(pwd):/mnt -e DEBUG_PKG=2 ubuntu:latest /mnt/hello
    []
    ------------------------------- virtual file system
    /snapshot
      test                                    27 Bytes
        hello.js                              27 Bytes
    Total size =  27 Bytes
    fs.existsSync [ '/snapshot/test/hello.js' ]
    fs.statSync [ '/snapshot/test/hello.js' ]
    fs.readSync []
    fs.realpathSync [ '/snapshot/test/hello.js' ]
    fs.readFileSync [ '/snapshot/test/hello.js', 'utf8' ]
    fs.readSync []
  4. Niek commented on Oct 16, 2025

    @Niek
    Author

    Cross compilation from and to macOS (without --public) doesnt work since Node 22 and I wasn't able to fix this in the latest Node 24 changes... Basically the code cache generated is not compatible between many OS/arch combinations because the V8 readonly heap snapshots are no longer the same

    Ah, that makes sense then. Might be worth adding a note to the README with this info (at least until there is a fix)?

  5. faulpeltz commented on Oct 16, 2025

    @faulpeltz

    Yes but currently its unfortunately trial and error to sort out which versions are compatible or not. (currently linux/win/linuxstatic x64 seems to work)
    This behavior is caused by the new V8 versions included in Node and is probably not fixable because V8 code cache / snapshot data is not designed to be portable.

    If you don't mind including your source bundle (with --public) than this restriction does not apply because the code cache is discarded by Node when its not valid for the current binary and it falls back to the source.

  6. robertsLando commented on Oct 16, 2025

    @robertsLando
    Member

    I added it here: #87

  7. rejetto commented on May 24, 2026

    @rejetto

    with latest version, from macos arm to linux arm, i had to add --public-packages "*"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions