Claude Code runs on Node, whose V8 build requires SSE4.2 and POPCNT (x86-64-v2). On an older x86_64 CPU it does not run, so it must not be installed there in the first place. Nix cannot detect the CPU (pure evaluation, hosts often built elsewhere), so add features.cpu.microarchLevel: the psABI level a host declares about itself, defaulting to 2. features.claudeCode.enable derives from it, and home/claude.nix reads that through home-manager's osConfig and installs nothing -- CLI, CLAUDE.md, output style or memory symlink -- when it is off. Hosts without the option (Darwin, the standalone homeConfigurations) keep the tool enabled. An assertion fails evaluation if a host force-enables the flag below the required level, so the mistake surfaces in nix flake check rather than as an illegal-instruction crash on the machine.
78 lines
2.9 KiB
Nix
78 lines
2.9 KiB
Nix
# Feature-flag option declarations shared by every NixOS host (imported via
|
|
# baseModules in flake.nix). Declaring the flags here -- rather than inside the
|
|
# module that implements them -- means a host can read or set a flag without
|
|
# importing the (often large) implementation module. In particular,
|
|
# features.swayDesktop.enable is read by modules/users.nix on every host, but a
|
|
# headless host (e.g. the Pi) must be able to leave it at its default without
|
|
# pulling in modules/sway.nix. The implementation lives in modules/sway.nix,
|
|
# gated on this flag.
|
|
#
|
|
# The file also carries the host capability facts those flags derive from
|
|
# (features.cpu.*). features.claudeCode.enable is such a derived flag: it is
|
|
# computed from the declared CPU level here and read by home/claude.nix through
|
|
# home-manager's osConfig, so a machine that cannot run the tool never installs
|
|
# it, on any host, without per-host opt-outs.
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.features;
|
|
|
|
# Claude Code runs on Node, whose V8 build requires SSE4.2 and POPCNT -- the
|
|
# x86-64-v2 feature set. On an older x86_64 CPU it does not run (illegal
|
|
# instruction), so it must not be installed there.
|
|
claudeCodeMinLevel = 2;
|
|
claudeCodeSupported =
|
|
!pkgs.stdenv.hostPlatform.isx86_64 || cfg.cpu.microarchLevel >= claudeCodeMinLevel;
|
|
in
|
|
{
|
|
options.features = {
|
|
swayDesktop.enable = lib.mkEnableOption "the Sway desktop";
|
|
|
|
cpu.microarchLevel = lib.mkOption {
|
|
type = lib.types.ints.between 1 4;
|
|
default = 2;
|
|
example = 1;
|
|
description = ''
|
|
The x86-64 psABI microarchitecture level the host CPU implements:
|
|
1 = the original baseline, 2 = SSE4.2/POPCNT (Nehalem, 2008+),
|
|
3 = AVX2, 4 = AVX-512.
|
|
|
|
Nix cannot detect this (evaluation is pure and hosts are often built
|
|
elsewhere), so a machine older than the default declares its own level
|
|
and the flags below derive from it. Ignored on non-x86_64 hosts.
|
|
'';
|
|
};
|
|
|
|
claudeCode.enable = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = claudeCodeSupported;
|
|
defaultText = lib.literalMD ''
|
|
`true`, unless the host declares an x86-64 microarchitecture level
|
|
below ${toString claudeCodeMinLevel}
|
|
'';
|
|
description = ''
|
|
Whether to install Claude Code in this host's home-manager profiles
|
|
(implemented in home/claude.nix). Defaults off on CPUs below
|
|
x86-64-v${toString claudeCodeMinLevel}, which cannot run it; forcing it
|
|
on such a host is an evaluation error.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config.assertions = [
|
|
{
|
|
assertion = cfg.claudeCode.enable -> claudeCodeSupported;
|
|
message = ''
|
|
features.claudeCode.enable is on, but this host declares
|
|
features.cpu.microarchLevel = ${toString cfg.cpu.microarchLevel}.
|
|
Claude Code needs x86-64-v${toString claudeCodeMinLevel}
|
|
(SSE4.2/POPCNT) and will not run on an older CPU.
|
|
'';
|
|
}
|
|
];
|
|
}
|