Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rrbutani/74efd7c99ae5f1b9a6737095aed73468 to your computer and use it in GitHub Desktop.
Save rrbutani/74efd7c99ae5f1b9a6737095aed73468 to your computer and use it in GitHub Desktop.
{
inputs = {
nixpkgs-working.url = github:NixOS/nixpkgs/2ebb6c1e5ae402ba35cca5eec58385e5f1adea04;
nixpkgs-broken.url = github:NixOS/nixpkgs/nixos-unstable; # d917136f550a8c36efb1724390c7245105f79023 as of this writing
nixpkgs-test.url = github:NixOS/nixpkgs/2fe19fe24a225c33c4011ee9dbc0b4310b798134;
};
outputs = { self, nixpkgs-working, nixpkgs-broken, nixpkgs-test }: let
old = nixpkgs-working.legacyPackages.x86_64-linux;
new = nixpkgs-broken.legacyPackages.x86_64-linux;
test = nixpkgs-test.legacyPackages.x86_64-linux;
shell = { pkgs, stdenv ? p: p.stdenv }:
(pkgs.mkShell.override { stdenv = stdenv pkgs; }) {
buildInputs = [ pkgs.which ];
shellHook = ''
set -e
exec 2>&1
echo "building C++ code with $CXX ($(which $CXX)):"
$CXX -xc++ - <<<"#include <cstdlib>" -E >/dev/null && echo okay
echo
echo "building C++ code with $CC ($(which $CC)):"
NIX_DEBUG=6 $CC -v -xc++ - <<<"#include <cstdlib>" -E >/dev/null && echo okay
echo
echo "---------------------------------------------------------------"
# See: https://github.com/NixOS/nixpkgs/issues/151879
#
# Note the `-c`!
NIX_DEBUG=6 $CXX -xc++ - -v -o /tmp/foo <<EOF
#include <cstdlib>
int main() {
std::abort();
return 0;
}
EOF
# exit 0
'';
};
in {
devShells.x86_64-linux = {
# `broken` is missing the `libstdc++` header include dirs:
#
# We're using `llvmPackages_13` here but this is reproducible with `14`
# too.
working = shell { pkgs = old; stdenv = p: p.llvmPackages_13.stdenv; };
broken = shell { pkgs = new; stdenv = p: p.llvmPackages_13.stdenv; };
working-libcxx = shell { pkgs = old; stdenv = p: p.llvmPackages_13.libcxxStdenv; };
broken-libcxx = shell { pkgs = new; stdenv = p: p.llvmPackages_13.libcxxStdenv; };
# Diffing the command line invocations printed out with `-v` reveals that
# `broken` is missing:
# ```
# -internal-isystem /nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0/lib64/gcc/x86_64-unknown-linux-gnu/10.3.0/../../../../include/c++/10.3.0
# -internal-isystem /nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0/lib64/gcc/x86_64-unknown-linux-gnu/10.3.0/../../../../include/c++/10.3.0/x86_64-unknown-linux-gnu
# -internal-isystem /nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0/lib64/gcc/x86_64-unknown-linux-gnu/10.3.0/../../../../include/c++/10.3.0/backward
# ```
# GCC does not have this issue; both `old` and `new` produce a
# `cc-wrapper` that has the `libstdc++` header include dirs:
gccOld = shell { pkgs = old; };
gccNew = shell { pkgs = new; };
# A little digging (a.k.a. running with `NIX_DEBUG=6`, diffing like
# `diff -y <(nix develop .#working) <(nix develop .#broken)`) reveals a
# discrepancy is some of the extra flags `cc-wrapper` appends to the
# invocation:
#
# for `working`:
# ```console
# -B/nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0/lib/gcc/x86_64-unknown-linux-gnu/10.3.0
# --gcc-toolchain=/nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0
# -B/nix/store/spmzni7pj4ldsp2q0pggcs9mbf68xg7r-clang-13.0.0-lib/lib
# -resource-dir=/nix/store/q52j3nyvc8947za806109xrxaz4dqdzf-clang-wrapper-13.0.0/resource-root
# -B/nix/store/65hafbsx91127farbmyyv4r5ifgjdg43-glibc-2.33-117/lib/
# /nix/store/msy4nj4gscw9csc82labx0xvh7vqlfif-glibc-2.33-117-dev/include
# -B/nix/store/q52j3nyvc8947za806109xrxaz4dqdzf-clang-wrapper-13.0.0/bin/
# ```
#
# for `broken`:
# ```console
# -B/nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/
# /nix/store/nasgvbblxi25r6y1s82il4m0m4ghib68-glibc-2.35-224-dev/include
# -B/nix/store/v1nxrwb4ls09sbbrwlkgxs7dlw8paksh-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0
# --gcc-toolchain=/nix/store/v1nxrwb4ls09sbbrwlkgxs7dlw8paksh-gcc-11.3.0
# -B/nix/store/zr0ks8jbnvpdly0z9x7mnrlf1y3kcda3-clang-13.0.1-lib/lib
# -resource-dir=/nix/store/5rgl4salg4jckzkd0672bqa7sf87q2db-clang-wrapper-13.0.1/resource-root
# -B/nix/store/5rgl4salg4jckzkd0672bqa7sf87q2db-clang-wrapper-13.0.1/bin/
# ```
# reordered:
# `working`:
# ```
# -B/nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0/lib/gcc/x86_64-unknown-linux-gnu/10.3.0
# --gcc-toolchain=/nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0
# -B/nix/store/spmzni7pj4ldsp2q0pggcs9mbf68xg7r-clang-13.0.0-lib/lib
# -resource-dir=/nix/store/q52j3nyvc8947za806109xrxaz4dqdzf-clang-wrapper-13.0.0/resource-root
# -B/nix/store/65hafbsx91127farbmyyv4r5ifgjdg43-glibc-2.33-117/lib/
# /nix/store/msy4nj4gscw9csc82labx0xvh7vqlfif-glibc-2.33-117-dev/include
# -B/nix/store/q52j3nyvc8947za806109xrxaz4dqdzf-clang-wrapper-13.0.0/bin/
# ```
# `broken`:
# ```
# -B/nix/store/v1nxrwb4ls09sbbrwlkgxs7dlw8paksh-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0
# --gcc-toolchain=/nix/store/v1nxrwb4ls09sbbrwlkgxs7dlw8paksh-gcc-11.3.0
# -B/nix/store/zr0ks8jbnvpdly0z9x7mnrlf1y3kcda3-clang-13.0.1-lib/lib
# -resource-dir=/nix/store/5rgl4salg4jckzkd0672bqa7sf87q2db-clang-wrapper-13.0.1/resource-root
# -B/nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/
# /nix/store/nasgvbblxi25r6y1s82il4m0m4ghib68-glibc-2.35-224-dev/include
# -B/nix/store/5rgl4salg4jckzkd0672bqa7sf87q2db-clang-wrapper-13.0.1/bin/
# ```
# These appear to be the same set of flags...
#
# So, maybe it's the compiler? (i.e. maybe something about how we patch
# `clang` in newer nixpkgs..)
#
# To test, we'll use the new stdenv and cc-wrapper (i.e. new flags) but
# with the old compiler:
testNewWrapperOldCompiler = shell {
pkgs = new;
stdenv = new: new.overrideCC new.llvmPackages_13.stdenv (new.llvmPackages_13.stdenv.cc.override {
cc = old.llvmPackages_13.stdenv.cc.cc;
});
};
# And indeed, this passes.
# To confirm that it *is* about the compiler and has nothing to do with
# the compiler flags, let's try the old stdenv + cc-wrapper (i.e. the old
# flags) but with the new compiler.
#
# We expect this to *fail*.
testOldWrapperNewCompiler = shell {
pkgs = old;
stdenv = old: old.overrideCC old.llvmPackages_13.stdenv (old.llvmPackages_13.stdenv.cc.override {
cc = new.llvmPackages_13.stdenv.cc.cc;
});
};
# And so it does.
# This tells us that we're looking for changes in `llvmPackages_13.clang`.
#
# Our known good commit (2ebb6c1e5ae402ba35cca5eec58385e5f1adea04) comes
# from the `nixos-21.11` branch, circa March 2022 which means the culprit
# we're looking for came after then *or* was a change that wasn't
# backported to `nixos-21.11`.
#
# Comparing:
# https://github.com/NixOS/nixpkgs/commits/2ebb6c1e5ae402ba35cca5eec58385e5f1adea04/pkgs/development/compilers/llvm/13/clang
# with:
# https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/compilers/llvm/13/clang
# gives us several likely candidates to test.
#
# At a glance https://github.com/NixOS/nixpkgs/commit/2fe19fe24a225c33c4011ee9dbc0b4310b798134
# looks like a likely cuplrit (https://github.com/NixOS/nixpkgs/issues/151879
# https://github.com/NixOS/nixpkgs/pull/153963) and indeed: if you run the
# below it indeed fails (but commits *before* this one pass)
#
# Be warned that the below will build clang and friends from source;
# cache.nixos.org no longer has these packages.
test = shell { pkgs = test; stdenv = p: p.llvmPackages_13.stdenv; };
# LLVM 15 does not have this patch and so this passes:
testLLVM15 = shell { pkgs = new; stdenv = p: p.llvmPackages_15.stdenv; };
# Note that this fails though, as the issue linked above (#151879)
# predicts:
testLLVM15libcxx = shell { pkgs = new; stdenv = p: p.llvmPackages_15.libcxxStdenv; };
# See here for more: https://github.com/NixOS/nixpkgs/issues/191152#issuecomment-1429029003
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment