How to use ccls with build containers

Florian Xaver 2021-11-09 21:32:37 +01:00
parent a81648d985
commit 09a3bc06a4

@ -1,7 +1,9 @@
ccls typically indexes an entire project. In order for this to work properly, `ccls` typically indexes an entire project. In order for this to work properly,
`ccls` needs to be able to obtain the source file list and their compilation `ccls` needs to be able to obtain the source file list and their compilation
command lines. command lines.
### How `ccls` obtains sources and compilation commands
There are two main ways this happens: There are two main ways this happens:
1. Provide `compile_commands.json` at the project root 1. Provide `compile_commands.json` at the project root
@ -12,6 +14,47 @@ There are two main ways this happens:
If neither exists, then when ccls starts it will not index anything: instead it If neither exists, then when ccls starts it will not index anything: instead it
will wait for LSP clients to open files and index only those files. will wait for LSP clients to open files and index only those files.
### Using build containers
Build containers are usually OCI containers and are often managed by Podman or Docker. Toolchains for building might run in these containers for reproducability.
There are two possibilities:
1. Execute the container for building only. Use `ccls` and your editor/IDE on the host.
2. The build container is running in the background with an installed and running `ccls`. Furthermore, it is using the host network so that editors/IDEs running on the host can connect.
#### `ccls` on the host
If you want to use `ccls` on the host, a path mapping has to be applied, since paths and compiler versions will most probably differ.
Thus, paths of following headers have to be translated to the host system:
* system and third-party libraries (if those headers do not already exist, install them. E.g., `openssl-devel` in Linux)
* the compiler's headers
See following initialization options (`ccls --init='...'`), which uses `build/compile_commands.json` already produced _in_ the container:
```
{
"clang": {
"resourceDir": "/usr/lib64/clang/13.0.0",
"pathMappings": [
"/project_container/>/project_host/",
"/opt/rh/gcc-toolset-10/root>"
],
"clang.extraArgs": [
"--gcc-toolchain=/opt/rh/gcc-toolset-10/root/usr"
]
},
"compilationDatabaseDirectory": "/project_host/build/"
}
```
`resourceDir` denotes the directory of the compiler's include files at the host. The compiler version is usually different from the container's. `pathMappings` substitute directories mounted into the container by the related host directories. If you are using `clang(++)` with `--gcc-toolchain=...`, then you have to add the corresponding directory to `pathMappings`, and add `clang.extraArgs`. Here the `compile_commands.json` is in a different directory, and, hence, `compilationDatabaseDirectory` has to be specified.
Note: On the host, you may have to install additional developer packages (e.g. openssh-devel), which include required headers. If headers are missing, you will see errors in the log file (start `ccls` by `--log-file=/tmp/ccls.log -v=1`) or error labels in your editor.
#### `ccls` on the container
1. Install `ccls` in the container
2. Execute the container with `--network=host` (Podman, Docker) such that it continues to run.
3. Start the build process by attaching to the contatiner and executing the build tool (`cmake`, `make`,...)
## `compile_commands.json` ## `compile_commands.json`
[Guillaume Papin(@Sarcasm)](https://github.com/sarcasm) has [a thorough article about compilation databases](https://sarcasm.github.io/notes/dev/compilation-database.html). [Guillaume Papin(@Sarcasm)](https://github.com/sarcasm) has [a thorough article about compilation databases](https://sarcasm.github.io/notes/dev/compilation-database.html).