Summary
Surfaced during the #360 recheck on v0.5.796: compiling a TypeScript program that imports from a module Perry decided to keep on the V8 fallback (i.e. one of the 21 JavaScript modules in a `Found 67 module(s): 46 native, 21 JavaScript` split) fails at link time with unresolved native symbols:
```
Undefined symbols for architecture arm64:
"_perry_fn_node_modules_ink_build_render_js__render", referenced from:
_main in counter_tsx.o
"_perry_closure_node_modules_ink_build_measure_text_js__0", referenced from:
... in node_modules_ink_build_measure_text_js.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: Linking failed
```
The codegen is emitting native callsites to functions defined in a V8-fallback module, but the V8-fallback path of course doesn't emit those native symbols — they only exist for natively-compiled modules.
Environment
- perry 0.5.796 (current main)
- macOS arm64
Minimal repro
```tsx
// counter.tsx
import React, { useState } from "react";
import { render, Text, Box } from "ink";
function App() {
const [count] = useState(0);
return React.createElement(Box, null, React.createElement(Text, null, `count=${count}`));
}
render(React.createElement(App));
```
`package.json`:
```json
{ "perry": { "compilePackages": ["react", "ink"] } }
```
`perry compile counter.tsx -o counter` reports `46 native, 21 JavaScript` then fails at the link step as above.
Hypothesis
The codegen for the main module's `import { render } from "ink"` lowers the call to a native `_perry_fn_node_modules_ink_build_render_js__render` extern, assuming the symbol will exist. But `ink/build/render.js` got demoted to the V8 fallback (because of an unsupported feature — likely a transitive dep, e.g. yoga-layout, that Perry can't compile). The fallback module doesn't emit native symbols, so the linker fails.
The fix is either:
- Detect at codegen that the callee module is V8-fallback, and route the call through the V8 bridge instead of an extern; OR
- Emit weak stub symbols for V8-fallback modules that the V8 bridge can intercept at runtime; OR
- Promote the dependency-blocked module path to a hard compile error earlier so we don't reach link.
Related
Summary
Surfaced during the #360 recheck on v0.5.796: compiling a TypeScript program that imports from a module Perry decided to keep on the V8 fallback (i.e. one of the 21 JavaScript modules in a `Found 67 module(s): 46 native, 21 JavaScript` split) fails at link time with unresolved native symbols:
```
Undefined symbols for architecture arm64:
"_perry_fn_node_modules_ink_build_render_js__render", referenced from:
_main in counter_tsx.o
"_perry_closure_node_modules_ink_build_measure_text_js__0", referenced from:
... in node_modules_ink_build_measure_text_js.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: Linking failed
```
The codegen is emitting native callsites to functions defined in a V8-fallback module, but the V8-fallback path of course doesn't emit those native symbols — they only exist for natively-compiled modules.
Environment
Minimal repro
```tsx
// counter.tsx
import React, { useState } from "react";
import { render, Text, Box } from "ink";
function App() {
const [count] = useState(0);
return React.createElement(Box, null, React.createElement(Text, null, `count=${count}`));
}
render(React.createElement(App));
```
`package.json`:
```json
{ "perry": { "compilePackages": ["react", "ink"] } }
```
`perry compile counter.tsx -o counter` reports `46 native, 21 JavaScript` then fails at the link step as above.
Hypothesis
The codegen for the main module's `import { render } from "ink"` lowers the call to a native `_perry_fn_node_modules_ink_build_render_js__render` extern, assuming the symbol will exist. But `ink/build/render.js` got demoted to the V8 fallback (because of an unsupported feature — likely a transitive dep, e.g. yoga-layout, that Perry can't compile). The fallback module doesn't emit native symbols, so the linker fails.
The fix is either:
Related
ink(React-based TUI framework) end-to-end viaperry.compilePackages#348 (ink-as-compilePackages) — the umbrella where ink/yoga V8-fallback originates.