bare-metal-bringup
Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot,…
Use when packaging EDA or hardware toolchains in Nix (Yosys, OpenROAD, simulators, vendor tools) and hitting dlopen/plugin/runtime-path failures, or writing derivations and build phases for hardware tooling on aarch64-linux
Claude Code
$ npx -y skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging --agent claude-code
Codex
$ npx skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging -a codex -y
Cursor
$ npx skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging -a cursor -y
Gemini CLI
$ npx skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging -a gemini-cli -y
GitHub Copilot
$ npx skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging -a github-copilot -y
OpenCode
$ npx skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging -a opencode -y
Windsurf
$ npx skills add lilithsemi/claude-for-hardware --skill nix-eda-packaging -a windsurf -y
name: nix-eda-packaging description: Use when packaging EDA or hardware toolchains in Nix (Yosys, OpenROAD, simulators, vendor tools) and hitting dlopen/plugin/runtime-path failures, or writing derivations and build phases for hardware tooling on aarch64-linux
EDA tools are awkward Nix citizens: they dlopen plugins at runtime, expect data files at fixed paths, and ship as prebuilt binaries with bad assumptions about the filesystem. The temptation is to paper over each failure with a wrapper or a binary patch. The discipline is to fix the actual dependency so the package is honest about what it needs.
**Core principle:** Make the package's real dependencies explicit, don't disguise them. A `wrapProgram` that injects a path or a `patchelf` that rewrites an interpreter hides a missing dependency instead of declaring it, and it breaks the next person who builds on your package.
These are the moves to avoid, and what they're hiding:
When a dlopen fails, find what the tool actually dlopens and at what path, then provide that path the way the tool expects (a real search path, a data dir, an env the program documents) rather than wrapping the binary.
When you need a custom build or install phase, write the phase as a build-phase string. Do not try to pass derivation outputs like `$out` through command-line-builder helpers (the `toCommandLineShellGNU`-style functions); `$out` is a shell variable that only exists at build time inside the phase, and threading it through a Nix-level argument builder produces the wrong thing.
# Right: $out is referenced inside the phase string, where it exists. buildPhase = '' make PREFIX=$out -j$NIX_BUILD_CORES ''; # Wrong: trying to bake $out into a CLI arg list at Nix eval time. # $out is not defined then; the helper sees a literal or empty value.
| Smell | Do instead | |-------|------------| | `wrapProgram --set LD_LIBRARY_PATH` to fix dlopen | Declare the dep; put the lib on rpath or the documented search path | | Hand `patchelf` to fix a from-source build | Fix the link / buildInputs | | `autoPatchelfHook` to solve a `dlopen` | Provide the runtime search path the tool expects | | Threading `$out` through a CLI-arg helper | Reference `$out` inside the buildPhase string | | Assuming x86_64 on the dev box | It's aarch64-linux |
Claude Code skills for hardware design, validation, and bring-up. A plugin of focused skills that teach Claude how to do real hardware work: designing reusable HDL, integrating an SoC, bringing up FPGAs and bare-metal targets, building firmware boot chains,
Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot,…
Use when building or debugging a compiler backend, codegen, or assembler and you need to prove the generated machine code is…
Use when verifying a hardware DUT (a CPU core, FPGA, or netlist) against a golden reference model, building coverage-guided…
Use when building or debugging a firmware and boot chain (RISC-V SBI, UEFI, ACPI, a bootloader handoff like Limine to an OS) or…
Use when loading a bitstream onto a physical FPGA and driving or observing it over JTAG or GPIO, especially bit-banged JTAG from…
Use when synthesizing RTL to an FPGA with yosys/nextpnr (ECP5/Lattice and similar), fighting area or routing congestion,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.