neoidiosyn/stdenv.nix
2024-11-21 13:58:54 +01:00

74 lines
2.5 KiB
Nix

{ lib, pkgs, ... }: { ... }@attrs: let
stdenv' = attrs.stdenv or attrs.baseStdenv;
pkgs' = attrs.pkgs or attrs.buildPackages;
inherit (pkgs') stdenv;
inherit (stdenv) buildPlatform hostPlatform targetPlatform;
inherit (stdenv.cc) isClang nativePrefix targetPrefix;
inherit (stdenv.cc.bintools) isLLVM;
inherit (lib) optionals toList;
inherit (lib) optionalAttrs filterAttrs mapAttrs mapAttrs';
in pkgs.addAttrsToDerivation (prevAttrs: let
ffpContract = prevAttrs.ffpContract or true;
autoVarInit = prevAttrs.autoVarInit or null;
boundsCheck = prevAttrs.boundsCheck or false;
overrideAlloc = prevAttrs.overrideAlloc or true;
env = let
tools = {
CC = if isClang then "clang" else "gcc";
CPP = "cpp";
CXX = if isClang then "clang++" else "g++";
LD = "ld";
AR = "ar";
NM = "nm";
OBJCOPY = "objcopy";
OBJDUMP = "objdump";
READELF = "readelf";
RANLIB = "ranlib";
};
in {
CBUILD = buildPlatform.config;
CHOST = hostPlatform.config;
CTARGET = targetPlatform.config;
} //
mapAttrs (name: value: lib.getExe' stdenv.cc (targetPrefix + value)) tools //
mapAttrs' (name: value: {
name = "HOST${name}";
value = lib.getExe' stdenv.cc (nativePrefix + value);
}) tools;
flags = rec {
NIX_CFLAGS_COMPILE = [ "-pipe" "-fno-semantic-interposition" ]
++ optionals (isClang && ffpContract) [ "-ffp-contract=fast-honor-pragmas" ]
++ optionals isLLVM [ "-flto" ]
++ optionals (autoVarInit != null) [ "-ftrivial-auto-var-init=${autoVarInit}" ]
++ optionals boundsCheck [ "-fsanitize-trap=bounds,object-size,vla-bound" ];
NIX_LDFLAGS = [ "-O2" "--hash-style=gnu" ]
++ optionals isLLVM [ "--icf=safe" "--lto-O2" ]
++ optionals overrideAlloc [ "-lmimalloc" ];
NIX_RUSTFLAGS = [
"-C" "opt-level=2"
"-C" "linker-flavor=ld.lld"
"-C" "lto"
"-C" "linker-plugin-lto"
"-C" "target-cpu=${targetPlatform.gcc.arch}"
] ++ (map (flag: [ "-C" "link-arg=${flag}" ]) NIX_LDFLAGS |> lib.flatten);
GOFLAGS = [ "-ldflags=-linkmode=external" ];
};
in {
buildInputs = optionals overrideAlloc [ pkgs.mimalloc ];
env = prevAttrs.env or { } //
filterAttrs (name: value: !prevAttrs ? env.${name}) env //
(filterAttrs (name: value: prevAttrs ? env.${name}) flags
|> mapAttrs (name: value: toList prevAttrs.env.${name} or [ ] ++ value |> toString));
} //
(filterAttrs (name: value: !prevAttrs ? env.${name}) flags
|> mapAttrs (name: value: toList prevAttrs.${name} or [ ] ++ value))
) stdenv';