Skip to content

macOS arm64 0.5.1220: any program importing node:http fails to link — 17 undefined _js_*http* symbols from libperry_stdlib.a #8907

Description

@proggeramlug

perry 0.5.1220 (current latest release), macOS arm64, clang from Xcode CLT.

Any program that imports node:http fails at the link step. The symbols are referenced from libperry_stdlib.a but defined nowhere on the link line.

Minimal repro

import { createServer } from "node:http";

function main(): void {
  const s = createServer((_req, res) => { res.end("ok"); });
  s.listen(0, () => { s.close(); });
}
main();
$ perry compile httpmin.ts -o /tmp/httpmin
...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1
Error: Linking failed

Remove the import and it links and runs:

function main(): void { console.log("ok"); }
main();
$ perry compile nohttp.ts -o /tmp/nohttp
Wrote executable: /tmp/nohttp
Binary size: 7.6MB

The undefined symbols — 17

_js_ext_http_agent_dispatch_method            _js_http_has_pending
_js_ext_http_agent_dispatch_property          _js_http_incoming_message_pipe
_js_ext_http_agent_dispatch_property_set      _js_http_is_incoming_message
_js_ext_http_agent_is_handle                  _js_http_response_trailers
_js_ext_http_client_incoming_message_is_handle    _js_node_http_create_server_with_options
_js_ext_http_client_incoming_message_set_encoding _js_node_http_server_close
_js_ext_http_client_inflight                  _js_node_http_server_listen
_js_ext_http_client_request_dispatch_method
_js_ext_http_client_request_dispatch_property
_js_ext_http_client_request_is_handle

All referenced from perry_stdlib::common::dispatch_http::* inside libperry_stdlib.a, e.g.

"_js_http_response_trailers", referenced from:
    perry_stdlib::common::dispatch_http::dispatch_client_incoming_property::h6300abf73b28a348
      in libperry_stdlib.a[260](perry_stdlib-….rcgu.o)

The _js_ext_http_* names suggest libperry_ext_http.a should be supplying them and is not reaching the link line; the bare _js_node_http_* and _js_http_* ones look like they should come from the runtime.

Notes

  • Identical with and without PERRY_NO_AUTO_OPTIMIZE=1 — the prebuilt-stdlib path and the default path both fail the same way, and neither triggers a rebuild (it fails in ~2 s).
  • #8587 looks like the same shape but is scoped to native Linux and is closed; this is macOS arm64 on the current release, so filing separately rather than commenting there. Close as a duplicate if one fix covers both.
  • Not a perry doctor skew case (#8752): a clean install of 0.5.1220 reproduces it, and non-HTTP programs link and run normally from the same toolchain.

Impact

This is what stops an HTTP server compiling at all, so it blocks the whole server side of our project rather than one feature — nine of eighteen tests in our compatibility suite die here, and they are the ones covering the database driver, the router, WebSockets, migrations, multipart upload, file streaming and long-run stability. Everything that does not touch node:http compiles and runs correctly, including some fairly demanding things (zod, vips via child_process, a 1 s scheduler tick with clean SIGTERM).

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