WEYL WEYL
← Back to Weyl Standard
guides

weyl-pkgs — The Debuggable Universe

Every package. Every library. Every time. RelWithDebInfo for the entire dependency closure.

weyl-pkgs — The Debuggable Universe

Every package. Every library. Every time.

RelWithDebInfo for the entire dependency closure.

No more black boxes.

Philosophy

Stock compilers. Stock C++ versions. Stock build systems.

Just the posture:

-O2 # optimize for real
-g3 -gdwarf-5 # symbols everywhere
-fno-omit-frame-pointer # stack traces work
-fno-limit-debug-info # don't truncate
hardeningDisable = [ "all" ] # no theater
dontStrip = true # never strip

Two Worlds

pkgs.ffmpeg # their way
weyl-pkgs.ffmpeg # our way

Both exist. Use whichever you need.

Build System Integration

CMake

CMAKE_BUILD_TYPE=RelWithDebInfo
CMAKE_C_FLAGS_RELWITHDEBINFO=-O2 -g3 -gdwarf-5 -DNDEBUG
CMAKE_CXX_FLAGS_RELWITHDEBINFO=-O2 -g3 -gdwarf-5 -DNDEBUG

Meson

--buildtype=debugoptimized
-Db_ndebug=true
-Ddebug=true
-Doptimization=2

Autotools

NIX_CFLAGS_COMPILE applies to everything.

Usage

In a Flake

{
inputs.weyl-std.url = "github:weyl-ai/weyl-std";
outputs = { self, nixpkgs, weyl-std, ... }: {
perSystem = { system, ... }:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ weyl-std.overlays.default ];
};
# The debuggable universe
weyl-pkgs = import nixpkgs {
inherit system;
overlays = [ weyl-std.overlays.posture ];
};
in {
devShells.default = pkgs.mkShell {
packages = [
# Your code: weyl-stdenv (clang, C++23)
(pkgs.weyl-stdenv.mkDerivation { ... })
# Dependencies: debuggable
weyl-pkgs.ffmpeg
weyl-pkgs.opencv
weyl-pkgs.boost
];
};
};
};
}

Debug a Crash in a Dependency

Terminal window
# Build with weyl-pkgs
nix build .#weyl-pkgs.ffmpeg
# Now gdb works
gdb --args ./result/bin/ffmpeg -i input.mp4 output.mkv
(gdb) bt
#0 av_frame_alloc () at libavutil/frame.c:234
#1 0x00007ffff7a12345 in decode_video () at libavcodec/decode.c:456
...
# Symbols. Line numbers. The works.

Verify the Posture

Terminal window
# Check a package was built with posture
nix eval '.#weyl-pkgs.ffmpeg.passthru.weyl-posture'
# => true
# Check symbols present
nm $(nix build .#weyl-pkgs.ffmpeg --print-out-paths)/lib/libavcodec.so | head
# Check not stripped
file $(nix build .#weyl-pkgs.ffmpeg --print-out-paths)/lib/libavcodec.so
# => ... not stripped

What Changes

AspectStock nixpkgsweyl-pkgs
OptimizationVariesAlways O2
Debug infoUsually noneAlways g3 + DWARF5
Frame pointersUsually omittedAlways kept
HardeningEnabledDisabled
StripUsually yesNever
NDEBUGVariesDefined (asserts off)

What Doesn’t Change

Same packages. Same versions. Just debuggable.

The Fixed Point

Both pkgs and weyl-pkgs are complete nixpkgs instances.

The overlay propagates through every package, every dependency, every transitive closure.

weyl-pkgs.python311Packages.numpy
→ numpy built with posture
→ openblas built with posture
→ gfortran runtime built with posture
→ ...

All the way down.

When to Use

Use pkgs.* when:

Use weyl-pkgs.* when:

pkg-config Generation

Libraries without .pc files get them auto-generated:

Terminal window
ls $(nix build .#weyl-pkgs.somelib --print-out-paths)/lib/pkgconfig/
# => somelib.pc (auto-generated if missing)

Introspection

Terminal window
# View posture info
nix eval .#weyl-pkgs-info --json | jq
{
"version": "1.0.0",
"posture": "RelWithDebInfo",
"optimization": "O2",
"debug": "g3 + DWARF5",
"frame-pointers": "always",
"hardening": "disabled",
"strip": "never"
}