-
Notifications
You must be signed in to change notification settings - Fork 263
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
Support for cross- or non-standard compilers? #138
Comments
A mad scientist still needs CMake to generate Makefile :)
The gcc you use has a unconventional sysroot and system search paths.
Right. ccls just calls std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
...
// clangDriver which detects system search paths
driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(),
*Diags, VFS);
...
// Similar as clang -cc1
if (!CompilerInvocation::CreateFromArgs(...) clangDriver has logic to detect system search paths as what a system gcc does, it may look like:
For your local GCC, the first 3 directories should differ. You need to figure out the search path replacement in your GCC installation directory, and specify You can add extra flags by:
I've also written some tips on #125 You can also play with |
If I didn't need to support Visual Studio and Xcode project files, I probably would just use a straightforward makefile system... I've definitely banged my head for hours against things in cmake that I could have written in 10 minutes in a makefile :).
Yes, definitely. In fact I have a wrapper script I invoke, that sets up all the sysroot etc. arguments. That's why I was hoping ccls would query the actual compiler somehow (e.g. by running The issue I was hitting is that by using I feel personally that to get the most accurate indexing with the least amount of effort from the user (and the fewest PEBCAK issues filed :) ) it would be great for ccls to query the compiler for include directories. I realize that's much more effort than simply asking the clang library for a set of directories. I don't know what your thoughts are on this. Also it would be great if ccls could accept configuration in more flexible ways than just the command line (I'm afraid it wasn't exactly clear to me from the initialization option wiki page, whether that was already true or not): for example, from an environment variable or a Thanks for your reply! |
One potential problem with the "query the damn compiler for its default include path" is that bundled includes may in theory contain arbitrary compiler-specific magic that can give clang severe indigestion, if the compiler in question is not clang (admittedly gcc is fine in my experience, but perhaps I've just had good luck with gcc/clang version combinations). |
You may try specifying
You can post process
clang does all the heavylifting here. I try to avoid inventing any compiler driver logic in ccls as the extra work can often lead to loss of generality and get in the way.
What ccls does should not be very different from what the compiler driver
If this command gives you index information, passing the same set of flags through
The customization is provided through LSP's initialization options, which are supposed to be sent by the language client to ccls (the language server). The command line option
I don't think a
|
Sorry for the lack of response, I got busy at work. I spent most of yesterday trying to make this work First, note that The only useful thing about This is really painful though. I have multiple different worktrees and each one can use a different instance of the compiler, so I can't hardcode these paths in my Emacs config; they need to be set per-project. What I'd like to do is create a general environment that I can publish for other people in my group to use, but as I mentioned all the compilers are relocatable so I can't use any hardcoded paths. Perhaps I'll need to write a somewhat sophisticated front-end script to ccls to try to manage all of this. Because of the way I did try out So I'm still thinking about which to use. Cheers! |
You may forget these So questions and start from here https://github.com/llvm-mirror/clang/tree/master/lib/Driver/ToolChains/Gnu.cpp#L1697 They are intricate logic which emulates standard GCC installation on some selected platforms. The code explains more.
This is a reasonable feature request. I pushed a commit to support multiple
For cquery, remember to set To have a fair comparison, |
I see. The problem is the hardcoded set of triples: our triple is
I thought I had done that, but I realized I used There's something strange about my ccls output: cquery caches almost twice as many files. Looking at the results, it seems like ccls is not caching most of my header files. It's very strange because it does cache the matching
Awesome! I'm wondering: if things are added at the end and overridden by later values, shouldn't the options from the client come last rather than first? i would think that the arguments the server was started with should be overridden by the options provided by the client.
I absolutely understand your distaste. Nevertheless, I fear that this will keep ccls unsuitable for a number of dev environments. Embedded development and a significant number of development teams (outside of FOSS) use non-default compilers. Even when not doing cross-compilation, for co-ordinated teams your choices are (a) allow everyone to use their own native compiler and deal with the broken compiles from people using different versions, (b) force everyone to use identical OS distributions/versions so they all have the same native compiler, or (c) provide a separate compiler outside of the default locations so everyone can use the same one. By far the least amount of hassle is (c) and that's how all the development shops I've worked at do things. As above, it appears that if you're lucky and your environment matches something Clang expects you can configure things with only a few extra arguments ( Anyway, thanks for your efforts on both |
For editors that are not as flexible as Emacs is: no buffer-local variables or dynamic scoping, it isn't easy to tweak client-side configuration and the shell wrapper responsible for starting the language server has the more flexibility here. I think it makes sense to let the flexible one (
Thanks for elaborating on the complexity. This run-clang-v-to-get-search-directories approach is not bulletproof and has caused many issues before.
I haven't tried it by myself, but if I understand it correctly, There are also users who don't code the full pathname of the compiler driver and rely on clang has provided good emulation of gcc but nuance is unavoidable. Users have to fight with command line options if they want to use different versions of GCC or switch to clang. clangDriver is a gigantic thing, ycmd has probably done some crazy twiddling on their side, I think, doing the least and handing over everything to clangDriver is the cleanest/most robust approach. Adding |
Header files are not compiled on their own. For header files that are not included, they may not get indexes. Also see #72 (comment) |
That's good info, thanks. But these headers are definitely included. I found the issue although I'm not sure why it happens. I had added a If I remove that option then I get a much more robust output which seems to include everything (and takes a lot more effort to generate 😁) |
That said, I think writing your own hack-y wrapper doing include path detection then add to compile_commands/init options in your favorite scripting language might be a good idea for this use case: fits the need; could be simple as the compilers are under your control; won't be a surprise to user. |
I use my own build of GCC to compile for my code. I use CMake and I have it generate
compile_commands.json
so ccls knows the complete command line. However, all the system C runtime and compiler header files are installed at a separate location and the local build of GCC knows where to find them. The compiler doesn't use any of the system libc headers or system compiler headers at all, ever.Unfortunately ccls doesn't seem to understand this; after running if I look at the
.ccls-cache/@@work@src
directory for the system and compiler headers, they are all from the clang instance that ccls was built with and the system's /usr/include. I know for sure that those were not the C / C++ headers that my code is compiled with.I'm not sure how ccls attempts to locate header files to index: I hoped it would ask the compiler itself where to look, either by parsing post-processed code or by getting the compiler to print the set of include paths it will use when searching for headers. Using these options ccls would locate the correct headers to index. However neither of those seem to be used.
Any thoughts?
The text was updated successfully, but these errors were encountered: