WEYL WEYL
← Back to Weyl Standard
guides

Standard Environments

The weyl-stdenv family provides opinionated build environments for serious systems work.

Standard Environments

The weyl-stdenv family provides opinionated build environments for serious systems work.

Philosophy

A stdenv defines how the world builds itself.

The flags are the building code:

-O2 real performance
-g3 -gdwarf-5 full symbols
-fno-omit-frame-pointer stack traces work
-fno-stack-protector no theater
-fcf-protection=none predictable addresses
hardeningDisable = [ "all" ] nix wrapper killed
dontStrip = true symbols stay

Available Stdenvs

StdenvDescription
weyl-stdenvglibc dynamic, clang, C++23
weyl-stdenv-staticglibc static
weyl-stdenv-muslmusl + libstdc++
weyl-stdenv-musl-staticfully static, deploy anywhere
weyl-stdenv-cudaCUDA device + host

Usage

# Basic derivation
pkgs.weyl-stdenv.mkDerivation {
name = "my-app";
src = ./.;
buildPhase = "$CXX -o app main.cpp";
}
# Static binary (glibc)
pkgs.weyl-stdenv-static.mkDerivation {
name = "my-tool";
src = ./.;
}
# Fully portable (musl static)
pkgs.weyl-stdenv-musl-static.mkDerivation {
name = "deploy-anywhere";
src = ./.;
}
# CUDA kernel
pkgs.weyl-stdenv-cuda.mkDerivation {
name = "cuda-kernel";
src = ./.;
buildPhase = "$CXX -o kernel main.cu";
# CUDA_HOME and CUDA_PATH are set
}

Cross-Compilation

Build on x86_64 workstation, deploy to ARM:

# Grace Hopper (aarch64 + sm_90a)
pkgs.weyl-cross.grace.mkDerivation {
name = "grace-app";
src = ./.;
}
# Jetson Orin (aarch64 + sm_87)
pkgs.weyl-cross.jetson.mkDerivation {
name = "jetson-app";
src = ./.;
}
# Generic aarch64 (no GPU)
pkgs.weyl-cross.aarch64.mkDerivation {
name = "arm-app";
src = ./.;
}

From aarch64, target x86_64:

pkgs.weyl-cross.x86-64.mkDerivation {
name = "blackwell-app";
src = ./.;
}

Cross Targets

TargetArchGPU
weyl-cross.graceaarch64sm_90a (Hopper)
weyl-cross.jetsonaarch64sm_87 (Orin)
weyl-cross.aarch64aarch64none
weyl-cross.x86-64x86_64sm_120 (Blackwell)

The Flags Explained

Optimization

-O2 Real performance, not debug toy

Debug Information

-g3 Maximum info (includes macros)
-gdwarf-5 Modern format, best tooling
-fno-limit-debug-info Don't truncate for speed
-fstandalone-debug Full info for system headers

Frame Pointers

-fno-omit-frame-pointer Keep RBP/X29
-mno-omit-leaf-frame-pointer Even in leaf functions

No Hardening

-U_FORTIFY_SOURCE Remove buffer "protection"
-D_FORTIFY_SOURCE=0 Really remove it
-fno-stack-protector No canaries
-fno-stack-clash-protection No stack clash mitigation
-fcf-protection=none No CET (x86_64 only)

Nix Attributes

dontStrip = true; # Symbols stay
separateDebugInfo = false; # Debug info in binary
hardeningDisable = [ "all" ]; # Kill nix wrapper hardening

Verification

Check Symbols Present

Terminal window
nm ./app | grep -E "^[0-9a-f]+ T"

Check Debug Info

Terminal window
readelf --debug-dump=info ./app | head

Check Not Stripped

Terminal window
file ./app | grep "not stripped"

Check Static

Terminal window
file ./app | grep "statically linked"
ldd ./app # Should fail

GDB Works

Terminal window
gdb -ex "break main" -ex "run" -ex "bt" -ex "quit" ./app

Introspection

Terminal window
# View configuration
nix eval .#weyl-stdenv-info --json | jq
# Check stdenv passthru
nix eval .#weyl-stdenv.passthru.weyl --json

Architecture

weyl-stdenv-overlay
├── platform detection
│ ├── x86_64-linux
│ └── aarch64-linux
├── gcc paths (auto-detected)
│ ├── include
│ ├── include-arch
│ └── lib
├── flags
│ ├── opt-flags (-O2)
│ ├── debug-flags (-g3 -gdwarf-5 ...)
│ ├── frame-flags (-fno-omit-frame-pointer ...)
│ └── no-harden-flags
├── clang wrappers
│ ├── clang-glibc (clang + gcc14 libstdc++)
│ └── clang-musl (clang + musl + libstdc++)
├── native stdenvs
│ ├── weyl-stdenv
│ ├── weyl-stdenv-static
│ ├── weyl-stdenv-musl
│ ├── weyl-stdenv-musl-static
│ └── weyl-stdenv-cuda
└── cross stdenvs
├── weyl-cross.grace
├── weyl-cross.jetson
├── weyl-cross.aarch64
└── weyl-cross.x86-64