可以格式化您的列表文件,使它们看起来不像废话
项目描述
cmake-format项目为cmake提供质量保证 (QA) 工具:
cmake-annotate可以从你的列表文件中生成漂亮的 HTML
cmake-format可以很好地格式化您的列表文件,使它们看起来不像废话。
cmake-lint可以检查您的列表文件是否有问题
ctest-to可以解析 ctest 输出树并将其转换为更结构化的格式(JSON 或 XML)。
安装
使用pip从pypi安装:
pip install cmakelang
或查看在线文档以了解其他选项。
集成
有一个官方的vscode 扩展
有人还创建了一个sublime 插件
您可以将cmake-format添加到您的预提交 配置中
用法
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: <标签>]] |
为了将位置参数列表注释为可排序,可接受的标签是:可排序或排序。对于上面列出的位置参数列表本身可排序的命令,您可以通过使用unsortable或unsort注释它们来本地禁用排序。例如:
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