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

Standard library headers not being found properly bear+gcc under Nix #424

Open
varungandhi-src opened this issue Sep 10, 2023 · 4 comments
Labels

Comments

@varungandhi-src
Copy link
Contributor

Reproduction steps (on Linux):

  1. Install Nix
  2. Run the following: (borrowed from the official docs)
git clone https://github.com/NixOS/nix.git && cd nix
git checkout 2cdc9c32e746a620458a1dd87655d2a6c3800f64
nix --extra-experimental-features nix-command --extra-experimental-features flakes develop

./bootstrap.sh
./configure $configureFlags --prefix=$(pwd)/outputs/out

sudo apt-get install bear
bear --force-wrapper -- make -j "$NIX_BUILD_CORES"

jq '[.[] | select(.file | contains("legacy.cc"))]' compile_commands.json > min.json
wget https://github.com/sourcegraph/scip-clang/releases/download/v0.2.7/scip-clang-x86_64-linux
chmod +x scip-clang
scip-clang --compdb-path=min.json --show-compiler-diagnostics
In file included from src/libcmd/legacy.cc:1:
src/libcmd/legacy.hh:4:10: fatal error: 'functional' file not found
#include <functional>
         ^~~~~~~~~~~~
1 error generated.

The above error shouldn't come up.

@varungandhi-src varungandhi-src added the bug Something isn't working label Sep 10, 2023
@varungandhi-src
Copy link
Contributor Author

varungandhi-src commented Sep 10, 2023

The functional header is located under /nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0/functional.

Added the following the the "arguments" array:

      "-isystem",
      "/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0",

New error:

In file included from src/libcmd/legacy.cc:1:
In file included from src/libcmd/legacy.hh:4:
/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0/functional:48:10: fatal error: 'bits/c++config.h' file not found
#include <bits/c++config.h>
         ^~~~~~~~~~~~~~~~~~
1 error generated.

Added the following to the "arguments" array:

      "-isystem",
      "/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0/x86_64-unknown-linux-gnu",

New error:

In file included from src/libcmd/legacy.cc:1:
In file included from src/libcmd/legacy.hh:4:
In file included from /nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0/functional:48:
In file included from /nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0/x86_64-unknown-linux-gnu/bits/c++config.h:586:
/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/include/c++/11.3.0/x86_64-unknown-linux-gnu/bits/os_defines.h:39:10: fatal error: 'features.h' file not found
#include <features.h>
         ^~~~~~~~~~~~
1 error generated.

The features.h header is found under /nix/store/4pqv2mwdn88h7xvsm7a5zplrd8sxzvw0-glibc-2.35-163-dev/include/features.h, so add the following to "arguments" after the previous -isystem flags (the after part is important because cstdlib from C++ has #include_next <stdlib.h>):

      "-isystem",
      "/nix/store/4pqv2mwdn88h7xvsm7a5zplrd8sxzvw0-glibc-2.35-163-dev/include",

This removes all compilation errors.

After that, the index's snapshot output contains:

  typedef std::function<void(int, char * *)> MainFunction;
//        ^^^ reference cxx $ std/
//             ^^^^^^^^ reference cxx $ std/function#
//                                           ^^^^^^^^^^^^ definition cxx $ nix/MainFunction#
//                                           documentation No documentation available.

  struct RegisterLegacyCommand
//       ^^^^^^^^^^^^^^^^^^^^^ definition cxx $ nix/RegisterLegacyCommand#
//       documentation No documentation available.
  {
      typedef std::map<std::string, MainFunction> Commands;
//            ^^^ reference cxx $ std/
//                 ^^^ reference cxx $ std/map#
//                     ^^^ reference cxx $ std/
//                          ^^^^^^ reference cxx $ std/string#
//                                  ^^^^^^^^^^^^ reference cxx $ nix/MainFunction#
//                                                ^^^^^^^^ definition cxx $ nix/RegisterLegacyCommand#Commands#
//                                                documentation No documentation available.

We need to figure out how to programatically determine these flags in the general case.

@varungandhi-src
Copy link
Contributor Author

Full output for gcc -print-search-dirs

install: /nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/
programs: =/nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/lib/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/lib/:/nix/store/mdck89nsfisflwjv6xv8ydj7dj0sj2pn-gcc-11.3.0-lib/lib/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/mdck89nsfisflwjv6xv8ydj7dj0sj2pn-gcc-11.3.0-lib/lib/:/nix/store/dq0xwmsk1g0i2ayg6pb7y87na2knzylh-gcc-wrapper-11.3.0/bin/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/dq0xwmsk1g0i2ayg6pb7y87na2knzylh-gcc-wrapper-11.3.0/bin/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/libexec/gcc/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/libexec/gcc/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/libexec/gcc/x86_64-unknown-linux-gnu/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/bin/
libraries: =/nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/lib/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/lib/:/nix/store/mdck89nsfisflwjv6xv8ydj7dj0sj2pn-gcc-11.3.0-lib/lib/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/mdck89nsfisflwjv6xv8ydj7dj0sj2pn-gcc-11.3.0-lib/lib/:/nix/store/dq0xwmsk1g0i2ayg6pb7y87na2knzylh-gcc-wrapper-11.3.0/bin/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/dq0xwmsk1g0i2ayg6pb7y87na2knzylh-gcc-wrapper-11.3.0/bin/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/lib/x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/lib/../lib64/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../x86_64-unknown-linux-gnu/11.3.0/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../lib64/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/lib/:/nix/store/1gf2flfqnpqbr1b4p4qz2f72y42bs56r-gcc-11.3.0/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../

@varungandhi-src
Copy link
Contributor Author

varungandhi-src commented Sep 10, 2023

One hacky way to do this programmatically, is that if the compiler is gcc/g++, then take the following file:

// scip-clang-magic-00 -- Locate glibc headers
#include <features.h>
// scip-clang-magic-01 -- Locate platform-specific stdlib headers
#include <bits/c++config.h>
// scip-clang-magic-02 -- Locate platform-independent stdlib headers
#include <cstdlib>

And run it through g++ -C -E tmp.cc, and parse the lines following the magic comments. (-C preserves comments)

This avoids having to detect any platform triples or any extra path calculation, as we get the paths from g++ itself.

I can't think of a better way at the moment.

@varungandhi-src
Copy link
Contributor Author

varungandhi-src commented Sep 11, 2023

The problem reproduces on macOS with Clang too. I had to use Bear 3.1.2 installed separately, the Bear 3.0.20 which was part of the Nix environment didn't work.

For Clang + macOS, the following is enough:

// scip-clang-magic-00 -- Locate libSystem headers
#include <aio.h>
// scip-clang-magic-02 -- Locate platform-independent stdlib headers
#include <cstdlib>

features.h is glibc-specific, so perhaps we should avoid that. aio.h is a POSIX header so it works equally well on Linux with glibc.

bits/c++config.h is not used by Clang on macOS (at least, in some situations), so we can skip that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant