0.9.0-next.47b67f9.0 • Published 1 year ago

@eclipse-cdt-cloud/clangd-contexts-cli v0.9.0-next.47b67f9.0

Weekly downloads
-
License
EPL-2.0 OR GPL-2....
Repository
-
Last release
1 year ago

@eclipse-cdt-cloud/clangd-contexts-cli

Overview

A CLI tool for management of clangd configuration files in C/C++ projects.

Features

  • identify multiple different projects in a C/C++ workspace edited with clangd support
  • quickly and easily apply clangd contexts, described by compile_commands.json files, to projects
  • customize the invocation of clang by clangd on a per project basis to account for differences between clang and the project's C/C++ toolchain

CLI Usage

The clangd contexts CLI application provides several commands to interact with the context API. It can be used to set the clangd context for a given project directory and retrieve the clangd context for a given project. In addition, the CLI provides commands to change the set of compilation flags that should be considered by the clangd server for a given project configuration (.clangd file).

Note that in order to run the clangd-context CLI tool as shown in these snippets, you need to link the @eclipse-cdt-cloud/clangd-contexts-cli package with "yarn link".

Once the clangd-contexts project has been built and the CLI linked as described in the root README file, the command is available to execute in a VScode terminal as shown here. The main help output of the CLI application looks like this:

$ clangd-context
Usage: clangd-context [options] [command]

Options:
  -h, --help      display help for command

Commands:
  get-context     get the context in a project configuration
  set-context     set or change the context in a project configuration
  list            list the projects in the clangd workspace
  list-contexts   list the contexts of the projects in the clangd workspace
  select-context  select a context to activate in every project in the workspace
  set-flags       set added/removed compile flags in a project
  unset-flags     unset added/removed compile flags in a project
  help [command]  display help for command

The select-contexts command requires knowledge of what the clangd contexts in the current workspace scope are. This scope is defined by an optional .clangd-contexts file.

Workspace Clangd Contexts Configuration

A workspace may optionally provide a .clangd-contexts file that tells the CLI the layout of projects in the workspace. It indicates which directories comprise projects, configured by .clangd files and how to find context directories containing the compile_commands.json files in each project. A workspace may contain any number of .clangd-contexts files that each describe the layout of their distinct subtree.

The .clangd-contexts file is a JSON object that looks like this example from the Example Clangd Contexts Workspace:

{
    "workspaceName": "CDT.cloud Clangd Contexts Example",
    "projects": [
        {
            "path": "app",
            "contextDirs": "flat"
        },
        {
            "path": "lib",
            "contextDirs": "flat"
        }
    ]
}

An optional name identifies the workspace but is not used by the CLI. The list of clangd projects specifies for each:

  • the path to the project directory, relative to the workspace root (which is the directory containing the .clangd-contexts file). This directory must contain the context directories (and therefore the compile_commands.json files) but is not required to contain the source files
  • the shape of context directories in the context, either "flat" or "nested". This tells the CLI how to search for the compile_commands.json files that describe each context and how to derive context names
    • in the flat scheme, the context name is just the name of the directory containing the compile_commands.json file
    • in the nested scheme, the context name is the slash-separated path of the directory containing the compile_commands.json file, relative to the project directory

For commands that use this workspace configuration file, the CLI searches up the directory hierarchy from the current working directory. The workspace scope is the directory tree rooted in the directory in which the .clangd-contexts file is found.

Getting a Context

If you haven't already, prepare the clangd-workspace example workspace by building it.

First retrieve the current context configuration of the app project. This can be done with the get-context command. This command takes the location of a .clangd configuration file or its parent directory as input. There should not be any .clangd file in the app/ directory yet so the expected output is:

$ clangd-context get-context app
{ name: 'NO_CONTEXT', compilationDatabase: '' }

Setting a Context

Next, set the active clangd context. The app/ and lib/ projects both contain two contexts Debug_x86-64 and Release_Atom. Set a context with the set-context command. As for the get-context command, the main argument is the location of the .clangd configuration file or its parent directory. It is also necessary to specify the compilation database (compile_commands.json file or its parent directory) to identify the context to set in the project. This is done with the --compile-commands (-c) option:

clangd-context set-context -c app/Debug_x86-64 app

Now the app/ directory should contain a new .clangd file with the following contents:

CompileFlags:
    CompilationDatabase: /home/me/git/clangd-contexts/examples/clangd-workspace/app/Debug_x86-64

Upon executing the previous get-context command again, the output should be as follows:

$ clangd-context get-context app
{
  name: 'Debug_x86-64',
  compilationDatabase: '/home/me/git/clangd-contexts/examples/clangd-workspace/app/Debug_x86-64'
}

With this configuration file the clangd server now has all of the information it needs to provide language support for the Debug_x86-64 context.

Listing the Projects in the Workspace

For workspaces that are configured with a .clangd-contexts file, the CLI supports an additional command list that lists the configured projects. For example, executing the following command in the example workspace:

$ clangd-context list
app/
lib/

results in the paths of existing clangd contexts being displayed relative to the current working directory.

Listing the Clangd Contexts in the Workspace

For workspaces that are configured with a .clangd-contexts file, the CLI supports an additional command list-contexts that lists the available context names across all projects in the workspace. For example, executing the following command in the example workspace:

$ clangd-context list-contexts
Debug_x86-64
Release_Atom

shows that across all projects in the workspace, the unique context names are Debug_x86-64 and Release_Atom.

Selecting a Context for the Workspace

For workspaces that are configured with a .clangd-contexts file, the CLI supports an additional command select-context that activates a named context in all projects that have a context of that name. For example, executing the following command:

clangd-context select-context Release_Atom

results in all of the context directories listed in the .clangd-context file having the build configuration "Release_Atom" applied to their .clangd file, if they have a "Release_Atom" configuration. In the example project, following up with a get-context command would look something like this:

$ clangd-context get-context lib
{
  name: 'Release_Atom',
  compilationDatabase: '/home/me/git/clangd-contexts/examples/clangd-workspace/lib/Release_Atom'
}

Projects that do not have the named context are unchanged. If the context name is not known in any project in the workspace, then the CLI exits with an error.

Changing Compile Flags

In addition to getting and setting the context, the CLI provides commands for setting the compile flags that are evaluated by the clangd server. This is done with the set-flags and unset-flags commands. As usual the main argument is the location of the .clangd configuration file or its parent directory.

Setting Compile Flags to be Added or Removed

The set-flags command updates the .clangd configuration to specify flags that the language server should add to or remove from its invocations of the compiler.

With the --add (-a) option the set of flags that should be added to those already specified in the compilation database can be configured. The --remove (-r) option sets which flags in the compilation database should be suppressed in the language server's invocation of the compiler.

A command that tells the clangd server to suppress the -fstack-usage flag looks like this:

clangd-context set-flags -r fstack-usage app

Note that the command line here names the -fstack-usage compiler flag simply as "fstack-usage" without the initial "-". This is necessary because otherwise it would be interpreted as a command-line option for the clangd-context tool, itself. Multiple compiler flags can be added or removed at once by specifying them in a comma-separated list in the -a or -r option.

The resulting .clangd file for the Release_Atom context in the app project looks like this:

CompileFlags:
    CompilationDatabase: >-
        /home/me/git/clangd-contexts/examples/clangd-workspace/app/Release_Atom
    Remove:
        - "-fstack-usage"

The project name argument ("app" in the example above) is optional if the workspace is configured with a .clangd-contexts file. In this case, omitting the project name applies the compile flags change to all projects listed in the .clangd-contexts file.

Forgetting Configuration of Compile Flags

To reverse previous additions or removals of compiler flags in the .clangd configuration, use the unset-flags command. This deletes occurrences of flags so that they are no longer added or removed from compiler command-lines by the language server, depending on the previous configuration.

A command that tells the clangd server not to override the usage of the -fstack-usage flag in the compiler command looks like this:

clangd-context unset-flags -f fstack-usage app

Note that, as for the set-flags command, at least the first flag of the comma-separated list in the -f option must omit the initial "-".

The resulting .clangd file for the Release_Atom context in the app project then is reverted to this:

CompileFlags:
    CompilationDatabase: >-
        /home/me/git/clangd-contexts/examples/clangd-workspace/app/Release_Atom

The project name argument ("app" in the example above) is optional if the workspace is configured with a .clangd-contexts file. In this case, omitting the project name applies the compile flags change to all projects listed in the .clangd-contexts file.

Example Workspaces

License