Python clang does not search system include paths

2019-05-05 07:12发布

问题:

When using libclang from Python, it doesn't seem to automatically search the system's include paths.

Is there a reliable way to get these paths? I don't like hardcoding paths as I'm writing code that will run on a variety of UNIX systems.

For example, given test.cpp

#include <stdio.h>

int main()
{
  puts("Hello, world!");
}

and test.py

from clang.cindex import Index

tu = Index.create().parse(None, ["test.cpp"])
print(list(tu.diagnostics))

running python test.py will print:

[<Diagnostic severity 4, location <SourceLocation file 'test.cpp', line 1, 
 column 10>, spelling "'stdio.h' file not found">]

Of course, I can find the system include paths by doing

$ clang -v -E test.cpp

and adding "-Isome/path" to the parse argument-list, i.e.

args = ["-I/Applications/[...]", "test.cpp"]

That actually works and produces no errors.

However, this isn't portable, and it would be really nice if I could programmatically get clang to automatically use them.

回答1:

This question has been up for some time, so I'll attempt to answer it myself.

It seems that even Clang itself uses mostly hardcoded paths.

It enumerates candidate paths and adds the ones that fit under the current context. This can be seen in clang/lib/Frontend/InitHeaderSearch.cpp. E.g.,

AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
                           "i686-apple-darwin10", "", "x86_64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
                           "i686-apple-darwin8", "", "", triple);

// ...

For Linux, this code has the notice:

llvm_unreachable("Include management is handled in the driver.");

Under clang/lib/Driver/ we can find more of these paths in files such as ToolChains.cpp, CrossWindowsToolChain.cpp and MinGWToolChain.cpp.

What I was hoping for was that the code in InitHeaderSearch.cpp would be exposed to Python through libclang.