将 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-tidy
或 cppcheck
。
它还可以确保 -j
正常工作。 $^
可以是几十个文件,这些文件将完成 1 个 lint 作业并花费很长时间。这种方式有点古怪,但每个文件都会做 1 个 lint 作业。
我想将 cpplint.py (https://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) 添加到基于 autotools 的项目中。有谁知道这样做的正确方法吗?
假设您想要 运行 所有 .cpp
个源文件的 linter 作为 make
的一部分。我们还假设 linter 在您的路径中并且您没有将它的副本作为包的一部分分发。
首先检查以确保您在 configure.ac
:
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
中。根据您的设置,您可能会将它们放在一个或多个不同的变量中。
如果您使用戳记文件而不是伪造目标,您甚至可以使用 $?
而不是 $^
.
配方开头的 -
告诉 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-tidy
或 cppcheck
。
它还可以确保 -j
正常工作。 $^
可以是几十个文件,这些文件将完成 1 个 lint 作业并花费很长时间。这种方式有点古怪,但每个文件都会做 1 个 lint 作业。