Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cc-wrapper: expose a single, consistent libcxx #282221

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkgs/applications/networking/pjsip/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ stdenv.mkDerivation (finalAttrs: {
++ lib.optional stdenv.isLinux alsa-lib
++ lib.optionals stdenv.isDarwin [ AppKit CoreFoundation Security ];

env = lib.optionalAttrs (stdenv.cc.libcxx != null) {
env = lib.optionalAttrs (stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) {
# work around https://github.com/NixOS/nixpkgs/issues/166205
NIX_LDFLAGS = "-l${stdenv.cc.libcxx.cxxabi.libName}";
} // lib.optionalAttrs stdenv.cc.isClang {
Expand Down
55 changes: 32 additions & 23 deletions pkgs/build-support/cc-wrapper/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,26 @@
, includeFortifyHeaders ? null
}:

let libcxx_args = libcxx; in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the sequence of let-expressions one could also add @args after the lambda's formal parameters, and then define libcxx = if args.libcxx != null then args.libcxx else .... Can't say which one is less "wacky". I've seen (and committed) both in nixpkgs

let
stdenv = stdenvNoCC;

useGccForLibs = useCcForLibs
&& libcxx_args == null
&& !stdenv.targetPlatform.isDarwin
&& !(stdenv.targetPlatform.useLLVM or false)
&& !(stdenv.targetPlatform.useAndroidPrebuilt or false)
&& !(stdenv.targetPlatform.isiOS or false)
&& gccForLibs != null;

libcxx =
if libcxx_args != null
then libcxx_args
else if useGccForLibs
then lib.getLib gccForLibs
else null;
Comment on lines +70 to +75
Copy link
Contributor

@SomeoneSerge SomeoneSerge Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libcxx has a connotation with the specific implementation; I think @rrbutani's naming was good: cxxStdlib

in

with lib;

assert nativeTools -> !propagateDoc && nativePrefix != "";
Expand All @@ -64,7 +84,6 @@ assert !(nativeLibc && noLibc);
assert (noLibc || nativeLibc) == (libc == null);

let
stdenv = stdenvNoCC;
inherit (stdenv) hostPlatform targetPlatform;

includeFortifyHeaders' = if includeFortifyHeaders != null
Expand Down Expand Up @@ -100,17 +119,7 @@ let
expand-response-params =
lib.optionalString ((buildPackages.stdenv.hasCC or false) && buildPackages.stdenv.cc != "/dev/null") (import ../expand-response-params { inherit (buildPackages) stdenv; });

useGccForLibs = useCcForLibs
&& libcxx == null
&& !stdenv.targetPlatform.isDarwin
&& !(stdenv.targetPlatform.useLLVM or false)
&& !(stdenv.targetPlatform.useAndroidPrebuilt or false)
&& !(stdenv.targetPlatform.isiOS or false)
&& gccForLibs != null;
gccForLibs_solib = getLib gccForLibs
+ optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}";

# Analogously to cc_solib and gccForLibs_solib
# Analogously to cc_solib
libcxx_solib = "${lib.getLib libcxx}/lib";

# The following two functions, `isGccArchSupported` and
Expand Down Expand Up @@ -394,7 +403,7 @@ stdenv.mkDerivation {

strictDeps = true;
propagatedBuildInputs = [ bintools ] ++ extraTools ++ optionals cc.langD or cc.langJava or false [ zlib ];
depsTargetTargetPropagated = optional (libcxx != null) libcxx ++ extraPackages;
depsTargetTargetPropagated = optional (libcxx_args != null) libcxx_args ++ extraPackages;

setupHooks = [
../setup-hooks/role.bash
Expand Down Expand Up @@ -437,11 +446,11 @@ stdenv.mkDerivation {
##
+ optionalString (useGccForLibs && isClang) ''

echo "-B${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-cflags
echo "-B${libcxx}/lib/gcc/${targetPlatform.config}/${libcxx.version}" >> $out/nix-support/cc-cflags
''
+ optionalString useGccForLibs ''
echo "-L${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-ldflags
echo "-L${gccForLibs_solib}/lib" >> $out/nix-support/cc-ldflags
echo "-L${libcxx}/lib/gcc/${targetPlatform.config}/${libcxx.version}" >> $out/nix-support/cc-ldflags
echo "-L${libcxx_solib}/lib" >> $out/nix-support/cc-ldflags
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be the following, right?

      echo "-L${libcxx_solib}${optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"}/lib" >> $out/nix-support/cc-ldflags

''

# TODO We would like to connect this to `useGccForLibs`, but we cannot yet
Expand Down Expand Up @@ -516,27 +525,27 @@ stdenv.mkDerivation {

# We have a libc++ directly, we have one via "smuggled" GCC, or we have one
# bundled with the C compiler because it is GCC
+ optionalString (libcxx != null || (useGccForLibs && gccForLibs.langCC or false) || (isGNU && cc.langCC or false)) ''
+ optionalString (libcxx_args != null || (useGccForLibs && gccForLibs.langCC or false) || (isGNU && cc.langCC or false)) ''
touch "$out/nix-support/libcxx-cxxflags"
touch "$out/nix-support/libcxx-ldflags"
''
# Adding -isystem flags should be done only for clang; gcc
# already knows how to find its own libstdc++, and adding
# additional -isystem flags will confuse gfortran (see
# https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903)
+ optionalString (libcxx == null && isClang && (useGccForLibs && gccForLibs.langCC or false)) ''
+ optionalString (libcxx_args == null && isClang && (useGccForLibs && gccForLibs.langCC or false)) ''
for dir in ${gccForLibs}${lib.optionalString (hostPlatform != targetPlatform) "/${targetPlatform.config}"}/include/c++/*; do
echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags
done
for dir in ${gccForLibs}${lib.optionalString (hostPlatform != targetPlatform) "/${targetPlatform.config}"}/include/c++/*/${targetPlatform.config}; do
echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags
done
''
+ optionalString (libcxx.isLLVM or false) ''
echo "-isystem ${lib.getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
echo "-isystem ${lib.getDev libcxx.cxxabi}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
+ optionalString (libcxx_args.isLLVM or false) ''
echo "-isystem ${lib.getDev libcxx_args}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
echo "-isystem ${lib.getDev libcxx_args.cxxabi}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags
echo "-l${libcxx.cxxabi.libName}" >> $out/nix-support/libcxx-ldflags
echo "-l${libcxx_args.cxxabi.libName}" >> $out/nix-support/libcxx-ldflags
''

##
Expand Down Expand Up @@ -566,7 +575,7 @@ stdenv.mkDerivation {
'' + ''
echo "$ccLDFlags" >> $out/nix-support/cc-ldflags
echo "$ccCFlags" >> $out/nix-support/cc-cflags
'' + optionalString (targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false)) ''
'' + optionalString (targetPlatform.isDarwin && (libcxx_args != null) && (cc.isClang or false)) ''
echo " -L${libcxx_solib}" >> $out/nix-support/cc-ldflags
''

Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/compilers/crystal/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ let
# See https://github.com/NixOS/nixpkgs/pull/195606#issuecomment-1356491277
substituteInPlace spec/compiler/loader/unix_spec.cr \
--replace 'it "parses file paths"' 'pending "parses file paths"'
'' + lib.optionalString (stdenv.cc.isClang && (stdenv.cc.libcxx != null)) ''
'' + lib.optionalString (stdenv.cc.isClang && (stdenv.cc.libcxx != null) && stdenv.cc.libcxx?cxxabi.libName) ''
# Darwin links against libc++ not libstdc++. Newer versions of clang (12+) require
# libc++abi to be linked explicitly (see https://github.com/NixOS/nixpkgs/issues/166205).
substituteInPlace src/llvm/lib_llvm.cr \
Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/compilers/open-watcom/v2.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ stdenv.mkDerivation rec {
];

# Work around https://github.com/NixOS/nixpkgs/issues/166205
env.NIX_LDFLAGS = lib.optionalString (stdenv.cc.isClang && stdenv.cc.libcxx != null) "-l${stdenv.cc.libcxx.cxxabi.libName}";
env.NIX_LDFLAGS = lib.optionalString (stdenv.cc.isClang && stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) "-l${stdenv.cc.libcxx.cxxabi.libName}";

configurePhase = ''
runHook preConfigure
Expand Down
23 changes: 12 additions & 11 deletions pkgs/development/cuda-modules/backend-stdenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ let
assertCondition = true;
in

/*

# We should use libstdc++ at least as new as nixpkgs' stdenv's one.
assert let
cxxStdlibCuda = cudaStdenv.cc.cxxStdlib.package;
cxxStdlibNixpkgs = stdenv.cc.cxxStdlib.package;
cxxStdlibCuda = (cxxStdlib cudaStdenv).package;
cxxStdlibNixpkgs = (cxxStdlib stdenv).package;

# Expose the C++ standard library we're using. See the comments on "General
# libc++ support". This is also relevant when using older gcc than the
# stdenv's, as may be required e.g. by CUDAToolkit's nvcc.
cxxStdlib = libcxx:
cxxStdlib = stdenv:
let
libcxx = stdenv.cc.libcxx;
givenLibcxx = libcxx != null && (libcxx.isLLVM or false);
givenGccForLibs = libcxx != null && !(libcxx.isLLVM or false) && (libcxx.isGNU or false);
libcxx_solib = "${lib.getLib libcxx}/lib";
Expand All @@ -39,14 +40,14 @@ assert let
else if givenLibcxx then
{ kind = "libc++"; package = libcxx; solib = libcxx_solib;}
else
# We're probably using the `libstdc++` that came with our `gcc`.
# TODO: this is maybe not always correct?
# TODO: what happens when `nativeTools = true`?
{ kind = "libstdc++"; package = cc; solib = cc_solib; }
;
{ kind = "libstdc++"; package = stdenv.cc;
solib = throw ''
# We're probably using the `libstdc++` that came with our `gcc`.
# TODO: this is maybe not always correct?
# TODO: what happens when `nativeTools = true`?
''; };
in
((stdenv.cc.cxxStdlib.kind or null) == "libstdc++")
(((cxxStdlib stdenv).kind or null) == "libstdc++")
-> lib.versionAtLeast cxxStdlibCuda.version cxxStdlibNixpkgs.version;
*/

lib.extendDerivation assertCondition passthruExtra cudaStdenv
2 changes: 1 addition & 1 deletion pkgs/development/cuda-modules/cuda/overrides.nix
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ attrsets.filterAttrs (attr: _: (builtins.hasAttr attr prev)) {
useCcForLibs = true;
gccForLibs = ccForLibs-wrapper.cc;
};
cxxStdlibDir = ccForLibs-wrapper.cxxStdlib.solib or (throw "necessary to fix CI");
cxxStdlibDir = "${lib.getLib ccForLibs-wrapper.libcxx}/lib";
in
{

Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/haskell-modules/generic-builder.nix
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ stdenv.mkDerivation ({
# Ensure libc++abi is linked even when clang is invoked as just `clang` or `cc`.
# Works around https://github.com/NixOS/nixpkgs/issues/166205.
# This can be dropped once a fix has been committed to cc-wrapper.
// lib.optionalAttrs (stdenv.hasCC && stdenv.cc.isClang && stdenv.cc.libcxx != null) {
// lib.optionalAttrs (stdenv.hasCC && stdenv.cc.isClang && stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) {
NIX_LDFLAGS = "-l${stdenv.cc.libcxx.cxxabi.libName}";
}
)
Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/libraries/jemalloc/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ stdenv.mkDerivation rec {
;

env.NIX_CFLAGS_COMPILE = lib.optionalString stdenv.isDarwin "-Wno-error=array-bounds";
env.NIX_LDFLAGS = lib.optionalString (stdenv.cc.libcxx != null) "-l${stdenv.cc.libcxx.cxxabi.libName}";
env.NIX_LDFLAGS = lib.optionalString (stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) "-l${stdenv.cc.libcxx.cxxabi.libName}";

# Tries to link test binaries binaries dynamically and fails
doCheck = !stdenv.hostPlatform.isStatic;
Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/libraries/libserdes/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ stdenv.mkDerivation rec {

postPatch = ''
patchShebangs configure lds-gen.pl
'' + lib.optionalString (stdenv.cc.libcxx != null) ''
'' + lib.optionalString (stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) ''
# fix for https://github.com/NixOS/nixpkgs/issues/166205
# llvm12+ isn't adding libc++abi
substituteInPlace src-cpp/Makefile \
Expand Down
2 changes: 1 addition & 1 deletion pkgs/servers/sql/postgresql/ext/postgis.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ stdenv.mkDerivation rec {
# postgis config directory assumes /include /lib from the same root for json-c library
NIX_LDFLAGS = "-L${lib.getLib json_c}/lib"
# Work around https://github.com/NixOS/nixpkgs/issues/166205.
+ lib.optionalString (stdenv.cc.isClang && stdenv.cc.libcxx != null) " -l${stdenv.cc.libcxx.cxxabi.libName}";
+ lib.optionalString (stdenv.cc.isClang && stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) " -l${stdenv.cc.libcxx.cxxabi.libName}";


preConfigure = ''
Expand Down
2 changes: 1 addition & 1 deletion pkgs/tools/security/hashcat/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ stdenv.mkDerivation rec {
# MACOSX_DEPLOYMENT_TARGET is defined by the enviroment
# Remove hardcoded paths on darwin
substituteInPlace src/Makefile \
'' + lib.optionalString (stdenv.cc.libcxx != null) ''
'' + lib.optionalString (stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) ''
--replace "-lstdc++" "-lc++ -l${stdenv.cc.libcxx.cxxabi.libName}" \
'' + ''
--replace "export MACOSX_DEPLOYMENT_TARGET" "#export MACOSX_DEPLOYMENT_TARGET" \
Expand Down
2 changes: 1 addition & 1 deletion pkgs/tools/typesetting/tectonic/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ rustPlatform.buildRustPackage rec {
++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ ApplicationServices Cocoa Foundation ]);

# workaround for https://github.com/NixOS/nixpkgs/issues/166205
NIX_LDFLAGS = lib.optionalString (stdenv.cc.isClang && stdenv.cc.libcxx != null) " -l${stdenv.cc.libcxx.cxxabi.libName}";
NIX_LDFLAGS = lib.optionalString (stdenv.cc.isClang && stdenv.cc.libcxx != null && stdenv.cc.libcxx?cxxabi.libName) " -l${stdenv.cc.libcxx.cxxabi.libName}";

postInstall = ''
# Makes it possible to automatically use the V2 CLI API
Expand Down
2 changes: 1 addition & 1 deletion pkgs/top-level/all-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11752,7 +11752,7 @@ with pkgs;
boost = boost179;
libclang = llvmPackages_15.libclang;
clang =
if stdenv.cc.libcxx != null
if stdenv.cc.isClang
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stdenv.cc.libcxx.pname should be checked. Not all clang based stdenvs use libcxx which would be the case in the else condition then…

then (overrideLibcxx llvmPackages_15.stdenv).cc
else clang_15;
llvm = llvm_15;
Expand Down