-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
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
building package with bazel and clang fails due to C++ headers not found #150655
Comments
Note, this effects bazel-watcher on Darwin (which is currently marked as broken). I did have a deeper look into this... Bazel tries to find the C++ compiler and uses the one called "gcc" by default (see https://github.com/bazelbuild/bazel/blob/df2f77c2a8602d1b729b6802ba2bfcac3dc54402/tools/cpp/unix_cc_configure.bzl#L297-L326). But, the bazel package in nixpkgs substitutes "gcc" with "clang" (see nixpkgs/pkgs/development/tools/build-managers/bazel/bazel_3/default.nix Lines 388 to 390 in 2c2a096
In a stdenv on Darwin, "clang" is provided by XcodeDefault.xctoolchain which has Each wrapper script determines if C++ should be "activated" by checking whether it was called with a
Later, the C++ include path is added to the compiler's arguments, but only if in C++ mode:
Without the include path, any attempt to compile C++ sources using any of the standard C++ headers fail. Trying to use Bottom line: Bazel assumes a generic compiler tool, which it expects to select the language automatically depending on the file's extension, but the tooling in nixpkgs only provides distinct scripts for C / C++ which need to be called accordingly. |
I could get bazel-watcher to build on darwin using this wrapper script as #! ${stdenv.shell}
function isCxx() {
if [ $# -eq 0 ]; then false
elif [ "$1" == '-xc++' ]; then true
elif [[ -f "$1" && "$1" =~ [.](hh|H|hp|hxx|hpp|HPP|h[+]{2}|tcc|cc|cp|cxx|cpp|CPP|c[+]{2}|C)$ ]]; then true
else isCxx "''${@:2}"; fi
}
if isCxx "$@"; then
exec "${stdenv.cc}/bin/c++" "$@"
else
exec "${stdenv.cc}/bin/cc" "$@"
fi Hey @NixOS/bazel 😄 any thoughts on how we can fix this? |
I tested with Xcode, the wrappers installed by it switch both based on the binary that is called and the extension of the file, so it makes sense for us to provide compatible wrappers with the |
I noticed the toolchain in |
@NixOS/darwin-maintainers does anyone have any context or opinions on which of the three options we should go for? They all affect more than just bazel, and that makes sense, since the issue we're hitting with bazel here is that bazel is assuming that if you're using gcc or clang on darwin it's going to be the ones from Xcode, an assumption that a lot of other tools and upstream build definitions are likely to make.
|
My preference is |
I just realized that I had this this problem with tensorflow in #145149. |
Good call out! So it's possible other derivations have added their own darwin workarounds for this issue and we could remove them if we have a more compatible wrapper. |
I have another good one. In python there was also a missing C++ compiler support in distutils: nixpkgs/pkgs/development/interpreters/python/cpython/default.nix Lines 244 to 258 in c478eaf
The distutils was already deprecated at that time, so the patch was never accepted upstream. We ended up putting a lot of effort into maintaining it, as numpy/cpython were relying on this. This, however, will resolve by itself with Python 3.10, where distutils is apparently removed. |
@avdv Just a quick note on this:
CC is supposed to be used for the C compiler, while CXX is for C++, so that may be the reason you're having issues using clang++ in that regard. You probably would have better luck with this: export CC=clang
export CXX=clang++ |
@Steven0351 every other build tool: yes, but Bazel does not care about def find_cc(repository_ctx, overriden_tools):
cc = _find_generic(repository_ctx, "gcc", "CC", overriden_tools) def _find_generic(repository_ctx, name, env_name, overriden_tools, warn = False, silent = False):
"""Find a generic C++ toolchain tool. Doesn't %-escape the result.""" (shouldn't |
🤦♂️ Apologies, between reading the title and not reading your original post carefully, i thought you were saying you couldn't build the nix package bazel (e.g. pkgs.bazel), not building a package with bazel
Yes, yes it should. I should probably refrain from attempting to be helpful at late at night 🥱 |
Yes, that was a bit misleading, I changed the title to make this clearer.
No problem, thanks for trying 🙂 |
This seems most pragmatic and expedient (perhaps with a guard for being on darwin). Provide a pointer back to this issue so option 2 or 3 can be implemented later if/when necessary. |
I've ran into this issue and found following workaround for passing C++ headers to Bazel builds: I've added
You can achieve similar result without
before running bazel, or like this:
to add it to |
Hi @YorikSar thank you for sharing this workaround! I was thinking about a way how we can leverage this as a device to fix this issue, but IMO the problem should not be fixed in the bazel layer, because introducing a breaking change in a bazel wrapper (say) when fiddling with +1 for option 1 of the choices #150655 (comment) |
Since other build tools know about this distinction it feels like a Bazel issue. If it won't be tackled upstream maybe we can create a new clang wrapper that branches on the file extension and calls the appropriate wrapper script, then just use that for Bazel? |
Hit by the same issue when trying to package workerd on linux, indeed we need a bazel specific cc-wrapper or file an upstream issue. |
In #256360 the reporter says
So if a |
So the con isn't actually valid then? Does Linux still not have the binary name distinction logic? |
So it's a difference between NixOS and non-NixOS, not a difference between macOS and linux. We should fix it by making clang in nixpkgs match the behaviour of other distros. |
+1 I've evaluated the issue with the compiler in #216047 which is pretty much a duplicate of this issue here. Indeed, the main reason is that |
Is there someone from lib.teams.llvm.members that we can ask to help getting this implemented ? |
I'm looking into this. There's nothing wrong with Clang. It still detects the files are C++ and behaves accordingly. The problem is it has no idea where to find the C++ stdlib. |
Please submit a PR for review |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
Do you have a pointer to your patch in progress to play with @toonn ? I've seen in the aforementioned discourse discussion that you had some issues with binutils. Maybe more eyes can help ? It would be wonderful if |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/how-to-search-nixpkgs-by-e-g-buildinputs/34507/1 |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
For easy testing, here is a one-liner to reproduce the issue at hand:
It will complain about not finding the c++ header. @toonn were you able to make progress ? |
For everyone running into this: Until this is available in the NixOS clang configuration, I've worked around this in my project by adding the So roughly a line like this in the
(relevant PR chipsalliance/verible#2104) |
Unfortunately, this only works if you are using the compiler directly. If you are passing the compiler binary name, apparently it does not work. To explain a bit, kythe is a code indexer that uses the Would be nice to remove this lever permanently and allow C++ compilations to pass even if invoked as IIRC someone had a patch that simply adds the C++ include paths to the default system paths of |
Updating minimal example in comment above - this is still an issue with clang-17
|
A workaround I’ve found is including the llvm toolchain in bazel directly. The downside of this is: 1) not nix managed 2) it adds a good 90 seconds to the initial analysis from a cold bazel server. |
Sadly the whole point of this exercise is to have it managed by
Ow, that seems like a lot. Are you sure you always pay this, vs only when the toolchain needs to be downloaded? |
Spent 1 hour debugging this on NixOS only to remember this issue from 6 months ago. My relevant comment:
Still works... |
I've been using https://github.com/hedronvision/bazel-compile-commands-extractor to try and generate For now I've been manually replacing clang -> clang++ in the compile commands to get the correct stdlib linked in. |
Yes indeed, I noticed as well: with clang stdenv, any tools from the clang family that need the compilation-DB ( I am wondering if there is just a configuration missing or was added in the build of the clang toolchain on nix ? Something is preventing the clang driver to recognize c++ files like it does in any other Linux distribution. |
@hzeller reading the previous comments does look to be the Nix wrappper; unfortunately that's a mess of bash I haven't gotten into to. I'd like to see this fixed. For now I might have to resort to #150655 (comment) as well since I have code that is C unable to build with a forced C++ so my global replace won't work anymore. |
[...] if I add
pkgs.bazel
to my shell.nix and try to build my project, I get errors loading headers, e.g.I can resolve this by adding both clang and gcc to my shell.nix. Not one or the other, but both. Which feels very odd.
And unfortunately for me, having both gcc and clang present breaks other things (building ruby native extensions).
Originally posted by @andrewhamon in #105573 (comment)
The text was updated successfully, but these errors were encountered: