CMake linter?

Does anyone have any recommendations for a CMake linter?

I realise this is controversial, but my response at the moment is, frankly, don’t use one. In all cases where I’ve seen them used in any meaningfully complicated project, it gives a worse result than manual formatting.

My reasoning for the above view is based on linters being unable to parse the semantic meaning of arguments. CMake commands frequently span across multiple lines, and the indenting of arguments usually (I’d say ideally) has multiple levels. Consider the following:

some_custom_command(targetName
    SOME_KEYWORD
        a_list_of_files.cpp
        another_one.cpp
    NO_VALUE_OPTION
    A_SINGLE_VALUE_KEYWORD
        make_me_coffee
)

The above demonstrates how arguments will indent keywords one level, and values an additional level. A linter would have to be able to identify keywords to be able to do that, but there’s no mechanism in CMake at the moment for a command to provide that information to a linter. At best, linters could embed knowledge of built-in CMake commands (and this is essentially what IDEs are currently doing), but they can’t cope with custom commands defined by the project. Currently linters will generally just flatten the whole set of arguments to the same indentation level, which is horrible from a readability point of view.

I’m thinking of proposing a way for commands to provide the information needed for linters to know the keywords supported by the command (e.g. through the CMake file API). The idea is still forming though, and I haven’t had a chance to distill it down to something sensible. If I get time, I may try to put together a proposal after 3.27 is out the door.

2 Likes

Additionally, for complicated add_custom_command and execute_process calls, grouping arguments is better, but the grouping is very complicated to describe at times:

add_custom_command(OUTPUT …
  COMMAND
    ${interpreter} -c ${module}
    -a
    --flag
    --with-an-argument "${arg}"
    ${more_args})