Files
UniXNU/scripts/linux/plutil
T
smeng9andClaude Opus 5.5 6dc20ebe08 build(linux): install the kernel step toolchain on a Linux host
scripts/linux/setup-toolchain.py, run once as root, builds into
/opt/unixnu-linux (or PREFIX, or $UNIXNU_TOOLCHAIN):

- clang from llvm-project 58c46bae2118 with llvm-xnu-builtin-type.patch,
  which adds __builtin_xnu_type_signature, __builtin_xnu_type_summary,
  __builtin_xnu_types_compatible and xnu_usage_semantics; kalloc.h uses
  the builtins with no fallback;
- cctools-port 1030.6.3-ld64-956.6 (its master, ld64-609, corrupts the
  kernel link), with libdispatch for ld64;
- mig and migcom from bootstrap_cmds-138;
- iig-port, with iig-port-darwin-target.patch;
- xnu-host-cc, the host compiler for xnu's SETUP tools;
- lzfse for the kernelcache.

It installs the Command Line Tools shims (clang, clang++, cc, install,
gm4) under the prefix and xcrun, plutil and codesign in /usr/bin, where
xnu's makefiles call them. libmacho.a and libstuff.a go to /usr/lib and
libdispatch to /usr/local. Each step is skipped when its output exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 19:48:06 +08:00

109 lines
2.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""plutil(1) shim backed by Python's plistlib.
MakeInc.def hard-codes PLUTIL = /usr/bin/plutil and MakeInc.kernel /
MakeInc.rule use it in three shapes:
plutil -convert xml1|binary1|json [-o OUT] IN
plutil -lint IN
plutil -extract KEYPATH KIND [-o OUT] IN (rare)
Anything else is refused loudly rather than silently succeeding.
"""
import plistlib
import sys
FMT = {"xml1": plistlib.FMT_XML, "binary1": plistlib.FMT_BINARY}
def read(path):
if path == "-":
return plistlib.loads(sys.stdin.buffer.read())
with open(path, "rb") as fh:
return plistlib.load(fh)
def write(obj, path, fmt):
data = plistlib.dumps(obj, fmt=fmt, sort_keys=True)
if path in (None, "-"):
sys.stdout.buffer.write(data)
else:
with open(path, "wb") as fh:
fh.write(data)
def main(argv):
out = None
mode = None
conv = None
extract = None
files = []
i = 0
while i < len(argv):
a = argv[i]
if a == "-convert":
mode, conv = "convert", argv[i + 1]
i += 2
elif a == "-o":
out = argv[i + 1]
i += 2
elif a == "-lint":
mode = "lint"
i += 1
elif a == "-extract":
mode, extract = "extract", (argv[i + 1], argv[i + 2])
i += 3
elif a in ("-s", "-r", "-p", "--"):
i += 1
elif a.startswith("-"):
print("plutil: unsupported option %s (UniXNU shim)" % a,
file=sys.stderr)
return 1
else:
files.append(a)
i += 1
if not files:
print("plutil: no input file", file=sys.stderr)
return 1
rc = 0
for path in files:
try:
obj = read(path)
except Exception as exc: # noqa: BLE001
print("%s: %s" % (path, exc), file=sys.stderr)
rc = 1
continue
if mode == "lint":
print("%s: OK" % path)
elif mode == "convert":
if conv == "json":
import json
data = json.dumps(obj).encode()
if out in (None, "-"):
sys.stdout.buffer.write(data)
else:
open(out, "wb").write(data)
elif conv in FMT:
write(obj, out if out else path, FMT[conv])
else:
print("plutil: unknown format %s" % conv, file=sys.stderr)
rc = 1
elif mode == "extract":
keypath, kind = extract
cur = obj
for part in keypath.split("."):
cur = cur[part]
if kind == "raw":
print(cur)
else:
write(cur, out, FMT.get(kind, plistlib.FMT_XML))
else:
write(obj, out, plistlib.FMT_XML)
return rc
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))