Skip to Content

Switch between different versions of clang-format

clang-format is an incredibly useful tool. It helps us to keep a code base such as liblouis, that has been touched by many contributors, at least somewhat stylistically consistent. We even added a test to the CI to make sure new contributions match the existing style.

The problem with clang-format is that its output is subtly different for each new version of it. So we have to make sure we use exactly the same version as the CI machine does. Luckily Ubuntu 20.04 has packaged versions 7, 8, 9 and 10 so installing is not a problem. But what if you want to use a newer version of some other code base?

This is exactly the kind of situation that the Debian Alternatives System is handling. Unfortunately clang-format has not been setup to work with update-alternatives. Luckily for us it is quite easy to extend the Debian alternatives system:

First install clang-format (all versions that you need)

$ sudo apt install clang-format clang-format-7 clang-format-8 clang-format-9 clang-format-10

Then add a new group named clang-format to the alternatives system. You can do that manually or use the small script below:

#!/usr/bin/env bash

BINARY=/usr/bin/clang-format
MANPAGE=/usr/share/man/man1/clang-format

function register_clang_format_version {
    local version=$1
    local priority=$2

    update-alternatives \
      --install ${BINARY} clang-format ${BINARY}-${version} ${priority} \
      --slave ${MANPAGE}.1.gz clang-format.1.gz ${MANPAGE}-${version}.1.gz
}

register_clang_format_version 10 100
register_clang_format_version 9 20
register_clang_format_version 8 10
register_clang_format_version 7 50

You can now use update-alternatives to list all the possible alternatives you have for the clang-format command and easily switch between them.

$ clang-format --version
clang-format version 10.0.0-4ubuntu1
$ sudo update-alternatives --config clang-format
There are 4 choices for the alternative clang-format (providing /usr/bin/clang-format).

  Selection    Path                      Priority   Status
------------------------------------------------------------
* 0            /usr/bin/clang-format-10   100       auto mode
  1            /usr/bin/clang-format-10   100       manual mode
  2            /usr/bin/clang-format-7    50        manual mode
  3            /usr/bin/clang-format-8    10        manual mode
  4            /usr/bin/clang-format-9    20        manual mode

Press <enter> to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/bin/clang-format-7 to provide /usr/bin/clang-format (clang-format) in manual mode
$ clang-format --version
clang-format version 7.0.1-12 (tags/RELEASE_701/final)