将 linting 添加到基于 autotools 的构建系统

Adding linting to autotools-based build system

我想将 cpplint.py (https://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) 添加到基于 autotools 的项目中。有谁知道这样做的正确方法吗?

假设您想要 运行 所有 .cpp 个源文件的 linter 作为 make 的一部分。我们还假设 linter 在您的路径中并且您没有将它的副本作为包的一部分分发。

首先检查以确保您在 configure.ac:

中有可用的 linter
AC_PATH_PROG([CPPLINT], [cpplint.py], [true])
AS_IF([test "x$CPPLINT" = xtrue],
    [AC_MSG_WARN([We recommend cpplint.py for developing this package.
Get it from https://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py
and put it in your path, or point the CPPLINT environment variable at it.])])

见下文true的解释,这里的true不是布尔真值。如果你想让 linter 成为绝对要求,请改用 AC_MSG_ERROR

实现它的最佳方法 运行 是编写 Makefile 代码并将其挂接到 Automake 的 all-local 目标。如果 linter 不可用,那么这将很好地调用 true 命令,该命令什么都不做。

lint: $(myprogram_SOURCES)
    -$(CPPLINT) $^

all-local: lint

.PHONY: lint

这假设您要检查的源文件都存储在变量 myprogram_SOURCES 中。根据您的设置,您可能会将它们放在一个或多个不同的变量中。

如果您使用戳记文件而不是伪造目标,您甚至可以使用 $? 而不是 $^.

使其仅对更改的文件进行 lint

配方开头的 - 告诉 Make 忽略来自该规则的错误。这一点很重要,否则即使出现一个 linting 错误,构建也会失败!那会很烦人,因为有些人喜欢先编写和测试粗略的代码,然后再清理它。另一方面,这个解决方案也让人们完全忽略 linting 错误。

因此,我建议将 linting 移动到 make check。这样,人们可以按照他们想要的方式进行开发,使用 make 进行编译,但您可以要求任何新代码通过 make check。为此,请删除 $(CPPLINT) 前面的 - 并将 all-local 更改为 check-local

受到@ptomato 的回答的启发,我开始在项目中这样做。

# Make this OK to fail, tee our lint to the file as well.
LINTER_FLAGS ?= -- -I. $(AM_CPPFLAGS) $(DEFS)
%.c.lint: %.c
    - $(LINTER) $? $(LINTER_FLAGS) | tee $@

# Select only C files
# We have to abuse the auto rule above so that -j works
lint: $(subst .c,.c.lint, $(filter %.c,$(lint_files)))

.PHONY: lint

check-local: lint

clean-local:
    rm -f *.lint

这让我们可以轻松使用 clang-tidycppcheck

它还可以确保 -j 正常工作。 $^ 可以是几十个文件,这些文件将完成 1 个 lint 作业并花费很长时间。这种方式有点古怪,但每个文件都会做 1 个 lint 作业。