argv[0] in libclang

Hi,

currently all libclang APIs that get passed a command line expect that
there is no argv[0] in the list, i. e. no binary name at the beginning
of the command line. We later fake one
(clang::createInvocationFromCommandLine) as the invocation gets passed
down into the proper clang machinery.

This is nasty because it changes the behavior if the original clang
invocation would've used a relative path to the standard library:

cmdline: /foo/bar/bin/clang -c test.cc
std lib in: /foo/bar/include/c++
libclang sees: -c test.cc

and the stdlib is lost. This comes up if we're using a compile
database, for example ycm is using it like this.

The only sane solution I see at the moment is to add a new libclang
API that expects a full argv. Any other ideas?

- Ben

In KDevelop, we parse the output of

  clang++ --std=c++11 -xc++ -E -v /dev/null

and pass those in to liblcang as explicit include paths. It works fine for our
use case. But for a simpler tool it might be far too much overhead of course
to get up and running. Couldn't the code path in clang use the path to the
clang library as a fallback when no binary is given? That way, nothing needs
to be changed.

Bye

Hi,

currently all libclang APIs that get passed a command line expect that
there is no argv[0] in the list, i. e. no binary name at the beginning
of the command line. We later fake one
(clang::createInvocationFromCommandLine) as the invocation gets passed
down into the proper clang machinery.

This is nasty because it changes the behavior if the original clang
invocation would’ve used a relative path to the standard library:

cmdline: /foo/bar/bin/clang -c test.cc
std lib in: /foo/bar/include/c++
libclang sees: -c test.cc

and the stdlib is lost. This comes up if we’re using a compile
database, for example ycm is using it like this.

The only sane solution I see at the moment is to add a new libclang
API that expects a full argv. Any other ideas?

In KDevelop, we parse the output of

clang++ --std=c++11 -xc++ -E -v /dev/null

and pass those in to liblcang as explicit include paths. It works fine for our
use case.

Note that this might also be wrong.
If you have multiple compilers / libstdc++'s installed, it is important to take the right one for the current project you work in.

+argyrios and richard for more opinions

Hi,

currently all libclang APIs that get passed a command line expect that
there is no argv[0] in the list, i. e. no binary name at the beginning
of the command line. We later fake one
(clang::createInvocationFromCommandLine) as the invocation gets passed
down into the proper clang machinery.

This is nasty because it changes the behavior if the original clang
invocation would've used a relative path to the standard library:

cmdline: /foo/bar/bin/clang -c test.cc
std lib in: /foo/bar/include/c++
libclang sees: -c test.cc

and the stdlib is lost. This comes up if we're using a compile
database, for example ycm is using it like this.

The only sane solution I see at the moment is to add a new libclang
API that expects a full argv. Any other ideas?

You are talking about inferring the resources path from argv[0], but this is not 100% correct, libclang should be including the right clang and stdlib headers for the version it was compiled with.

Is there a particular reason why you can’t have libclang setup so that it can find the proper headers ?

Note that this is about the standard c++ headers, not the builtin headers.