Skip to main content

可以格式化您的列表文件,使它们看起来不像废话

项目描述

https://travis-ci.com/cheshirekow/cmake_format.svg?branch=master https://readthedocs.org/projects/cmake-format/badge/?version=latest

cmake-format项目为cmake提供质量保证 (QA) 工具:

  • cmake-annotate可以从你的列表文件中生成漂亮的 HTML

  • cmake-format可以很好地格式化您的列表文件,使它们看起来不像废话。

  • cmake-lint可以检查您的列表文件是否有问题

  • ctest-to可以解析 ctest 输出树并将其转换为更结构化的格式(JSON 或 XML)。

安装

使用pippypi安装:

pip install cmakelang

或查看在线文档以了解其他选项。

集成

用法

usage:
cmake-format [-h]
             [--dump-config {yaml,json,python} | -i | -o OUTFILE_PATH]
             [-c CONFIG_FILE]
             infilepath [infilepath ...]

Parse cmake listfiles and format them nicely.

Formatting is configurable by providing a configuration file. The configuration
file can be in json, yaml, or python format. If no configuration file is
specified on the command line, cmake-format will attempt to find a suitable
configuration for each ``inputpath`` by checking recursively checking it's
parent directory up to the root of the filesystem. It will return the first
file it finds with a filename that matches '\.?cmake-format(.yaml|.json|.py)'.

cmake-format can spit out the default configuration for you as starting point
for customization. Run with `--dump-config [yaml|json|python]`.

positional arguments:
  infilepaths

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -l {error,warning,info,debug}, --log-level {error,warning,info,debug}
  --dump-config [{yaml,json,python}]
                        If specified, print the default configuration to
                        stdout and exit
  --dump {lex,parse,parsedb,layout,markup}
  --no-help             When used with --dump-config, will omit helptext
                        comments in the output
  --no-default          When used with --dump-config, will omit any unmodified
                        configuration value.
  -i, --in-place
  --check               Exit with status code 0 if formatting would not change
                        file contents, or status code 1 if it would
  -o OUTFILE_PATH, --outfile-path OUTFILE_PATH
                        Where to write the formatted file. Default is stdout.
  -c CONFIG_FILES [CONFIG_FILES ...], --config-files CONFIG_FILES [CONFIG_FILES ...]
                        path to configuration file(s)
usage:
cmake-lint [-h]
           [--dump-config {yaml,json,python} | -o OUTFILE_PATH]
           [-c CONFIG_FILE]
           infilepath [infilepath ...]

Check cmake listfile for lint

positional arguments:
  infilepaths

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -l {error,warning,info,debug}, --log-level {error,warning,info,debug}
  --dump-config [{yaml,json,python}]
                        If specified, print the default configuration to
                        stdout and exit
  -o OUTFILE_PATH, --outfile-path OUTFILE_PATH
                        Write errors to this file. Default is stdout.
  --no-help             When used with --dump-config, will omit helptext
                        comments in the output
  --no-default          When used with --dump-config, will omit any unmodified
                        configuration value.
  --suppress-decorations
                        Suppress the file title decoration and summary
                        statistics
  -c CONFIG_FILES [CONFIG_FILES ...], --config-files CONFIG_FILES [CONFIG_FILES ...]
                        path to configuration file(s)

配置

cmake-format接受 yaml、json 或 python 格式的配置文件。在线文档中提供了一个示例配置文件。提供自定义命令的结构将有助于cmake-format以愉快的方式分解它们,并有助于cmake-lint检测它们的不当使用。

python格式的示例简短配置文件是:

# -----------------------------
# Options effecting formatting.
# -----------------------------
with section("format"):

  # How wide to allow formatted cmake files
  line_width = 80

  # How many spaces to tab for indent
  tab_size = 2

  # If true, separate flow control names from their parentheses with a space
  separate_ctrl_name_with_space = False

  # If true, separate function names from parentheses with a space
  separate_fn_name_with_space = False

  # If a statement is wrapped to more than one line, than dangle the closing
  # parenthesis on its own line.
  dangle_parens = False

您可以使用--config-file命令行选项指定一个或多个配置文件的路径 。否则,cmake-format将搜索每个infilepath的祖先以寻找要使用的配置文件。如果没有找到配置文件,它将使用合理的默认值。

自动检测到的配置文件可能具有与 \.?cmake-format(.yaml|.json|.py)匹配的任何名称。

如果您想创建一个新的配置文件,cmake-format可以通过以您喜欢的格式转储默认配置来提供帮助。您可以运行 cmake-format --dump-config [yaml|json|python]来打印默认配置标准输出并将其用作起点。

标记

cmake-format适合非常懒惰的人。它甚至会为您格式化您的评论。它会将您的评论文本重新排列到配置的线宽内。它还理解一些常见位的非常有限的标记格式。

标尺:标尺是以三个或更多非字母数字或空格字符开头和结尾的行:

# ---- This is a Ruler ----
# cmake-format will know to keep the ruler separated from the
# paragraphs around it. So it wont try to reflow this text as
# a single paragraph.
# ---- This is also a Ruler ---

list:列表从第一个遇到的列表项开始,它以项目符号 ( * ) 开头,后跟一个空格,然后是一些文本。后续行将包含在列表项中,直到遇到下一个列表项(项目符号必须处于相同的缩进级别)。该列表必须被一对空行包围。嵌套列表将被格式化为嵌套文本:

# here are some lists:
#
# * item 1
# * item 2
#
#   * subitem 1
#   * subitem 2
#
# * second list item 1
# * second list item 2

enumerations:枚举类似于列表,但项目符号字符是一些整数,后跟一个句点。只要第一个数字或标点符号与前一个项目在同一列中,就会检测到新的枚举项目。cmake-format将为您的项目重新编号并对齐它们的标签:

# This is an enumeration
#
#   1. item
#   2. item
#   3. item

围栏:如果您有任何不想被格式化的文本,您可以用一对围栏保护它。栅栏是三个或更多波浪字符:

# ~~~
# This comment is fenced
#   and will not be formatted
# ~~~

请注意,评论围栏保护评论文本的重排,而不是 cmake 代码。如果您希望防止格式化 cmake、代码,请参见下文。除了受保护的文字之外,还有其他三种方法可以从标记和/或重排处理中保留注释文本:

  • --first -comment-is-literal配置选项将完全保留文件中的第一个注释。这是为了保留版权或其他格式的标题注释。

  • --literal -comment-pattern配置选项允许一种更通用的方式来识别应该按字面保留的注释。此配置采用正则表达式模式。

  • --enable-markup配置选项全局启用注释标记处理。它默认为 true,因此如果您希望全局禁用评论标记处理,请将其设置为 false。请注意,尾随空格仍然从评论中剔除。

禁用本地格式化

您可以使用特殊注释# cmake-format: off# cmake-format: on 在本地禁用和启用代码格式化。

排序参数列表

从版本0.5.0开始,cmake-format可以为您排序参数列表。如果配置包括autosort=True(默认),它将替换:

add_library(foobar STATIC EXCLUDE_FROM_ALL
            sourcefile_06.cc
            sourcefile_03.cc
            sourcefile_02.cc
            sourcefile_04.cc
            sourcefile_07.cc
            sourcefile_01.cc
            sourcefile_05.cc)

和:

add_library(foobar STATIC EXCLUDE_FROM_ALL
            sourcefile_01.cc
            sourcefile_02.cc
            sourcefile_03.cc
            sourcefile_04.cc
            sourcefile_05.cc
            sourcefile_06.cc
            sourcefile_07.cc)

这适用于解析器知道本质上可排序的任何参数列表。这包括以下 cmake 命令:

  • add_library

  • add_executable

对于大多数其他 cmake 命令,您可以使用注释注释来提示 cmake-format参数列表是可排序的。例如:

set(SOURCES
    # cmake-format: sortable
    bar.cc
    baz.cc
    foo.cc)

注释可以在行注释或括号注释中给出。每个都有一个长格式和一个短格式。可接受的格式是:

行注释

# cmake 格式: <标签>

行注释

短的

# cmf: <标签>

括号注释

#[[cmake 格式: <标签>]]

括号注释

短的

#[[cmf: <标签>]]

为了将位置参数列表注释为可排序,可接受的标签是:可排序排序。对于上面列出的位置参数列表本身可排序的命令,您可以通过使用unsortableunsort注释它们来本地禁用排序。例如:

add_library(foobar STATIC
            # cmake-format: unsort
            sourcefile_03.cc
            sourcefile_01.cc
            sourcefile_02.cc)

请注意,仅当您的配置启用了autosort时才需要这样做,并且您可以通过将此配置设置为False来全局禁用排序 。

自定义命令

由于 cmake 是一种宏语言,因此cmake-format必然是一种语义源代码格式化程序。通常,它会尝试根据 cmake 语句中非结构化参数列表中参数的含义做出明智的格式化决策。cmake-format可以智能地格式化您的自定义命令,但您需要告诉它如何解释您的参数。

目前,您可以通过将命令规范添加到 附加命令配置变量来执行此操作,例如:

# Additional FLAGS and KWARGS for custom commands
additional_commands = {
  "foo": {
    "pargs": 2,
    "flags": ["BAR", "BAZ"],
    "kwargs": {
      "HEADERS": '*',
      "SOURCES": '*',
      "DEPENDS": '*',
    }
  }
}

格式是嵌套字典,将语句名称(字典键)映射到参数规范。对于上面的示例规范,自定义命令看起来像这样:

foo(hello world
    HEADERS a.h b.h c.h d.h
    SOURCES a.cc b.cc c.cc d.cc
    DEPENDS flub buzz bizz
    BAR BAZ)

报告问题并获得帮助

如果您遇到任何错误或回归,或者如果cmake-format没有按照您预期的方式运行,请在 github 问题跟踪器上发布问题。如果您可以提供 cmake listfile 片段来演示您遇到的任何问题,这将特别有用。

您也可以加入我们discord 服务器上的#cmake-format频道。

开发者

如果您想破解cmake-format,请参阅文档以了解贡献规则和指南。

例子

会变成这样:

# The following multiple newlines should be collapsed into a single newline




cmake_minimum_required(<s>VERSION</s> <s>2.8.11</s>)
project(<s>cmakelang_test</s>)

# This multiline-comment should be reflowed
# into a single comment
# on one line

# This comment should remain right before the command call.
# Furthermore, the command call should be formatted
# to a single line.
add_subdirectories(<s>foo</s> <s>bar</s> <s>baz</s>
  <s>foo2</s> <s>bar2</s> <s>baz2</s>)

# This very long command should be wrapped
set(<s>HEADERS</s> <s>very_long_header_name_a.h</s> <s>very_long_header_name_b.h</s> <s>very_long_header_name_c.h</s>)

# This command should be split into one line per entry because it has a long argument list.
set(<s>SOURCES</s> <s>source_a.cc</s> <s>source_b.cc</s> <s>source_d.cc</s> <s>source_e.cc</s> <s>source_f.cc</s> <s>source_g.cc</s> <s>source_h.cc</s>)

# The string in this command should not be split
set_target_properties(<s>foo</s> <s>bar</s> <s>baz</s> <s>PROPERTIES</s> <s>COMPILE_FLAGS</s> "-std=c++11 -Wall -Wextra")

# This command has a very long argument and can't be aligned with the command
# end, so it should be moved to a new line with block indent + 1.
some_long_command_name("Some very long argument that really needs to be on the next line.")

# This situation is similar but the argument to a KWARG needs to be on a
# newline instead.
set(<s>CMAKE_CXX_FLAGS</s> "-std=c++11 -Wall -Wno-sign-compare -Wno-unused-parameter -xx")

set(<s>HEADERS</s> <s>header_a.h</s> <s>header_b.h</s> # This comment should
                                  # be preserved, moreover it should be split
                                  # across two lines.
    <s>header_c.h</s> <s>header_d.h</s>)


# This part of the comment should
# be formatted
# but...
# cmake-format: off
# This bunny should remain untouched:
# .   _ ∩
#   レヘヽ| |
#     (・x・)
#    c( uu}
# cmake-format: on
#          while this part should
#          be formatted again

# This is a paragraph
#
# This is a second paragraph
#
# This is a third paragraph

# This is a comment
# that should be joined but
# TODO(josh): This todo should not be joined with the previous line.
# NOTE(josh): Also this should not be joined with the todo.

if(<s>foo</s>)
if(<s>sbar</s>)
# This comment is in-scope.
add_library(<s>foo_bar_baz</s> <s>foo.cc</s> <s>bar.cc</s> # this is a comment for arg2
                                      # this is more comment for arg2, it should be joined with the first.
    <s>baz.cc</s>) # This comment is part of add_library

other_command(<s>some_long_argument</s> <s>some_long_argument</s>) # this comment is very long and gets split across some lines

other_command(<s>some_long_argument</s> <s>some_long_argument</s> <s>some_long_argument</s>) # this comment is even longer and wouldn't make sense to pack at the end of the command so it gets it's own lines
endif()
endif()


# This very long command should be broken up along keyword arguments
foo(<s>nonkwarg_a</s> <s>nonkwarg_b</s> <s>HEADERS</s> <s>a.h</s> <s>b.h</s> <s>c.h</s> <s>d.h</s> <s>e.h</s> <s>f.h</s> <s>SOURCES</s> <s>a.cc</s> <s>b.cc</s> <s>d.cc</s> <s>DEPENDS</s> <s>foo</s> <s>bar</s> <s>baz</s>)

# This command uses a string with escaped quote chars
foo(<s>some_arg</s> <s>some_arg</s> "This is a \"<s>string\</s>" within a string")

# This command uses an empty string
foo(<s>some_arg</s> <s>some_arg</s> "")

# This command uses a multiline string
foo(<s>some_arg</s> <s>some_arg</s> "
    This string is on multiple lines
")

# No, I really want this to look ugly
# cmake-format: off
add_library(<s>a</s> <s>b.cc</s>
  <s>c.cc</s>         <s>d.cc</s>
           <s>e.cc</s>)
# cmake-format: on

进入这个:

# The following multiple newlines should be collapsed into a single newline

cmake_minimum_required(<s>VERSION</s> <s>2.8.11</s>)
project(<s>cmakelang_test</s>)

# This multiline-comment should be reflowed into a single comment on one line

# This comment should remain right before the command call. Furthermore, the
# command call should be formatted to a single line.
add_subdirectories(<s>foo</s> <s>bar</s> <s>baz</s> <s>foo2</s> <s>bar2</s> <s>baz2</s>)

# This very long command should be wrapped
set(<s>HEADERS</s> <s>very_long_header_name_a.h</s> <s>very_long_header_name_b.h</s>
            <s>very_long_header_name_c.h</s>)

# This command should be split into one line per entry because it has a long
# argument list.
set(<s>SOURCES</s>
    <s>source_a.cc</s>
    <s>source_b.cc</s>
    <s>source_d.cc</s>
    <s>source_e.cc</s>
    <s>source_f.cc</s>
    <s>source_g.cc</s>
    <s>source_h.cc</s>)

# The string in this command should not be split
set_target_properties(<s>foo</s> <s>bar</s> <s>baz</s> <s>PROPERTIES</s> <s>COMPILE_FLAGS</s>
                                             "-std=c++11 -Wall -Wextra")

# This command has a very long argument and can't be aligned with the command
# end, so it should be moved to a new line with block indent + 1.
some_long_command_name(
  "Some very long argument that really needs to be on the next line.")

# This situation is similar but the argument to a KWARG needs to be on a newline
# instead.
set(<s>CMAKE_CXX_FLAGS</s>
    "-std=c++11 -Wall -Wno-sign-compare -Wno-unused-parameter -xx")

set(<s>HEADERS</s>
    <s>header_a.h</s> <s>header_b.h</s> # This comment should be preserved, moreover it should
                          # be split across two lines.
    <s>header_c.h</s> <s>header_d.h</s>)

# This part of the comment should be formatted but...
# cmake-format: off
# This bunny should remain untouched:
# .   _ ∩
#   レヘヽ| |
#     (・x・)
#    c( uu}
# cmake-format: on
# while this part should be formatted again

# This is a paragraph
#
# This is a second paragraph
#
# This is a third paragraph

# This is a comment that should be joined but
# TODO(josh): This todo should not be joined with the previous line.
# NOTE(josh): Also this should not be joined with the todo.

if(<s>foo</s>)
  if(<s>sbar</s>)
    # This comment is in-scope.
    add_library(
      <s>foo_bar_baz</s>
      <s>foo.cc</s> <s>bar.cc</s> # this is a comment for arg2 this is more comment for arg2,
                    # it should be joined with the first.
      <s>baz.cc</s>) # This comment is part of add_library

    other_command(
      <s>some_long_argument</s> <s>some_long_argument</s>) # this comment is very long and
                                             # gets split across some lines

    other_command(
      <s>some_long_argument</s> <s>some_long_argument</s> <s>some_long_argument</s>) # this comment
                                                                # is even longer
                                                                # and wouldn't
                                                                # make sense to
                                                                # pack at the
                                                                # end of the
                                                                # command so it
                                                                # gets it's own
                                                                # lines
  endif()
endif()

# This very long command should be broken up along keyword arguments
foo(<s>nonkwarg_a</s> <s>nonkwarg_b</s>
    <s>HEADERS</s> <s>a.h</s> <s>b.h</s> <s>c.h</s> <s>d.h</s> <s>e.h</s> <s>f.h</s>
    <s>SOURCES</s> <s>a.cc</s> <s>b.cc</s> <s>d.cc</s>
    <s>DEPENDS</s> <s>foo</s>
    <s>bar</s> <s>baz</s>)

# This command uses a string with escaped quote chars
foo(<s>some_arg</s> <s>some_arg</s> "This is a \"<s>string\</s>" within a string")

# This command uses an empty string
foo(<s>some_arg</s> <s>some_arg</s> "")

# This command uses a multiline string
foo(<s>some_arg</s> <s>some_arg</s> "
    This string is on multiple lines
")

# No, I really want this to look ugly
# cmake-format: off
add_library(<s>a</s> <s>b.cc</s>
  <s>c.cc</s>         <s>d.cc</s>
           <s>e.cc</s>)
# cmake-format: on

项目详情