mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-21 05:50:55 +08:00
59 lines
3.2 KiB
Plaintext
59 lines
3.2 KiB
Plaintext
---
|
|
title: "Native Program Objects"
|
|
---
|
|
|
|
`scriptc build --emit=obj` produces one relocatable program object without invoking clang, a linker, or an SDK on a supported target. The object defines `main`; it is intended to become the program in an external native link. It is not a host-callable library—use `scriptc build --lib --profile ...` for that interface.
|
|
|
|
## ABI and runtime contract
|
|
|
|
The external object ABI is **experimental**. Its `scr_*` function and data surface may change before 1.0, so consumers must use the exact runtime-pack version reported by the same compiler installation. This is stricter than semver compatibility.
|
|
|
|
The object intentionally leaves its selected runtime symbols undefined. It also holds a strong reference to `scr_runtime_abi_v6`, which the matching runtime defines. Linking an object against a runtime with another ABI marker fails at link time with the missing versioned symbol; it cannot become a latent runtime incompatibility.
|
|
|
|
## Machine-readable link information
|
|
|
|
Add `--print=native-link-info` to emit the object and print a JSON document instead of the ordinary path line:
|
|
|
|
```console
|
|
$ scriptc build main.ts --print=native-link-info -o app.o > link-info.json
|
|
```
|
|
|
|
The `scriptc.native-link-info.v1` document reports:
|
|
|
|
- target triple, object format, architecture, minimum OS, and relocation model;
|
|
- the `main` entry and versioned runtime ABI marker;
|
|
- the matching installed precompiled runtime-pack root, selected objects and archives, sizes, and hashes;
|
|
- ordered program, FFI, runtime, and vendor inputs; and
|
|
- required system libraries and frameworks.
|
|
|
|
Runtime artifact paths are relative to `runtime_pack.root`. FFI library paths are absolute. The document names installed, verified pack artifacts and their link order. The example consumer verifies and copies those artifacts before linking.
|
|
|
|
## C compiler as linker driver
|
|
|
|
The repository's `examples/native-object` directory is a runnable example with a TypeScript program, a C FFI function, and a small consumer for the JSON recipe:
|
|
|
|
```console
|
|
$ cd examples/native-object
|
|
$ clang -target arm64-apple-macosx14.0.0 -O2 -c native.c -o native.o
|
|
$ scriptc build main.ts --ffi ffi.json --print=native-link-info -o app.o > link-info.json
|
|
$ node link.mjs cc link-info.json app-cc
|
|
$ ./app-cc
|
|
42
|
|
```
|
|
|
|
The example gives clang the reported objects, archives, and system libraries. Linux objects need the target glibc or musl linker/sysroot; Windows x64 objects use Zig's MinGW sysroot with the supplied runtime pack; WASI objects need a Preview 1 linker/sysroot.
|
|
|
|
## Native Apple linker
|
|
|
|
The same example can invoke Apple `ld` directly with the precompiled runtime objects:
|
|
|
|
```console
|
|
$ node link.mjs ld link-info.json app-ld
|
|
$ ./app-ld
|
|
42
|
|
```
|
|
|
|
This lane asks `xcrun` for the selected macOS SDK and linker, then supplies the target's minimum OS, every ordered object/archive input, and each reported system library. It demonstrates the code-generation boundary precisely: scriptc owns `app.o`; the external toolchain performs the platform link.
|
|
|
|
Outbound FFI declarations retain the same C ABI in clang-compiled LLVM and helper-produced object paths. Scalar widths, string/byte pointer-plus-length pairs, and callback signatures follow the [Native FFI](/docs/ffi) manifest.
|