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
stdenv.cc: use libc++ as default c++ standard library on darwin #41589
Conversation
@@ -126,9 +126,9 @@ fi | |||
|
|||
if [[ "$isCpp" = 1 ]]; then | |||
if [[ "$cppInclude" = 1 ]]; then | |||
NIX_@infixSalt@_CFLAGS_COMPILE+=" ${NIX_@infixSalt@_CXXSTDLIB_COMPILE-@default_cxx_stdlib_compile@}" | |||
NIX_@infixSalt@_CFLAGS_COMPILE+=" ${NIX_@infixSalt@_CXXSTDLIB_COMPILE:-@default_cxx_stdlib_compile@}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The missing :
might have been a bug: since the variable is declared in add-flags.sh
the default substitution will not come into play with -
, only with :-
.
default_cxx_stdlib_compile = if (targetPlatform.isLinux && !(cc.isGNU or false) && !nativeTools) then | ||
"-isystem $(echo -n ${cc.gcc}/include/c++/*) -isystem $(echo -n ${cc.gcc}/include/c++/*)/$(${cc.gcc}/bin/gcc -dumpmachine)" | ||
else if (targetPlatform.isDarwin && (cc.isClang or true) && !nativeTools && libcxx != null) then | ||
"-isystem ${libcxx}/include/c++/v1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be ${libcxx}/include/c++/*
instead like the gcc one? I'm not sure which is the correct way, especially since if it has multiple versions that would make the oldest version win, assuming the *
works like shell globs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be wrong, but I think this has impact on bootstrapping the darwin stdenv.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally would have preferred passing libcxx
only from all-packages.nix
's clang
. My interest is in having nix-env -iA clang
install a working clang on darwin. I understand that when using clang from within nixpkgs the right flags are threaded through via the hooks and environment variables.
But it didn't seem like nix-env -iA clang
was installing that clang at all, at least builtins.trace
showed that wasn't getting evaluated at all. I'm a bit confused on how nix-env -iA
finds the derivations to install.
else | ||
""; | ||
default_cxx_stdlib_link = optionalString (targetPlatform.isDarwin && (cc.isClang or true) && !nativeTools && libcxx != null) | ||
"-L${libcxx}/lib -stdlib=libc++"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a function to get the library directory of a derivation, I forget what it was though (getLib
maybe), and whether it should be used in this situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's probably safer to use getLib here. libc++ could become multiple outputs in the future.
Wouldn't you want to merge this into |
See #30670 I'd personally prefer to get rid of the |
@@ -360,6 +360,7 @@ in rec { | |||
cc = pkgs.llvmPackages.clang-unwrapped; | |||
bintools = pkgs.darwin.binutils; | |||
libc = pkgs.darwin.Libsystem; | |||
libcxx = pkgs.libcxx; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't pass in libcxx
here then stdenv is unaffected.
I'm trying to get this to work: #30670 (comment) I'd like According to the discussion in #30670 we should have an wrapper for clang being used outside of nixpkgs, then nixpkgs can used the unwrapped one? I thought that was already the case with |
That shouldn't be too hard if it's not being used anywhere else. Just set:
and you should get the "unwrapped" version. We will probably need to refactor things for this to work but I agree with it & I think that that's what most users would expect. Of course it won't pick up your dependencies correctly (NIX_CFLAGS_COMPILE will be broken). |
That would be a really good refactoring project if someone is looking for something to do: remove all references in Nixpkg to clang or gcc directly - packages shouldn't depend on them, instead they should use the corresponding stdenv (there are a few exceptions with libclang however). |
I don't understand. The unwrapped version cannot be used outside of nixpkgs since it doesn't have the c++ standard library, so that wouldn't help? Do you mean nixpkgs should use the unwrapped one everywhere, and then we can make the wrapped one work outside of nixpkgs? I'm confused what the wrapping is for now if it's not to make it work outside of nixpkgs? |
Ok that's true w.r.t. to c++ being missing. The wrapped version is meant to only be run in mkDerivation & nix-shell. There are many hacks that we apply that are pretty specific to Nixpkgs & it's possible that with some work we can get it to work correctly, but I've never used it that way. My understanding is that the "unwrapped" clang should be identical to what you would get in any other package manager but it's possible that the missing libc++ will be an issue. We may need a different wrapper to make it behave like a normal c++ compiler. |
Okay yeah there's other ways to fix this with like a pkg-config wrapper which is what I really want. Let's hold off for a second sorry. |
I tested it a bit more and I'm really confused:
so what is |
Opened a higher level issue to understand whether the expectation of clang working outside of nix-shell and nixpkgs is correct: #42059. |
@Ericson2314 can you elaborate on the According to @orivej in #42059 and @matthewbauer above it should be ok to have two different derivations for clang, one for use in a nix environment and one outside, so I will be looking at doing that, is that related? |
The pkg-config wrapper would use pkg-config where possible to get the Two different clangs is fine, yes. |
I've run into this today too. I was expecting the following to show me the ls -l $($(nix-store -r $(nix-instantiate --expr 'let pkgs = import <nixpkgs> {}; in pkgs.llvmPackages_6.libcxxStdenv.cc.cc') | head -1)/bin/clang++ -print-search-dirs | tail -1 | sed 's/libraries: =//')/include/ctime However, |
The missing clang++ on nix-shell should be addressed on master. Feel free to reopen if this is still relevant. |
Motivation for this change
When installing clang on darwin the default c++ standard library isn't set up as it is for gcc on Linux, so compiling c++ code will fail unless include and link flags for the standard library as specified explicitly, which is counter intuitive as the compiler will add them automatically in a traditional installation unless
-nostdlib
or similar is used.In fact the derivation of gcc does take care of this.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)