Skip to content

Commit d2e27e7

Browse files
feat: add libDirs to native library manifest (v0.5.909) (#762)
* feat: add libDirs support Add support for specifying library search paths in native library target configurations via the new `libDirs` field in package.json. Changes: - Add `lib_dirs` field to TargetNativeConfig - Parse `libDirs` from package.json - Add `-L` flags for libDirs before linking * chore(libDirs): MSVC /LIBPATH branch + package_dir anchoring + tests/docs (v0.5.909) Maintainer fold-in on top of @Lebei2046's libDirs feature: - link.rs: emit /LIBPATH:<dir> on is_windows (MSVC link.exe) instead of -L<dir>, mirroring the existing libs loop's MSVC/Unix split. - resolve.rs: anchor relative libDirs entries to package_dir via package_dir.join(p), matching swift_sources / metal_sources. Field type is now Vec<PathBuf>. - compile.rs: doc-comment on the new field. - manifest-v1.md: row added for libDirs. - resolve.rs: two new tests in manifest_parse_tests covering package_dir anchoring + empty-by-default behavior. - Cargo.toml / Cargo.lock / CLAUDE.md / CHANGELOG.md: 0.5.908 → 0.5.909 (renumbered to follow #760 which took 0.5.908 mid-review). --------- Co-authored-by: Ralph Küpper <ralph.kuepper@skelpo.com>
1 parent 2f3a82c commit d2e27e7

8 files changed

Lines changed: 170 additions & 70 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Detailed changelog for Perry. See CLAUDE.md for concise summaries.
44

5+
## v0.5.909 — feat: add `libDirs` to native library manifest (#762). New optional `targets.<target>.libDirs` field in `package.json`'s `perry.nativeLibrary` block — array of linker search paths emitted ahead of the `libs` list. **Surface.** Documented in `docs/src/native-libraries/manifest-v1.md` alongside the existing `libs` / `frameworks` / `pkgConfig` entries. Use it when a wrapper ships a vendored `.a`/`.dylib` outside the cargo crate (the standard `lib_name` lookup probes `target/<triple>/release/`); previously the only escape hatch was an absolute path glued into `libs` via a workaround. **Plumbing.** Three edits — (1) `TargetNativeConfig.lib_dirs: Vec<PathBuf>` field added in `crates/perry/src/commands/compile.rs`; (2) `parse_native_library_manifest` parses `libDirs` and anchors relative entries to `package_dir` via `package_dir.join(p)` — mirrors the existing `swift_sources` / `metal_sources` pattern so a `"./vendor/lib"` in the manifest resolves against the wrapper's directory, not the user's cwd (absolute entries pass through unchanged since `PathBuf::join` ignores the base on an absolute right-hand side); (3) `build_and_run_link` in `crates/perry/src/commands/compile/link.rs` emits each entry between the `frameworks` loop and the `libs` loop — `-L<dir>` on every non-Windows target, `/LIBPATH:<dir>` when `is_windows` (mirrors the `libs` loop's existing `{lib}.lib` vs `-l{lib}` MSVC/Unix split, so a `targets.windows.libDirs` entry actually resolves the `{lib}.lib` lookups instead of being a silent no-op against link.exe). **Validation.** Two new unit tests in `crates/perry/src/commands/compile/resolve.rs::manifest_parse_tests` — `lib_dirs_relative_paths_anchored_to_package_dir` round-trips a manifest with both `"vendor/lib"` and `"/abs/path"` and asserts the package_dir-anchored / pass-through behavior; `lib_dirs_defaults_to_empty_when_absent` confirms the field is optional. `cargo build --release` clean; `cargo test -p perry --lib` green. **Version-bump note.** Renumbered v0.5.908 → v0.5.909 because #760 (test: argon2 + ethers parity) landed on main mid-review and took the v0.5.908 slot. **Contributor.** Implementation by @Lebei2046; MSVC `/LIBPATH:` branch + `package_dir` anchoring + tests + manifest doc entry + this changelog folded in at merge time.
6+
57
## v0.5.908 — test: #698 — behavioral parity tests for argon2 + ethers integrations (#760). Follow-up to #694, addressing #698. Adds two new parity fixtures and a `@covers` block on `test_parity_crypto.ts`, moving 18 FFI entries out of `test_ffi_surface_stdlib_integrations.ts` (156 → 138 unique names) into behavioral coverage. **`test_parity_argon2.ts`** — round-trips `argon2.hash` / `argon2.verify` against the `perry-ext-argon2` wrapper; non-deterministic salt is handled by shape-checking the `$argon2id$` prefix and asserting verify round-trips against a freshly produced hash. Only the async path is in `NativeModSig`, so this covers the two FFI entries (`js_argon2_hash`, `js_argon2_verify`) reachable end-to-end. **`test_parity_ethers.ts`** — pure deterministic helpers from `perry-ext-ethers`: `getAddress` (EIP-55 checksum on lower- and upper-case input), `parseEther`/`formatEther` round-trip on 1.5 ETH, `parseUnits`/`formatUnits` at 6- (USDC) and 9-decimal (gwei) positions. Covers the five `js_ethers_*` helpers. Both new fixtures use the `test-parity/expected/` mechanism — Perry routes the npm-style imports to the bundled `perry-ext-*` wrappers, but Node can't resolve the same names without `node_modules`, so they fall through to stored expected-output comparison. **`test_parity_crypto.ts`** — adds a `@covers` block declaring the crypto/webcrypto/crypto_e2e FFI surface it already exercises via `node:crypto` and `crypto.subtle` (digest, hash, pbkdf2/hkdf, subtle.sign/verify); no behavioral change. **Out of scope (each gets its own follow-up).** `jsonwebtoken.sign` — `NativeModSig` passes `payload`/`secret` as `NA_F64` (NaN-boxed) but `js_jwt_sign` reads them as `*const StringHeader`, producing garbage tokens (calling-convention mismatch, same shape as the #591 argon2 fix). `bcrypt.hash` — return value reports `typeof === "object"` in user code; `compare` round-trips correctly but `.startsWith(...)` on the hash fails. `cheerio` — `$.select(...)` returns a bare-number handle, so `.length()` / `.first()` etc. fail with `(number).method is not a function` at the prototype check. Service-backed integrations (MongoDB, MySQL, PG, ioredis, Nodemailer, Sharp) also remain in the inventory pending the local-container / opt-in test setup described in #698. **Audit.** `./test-coverage/audit.sh --markdown` keeps TS-side and combined FFI coverage at **1791/1791 (100.0%)**. `test_ffi_surface_stdlib_integrations.ts` re-regenerated via `regen_ts_surface_inventory.py` to fold in the new `@covers` blocks. Comment-only changes; no behavioral or runtime impact. Contributor: @TheHypnoo.
68

79
## v0.5.907 — test(stdlib): #697 — move stdlib_io FFI coverage into behavioral tests (#758). Follow-up to #694: relocates the 155 inventory entries from `test_ffi_surface_stdlib_io.ts` into `@covers` annotations attached to the existing behavioral fixtures for each surface — `fetch.rs` (43 names) → `test_gap_fetch_response.ts`; `streams.rs` (37) → `test_parity_stream_web.ts`; `http.rs` (13) → `test_parity_http.ts`; `net/mod.rs` (10) → `test_net_socket.ts`; `readline.rs` (5) → `test_parity_readline.ts`; `worker_threads.rs` (6) → `test_parity_worker_threads.ts`; `ws.rs` (11) → `test_node_http_ws_upgrade.ts`; `framework/{multipart,request,response,server}.rs` (28) → `test_fastify_integration.ts`. Each receiving fixture already exercises real behavior on its surface (local loopback servers / deterministic in-memory probes / Headers + Blob + Response API roundtrips) — no external services added. **Mechanism.** `regen_ts_surface_inventory.py` excludes the six `test_ffi_surface_*.ts` inventory files when scanning for `@covers` references, so any FFI name that appears in a non-inventory fixture's `@covers` block is dropped from its inventory file on the next regen. After this PR, `test_ffi_surface_stdlib_io.ts` shrinks from **155 → 0** unique FFI names. **Audit.** `./test-coverage/audit.sh --markdown` keeps TypeScript and combined FFI coverage at **1791/1791 (100.0%)**. `test_ffi_surface_runtime_core.ts` re-regenerated against current `main` post-rebase — the inventory drift visible in the diff (added `js_array_flat_depth`, `js_template_raw`, `js_path_matches_glob`, `js_async_first_call`, the 7 new `webassembly.rs` exports; removed `js_mul`, `js_net_socket_destroy/end/write`, the 9 `js_ws_*` stubs from `stdlib_stubs.rs`) reflects upstream Rust refactors, not hand edits. Comment-only changes; no behavioral or runtime impact. Contributor: @TheHypnoo.

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
88

99
Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation.
1010

11-
**Current Version:** 0.5.908
11+
**Current Version:** 0.5.909
1212

1313

1414
## TypeScript Parity Status

0 commit comments

Comments
 (0)