mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-25 08:00:22 +00:00
118 lines
4.5 KiB
Nix
118 lines
4.5 KiB
Nix
# Custom-glibc compiler toolchain shared by the CI environment (ci-env.nix) and
|
|
# the Linux dev shell (devshell.nix): gcc / clang / binutils rebuilt to target
|
|
# the pinned custom glibc. Linux only — the pinned glibc snapshot does not build
|
|
# on darwin, so callers must not evaluate this on macOS.
|
|
{
|
|
pkgs,
|
|
customGlibc,
|
|
}:
|
|
let
|
|
inherit (import ./packages.nix { inherit pkgs; })
|
|
gccPackage
|
|
llvmPackages
|
|
llvmVersion
|
|
mkGcov
|
|
;
|
|
|
|
# binutils wrapped to emit binaries that reference the custom glibc
|
|
# (dynamic linker path, library search path, RPATH).
|
|
customBinutils = pkgs.wrapBintoolsWith {
|
|
bintools = pkgs.binutils-unwrapped;
|
|
libc = customGlibc;
|
|
};
|
|
|
|
# Rebuild gcc (specifically libstdc++ / libgcc_s) against the custom
|
|
# glibc. The override swaps gcc.cc's bootstrap stdenv for one that uses
|
|
# the existing gcc binary but links against the custom glibc, so the
|
|
# resulting compiler ships runtime libraries that only reference symbols
|
|
# available in that glibc.
|
|
customGccCc = gccPackage.cc.override {
|
|
stdenv = pkgs.stdenvAdapters.overrideCC pkgs.stdenv (
|
|
pkgs.wrapCCWith {
|
|
cc = gccPackage.cc;
|
|
libc = customGlibc;
|
|
bintools = customBinutils;
|
|
}
|
|
);
|
|
};
|
|
|
|
# cc-wrapper around the rebuilt compiler, pointing at the custom glibc
|
|
# headers and libraries. This is what we actually expose to users.
|
|
customGcc = pkgs.wrapCCWith {
|
|
cc = customGccCc;
|
|
libc = customGlibc;
|
|
bintools = customBinutils;
|
|
};
|
|
|
|
# gcov matching the rebuilt gcc (linked against the custom glibc), so gcovr
|
|
# can produce coverage reports both in CI and in the dev shell.
|
|
customGcov = mkGcov {
|
|
name = "custom";
|
|
cc = customGccCc;
|
|
};
|
|
|
|
# stdenv built around the rebuilt gcc / custom glibc. Exported as the dev
|
|
# shell's gcc stdenv, and used below to rebuild compiler-rt so its sanitizer
|
|
# runtimes see the custom glibc headers.
|
|
customStdenv = pkgs.stdenvAdapters.overrideCC pkgs.stdenv customGcc;
|
|
|
|
# Rebuild compiler-rt against the custom glibc so the sanitizer runtimes
|
|
# don't use glibc symbols (or sysconf constants like _SC_SIGSTKSZ) that
|
|
# only exist in newer glibc versions. scudo is dropped because its CMake
|
|
# includes CheckAtomic with -nostdinc++ in CMAKE_REQUIRED_FLAGS, which
|
|
# makes std::atomic unfindable in our stdenv; we don't use scudo (only
|
|
# asan/ubsan/tsan etc.).
|
|
customCompilerRt =
|
|
(llvmPackages.compiler-rt.override {
|
|
stdenv = customStdenv;
|
|
}).overrideAttrs
|
|
(old: {
|
|
postPatch = (old.postPatch or "") + ''
|
|
substituteInPlace lib/CMakeLists.txt \
|
|
--replace-quiet 'add_subdirectory(scudo/standalone)' \
|
|
'# scudo/standalone disabled in xrpld ci-env'
|
|
'';
|
|
});
|
|
|
|
# cc-wrapper around clang, pointing at the custom glibc headers and
|
|
# libraries. Reuses the rebuilt gcc for libstdc++ / libgcc_s so that
|
|
# C++ binaries produced by clang also only reference symbols available
|
|
# in the custom glibc. compiler-rt is wired into a resource-root so
|
|
# sanitizer runtimes (libclang_rt.*.a) are found at link time; this
|
|
# mirrors what nixpkgs does internally when building llvmPackages.clang.
|
|
customClang = pkgs.wrapCCWith {
|
|
cc = llvmPackages.clang-unwrapped;
|
|
libc = customGlibc;
|
|
bintools = customBinutils;
|
|
gccForLibs = customGccCc;
|
|
extraPackages = [ customCompilerRt ];
|
|
extraBuildCommands = ''
|
|
rsrc="$out/resource-root"
|
|
mkdir "$rsrc"
|
|
ln -s "${llvmPackages.clang-unwrapped.lib}/lib/clang/${toString llvmVersion}/include" "$rsrc/include"
|
|
ln -s "${customCompilerRt.out}/lib" "$rsrc/lib"
|
|
ln -s "${customCompilerRt.out}/share" "$rsrc/share" || true
|
|
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
|
|
# compiler-rt ships the sanitizer/profile/xray interface headers (e.g.
|
|
# <sanitizer/lsan_interface.h>) in its `dev` output. In a normal Nix
|
|
# build these reach the include path because compiler-rt is propagated
|
|
# via depsTargetTargetPropagated and stdenv's setup hooks add its
|
|
# dev/include. The CI image runs clang outside a Nix stdenv (binaries
|
|
# on PATH, no setup hooks), so that never happens; add the headers
|
|
# explicitly. gcc ships its own copy, which is why this is clang-only.
|
|
echo "-isystem ${customCompilerRt.dev}/include" >> $out/nix-support/cc-cflags
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
inherit
|
|
customGcc
|
|
customClang
|
|
customBinutils
|
|
customStdenv
|
|
customGcov
|
|
;
|
|
|
|
customClangStdenv = pkgs.stdenvAdapters.overrideCC pkgs.stdenv customClang;
|
|
}
|