Files
rippled/nix/devshell.nix

199 lines
6.5 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ pkgs, customGlibc, ... }:
let
inherit (import ./packages.nix { inherit pkgs; })
commonPackages
gccPackage
gccVersion
llvmVersion
llvmPackages
mkVersionedToolLinks
mkGcov
;
# Plain nixpkgs stdenvs — no custom glibc.
plainGccStdenv = pkgs."gcc${toString gccVersion}Stdenv";
plainClangStdenv = llvmPackages.stdenv;
# Each forces something absent on the other platform, so both stay lazy.
linux = import ./linux.nix { inherit pkgs customGlibc; };
darwin = import ./darwin.nix { inherit pkgs; };
# Custom-glibc stdenvs, matching the CI environment. darwin has no custom
# glibc, so there they fall back to the plain nixpkgs stdenvs.
customGccStdenv = if pkgs.stdenv.hostPlatform.isLinux then linux.gccStdenv else plainGccStdenv;
customClangStdenv =
if pkgs.stdenv.hostPlatform.isLinux then linux.clangStdenv else plainClangStdenv;
# gcov matching each gcc shell, so `-Dcoverage=ON` builds work in the shell.
plainGcov = mkGcov {
name = "plain";
cc = gccPackage.cc;
};
customGccGcov = if pkgs.stdenv.hostPlatform.isLinux then linux.gcov else plainGcov;
# commonPackages whose clang tools parse with the custom toolchain's headers.
customCommonPackages = (import ./packages.nix { inherit pkgs customGlibc; }).commonPackages;
# Whole directory: init.sh locates the profiles relative to itself.
conanDir = ../conan;
# Own Conan home, so Nix-built packages never share a cache with a system
# Conan. The stamp holds a content-addressed store path, so init.sh re-runs
# only when something in conan/ changes.
conanHook = ''
export CONAN_HOME=~/.conan2-nix
_xrpl_conan_stamp="$CONAN_HOME/.xrpld-devshell"
if [ "$(cat "$_xrpl_conan_stamp" 2>/dev/null)" != "${conanDir}" ]; then
if ${conanDir}/init.sh; then
printf '%s' "${conanDir}" >"$_xrpl_conan_stamp"
else
echo "⚠️ Conan setup failed - run ./conan/init.sh from the repository root to retry."
fi
fi
unset _xrpl_conan_stamp
'';
# Not sdkEnv: a shell's stdenv already sets that up. Prepended so the stub
# beats the nixpkgs libresolv this shell's tooling drags in.
darwinLibresolvHook = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin (
pkgs.lib.concatLines (
pkgs.lib.mapAttrsToList (
name: value: ''export ${name}="${value} ''${${name}:-}"''
) darwin.libresolvEnv
)
);
# Shown when entering a *-plain shell. These exist only on Linux (see below),
# where the stock toolchain diverges from CI.
plainWarningHook = ''
echo "⚠️ WARNING: this is the stock nixpkgs toolchain and does not match CI's glibc. Prefer 'nix develop .#gcc' / '.#clang' unless you need to skip the custom-glibc build."
'';
# Tools to expose under version-suffixed names (see mkVersionedToolLinks).
gccVersionedTools = [
"gcc"
"g++"
"cpp"
];
clangVersionedTools = [
"clang"
"clang++"
];
# compilerName is the command used to print the version, or null for none.
makeShell =
{
shellName,
stdenv,
compilerName,
version ? null,
versionedTools ? [ ],
extraPackages ? [ ],
# The stock nixpkgs toolchain: warn that it doesn't match CI, keep the
# clang tools off the custom toolchain, and opt out of PatchNixBinary.cmake
# retargeting binaries to the system loader (the plain toolchain links a
# newer glibc, so it must not be patched).
plain ? false,
}:
let
compilerVersionHook =
if compilerName == null then
''echo "No compiler specified - using system compiler"''
else
''
echo "Compiler: "
${compilerName} --version
'';
versionedLinks = pkgs.lib.optional (version != null) (mkVersionedToolLinks {
name = compilerName;
package = stdenv.cc;
inherit version;
tools = versionedTools;
});
in
(pkgs.mkShell.override { inherit stdenv; }) (
{
packages =
(if plain then commonPackages else customCommonPackages) ++ versionedLinks ++ extraPackages;
# Marks a managed dev shell, so the build (XrplSanity.cmake) can tell an
# intentional Nix toolchain from one leaked into a bare shell.
XRPL_DEVSHELL = shellName;
shellHook = ''
echo "Welcome to xrpld development shell";
${compilerVersionHook}
${darwinLibresolvHook}
${conanHook}
${pkgs.lib.optionalString plain plainWarningHook}
'';
}
// pkgs.lib.optionalAttrs plain { XRPLD_NO_PATCH_NIX_BINARY = "1"; }
);
in
rec {
# macOS: Nix Clang. Linux: Nix GCC.
default = if pkgs.stdenv.hostPlatform.isDarwin then clang else gcc;
# gcc/clang use the custom-glibc toolchain, matching CI. On darwin there is no
# custom glibc, so they fall back to the plain nixpkgs toolchain.
gcc = makeShell {
shellName = "gcc";
stdenv = customGccStdenv;
compilerName = "gcc";
version = gccVersion;
versionedTools = gccVersionedTools;
extraPackages = [ customGccGcov ];
};
clang = makeShell {
shellName = "clang";
stdenv = customClangStdenv;
compilerName = "clang";
version = llvmVersion;
versionedTools = clangVersionedTools;
};
# The gcc shell plus the Lean4 formal verification toolchain
formal-verification = makeShell {
shellName = "formal-verification";
stdenv = customGccStdenv;
compilerName = "gcc";
version = gccVersion;
versionedTools = gccVersionedTools;
extraPackages = [
customGccGcov
pkgs.lean4
];
};
# Nix provides no compiler; use the one from your system (e.g. Apple Clang).
no-compiler = makeShell {
shellName = "no-compiler";
stdenv = pkgs.stdenvNoCC;
compilerName = null;
};
apple-clang = no-compiler;
}
# The *-plain shells (stock nixpkgs toolchain) exist only on Linux: on darwin
# gcc/clang are already plain, so these would be redundant and are omitted, which
# makes `nix develop .#gcc-plain` fail there rather than silently aliasing gcc.
// pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
gcc-plain = makeShell {
shellName = "gcc-plain";
stdenv = plainGccStdenv;
compilerName = "gcc";
version = gccVersion;
versionedTools = gccVersionedTools;
extraPackages = [ plainGcov ];
plain = true;
};
clang-plain = makeShell {
shellName = "clang-plain";
stdenv = plainClangStdenv;
compilerName = "clang";
version = llvmVersion;
versionedTools = clangVersionedTools;
plain = true;
};
}