
编译器语言运行时开发工具CLI【免费下载链接】scriptcTypeScript-to-Native Compiler项目地址https://gitcode.com/GitHub_Trending/sc/scriptc点击查看免费下载本篇技术指南聚焦 scriptcTypeScript-to-Native 编译器运行时组件中一个容易被忽视却至关重要的目录——packages/runtime/vendor/它集中管理所有被内嵌进编译器产出物的第三方 C 代码。文章将逐一拆解六个 vendored 组件libucontext 派生源码、Ryū、QuickJS-ng、zlib、curl 头文件、mbedTLS各自的上游来源、版本锁定方式、裁剪范围、编译接入点与构建缓存策略并结合packages/runtime/src/下的对应实现源码说明每个组件在实际二进制中的真实用途。读完后你将掌握 scriptc 如何在不引入运行时动态依赖的前提下通过按需编译 惰性构建缓存复用成熟开源库以及如何安全地升级这些 vendored 代码。vendor 目录的定位可复现构建的基石packages/runtime/vendor/README.md是这一目录的权威清单。它回答了一个关键问题一个声称静态原生编译的 TypeScript 编译器为什么还需要带着一整包 C 代码答案在于 scriptc 的运行时runtime需要在多种目标平台上提供node:内建模块如node:zlib、node:tls、node:fetch以及 JS 语言运行时能力而部分平台尤其是 zig 交叉编译的 sysroot并不携带这些系统库。与其要求目标环境预装依赖scriptc 选择把这些库的源码按固定 commit/版本钉进仓库由编译器按需编译并链接进最终二进制。整个目录遵循几条贯穿始终的原则只 vendored 必要切片每个组件都只保留构建真正需要的最小文件集例如 Ryū 只留 d2s 相关文件mbedTLS 只留include/与library/尽量零修改多数组件不修改任何 vendored 文件以保持与上游的逐字节可比对性惰性编译大多数库的归档文件如libqjs.a、libmbedtls.a、zlib 对象文件不在仓库里而是在首次需要时才构建进每用户构建缓存无用的绝不编译不使用某功能的二进制对应的 vendored 代码在编译阶段就被排除不会增大产物。libucontext派生源码为 musl 目标补齐 ucontext属性值上游项目libucontextAriadne Conill 维护上游 commit49e671dd52ff6791295d8161ad3b6da7dc5f6f9d许可ISC版权与许可声明完整复制于src/scr_musl.c文件头musl libc 有一个著名的缺口它暴露了 POSIX 的ucontext_t类型却故意不实现getcontext/setcontext/swapcontext/makecontext这些遗留函数。而 scriptc 的 async/generator 纤程fiber机制恰恰需要用户态寄存器切换。因此scr_musl.c 将 libucontext 的 x86_64 与 AArch64 寄存器保存/恢复逻辑直接改编进来以标准符号名getcontext、setcontext、swapcontext、makecontext补上 musl 未解析的符号。从源码结构可以观察到几个重要的实现细节仅服务于 linux-musl 目标文件开头即注明该 TU 只在x86_64-linux-musl与aarch64-linux-musl目标下编译由-DSCR_MUSL目标宏门控且当前只支持这两种架构见文件中的#error检查。不做信号掩码README 明确说明故意不包含信号掩码兼容包装——scriptc 纤程只做用户态寄存器交换从不通过 context 修改每纤程的信号掩码因此可以采用 libucontext 的快速非 POSIX 信号掩码实现。布局用_Static_assert钉死汇编代码依赖 musl 的ucontext_t内存布局因此代码用编译期断言锁死关键偏移x86_64 下gregs偏移 40、fpregs偏移 224AArch64 下regs[0]偏移 184、sp偏移 432、pc偏移 440一旦头文件布局变化立即编译失败而非运行时崩溃。汇编与 C 分离x86_64 分支用内联汇编实现getcontext/setcontext/swapcontext并用一个隐藏的scr_musl_context_trampoline承接makecontext启动的新上下文AArch64 分支同样按regs/sp/pc/pstate/fpsimd布局手写保存与恢复SIMD 状态q8–q15也一并处理。参数传递细节makecontext按 ABI 规则分发参数——x86_64 下前 6 个参数进寄存器RDI/RSI/RDX/RCX/R8/R9超出的压栈AArch64 下前 8 个进regs[0..7]超出的写栈。此外scr_musl.c还附带一个arc4random_bufshim它基于 Linuxgetrandom实现运行时约定的不可失败 CSPRNG契约处理EINTR中断与短读任何其他失败都进入运行时 trap 漏斗。ryu/把 Ryū 算法文本包含进数字格式化属性值上游项目Ryūulfjack上游 commit4c0618b0e44f7ef027ebae05d2cc7812048f7c8f许可Apache-2.0 OR BSL-1.0此处按 Boost Software License 1.0 使用见 ryu/LICENSE-BoostRyū 是著名的 double-to-shortest-decimal浮点数转最短十进制算法。vendor 目录只收纳了 d2s 核心及其头文件——float 与 fixed/exponent 变体不在其中。它在 scr_number.c 中的接入方式非常特殊不是链接一个库而是通过#include ../vendor/ryu/d2s.c文本式包含直接调用其内部d2d()、d2d_small_int()、decimalLength17()、div10()等函数见 scr_number.c。注释明确说明这样做的原因保持构建系统的运行时源文件清单不变。职责划分值得注意数字生成digit generation来自 Ryū而 ECMA-262 规定的数字摆放digit placement即指数格式、前导零等仍留在 scr_number.c 自己手中。README 还记录了对上游文件的唯一修改把d2s.c与d2s_intrinsics.h里的#include ryu/x.h拍平为#include x.h使目录自包含。升级流程也因此非常简单在目标 commit 重新抓取这些文件再重放一次 include 拍平即可。quickjs-ng/--dynamic构建模式内嵌的 JS 引擎属性值上游项目QuickJS-ngquickjs 的活跃分支版本v0.15.1上游 commit3c8f3d68953955950074c41c6e4d999562ae82a7许可MIT见 quickjs-ng/LICENSEQuickJS-ng 是 scriptc 的可选动态执行引擎由--dynamic构建模式scr_island.c 中对应的-DSCR_DYNAMIC宏内嵌用于处理动态岛dynamic island——即那些需要运行时解释执行的unknown/动态值路径。README 强调静态构建从不编译或链接任何 QuickJS 代码整个子树不会进入静态产物的依赖图。vendored 树是上游 commit 的纯快照只删除了库构建不需要的目录tests/、docs/、examples/、test262 fixtures、CI 配置、生成脚本不改动任何 vendored 文件。实际上只有四个源文件参与构建——vendor-archives.ts 中的QJS_ENGINE_SOURCES [dtoa.c, libregexp.c, libunicode.c, quickjs.c]其余qjs.c、qjsc.c、quickjs-libc.c等只是快照冗余。顺带一提即使在静态构建中QuickJS-ng 的libregexp也被复用于静态正则支持只是把JSContext当作不透明对象见 scr_island.c。引擎归档libqjs.a的构建时机遵循best-effort 预构建 惰性兜底npm 安装期间尽力预构建或由scriptc cache warm显式触发否则在首次--dynamic编译时惰性构建。产物落在每用户构建缓存的vendor/commit-flavor-target-toolchain/目录——flavor 指构建通道plain、asantarget 指原生平台/架构或显式交叉目标toolchain 指编译器环境/身份三者组合保证不同配置的归档互不串用。zlib/交叉目标下 node:zlib 的 vendored 实现属性值上游项目zlibmadler版本1.3.1发布 tarballzlib-1.3.1.tar.gzsha2569a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23许可zlib见 zlib/LICENSEzlib 是node:zlib的底层实现见 scr_zlib.c。这里的策略区分了宿主与交叉目标宿主host构建保持历史行为链接系统-lzmacOS 自带 libz交叉目标CROSS构建zig 的交叉 sysroot 没有 libz因此SCRIPTC_TARGET构建改为按目标编译这份 vendored 拷贝。vendor 只收纳发行版根目录下的扁平*.c/*.h文件LICENSE 放在旁边contrib、tests、构建机制与 docs 一律不进入。README 特别说明gz*文件 I/O 的 TUgzclose.c、gzlib.c、gzread.c、gzwrite.c虽然为了忠实性被保留但从不参与编译——没有任何代码引用 gzFile API。真正参与编译的清单是 vendor-archives.ts 中的ZLIB_SOURCES [adler32.c, compress.c, crc32.c, deflate.c, infback.c, inffast.c, inflate.c, inftrees.c, trees.c, uncompr.c, zutil.c]不含 gz* TU。zlib 对象同样惰性构建首次 zlib 交叉编译时在缓存目录vendor/zlib-version-flavor-target-toolchain/生成。值得注意的验证约束压缩输出的字节是 zlib 版本相关的因此测试语料只比较往返round-trip与固定 blob 的膨胀结果从不比对原始 deflate 输出见 scr_zlib.c 的注释说明。升级方式重新拉取发布 tarball、复制同样的扁平文件集、并在 vendor-archives.ts 中同步ZLIB_VERSION。curl/仅供已退役 fetch 参考实现的头文件属性值上游项目curlDebian bookworm 的 libcurl4-openssl-dev 7.88.1版本7.88.1头文件从node:24.15.0-bookworm镜像的/usr/include/aarch64-linux-gnu/curl/逐字节复制许可curl见 curl/COPYRIGHT即 Debian 机器可读版权文件curl 是 vendor 目录中最轻也最特殊的一项只 vendored 头文件没有任何 curl C 源码也从不编译 curl。这些头文件目前只为RETIRED已退役的 fetch 参考实现服务——即 scr_fetch_curl.c由构建时环境变量SCRIPTC_FETCH_CURL1选择仅在原生实现切换的过渡期内保持可编译充当参考对照见 scr_fetch.c。默认的 fetch 走的是 scr_net/scr_tls/scr_http/zlib 栈完全不触碰这里的任何文件见 scr_fetch.c 顶部的分层说明。在该 flag 下的接入方式有两个值得学习的工程细节宿主构建链接系统-lcurlmacOS 自带 libcurllinux-gnu 交叉构建用这些头文件编译scr_fetch_curl.c然后链接一个生成的 STUBlibcurl.sosonamelibcurl.so.4只含scr_fetch_curl.c调用的符号的空定义见 vendor-archives.ts 的CURL_STUB_SYMBOLS——这是标准的交叉链接导入桩技术产物记录一个朴素的DT_NEEDED libcurl.so.4由目标系统的真实 libcurl 在加载时满足。头文件本身架构无关system.h在预处理时按架构选择 typedef而 7.88.1 的版本钉是下限而非锁scr_fetch_curl.c最新的需求是CURLOPT_PROTOCOLS_STR7.85.0 引入且无版本符号引用可绑定到任何libcurl.so.4。STUB 按 zlib-objects 模式惰性构建到vendor/curl-stub-target-toolchain/。README 的最后一句也预告了它的归宿整个目录会随scr_fetch_curl.c的正式退役一起离开。mbedtls/node:tls/node:https 的 TLS 提供者属性值上游项目mbedTLSMbed-TLS 组织版本mbedtls-3.6.73.6 LTS 线许可Apache-2.0见 mbedtls/LICENSEmbedTLS 是 scriptc 的 TLS 层node:tls/node:https的提供者实现集中于 scr_tls.c。文件顶部有一段详实的设计说明记录了为什么选 mbedTLS 而不是另外三个候选见 scr_tls.cSecureTransportmacOS 原生零 vendoring、每台 macOS 都有但已废弃、仅限 macOSLinux 移植需要第二套后端且存在一个致命问题——服务器身份必须是SecIdentity公开 API 只能通过钥匙串导入铸造与无端口地加载 per-hostname 的 PEM 证书文件的需求相悖BoringSSL没有可供钉死的发布/版本CMakeGo 构建代码量比所需切片大一个数量级LibreSSL libtlsAPI 最干净但 macOS 不提供可链接的 libtls系统 LibreSSL 仅限 CLI需要 brew 依赖mbedTLS 胜出的两个关键轴PEM 证书/密钥/CA 加载是一等公民mbedtls_x509_crt_parse/pk_parse_key直接吃字节恰好满足无端口本地 CA 流程且同一棵 vendored 树可在 Linux 上原样编译移植零额外成本。接入方式同样遵循切片 惰性模式只 vendoredinclude/与library/LICENSE 旁边tests、docs、programs、scripts 与 CMake 机制一概不收不修改任何文件、不应用自定义配置用库存mbedtls_config.h把每个library/*.c以 clang 独立编译为 C11。运行时层面mbedTLS 的 nonblocking BIO 契约WANT_READ/WANT_WRITE与 kqueue 就绪循环 1:1 映射见 scr_tls.c所有 mbedTLS 特有的东西都藏在ScrNetTransportOps表后面未来如需更换提供者迁移成本被限制在单文件内scr_tls.c。归档libmbedtls.a采用与libqjs.a完全相同的模式npm 安装时 best-effort 预构建或scriptc cache warm显式触发否则首次 TLS 编译时惰性构建到vendor/mbedtls-version-flavor-target-toolchain/。TLS-free 的二进制从不编译或链接其中的任何文件。升级方式重新拉取发布 tarball、复制同样的两个目录、并在 vendor-archives.ts 中同步MBEDTLS_VERSION。贯穿各组件的关键机制构建缓存vendor/key-flavor-target-toolchain/模式README 反复出现的缓存路径并非巧合它是所有惰性构建归档的统一约定QuickJS 用commit 前 12 位zlib 用versionmbedTLS 用versioncurl stub 用stub。四个维度各自独立版本/commit保证缓存与源码树一一对应升级后自动换新目录flavor通道plain 与 asan 等不同消毒器配置产物互不串用target目标原生平台/架构与显式交叉目标分离toolchain工具链编译器环境/身份参与键值避免不同工具链产物混用。统一的升级流程README 为每个组件都写明了升级步骤可以归纳为三种模板源码型libucontext 派生的 scr_musl.c、Ryū拉取新 commit 的文件重放拍平 include等本地改编快照型QuickJS-ng在新 commit 重新 clone、删.git、重放同样的目录裁剪、更新本 READMEtarball 型zlib、mbedTLS、curl 头重新拉取发布 tarball、复制同样的文件切片、并在packages/compiler/src/backend/vendor-archives.ts中同步ZLIB_VERSION/MBEDTLS_VERSION常量。按需链接的纪律整个 vendor 体系最强的一条约束是**不用则不编译**静态构建不碰 QuickJSTLS-free 二进制不碰 mbedTLSzlib-free 二进制不编译 zlib 对象默认 fetch 不碰 curl 头文件。编译器的链接门控见 vendor-archives.ts 与 scr_zlib.c 的注释确保这些切片只进入确实需要它们的产物。组件速查表组件版本/commit许可vendored 切片用途与接入点是否修改上游libucontext49e671ddISCx86_64/AArch64 寄存器切换逻辑为 musl 补 ucontextscr_musl.c改编去掉信号掩码包装ryu4c0618b0Apache-2.0 OR BSL-1.0d2s 核心及头文件浮点最短十进制scr_number.c 文本 include仅拍平 include 路径quickjs-ngv0.15.1 /3c8f3d68MIT库构建所需快照--dynamic动态岛scr_island.c仅删目录不改文件zlib1.3.1zlib根目录扁平 C/H交叉目标的 node:zlibscr_zlib.c不改curl7.88.1curl仅头文件已退役 fetch 参考scr_fetch_curl.c不改且从不编译mbedtls3.6.7Apache-2.0include/library/node:tls/node:httpsscr_tls.c不改用库存配置结语packages/runtime/vendor/展示了一种务实的开源复用哲学要源码、不要依赖。通过精准的版本锁定、最小切片裁剪、零或近似零的上游修改以及版本-通道-目标-工具链四维分离的惰性构建缓存scriptc 得以在静态原生产物中嵌入 Ryū 的浮点算法、musl 缺失的 ucontext、TLS 与压缩能力而无需任何目标环境预装系统库也让每一条依赖的升级路径都变得可审计、可重放。对于希望理解 scriptc 运行时边界哪些平台能力是自带的、哪些是借用上游的的读者这份 README 连同packages/runtime/src/下对应的 C 实现是一份完整的索引地图。赞分享编译器语言运行时开发工具CLI【免费下载链接】scriptcTypeScript-to-Native Compiler项目地址https://gitcode.com/GitHub_Trending/sc/scriptc点击查看免费下载相关推荐BuildKit依赖管理第三方库与运行时依赖BuildKit依赖管理第三方库与运行时依赖 概述 BuildKit作为Docker生态系统中的核心构建工具其依赖管理机制直接影响构建性能、安全性和可维护性构建工具云原生后端jianying-headless 运行依赖与来源溯源Skill、闭源剪映运行时与第三方许可边界全解析jianying headless 运行依赖与来源溯源Skill、闭源剪映运行时与第三方许可边界全解析 本文是 jianying headless 项目中「运音视频AI 技能AI 应用Maka 的嵌入式沙箱依赖治理run2.1.4 第三方依赖声明与 QuickJS WASM 审查机制Maka 的嵌入式沙箱依赖治理run2.1.4 第三方依赖声明与 QuickJS WASM 审查机制 本篇文章以仓库中 patches/run 2.1.4人工智能AI Agent自主智能体工具调用交互助手AI 评测创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考