Every rung of the macOS SDK resolver is a read: a failing xcode-select, an SDKROOT that names no installed SDK, or a bare directory posing as one falls to the next rung, ending in the xcrun selection the builders used before. An unusable SDKROOT is reported on stderr and ignored, which matches how `xcrun --sdk macosx` treated it. SDKSettings.plist proves a directory is an SDK, since xcrun accepts any existing path. Native coverage builds both universal helpers with a stale SDKROOT, a plain directory as SDKROOT, and an older installed SDK when the host has one.
57 lines
2.3 KiB
JavaScript
57 lines
2.3 KiB
JavaScript
// Build-time only: resolves the macOS SDK the native helpers compile against.
|
|
import { execFileSync } from 'node:child_process'
|
|
import { existsSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
|
|
// Every rung below is a read: a failing tool or a missing directory falls to
|
|
// the next rung instead of failing the build.
|
|
const read = (file, args, env) => {
|
|
try {
|
|
return execFileSync(file, args, { encoding: 'utf8', env, stdio: 'pipe' }).trim()
|
|
} catch {
|
|
return ''
|
|
}
|
|
}
|
|
|
|
// Every macOS SDK carries SDKSettings.plist; xcrun accepts any existing
|
|
// directory as an SDK path, so existence alone does not prove one.
|
|
const isSdk = path => Boolean(path) && existsSync(resolve(path, 'SDKSettings.plist'))
|
|
|
|
// The installed SDK an explicit SDKROOT names, or null. SDKROOT accepts SDK
|
|
// names as well as paths; clang's -isysroot only accepts paths, so both forms
|
|
// go through xcrun.
|
|
function explicitSysroot(sdkroot, env) {
|
|
const path = read('xcrun', ['--sdk', sdkroot, '--show-sdk-path'], env)
|
|
return isSdk(path) ? path : null
|
|
}
|
|
|
|
// The MacOSX.sdk alias of the active developer directory (Command Line Tools
|
|
// layout first, then Xcode's), or null when the toolchain has neither.
|
|
function developerSysroot(env) {
|
|
const developerDir = read('xcode-select', ['-p'], env)
|
|
if (!developerDir) return null
|
|
return [
|
|
resolve(developerDir, 'SDKs/MacOSX.sdk'),
|
|
resolve(developerDir, 'Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk'),
|
|
].find(isSdk) ?? null
|
|
}
|
|
|
|
// `--sdk macosx` can select a newer SDK than the linker understands (#113708).
|
|
// Prefer the active toolchain's MacOSX.sdk alias unless the caller pins an SDK.
|
|
// A stale SDKROOT never fails the build: it is reported, then ignored, which
|
|
// matches what `xcrun --sdk macosx` did with it before this resolver existed.
|
|
export function macosSysroot(env = process.env) {
|
|
if (env.SDKROOT) {
|
|
const explicit = explicitSysroot(env.SDKROOT, env)
|
|
if (explicit) return explicit
|
|
console.warn(`[macos-sysroot] SDKROOT=${env.SDKROOT} is not an installed SDK; using the active toolchain's default`)
|
|
}
|
|
return developerSysroot(env)
|
|
}
|
|
|
|
// Preserve xcrun's previous selection when no rung produced a sysroot.
|
|
// `--sdk` must precede the tool name or xcrun passes it to clang.
|
|
export function xcrunClangArgv(sysroot) {
|
|
return sysroot ? ['clang', '-isysroot', sysroot] : ['--sdk', 'macosx', 'clang']
|
|
}
|