The Clangd Language Server
==========================
About Clangd
------------
`Clangd `_ is a C/C++ language server, providing IDE-like features such as code completion, diagnostics, and refactoring.
Clangd can be used to develop DPU code. But for that it needs to know about the ``dpu-upmem-dpurte`` triplet.
The clangd binary we distribute is built with support for the ``dpu-upmem-dpurte`` triplet. It is available as part of the upmem toolchain.
Installing Clangd
-----------------
DEB/RPM install
~~~~~~~~~~~~~~~
If you installed the upmem SDK with a debian or rpm package, UPMEM Clangd is already installed on your system.
Tarball install
~~~~~~~~~~~~~~~
If you're using the tarball, the clangd binary is available in the ``bin`` directory of the SDK.
It will be in your PATH if you sourced the ``upmem_env.sh`` script.
Checking Clangd version
-----------------------
To check the version of clangd, run:
.. code-block:: bash
clangd --version
The output should be similar to: ``clangd version 12.0.0 (https://github.com/upmem/llvm-project.git )``
Making Clangd aware of the DPU target
-------------------------------------
By default, Clangd assumes that the target is the host machine. In your project, you probably have some source files for the host and some for the DPU.
There are two ways to inform Clangd about which is which.
Using a compilation database (recommended)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The compilation database is a ``compile_commands.json`` file that describes the compilation of your project. It is usually generated by the build system.
For example, with CMake, you can generate it by adding the ``-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`` option to the ``cmake`` command, or adding
.. code-block:: cmake
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
in your ``CMakeLists.txt`` file.
Make this file visible at the top-level folder of your project with a symbolic link (in this case, we assume you're building in a ``build`` folder):
.. code-block:: bash
ln -s build/compile_commands.json .
Then, when you run Clangd, it will use this file to know which files are compiled for the host and which are compiled for the DPU.
Using a configuration file
~~~~~~~~~~~~~~~~~~~~~~~~~~
In the absence of a compilation database, Clangd can use a configuration file to know which compilation options to use for each source file.
The configuration file is a YAML file named ``.clangd``. It should be placed at the top-level folder of your project.
Here is an example ``.clangd`` file for an UPMEM DPU project:
.. code-block:: YAML
If:
PathMatch: [.*host.*.c, .*host.*.cpp, .*host.*.h] # Configuration for host binaries
CompileFlags:
Add: [-I/usr/include/dpu, -ldpu]
---
If:
PathExclude: [.*host.*.c, .*host.*.cpp, .*host.*.h] # Configuration for dpu binaries
CompileFlags:
Add: [--target=dpu-upmem-dpurte]
The first part of the file describes the configuration for the host binaries. It matches all files whose name or path contains ``host`` and ends with ``.c`` or ``.cpp``.
The compile flags are the output of ``dpu-pkg-config --cflags --libs dpu``, in a comma-separated list.
The second part of the file describes the configuration for the DPU binaries. It matches all files whose name or path does not contain ``host`` and ends with ``.c`` or ``.cpp``.
Enabling additional linting
---------------------------
Clangd embeds `clang-tidy `_, a tool that can perform additional linting on your code.
To configure it, create a ``.clang-tidy`` file at the top-level folder of your project and enable/disable the checks you want.
Example ``.clang-tidy`` file:
.. code-block:: YAML
Checks: >
bugprone-*,
google-*,
misc-*,
modernize-*,
performance-*,
portability-*,
readability-*,
WarningsAsErrors: "*"
Using Clangd in your editor
---------------------------
Clangd is a language server. It communicates with your editor through the Language Server Protocol (LSP). Virtually all modern editors support LSPs.
Here are some examples of how to use Clangd with some popular editors.
VSCode
~~~~~~
* Install the `clangd extension `_.
If you installed the upmem SDK with a debian or rpm package, you're done.
If you're using the tarball, the recommended method is to use direnv to set all your environment variables:
* Install `direnv `_.
* Install `VSCode direnv extension `_.
* Create a ``.envrc`` file at the top-level folder of your project with the following content:
.. code-block:: bash
source /upmem_env.sh
* In VSCode, allow the file, and reload the environment.
* All your environment variables are now set in VSCode, including the PATH to the upmem clangd binary, as well as the PATH for clang, dpu-lldb and so on.
Vim
~~~
* Install `vim-clangd `_.
If you installed the upmem SDK with a debian or rpm package, you're done.
If you're using the tarball, source the ``upmem_env.sh`` script before starting vim.
Alternatively:
* In your vimrc file, set
.. code-block:: vim
let g:clangd_binary_path = '/bin/clangd'
Emacs
~~~~~
* Install `lsp-mode `_.
If you installed the upmem SDK with a debian or rpm package, you're done.
If you're using the tarball, source the ``upmem_env.sh`` script before starting emacs.
Alternatively, set ``lsp-clangd-binary-path`` to ``/bin/clangd``.