Files
NODEDC_MISSION_CORE/plugins/insta360-x4/packaging/build_native.py
T
DCCONSTRUCTIONS a3c15e11e9 Add packaged Insta360 X4 integration and recover paired Node channels
Discover independent camera instances and prepare their versioned runtime
from Node or remote Core. Add isolated SDK workers, camera controls, raw
dual-fisheye WebRTC preview, and shared action/region loading states.

Recover existing Node bindings over known Tailscale addresses after a Core
LAN address change. Preserve identities and trust, pin both peers, migrate
endpoints with revision checks, and require real heartbeats for online status.
Fix the Python client certificate profile for Go X509 verification.

Pin Design Guideline 8c53f73 and retain installer/build/acceptance history.
Node 0.8.19 is installed; X4 0.1.3-3 is bundled but hardware activation is pending.

Validation: qualified DG/Node builds and Go race tests; 31 fleet tests;
Python-to-Go certificate interoperability and live tailnet recovery with five
fresh heartbeats; prior 38 X4 tests and bounded remote WebRTC acceptance.
Clean-OS, replug/power autonomy, local X4 video and long-run stability remain open.
2026-09-10 09:21:24 +03:00

100 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""Build the private X4 adapter through a versioned Linux build artifact.
Input SDK bytes must already satisfy sdk-lock.json. No network, dependency
installation, SDK execution, device access or mutation of system directories.
"""
import argparse
import hashlib
import json
import os
import platform
import shutil
import subprocess
import tempfile
from pathlib import Path
from fetch_sdk import LOCK, ROOT, inspect_elf, verify
def build(sdk, destination):
if platform.system() != "Linux" or platform.machine() != "x86_64":
raise RuntimeError("Native compilation requires Linux x86_64 and the declared compiler")
lock = json.loads(LOCK.read_text())
verify(sdk, lock)
if destination.exists():
raise ValueError("Do not replace a previously built adapter")
destination.parent.mkdir(parents=True, exist_ok=True)
stage = Path(tempfile.mkdtemp(prefix=".native-", dir=destination.parent))
env = {"PATH": "/usr/bin:/bin", "LANG": "C.UTF-8", "SOURCE_DATE_EPOCH": "1788825600"}
try:
target = stage / "libmissioncore_x4.so"
subprocess.run(
[
"/usr/bin/g++",
"-std=c++17",
"-O2",
"-Wall",
"-Wextra",
"-Werror",
"-fPIC",
"-fvisibility=hidden",
"-shared",
"-pthread",
"-ffile-prefix-map=" + str(ROOT) + "=/source/insta360-x4",
"-I",
str(sdk / "include"),
str(ROOT / "native/bridge.cpp"),
"-L",
str(sdk / "lib"),
"-Wl,-z,defs,-z,relro,-z,now",
"-Wl,-rpath,$ORIGIN",
"-lCameraSDK",
"-o",
str(target),
],
env=env,
check=True,
timeout=120,
)
elf = inspect_elf(target)
if "libCameraSDK.so" not in elf["needed"]:
raise ValueError("Built adapter does not depend on the admitted SDK")
report = {
"schema": "missioncore.insta360.native-build/v1",
"abi": 1,
"sdk_lock_sha256": hashlib.sha256(LOCK.read_bytes()).hexdigest(),
"source": {
p.name: hashlib.sha256(p.read_bytes()).hexdigest()
for p in sorted((ROOT / "native").glob("*"))
if p.is_file()
},
"compiler": subprocess.check_output(
["/usr/bin/g++", "--version"], env=env, text=True
).splitlines()[0],
"binary": {
"name": target.name,
"bytes": target.stat().st_size,
"sha256": hashlib.sha256(target.read_bytes()).hexdigest(),
},
"elf": elf,
"sdk_executed": False,
"hardware_tested": False,
}
target.chmod(0o644)
(stage / "provenance.json").write_text(json.dumps(report, indent=2) + "\n")
os.rename(stage, destination)
return report
finally:
if stage.exists():
shutil.rmtree(stage)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--sdk", type=Path, default=ROOT / "build/sdk")
parser.add_argument("--output", type=Path, default=ROOT / "build/native")
args = parser.parse_args()
print(json.dumps(build(args.sdk.resolve(), args.output.resolve()), indent=2))