@scriptc/compiler 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +5 -13
- package/dist/backend/cc.d.ts +23 -2
- package/dist/backend/cc.js +250 -9
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-async.d.ts +1 -0
- package/dist/backend/emission/emit-async.js +27 -1
- package/dist/backend/emission/emit-async.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +109 -18
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +1 -0
- package/dist/backend/emission/emitter.js +25 -3
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.js +152 -0
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/mangle.d.ts +1 -0
- package/dist/backend/mangle.js +3 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/coverage/surface-manifest.js +1 -0
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +23 -1
- package/dist/diagnostics/diagnostic.js +34 -0
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +3 -1
- package/dist/frontend/lowering/lower-calls.js +196 -33
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +6 -5
- package/dist/frontend/lowering/lower-containers.js +15 -11
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +11 -1
- package/dist/frontend/lowering/lower-exprs.js +366 -25
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +5 -0
- package/dist/frontend/lowering/lower-server.js +105 -55
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +71 -9
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +24 -5
- package/dist/frontend/lowering/lowerer.js +28 -4
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +84 -5
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +52 -19
- package/dist/ir/nodes.js +2 -2
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +67 -9
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/profile.d.ts +33 -0
- package/dist/library/profile.js +178 -4
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar.d.ts +3 -2
- package/dist/library/sidecar.js +7 -3
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +2 -1
|
@@ -2444,18 +2444,10 @@ declare module "node:https" {
|
|
|
2444
2444
|
export * from "https";
|
|
2445
2445
|
}
|
|
2446
2446
|
|
|
2447
|
-
/* node:http2 — the
|
|
2448
|
-
*
|
|
2449
|
-
*
|
|
2450
|
-
*
|
|
2451
|
-
* HTTP/1.1 (h2-only clients fail the handshake; no multiplexing, no
|
|
2452
|
-
* server push). The handler arrives via server.on("request", ...);
|
|
2453
|
-
* Http2ServerRequest/Response ARE the http req/res surface (exactly
|
|
2454
|
-
* what Node hands an allowHTTP1 server's HTTP/1.1 connections), with
|
|
2455
|
-
* the h2-only members (stream, session) answering undefined behind a
|
|
2456
|
-
* '?.' guard and fencing unguarded. 'sessionError' registers and never
|
|
2457
|
-
* fires (no h2 session ever exists). h2 sessions themselves — connect,
|
|
2458
|
-
* the h2c createServer — have no lowering. */
|
|
2447
|
+
/* node:http2 — the compatibility surface: allowHTTP1 servers negotiate
|
|
2448
|
+
* h2 or HTTP/1.1 and expose the shared request/response API. HTTP/2
|
|
2449
|
+
* requests retain their backing stream; server session failures surface
|
|
2450
|
+
* through sessionError. */
|
|
2459
2451
|
declare module "http2" {
|
|
2460
2452
|
import { Socket } from "net";
|
|
2461
2453
|
export interface Http2Stream {
|
|
@@ -2529,7 +2521,7 @@ declare module "http2" {
|
|
|
2529
2521
|
on(event: "request", listener: (req: Http2ServerRequest, res: Http2ServerResponse) => void): void;
|
|
2530
2522
|
on(event: "error", listener: (err: Error) => void): void;
|
|
2531
2523
|
on(event: "close", listener: () => void): void;
|
|
2532
|
-
on(event: "sessionError", listener: () => void): void;
|
|
2524
|
+
on(event: "sessionError", listener: (err: Error, session: ServerHttp2Session) => void): void;
|
|
2533
2525
|
/* The ALPN=h2 server's surface (createSecureServer WITHOUT
|
|
2534
2526
|
* allowHTTP1 — the real h2-over-TLS stack): per-stream and
|
|
2535
2527
|
* per-session listeners, exactly the h2c server's. */
|
package/dist/backend/cc.d.ts
CHANGED
|
@@ -208,11 +208,31 @@ export interface CcDriver {
|
|
|
208
208
|
argv: string[];
|
|
209
209
|
/** The SCRIPTC_TARGET triple, or null for a host-native build. */
|
|
210
210
|
target: string | null;
|
|
211
|
+
/** The spelling handed to `zig cc -target` (and the relocatable-merge
|
|
212
|
+
* link). Identical to `target` except for the mobile triples, whose
|
|
213
|
+
* canonical LLVM spellings map to zig's own (`aarch64-apple-ios` →
|
|
214
|
+
* `aarch64-ios.15.0`), pinning the minimum OS version in the same
|
|
215
|
+
* breath. Null for a host-native build. */
|
|
216
|
+
zigTarget: string | null;
|
|
211
217
|
/** Extra compile args the produced platform demands. */
|
|
212
218
|
targetArgs: string[];
|
|
213
219
|
/** Platform libraries appended after every object/archive input. */
|
|
214
220
|
linkArgs: string[];
|
|
215
221
|
}
|
|
222
|
+
export declare const IPHONEOS_MIN_VERSION = "15.0";
|
|
223
|
+
export declare const ANDROID_MIN_API = 26;
|
|
224
|
+
export declare function isIosTarget(target: string | null): boolean;
|
|
225
|
+
export declare function isAndroidTarget(target: string | null): boolean;
|
|
226
|
+
export declare function isMobileTarget(target: string | null): boolean;
|
|
227
|
+
/** The canonical mobile triple SCRIPTC_TARGET selects, or null when the
|
|
228
|
+
* environment names none. Pure string inspection — safe to consult before
|
|
229
|
+
* any toolchain discovery runs. */
|
|
230
|
+
export declare function mobileLibraryTarget(env?: NodeJS.ProcessEnv): string | null;
|
|
231
|
+
/** The admission verdict for a mobile-family triple: null when the spelling
|
|
232
|
+
* and host pairing are supported, otherwise the refusal text (the same text
|
|
233
|
+
* resolveCc throws and compileLibrary reports as SC3002). Pure string/host
|
|
234
|
+
* inspection — no discovery, no subprocess. */
|
|
235
|
+
export declare function mobileTargetRefusal(target: string, hostPlatform?: NodeJS.Platform): string | null;
|
|
216
236
|
export declare function resolveCc(env?: NodeJS.ProcessEnv, hostPlatform?: NodeJS.Platform): CcDriver;
|
|
217
237
|
/** Musl intentionally has no predefined libc macro. The explicit Zig target
|
|
218
238
|
* is therefore the source of truth for selecting its small runtime shim. */
|
|
@@ -259,8 +279,9 @@ export interface LibArchiveOptions {
|
|
|
259
279
|
* sanitizer ABI in instrumented builds) keep their global binding. Windows
|
|
260
280
|
* embedders additionally link advapi32, iphlpapi, and ws2_32. Omitted = the
|
|
261
281
|
* classic archive, byte-for-byte. Admitted for darwin/linux/win32 native
|
|
262
|
-
* hosts, linux
|
|
263
|
-
* triples from a darwin host (compileLibrary owns the refusal
|
|
282
|
+
* hosts, linux/android/windows cross triples from any host, and macos/ios
|
|
283
|
+
* cross triples from a darwin host (compileLibrary owns the refusal
|
|
284
|
+
* fence). */
|
|
264
285
|
localizeSymbols?: readonly string[];
|
|
265
286
|
/** Thread-instanced state (the profile's abi.instance_per_thread): every
|
|
266
287
|
* TU of the archive compiles with -DSCR_THREAD_INSTANCES, moving the
|
package/dist/backend/cc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
1
|
+
import { execFile, spawnSync } from "node:child_process";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { constants as fsConstants } from "node:fs";
|
|
3
|
+
import { constants as fsConstants, existsSync, readdirSync } from "node:fs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { access, chmod, copyFile, link, mkdir, mkdtemp, readdir, readFile, realpath, rename, rm, stat, unlink, utimes, writeFile } from "node:fs/promises";
|
|
6
6
|
import { availableParallelism, homedir, tmpdir } from "node:os";
|
|
@@ -176,6 +176,181 @@ export function runtimeSrcDir() {
|
|
|
176
176
|
const require = createRequire(import.meta.url);
|
|
177
177
|
return join(dirname(require.resolve("@scriptc/runtime/package.json")), "src");
|
|
178
178
|
}
|
|
179
|
+
/* ── mobile targets (library mode) ─────────────────────────────────────────
|
|
180
|
+
* Three mobile triples are admitted, and only for LIBRARY-MODE archive
|
|
181
|
+
* builds — the consuming pattern is an embedding app linking the archive,
|
|
182
|
+
* never a standalone executable (compile()/compileC refuse the executable
|
|
183
|
+
* lane with the pointer to --lib):
|
|
184
|
+
*
|
|
185
|
+
* aarch64-apple-ios device archives; zig `aarch64-ios.15.0`
|
|
186
|
+
* aarch64-apple-ios-simulator simulator archives; zig
|
|
187
|
+
* `aarch64-ios.15.0-simulator`
|
|
188
|
+
* aarch64-linux-android zig `aarch64-linux-android.26`
|
|
189
|
+
*
|
|
190
|
+
* The minimum-version floors are part of the target contract: iOS archives
|
|
191
|
+
* build for iOS 15.0 (IPHONEOS_MIN_VERSION), Android archives for API level
|
|
192
|
+
* 26 (ANDROID_MIN_API) — LC_BUILD_VERSION minos and the bionic stub level
|
|
193
|
+
* both come from the pinned zig spelling above, so an embedder's deployment
|
|
194
|
+
* target at or above the floor links cleanly.
|
|
195
|
+
*
|
|
196
|
+
* Zig bundles no Apple or bionic libc, so both families compile against an
|
|
197
|
+
* explicit sysroot discovered here and spelled into targetArgs (where every
|
|
198
|
+
* cache tier already keys it):
|
|
199
|
+
*
|
|
200
|
+
* iOS darwin hosts only — `xcrun --show-sdk-path` selects the
|
|
201
|
+
* iPhoneOS/iPhoneSimulator SDK; compiles add `-isysroot <sdk>`
|
|
202
|
+
* plus `-isystem <sdk>/usr/include` (zig's driver manages libc
|
|
203
|
+
* header search itself and would otherwise find no headers).
|
|
204
|
+
* Android any host with an NDK — ANDROID_NDK_ROOT/ANDROID_NDK_HOME, or
|
|
205
|
+
* the newest ndk/<version> under ANDROID_HOME/ANDROID_SDK_ROOT
|
|
206
|
+
* or the platform-default SDK location; compiles add the NDK
|
|
207
|
+
* sysroot's generic and per-triple include directories.
|
|
208
|
+
*
|
|
209
|
+
* Library archives never link, so the sysroot's LIBRARIES are the
|
|
210
|
+
* embedder's side of the contract: Xcode links iOS archives against the
|
|
211
|
+
* selected SDK, and Gradle/NDK builds link Android archives against the
|
|
212
|
+
* API-26+ bionic stubs. */
|
|
213
|
+
export const IPHONEOS_MIN_VERSION = "15.0";
|
|
214
|
+
export const ANDROID_MIN_API = 26;
|
|
215
|
+
const MOBILE_LIBRARY_TARGETS = [
|
|
216
|
+
"aarch64-apple-ios",
|
|
217
|
+
"aarch64-apple-ios-simulator",
|
|
218
|
+
"aarch64-linux-android",
|
|
219
|
+
];
|
|
220
|
+
export function isIosTarget(target) {
|
|
221
|
+
return target === "aarch64-apple-ios" || target === "aarch64-apple-ios-simulator";
|
|
222
|
+
}
|
|
223
|
+
export function isAndroidTarget(target) {
|
|
224
|
+
return target === "aarch64-linux-android";
|
|
225
|
+
}
|
|
226
|
+
export function isMobileTarget(target) {
|
|
227
|
+
return isIosTarget(target) || isAndroidTarget(target);
|
|
228
|
+
}
|
|
229
|
+
/** The canonical mobile triple SCRIPTC_TARGET selects, or null when the
|
|
230
|
+
* environment names none. Pure string inspection — safe to consult before
|
|
231
|
+
* any toolchain discovery runs. */
|
|
232
|
+
export function mobileLibraryTarget(env = process.env) {
|
|
233
|
+
const target = env["SCRIPTC_TARGET"] ?? "";
|
|
234
|
+
return isMobileTarget(target) ? target : null;
|
|
235
|
+
}
|
|
236
|
+
/** The admission verdict for a mobile-family triple: null when the spelling
|
|
237
|
+
* and host pairing are supported, otherwise the refusal text (the same text
|
|
238
|
+
* resolveCc throws and compileLibrary reports as SC3002). Pure string/host
|
|
239
|
+
* inspection — no discovery, no subprocess. */
|
|
240
|
+
export function mobileTargetRefusal(target, hostPlatform = process.platform) {
|
|
241
|
+
if (isIosTarget(target)) {
|
|
242
|
+
return hostPlatform === "darwin"
|
|
243
|
+
? null
|
|
244
|
+
: `${target} library archives build on macOS hosts only (the Apple iOS SDK sysroot and Mach-O symbol localization live there); this host is ${hostPlatform}`;
|
|
245
|
+
}
|
|
246
|
+
if (isAndroidTarget(target))
|
|
247
|
+
return null;
|
|
248
|
+
// A near-miss mobile spelling must refuse with the supported set named,
|
|
249
|
+
// never reach zig with no sysroot wired (the compile would fail on the
|
|
250
|
+
// first libc header) or produce an artifact for an unverified device
|
|
251
|
+
// class.
|
|
252
|
+
if (/(?:^|-)(?:ios|tvos|watchos|visionos|android)/.test(target)) {
|
|
253
|
+
return `unsupported mobile target '${target}' (supported: ${MOBILE_LIBRARY_TARGETS.join(", ")})`;
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
/** The Apple SDK root for one mobile platform, discovered through xcrun the
|
|
258
|
+
* way Xcode's own build system selects it. Memoized per SDK name and
|
|
259
|
+
* selection environment: production rediscovers per process, and the two
|
|
260
|
+
* selection variables (DEVELOPER_DIR/SDKROOT) are already mutable-input
|
|
261
|
+
* keys that disable persistent caching. */
|
|
262
|
+
const appleSdkMemos = new Map();
|
|
263
|
+
function appleSdkRoot(sdk, env) {
|
|
264
|
+
const key = [sdk, env["PATH"] ?? "", env["DEVELOPER_DIR"] ?? "", env["SDKROOT"] ?? ""].join("\0");
|
|
265
|
+
const memo = appleSdkMemos.get(key);
|
|
266
|
+
if (memo !== undefined)
|
|
267
|
+
return memo;
|
|
268
|
+
const probe = spawnSync("xcrun", ["--sdk", sdk, "--show-sdk-path"], {
|
|
269
|
+
encoding: "utf8",
|
|
270
|
+
env,
|
|
271
|
+
});
|
|
272
|
+
const path = probe.status === 0 ? (probe.stdout ?? "").trim() : "";
|
|
273
|
+
if (path === "" || !existsSync(join(path, "usr", "include"))) {
|
|
274
|
+
throw new Error(`the ${sdk} SDK was not found (xcrun --sdk ${sdk} --show-sdk-path failed) — ` +
|
|
275
|
+
`iOS targets need Xcode with the ${sdk === "iphoneos" ? "iPhoneOS" : "iPhoneSimulator"} SDK installed`);
|
|
276
|
+
}
|
|
277
|
+
appleSdkMemos.set(key, path);
|
|
278
|
+
return path;
|
|
279
|
+
}
|
|
280
|
+
/** Compare dotted-numeric NDK version directory names, newest first. */
|
|
281
|
+
function compareNdkVersionsDesc(a, b) {
|
|
282
|
+
const as = a.split(".").map((s) => Number.parseInt(s, 10));
|
|
283
|
+
const bs = b.split(".").map((s) => Number.parseInt(s, 10));
|
|
284
|
+
for (let i = 0; i < Math.max(as.length, bs.length); i++) {
|
|
285
|
+
const d = (bs[i] ?? 0) - (as[i] ?? 0);
|
|
286
|
+
if (d !== 0 && Number.isFinite(d))
|
|
287
|
+
return d;
|
|
288
|
+
}
|
|
289
|
+
return a < b ? 1 : a > b ? -1 : 0;
|
|
290
|
+
}
|
|
291
|
+
/** The Android NDK sysroot for the selected environment: an explicit
|
|
292
|
+
* ANDROID_NDK_ROOT/ANDROID_NDK_HOME wins; otherwise the newest ndk/<version>
|
|
293
|
+
* under ANDROID_HOME, ANDROID_SDK_ROOT, or the platform-default SDK
|
|
294
|
+
* location. The prebuilt host directory is discovered rather than guessed —
|
|
295
|
+
* the NDK ships exactly one per host OS. Memoized per selection
|
|
296
|
+
* environment. */
|
|
297
|
+
const ndkSysrootMemos = new Map();
|
|
298
|
+
function androidNdkSysroot(env) {
|
|
299
|
+
const key = ["ANDROID_NDK_ROOT", "ANDROID_NDK_HOME", "ANDROID_HOME", "ANDROID_SDK_ROOT"]
|
|
300
|
+
.map((name) => env[name] ?? "")
|
|
301
|
+
.join("\0");
|
|
302
|
+
const memo = ndkSysrootMemos.get(key);
|
|
303
|
+
if (memo !== undefined)
|
|
304
|
+
return memo;
|
|
305
|
+
const ndkRoots = [];
|
|
306
|
+
const explicit = [env["ANDROID_NDK_ROOT"], env["ANDROID_NDK_HOME"]]
|
|
307
|
+
.find((root) => root !== undefined && root !== "");
|
|
308
|
+
if (explicit !== undefined) {
|
|
309
|
+
ndkRoots.push(explicit);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
const sdkRoots = [
|
|
313
|
+
env["ANDROID_HOME"],
|
|
314
|
+
env["ANDROID_SDK_ROOT"],
|
|
315
|
+
process.platform === "darwin"
|
|
316
|
+
? join(homedir(), "Library", "Android", "sdk")
|
|
317
|
+
: process.platform === "win32"
|
|
318
|
+
? join(env["LOCALAPPDATA"] ?? join(homedir(), "AppData", "Local"), "Android", "Sdk")
|
|
319
|
+
: join(homedir(), "Android", "Sdk"),
|
|
320
|
+
].filter((root) => root !== undefined && root !== "");
|
|
321
|
+
for (const root of sdkRoots) {
|
|
322
|
+
let versions = [];
|
|
323
|
+
try {
|
|
324
|
+
versions = readdirSync(join(root, "ndk")).filter((name) => /^\d/.test(name));
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
versions.sort(compareNdkVersionsDesc);
|
|
330
|
+
ndkRoots.push(...versions.map((version) => join(root, "ndk", version)));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
for (const ndk of ndkRoots) {
|
|
334
|
+
const prebuilt = join(ndk, "toolchains", "llvm", "prebuilt");
|
|
335
|
+
let hosts = [];
|
|
336
|
+
try {
|
|
337
|
+
hosts = readdirSync(prebuilt).sort();
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
for (const host of hosts) {
|
|
343
|
+
const sysroot = join(prebuilt, host, "sysroot");
|
|
344
|
+
if (existsSync(join(sysroot, "usr", "include", "aarch64-linux-android"))) {
|
|
345
|
+
ndkSysrootMemos.set(key, sysroot);
|
|
346
|
+
return sysroot;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
throw new Error("no Android NDK sysroot was found — install an NDK (sdkmanager 'ndk;<version>') and/or set " +
|
|
351
|
+
"ANDROID_NDK_ROOT to it (ANDROID_HOME with an ndk/ directory also works). " +
|
|
352
|
+
"aarch64-linux-android compiles against the NDK's bionic headers.");
|
|
353
|
+
}
|
|
179
354
|
/** Resolve native platform flags independently of the machine running tests,
|
|
180
355
|
* so the host-Linux contract remains pinned on every development host. */
|
|
181
356
|
function nativePlatformArgs(platform) {
|
|
@@ -191,22 +366,70 @@ export function resolveCc(env = process.env, hostPlatform = process.platform) {
|
|
|
191
366
|
if (target !== "") {
|
|
192
367
|
throw new Error(`SCRIPTC_TARGET=${target} requires SCRIPTC_CC=zigcc — the default clang path has no cross-target sysroots.`);
|
|
193
368
|
}
|
|
194
|
-
return { argv: ["clang"], target: null, ...hostArgs };
|
|
369
|
+
return { argv: ["clang"], target: null, zigTarget: null, ...hostArgs };
|
|
195
370
|
}
|
|
196
371
|
if (cc !== "zigcc") {
|
|
197
372
|
throw new Error(`unknown SCRIPTC_CC '${cc}' (supported: clang, zigcc)`);
|
|
198
373
|
}
|
|
199
374
|
if (target === "")
|
|
200
|
-
return { argv: ["zig", "cc"], target: null, ...hostArgs };
|
|
375
|
+
return { argv: ["zig", "cc"], target: null, zigTarget: null, ...hostArgs };
|
|
201
376
|
if (target.includes("wasi") && target !== "wasm32-wasi") {
|
|
202
377
|
throw new Error(`unsupported WASI target '${target}' (supported: wasm32-wasi)`);
|
|
203
378
|
}
|
|
379
|
+
const mobileRefusal = mobileTargetRefusal(target, hostPlatform);
|
|
380
|
+
if (mobileRefusal !== null)
|
|
381
|
+
throw new Error(mobileRefusal);
|
|
382
|
+
if (isIosTarget(target)) {
|
|
383
|
+
// Library-mode-only target (compile()/compileC own the executable-lane
|
|
384
|
+
// refusal). Zig bundles no Apple libc: the compile rides the selected
|
|
385
|
+
// SDK sysroot, with the libc header directory spelled explicitly
|
|
386
|
+
// because zig's driver manages libc search itself and consults no
|
|
387
|
+
// -isysroot for it. The zig spelling pins the iOS 15.0 floor into
|
|
388
|
+
// every object's LC_BUILD_VERSION minos.
|
|
389
|
+
const simulator = target === "aarch64-apple-ios-simulator";
|
|
390
|
+
const sdk = appleSdkRoot(simulator ? "iphonesimulator" : "iphoneos", env);
|
|
391
|
+
const zigTarget = `aarch64-ios.${IPHONEOS_MIN_VERSION}${simulator ? "-simulator" : ""}`;
|
|
392
|
+
return {
|
|
393
|
+
argv: ["zig", "cc"],
|
|
394
|
+
target,
|
|
395
|
+
zigTarget,
|
|
396
|
+
targetArgs: ["-target", zigTarget, "-isysroot", sdk, "-isystem", join(sdk, "usr", "include")],
|
|
397
|
+
linkArgs: [],
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
if (isAndroidTarget(target)) {
|
|
401
|
+
// Library-mode-only target. Zig bundles no bionic: compiles ride the
|
|
402
|
+
// NDK sysroot's generic and per-triple include directories. Bionic
|
|
403
|
+
// supports _GNU_SOURCE like glibc (and hides some POSIX declarations
|
|
404
|
+
// without it); the zig spelling pins the API 26 floor, which the NDK's
|
|
405
|
+
// versioned stub libraries enforce at the embedder's link. API 26
|
|
406
|
+
// bionic carries everything the library-lane units call (arc4random_buf
|
|
407
|
+
// included), so no shim TU joins the archive.
|
|
408
|
+
const sysroot = androidNdkSysroot(env);
|
|
409
|
+
const zigTarget = `aarch64-linux-android.${ANDROID_MIN_API}`;
|
|
410
|
+
return {
|
|
411
|
+
argv: ["zig", "cc"],
|
|
412
|
+
target,
|
|
413
|
+
zigTarget,
|
|
414
|
+
targetArgs: [
|
|
415
|
+
"-target",
|
|
416
|
+
zigTarget,
|
|
417
|
+
"-D_GNU_SOURCE",
|
|
418
|
+
"-isystem",
|
|
419
|
+
join(sysroot, "usr", "include"),
|
|
420
|
+
"-isystem",
|
|
421
|
+
join(sysroot, "usr", "include", "aarch64-linux-android"),
|
|
422
|
+
],
|
|
423
|
+
linkArgs: ["-lm"],
|
|
424
|
+
};
|
|
425
|
+
}
|
|
204
426
|
const linux = target.includes("linux");
|
|
205
427
|
const wasi = target.includes("wasi");
|
|
206
428
|
const musl = target.includes("linux-musl");
|
|
207
429
|
return {
|
|
208
430
|
argv: ["zig", "cc"],
|
|
209
431
|
target,
|
|
432
|
+
zigTarget: target,
|
|
210
433
|
targetArgs: [
|
|
211
434
|
"-target",
|
|
212
435
|
target,
|
|
@@ -237,6 +460,11 @@ export function targetPlatform(driver) {
|
|
|
237
460
|
return process.platform;
|
|
238
461
|
if (driver.target.includes("wasi"))
|
|
239
462
|
return "wasi";
|
|
463
|
+
// iOS is a darwin-family target: Mach-O objects, ld64 localization,
|
|
464
|
+
// POSIX path/EOL semantics. Android falls to the linux arm below —
|
|
465
|
+
// bionic is a linux libc and its archives are ordinary ELF.
|
|
466
|
+
if (isIosTarget(driver.target))
|
|
467
|
+
return "darwin";
|
|
240
468
|
if (driver.target.includes("linux"))
|
|
241
469
|
return "linux";
|
|
242
470
|
if (driver.target.includes("windows"))
|
|
@@ -1079,9 +1307,12 @@ export async function compileLibArchive(opts) {
|
|
|
1079
1307
|
* private extern, and -r without -keep_private_externs writes
|
|
1080
1308
|
* private externs out as non-external symbols. Apple ASan's
|
|
1081
1309
|
* image-registration COMMON remains shared so the final Mach-O
|
|
1082
|
-
* image registers its globals once. ld64 reads every
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1310
|
+
* image registers its globals once. ld64 reads every Apple
|
|
1311
|
+
* platform's objects — macOS architectures and the iOS/
|
|
1312
|
+
* iOS-simulator triples alike (LC_BUILD_VERSION platform and
|
|
1313
|
+
* minos survive the merge) — so darwin-host macos AND ios
|
|
1314
|
+
* targets ride the same arm; compileLibrary refuses those
|
|
1315
|
+
* targets elsewhere.
|
|
1085
1316
|
* ELF, native linux host — ld -r merges with --force-group-allocation
|
|
1086
1317
|
* (ASan's instrumented globals ride ELF section groups whose
|
|
1087
1318
|
* signatures repeat across archives sharing runtime objects;
|
|
@@ -1146,11 +1377,13 @@ async function localizeLibraryObjects(driver, arArgv, buildDir, programObject, s
|
|
|
1146
1377
|
// Cross ELF: the cross driver's own lld performs the relocatable merge
|
|
1147
1378
|
// (with the staging archive's member semantics); demotion and section-
|
|
1148
1379
|
// group resolution happen in process. -nostdlib keeps zig from feeding
|
|
1149
|
-
// libc/compiler-rt inputs into the merge.
|
|
1380
|
+
// libc/compiler-rt inputs into the merge. Android rides this arm
|
|
1381
|
+
// unchanged: bionic archives are ordinary aarch64 ELF64, and the merge
|
|
1382
|
+
// uses the driver's zig spelling (which pins the API floor).
|
|
1150
1383
|
await run([
|
|
1151
1384
|
driver.argv[0] ?? "zig",
|
|
1152
1385
|
...driver.argv.slice(1),
|
|
1153
|
-
"-target", driver.target,
|
|
1386
|
+
"-target", driver.zigTarget ?? driver.target,
|
|
1154
1387
|
"-nostdlib",
|
|
1155
1388
|
"-r", programObject, staging,
|
|
1156
1389
|
"-o", combined,
|
|
@@ -2330,6 +2563,14 @@ export async function compileC(opts) {
|
|
|
2330
2563
|
const http = (opts.http ?? false) || nativeFetch || netIsland;
|
|
2331
2564
|
const tls = (opts.tls ?? false) || nativeFetch || netIsland;
|
|
2332
2565
|
const driver = resolveCc();
|
|
2566
|
+
// Mobile triples produce library archives, never standalone executables:
|
|
2567
|
+
// the executable-lane runtime (event loop, sockets, child processes) is
|
|
2568
|
+
// not verified on those device classes. compile() reports the SC3002
|
|
2569
|
+
// diagnostic first; this is the backstop for direct compileC callers.
|
|
2570
|
+
if (isMobileTarget(driver.target)) {
|
|
2571
|
+
throw new Error(`SCRIPTC_TARGET=${driver.target} builds library-mode static archives only — ` +
|
|
2572
|
+
`compile with a library profile (SCRIPTC_CC=zigcc scriptc build --lib --profile <profile.json>) and link the archive from the app project.`);
|
|
2573
|
+
}
|
|
2333
2574
|
const runtimeSources = targetPlatform(driver) === "wasi"
|
|
2334
2575
|
? RUNTIME_SOURCES.filter((source) => source !== "scr_child.c")
|
|
2335
2576
|
: RUNTIME_SOURCES;
|