mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-11 04:00:38 +00:00
93 lines
4.2 KiB
TypeScript
93 lines
4.2 KiB
TypeScript
/**
|
|
* Build this host's declared system binaries. Landlock is a static musl
|
|
* executable; flock uses stable Node-API with separate Linux libc builds.
|
|
* Node headers come from the Node installation running this script.
|
|
*/
|
|
import { spawnSync } from 'node:child_process'
|
|
import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync } from 'node:fs'
|
|
import { basename, dirname, join, resolve } from 'node:path'
|
|
import { parseArgs } from 'node:util'
|
|
|
|
const root = resolve(import.meta.dirname, '..')
|
|
const { values } = parseArgs({ options: { 'host-addon-only': { type: 'boolean' } }, allowPositionals: false })
|
|
const hostAddonOnly = values['host-addon-only'] === true
|
|
const sources: Record<string, string> = {
|
|
'landlock-run': 'packages/entry/src/main.c',
|
|
flock: 'packages/entry/src/flock.c',
|
|
}
|
|
|
|
interface Binary {
|
|
tool: string
|
|
kind: string
|
|
path: string
|
|
napi?: number
|
|
libc?: string
|
|
}
|
|
|
|
if (process.platform !== 'linux' && process.platform !== 'darwin') {
|
|
if (hostAddonOnly) process.exit(0)
|
|
throw new Error('build: system binaries are built on Linux or macOS; no native target for this host')
|
|
}
|
|
const host = `${process.platform}-${process.arch}`
|
|
const libc = process.platform === 'linux'
|
|
? ((process.report.getReport() as { header: { glibcVersionRuntime?: string } }).header.glibcVersionRuntime ? 'glibc' : 'musl')
|
|
: undefined
|
|
const headers = resolve(dirname(process.execPath), '../include/node')
|
|
let built = 0
|
|
|
|
for (const name of readdirSync(join(root, 'packages')).sort()) {
|
|
const dir = join(root, 'packages', name)
|
|
const metadata = join(dir, 'prebuilds.json')
|
|
if (!existsSync(metadata)) continue
|
|
const spec = JSON.parse(readFileSync(metadata, 'utf8')) as { platform: string; binaries: Binary[] }
|
|
if (spec.platform !== host) continue
|
|
|
|
for (const binary of spec.binaries) {
|
|
if (hostAddonOnly && (binary.kind !== 'node-api' || (binary.libc !== undefined && binary.libc !== libc))) continue
|
|
const source = sources[binary.tool]
|
|
if (source === undefined) throw new Error(`build: unknown tool ${binary.tool}`)
|
|
const output = join(dir, binary.path)
|
|
mkdirSync(dirname(output), { recursive: true })
|
|
let compiler: string
|
|
let flags: string[]
|
|
|
|
if (binary.kind === 'static-musl' && process.platform === 'linux' && binary.tool === 'landlock-run') {
|
|
compiler = 'musl-gcc'
|
|
flags = ['-std=c11', '-Os', '-Wall', '-Wextra', '-Werror', '-static', '-s']
|
|
} else if (binary.kind === 'node-api' && binary.tool === 'flock' && binary.napi === 8) {
|
|
if (!existsSync(join(headers, 'node_api.h'))) {
|
|
throw new Error(`build: Node-API headers missing at ${headers}; use a Node installation with development headers`)
|
|
}
|
|
compiler = process.platform === 'linux' && binary.libc === 'musl' ? 'musl-gcc' : 'cc'
|
|
flags = ['-std=c11', '-O2', '-Wall', '-Wextra', '-Werror', '-fPIC', '-fvisibility=hidden', '-DNAPI_VERSION=8', '-I', headers]
|
|
if (process.platform === 'darwin') {
|
|
if (binary.libc !== undefined) throw new Error('build: macOS flock does not select a Linux libc')
|
|
flags.push('-bundle', '-undefined', 'dynamic_lookup', '-mmacosx-version-min=11.0')
|
|
} else {
|
|
if (binary.libc !== 'glibc' && binary.libc !== 'musl') {
|
|
throw new Error('build: Linux flock must select glibc or musl')
|
|
}
|
|
flags.push('-shared')
|
|
}
|
|
} else {
|
|
throw new Error(`build: unsupported ${binary.tool}/${binary.kind} target on ${host}`)
|
|
}
|
|
|
|
mkdirSync(join(root, '.release'), { recursive: true })
|
|
const temporary = mkdtempSync(join(root, '.release', 'native-build-'))
|
|
try {
|
|
const pending = join(temporary, basename(output))
|
|
const result = spawnSync(compiler, [...flags, '-o', pending, join(root, source)], { stdio: 'inherit' })
|
|
if (result.error) throw result.error
|
|
if (result.status !== 0) throw new Error(`build: ${compiler} failed for ${binary.path}`)
|
|
// Readers never see a truncated addon when source checks build concurrently.
|
|
renameSync(pending, output)
|
|
} finally {
|
|
rmSync(temporary, { recursive: true, force: true })
|
|
}
|
|
console.log(`build: built ${basename(dir)}/${binary.path}`)
|
|
built++
|
|
}
|
|
}
|
|
if (built === 0) throw new Error(`build: no declared binaries for ${host}`)
|