does not work, because the libstdc++ is not located in pkgs.clang16Stdenv.cc.cc.lib, but then where is it?
It is certainly in the GCC package but how do I know which libstdc++ is used in pkgs.clang16Stdenv ??
But how does stdenv.cc.cc.lib relate to the GCC version clang version 16 is using? Isnt this the default stdenv… which might be using some other GCC version then pkgs.clang16Stdenv is using (therefore having another libstdc++)
Clang’s and gcc’s libstdc++'s are different. You have some binary that needs libstdc++.so.6 in runpath to run. You say it’s your binary, but your post does not have enough information how you actually construct the binary.
There is libc++ from LLVM toolchain and there is libstdc++ from gcc. I want do use libstdc++ which is standardt in NixOS. I am building a simple hello world c++ main.cpp -o out which works and links the libstdc++.so.6 but obviously its not in my shell environment, so I need to set LD_LIBRARY_PATH to execute it in the nix-shell. However I dont know how to construct this path.
I came up with the following solution which constructs a clang stdenv, (not sure if everything is correct here)
{
description = "Cpp Playground";
nixConfig = {
substituters = [
# Add here some other mirror if needed.
"https://cache.nixos.org/"
];
extra-substituters = [
# Nix community's cache server
"https://nix-community.cachix.org"
];
extra-trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
inputs = {
# Nixpkgs (take the systems nixpkgs version)
nixpkgs.url = "nixpkgs";
# You can access packages and modules from different nixpkgs revs
# at the same time. Here's an working example:
nixpkgsStable.url = "github:nixos/nixpkgs/nixos-23.11";
# Also see the 'stable-packages' overlay at 'overlays/default.nix'.
};
outputs = {
self,
nixpkgs,
nixpkgsStable,
flake-utils,
...
} @ inputs: let
# Supported systems for your flake packages, shell, etc.
systems = [
"x86_64-linux"
"aarch64-darwin"
];
# This is a function that generates an attribute by calling a function you
# pass to it, with the correct `system` and `pkgs` as arguments.
forAllSystems = func: nixpkgs.lib.genAttrs systems (system: func system nixpkgs.legacyPackages.${system});
in {
# Formatter for your nix files, available through 'nix fmt'
# Other options beside 'alejandra' include 'nixpkgs-fmt'
formatter = forAllSystems (system: pkgs: pkgs.alejandra);
devShells =
forAllSystems
(
system: pkgs: let
# Some Node packages for development.
nodePackages = pkgs.callPackage ./tools/nix/node-packages/default.nix {};
# Toolchain.
gccVersion = "13";
gccPkg = pkgs."gcc${gccVersion}";
llvmVersion = "16";
llvmPkgs = pkgs."llvmPackages_${llvmVersion}";
clangStdEnv = pkgs.stdenvAdapters.overrideCC llvmPkgs.stdenv (llvmPkgs.clang.override {gccForLibs = gccPkg;});
compilerLinks = pkgs.runCommand "clang-links" {} ''
mkdir -p $out/bin
ln -s ${llvmPkgs.clang}/bin/clang $out/bin/clang-${llvmVersion}
ln -s ${llvmPkgs.clang}/bin/clang++ $out/bin/clang++-${llvmVersion}
ln -s ${llvmPkgs.llvm}/bin/llvm-as $out/bin/llvm-as-${llvmVersion}
'';
dependencies = with pkgs; [
# Dependencies
fmt
grpc
protobuf
];
nativeBuildInputs = with pkgs;
[
ninja
cmake
# Toolchain
# Clangd from clang-tools must come first.
(hiPrio clang-tools.override {
llvmPackages = llvmPkgs;
enableLibcxx = false;
})
# Do not use the clangd from this package as it does not work correctly with
# stdlib headers.
llvmPkgs.lld
llvmPkgs.lldb
# Compiler Links
compilerLinks
]
++ dependencies;
in {
default = pkgs.mkShell.override {stdenv = clangStdEnv;} rec {
inherit nativeBuildInputs;
LD_LIBRARY_PATH = nixpkgs.lib.makeLibraryPath [gccPkg.cc.lib];
};
}
);
};
}
Ah strange, whats the difference between the above and nix shell -p nixpkgs#llvmPackages_17.libstdcxxClang, for the flake somehow, libstdc++ does not get found after compiling, but with your thing it works… Is LD_LIBRARY_PATH set?
If you want to use clang like this in mkShell, you have to use libstdcxxClang.
stdenv’s are only really meant for mkDerivations when you override mkShell’s stdenv it overrides the mkDerivation’s stdenv for the mkShell but it does not have much meaning inside the shell itself.