I’m using libclang
to parse some C++ code. It seems that libclang
has no default include path so I need to provide them. Is there a way to locate the C/C++ stdlib include paths for current nix-shell
and, say, export them as an environment variable?
The source code is a mess and I cannot easily generate a compile_commands.json
so the method listed at Get clangd to find standard headers in nix-shell - #12 by danielbarter probably won’t work.
Yes, if you look in ${clang}/nix-support
, there are text files that contain all the system compilation flags that are used by the wrapper. What you need should be in there
1 Like
you can probably use bear to generate such a file.
Bear does not work particularly well with nix because it struggles to distinguish the compiler wrappers from the compilers themselves (at least last time I tried using it). The project @yipengsun links to is a simple bear like program that works with nix, but rather than listening to system calls, it instruments the compiler wrappers.
Thank you! I think libc-cflags
and libcxx-cxxflags
are probably what I’m looking for.
For the record, here’s what I’m doing to find C/C++ standard headers:
import subprocess
from glob import glob
from pathlib import Path
import chardet
def decodeStdout(proc):
stdout, _ = proc.communicate()
enc = chardet.detect(stdout)
return stdout.decode(enc["encoding"])
def findCCppStdHeadersNix():
# find clang
process = subprocess.Popen(
["which", "clang"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
clangPath = Path(decodeStdout(process).strip())
clangFlagsPath = clangPath.parent.parent / "nix-support"
with open(clangFlagsPath / "libcxx-cxxflags") as f:
flag = f.read().strip()
cppHeader = flag.split(" ")[1]
with open(clangFlagsPath / "libc-cflags") as f:
flag = f.read().strip()
cHeader = flag.split(" ")[1]
# need bits/c++config.h
bitsCppConfig = glob(f"{cppHeader}/**/bits/c++config.h", recursive=True)[0]
bitsCppConfig = Path(bitsCppConfig).parent.parent
# need stddef.h, a compiler-specific header
process = subprocess.Popen(
["gcc", "--print-file-name=include"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
stddefHeader = decodeStdout(process).strip()
return [
cppHeader,
cHeader,
stddefHeader,
str(bitsCppConfig)
]