okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
32975a8
main
1"""Programs the kernel puts first on PATH for the model's jobs, each in its 2own directory under $ALBEDO_HOME/shims, prepended only where the program it 3needs is on the job's PATH. They are written where the kernel runs (only .py 4files travel to a remote kernel). robot-docs/shims.md has the measurements. 5 6`nix` (needs nix) runs albedo_nix.py with the kernel's Python: a flake in a jj 7workspace is read from its commit instead of copied into the store, and 8`nix develop -c` reuses a cached dev shell. ALBEDO_PLAIN_NIX=1 runs nix as is. 9 10`cargo` (needs mbx, jdx's mr-boxington) runs cargo through mbx, so every 11checkout of a project shares compiled work: a second checkout of 12native/render builds in 2 s instead of 32 s. ALBEDO_NO_MBX=1 runs plain cargo. 13For mbx's process only, SDKROOT goes, because mbx names the macOS linker with 14`xcrun --sdk $SDKROOT`, which rejects a path such as a nix shell's, and an 15unnamed linker leaves every link, build script, and proc macro uncached. 16Inside a nix shell (ALBEDO_NIX_ENV, set by albedo_nix.py) CC and CXX go too 17when they are the shell's cc and c++ anyway (a shell that picks another 18compiler keeps it), so build scripts' C compiles through mbx, which an 19explicit CC hides it from, and HOST_CFLAGS names the shell's 20compiler-wrapper flags, which no mbx key covers: without it a changed shell 21could be served another checkout's stale object. 22""" 23 24from __future__import annotations 25 26import os 27import shutil 28import sys 29from pathlib import Path 30 31CARGO = r"""#!/bin/sh 32# albedo's cargo: mbx when it is installed (see albedo_shims.py), else the next 33# cargo on PATH. 34here=$(cd "$(dirname "$0")" && pwd) 35# whether compiler $1 is the $2 on PATH, which a build script runs without it 36default() { 37a=$(command -v "$1" 2>/dev/null) && b=$(command -v "$2" 2>/dev/null) || return 1 38a=$(realpath "$a" 2>/dev/null) && b=$(realpath "$b" 2>/dev/null) || return 1 39[ "$a" = "$b" ] 40} 41if [ -z "${ALBEDO_NO_MBX:-}" ] && mbx=$(command -v mbx); then 42if [ -n "${ALBEDO_NIX_ENV:-}" ]; then 43HOST_CFLAGS="${HOST_CFLAGS:-${CFLAGS:-}} -DALBEDO_NIX_ENV_$ALBEDO_NIX_ENV" 44HOST_CXXFLAGS="${HOST_CXXFLAGS:-${CXXFLAGS:-}} -DALBEDO_NIX_ENV_$ALBEDO_NIX_ENV" 45export HOST_CFLAGS HOST_CXXFLAGS 46if default "${CC:-}" cc; then unset CC; fi 47if default "${CXX:-}" c++; then unset CXX; fi 48fi 49MBX_CARGO_SHIM_MODE=1 MBX_CARGO_SHIM_PATH="$0" exec env -u SDKROOT "$mbx" "$@" 50fi 51PATH=$(printf %s "$PATH" | tr : '\n' | grep -vxF "$here" | paste -sd: -) 52exec cargo "$@" 53""" 54 55NIX = r"""#!/bin/sh 56# albedo's nix: albedo_nix.py with the kernel's Python, else the next nix on PATH. 57here=$(cd "$(dirname "$0")" && pwd) 58if [ -z "${ALBEDO_PLAIN_NIX:-}" ] && [ -x "${ALBEDO_SHIMS_PYTHON:-}" ]; then 59exec "$ALBEDO_SHIMS_PYTHON" -E -s "$ALBEDO_SHIMS_LIB/albedo_nix.py" "$here" "$@" 60fi 61PATH=$(printf %s "$PATH" | tr : '\n' | grep -vxF "$here" | paste -sd: -) 62exec nix "$@" 63""" 64 65# directory (named for the program a shim needs on PATH) -> (shim, script) 66SHIMS = {"nix" : ("nix" ,NIX ),"mbx" : ("cargo" ,CARGO )} 67# where a program lives when the process that started the daemon had a thin 68# PATH (a GUI or launchd start never ran the user's profile) 69FALLBACKS = {"nix" : ("/nix/var/nix/profiles/default/bin" ,"~/.nix-profile/bin" )} 70_written :set [Path ]= set () 71 72 73def _with_fallbacks (entries :list [str ])-> list [str ]: 74"""`entries`, plus the directory providing each program of FALLBACKS that 75PATH lacks. It goes last, so it never shadows what the user put on PATH, and 76only the first directory that holds the program is added, not a whole profile.""" 77for program ,directories in FALLBACKS .items (): 78if shutil .which (program ,path = os .pathsep .join (entries )): 79continue 80for directory in map (os .path .expanduser ,directories ): 81if os .access (os .path .join (directory ,program ),os .X_OK ): 82entries = [* entries ,directory ] 83break 84return entries 85 86 87def _directory (needs :str )-> Path : 88"""The directory of the shim that needs `needs`, written once per kernel.""" 89home = os .environ .get ("ALBEDO_HOME" )or os .path .expanduser ("~/.albedo" ) 90directory = Path (home ,"shims" ,needs ) 91if directory not in _written : 92name ,script = SHIMS [needs ] 93directory .mkdir (parents = True ,exist_ok = True ) 94shim = directory / name 95if not shim .is_file ()or shim .read_text ()!= script : 96temporary = directory / f". { name } . { os . getpid () } " 97temporary .write_text (script ) 98temporary .chmod (0o755 ) 99temporary .replace (shim ) 100_written .add (directory ) 101return directory 102 103 104def prepend (environment :dict [str ,str ]| None )-> dict [str ,str ]| None : 105"""Return the job environment with only this kernel's shims before real tools. 106Remove inherited shim generations even when their tools are absent.""" 107base = environment or os .environ 108path = base .get ("PATH" ,"" ) 109entries = path .split (os .pathsep ) 110# Remove inherited generations before adding this kernel's shims. 111entries = [ 112entry 113for entry in entries 114if not (Path (entry ).name in SHIMS and Path (entry ).parent .name == "shims" ) 115 ] 116path = os .pathsep .join (_with_fallbacks (entries )) 117shims = [ 118str (_directory (needs )) 119for needs in SHIMS 120if shutil .which (needs ,path = path )is not None 121 ] 122if not shims : 123if environment is None and path == base .get ("PATH" ,"" ): 124return None 125return {** base ,"PATH" :path } 126return { 127** base , 128"PATH" :os .pathsep .join ([* shims ,path ]), 129"ALBEDO_SHIMS_PYTHON" :sys .executable , 130"ALBEDO_SHIMS_LIB" :str (Path (__file__ ).resolve ().parent ), 131 }