diff mbox series

[RFC,v2,1/2] Add 'make check' and clang-check to build system

Message ID 20210604111434.21422-2-rpalethorpe@suse.com
State Changes Requested
Headers show
Series Libclang based analyzer | expand

Commit Message

Richard Palethorpe June 4, 2021, 11:14 a.m. UTC
Allows the user to run 'make check' to check all source files or
'make check-<target>' to check one source file corresponding to a
target.

Adds makefile pieces for tools/clang-check/main which will be a
libclang based tool. By default this is ran by 'make check'.

In theory allows other tools to be specified with
'make CHECK=tool CHECK_FLAGS=<args> check...'. e.g. 'make CHECK=sparse
CHECK_FLAGS= check-tst_cgroup'

Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
 configure.ac                       |  2 ++
 include/mk/clang-check.mk          |  9 +++++++++
 include/mk/config.mk.in            |  5 +++++
 include/mk/env_post.mk             |  8 ++++++++
 include/mk/generic_leaf_target.inc |  5 ++++-
 include/mk/lib.mk                  |  3 +++
 include/mk/rules.mk                |  9 +++++++++
 include/mk/testcases.mk            |  1 +
 tools/clang-check/.gitignore       |  1 +
 tools/clang-check/Makefile         | 14 ++++++++++++++
 10 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 include/mk/clang-check.mk
 create mode 100644 tools/clang-check/.gitignore
 create mode 100644 tools/clang-check/Makefile

Comments

Petr Vorel June 4, 2021, 2:10 p.m. UTC | #1
Hi Richie,

> Allows the user to run 'make check' to check all source files or
> 'make check-<target>' to check one source file corresponding to a
> target.

> Adds makefile pieces for tools/clang-check/main which will be a
> libclang based tool. By default this is ran by 'make check'.

I haven't looked at Coccinelle, but this LGTM.

But, it still fails to compile:

$ make autotools && ./configure && cd testcases/kernel/syscalls/chown/
$ make clean; make

make -C "/home/pvorel/install/src/ltp.git/lib" -f "/src/ltp/lib/Makefile" all
make[1]: Entering directory '/src/ltp/lib'
make[2]: Nothing to be done for 'all'.
make[2]: Nothing to be done for 'all'.
make[1]: Leaving directory '/src/ltp/lib'
CC testcases/kernel/syscalls/chown/chown01.o
LD testcases/kernel/syscalls/chown/chown01
CC testcases/kernel/syscalls/chown/chown02.o
LD testcases/kernel/syscalls/chown/chown02
CC testcases/kernel/syscalls/chown/chown03.o
LD testcases/kernel/syscalls/chown/chown03
CC testcases/kernel/syscalls/chown/chown04.o
LD testcases/kernel/syscalls/chown/chown04
CC testcases/kernel/syscalls/chown/chown05.o
LD testcases/kernel/syscalls/chown/chown05
make: *** No rule to make target 'chown01_16.c', needed by 'chown01_16'.  Stop.
rm chown01.o chown03.o chown02.o chown05.o chown04.o

This is a newly introduced failure caused by some change in include/mk/ in this
commit.

Could we have also make check in the top level Makefile?

$ make check
make: *** No rule to make target 'check'.  Stop.

$ cd lib && make check
CHECK lib/cloner.c
CHECK lib/get_path.c
CHECK lib/parse_opts.c
CHECK lib/random_range.c
CHECK lib/safe_file_ops.c
CHECK lib/safe_macros.c
CHECK lib/safe_net.c
CHECK lib/safe_pthread.c
CHECK lib/safe_stdio.c
CHECK lib/self_exec.c
CHECK lib/tlibio.c
tst_af_alg.c:16:2: CHECK ERROR: TEST() macro should not be used in library
tst_af_alg.c:27:2: CHECK ERROR: TEST() macro should not be used in library
tst_af_alg.c:74:2: CHECK ERROR: TEST() macro should not be used in library
tst_af_alg.c:109:2: CHECK ERROR: TEST() macro should not be used in library
tst_af_alg.c:119:2: CHECK ERROR: TEST() macro should not be used in library
make: *** [../include/mk/rules.mk:46: check-tst_af_alg] Error 1

Similarly what I added to my patchset which also adds new make target:
https://patchwork.ozlabs.org/project/ltp/patch/20210603183827.24339-2-pvorel@suse.cz/
Although my code has duplicate issue:
../include/mk/generic_trunk_target.inc:105: warning: overriding recipe for target 'check-c'
../include/mk/generic_leaf_target.inc:110: warning: ignoring old recipe for target 'check-c'
../include/mk/generic_trunk_target.inc:105: warning: overriding recipe for target 'check-shell'
../include/mk/generic_leaf_target.inc:118: warning: ignoring old recipe for target 'check-shell'

Also make check on regular test expect it's a library. IMHO these two must be
probably separated:

$ cd testcases/kernel/syscalls/fchown/ && make check
CHECK testcases/kernel/syscalls/fchown/fchown01.c
CHECK testcases/kernel/syscalls/fchown/fchown02.c
CHECK testcases/kernel/syscalls/fchown/fchown03.c
CHECK testcases/kernel/syscalls/fchown/fchown04.c
fchown05.c:80:4: CHECK ERROR: TEST() macro should not be used in library
make: *** [../../../../include/mk/rules.mk:46: check-fchown05] Error 1

Kind regards,
Petr
Cyril Hrubis June 4, 2021, 2:11 p.m. UTC | #2
Hi!
> make -C "/home/pvorel/install/src/ltp.git/lib" -f "/src/ltp/lib/Makefile" all
> make[1]: Entering directory '/src/ltp/lib'
> make[2]: Nothing to be done for 'all'.
> make[2]: Nothing to be done for 'all'.
> make[1]: Leaving directory '/src/ltp/lib'
> CC testcases/kernel/syscalls/chown/chown01.o
> LD testcases/kernel/syscalls/chown/chown01
> CC testcases/kernel/syscalls/chown/chown02.o
> LD testcases/kernel/syscalls/chown/chown02
> CC testcases/kernel/syscalls/chown/chown03.o
> LD testcases/kernel/syscalls/chown/chown03
> CC testcases/kernel/syscalls/chown/chown04.o
> LD testcases/kernel/syscalls/chown/chown04
> CC testcases/kernel/syscalls/chown/chown05.o
> LD testcases/kernel/syscalls/chown/chown05
> make: *** No rule to make target 'chown01_16.c', needed by 'chown01_16'.  Stop.
> rm chown01.o chown03.o chown02.o chown05.o chown04.o
> 
> This is a newly introduced failure caused by some change in include/mk/ in this
> commit.

This is caused by the definition of CHECK_TARGETS in the env_post.mk,
the foo_16 binaries are generated from foo.c sources and there is no
foo_16.c which in turn confuses the check code. I.e. what this means is
that MAKE_TARGETS != list of sources without suffix and we have to do:

diff --git a/include/mk/env_post.mk b/include/mk/env_post.mk
index 8903a934d..c6367b0a5 100644
--- a/include/mk/env_post.mk
+++ b/include/mk/env_post.mk
@@ -89,7 +89,7 @@ $(error You must define $$(prefix) before executing install)
 endif # END $(filter-out install,$(MAKECMDGOALS)),$(MAKECMDGOALS)
 endif
 
-CHECK_TARGETS                  ?= $(addprefix check-,$(MAKE_TARGETS))
+CHECK_TARGETS                  ?= $(addprefix check-, $(patsubst %.c,%,$(sort $(wildcard $(abs_srcdir)/*.c))))
 CHECK                          ?= $(abs_top_srcdir)/tools/clang-check/main
 CHECK_FLAGS                    ?= -resource-dir $(shell $(CLANG) -print-resource-dir)


> Also make check on regular test expect it's a library. IMHO these two must be
> probably separated:
> 
> $ cd testcases/kernel/syscalls/fchown/ && make check
> CHECK testcases/kernel/syscalls/fchown/fchown01.c
> CHECK testcases/kernel/syscalls/fchown/fchown02.c
> CHECK testcases/kernel/syscalls/fchown/fchown03.c
> CHECK testcases/kernel/syscalls/fchown/fchown04.c
> fchown05.c:80:4: CHECK ERROR: TEST() macro should not be used in library
> make: *** [../../../../include/mk/rules.mk:46: check-fchown05] Error 1

I guess that we can pass different flags to the binary so that it gets
the context right.
Richard Palethorpe June 4, 2021, 2:28 p.m. UTC | #3
Hell Petr,

Petr Vorel <pvorel@suse.cz> writes:

> Hi Richie,
>
>> Allows the user to run 'make check' to check all source files or
>> 'make check-<target>' to check one source file corresponding to a
>> target.
>
>> Adds makefile pieces for tools/clang-check/main which will be a
>> libclang based tool. By default this is ran by 'make check'.
>
> I haven't looked at Coccinelle, but this LGTM.
>
> But, it still fails to compile:
>
> $ make autotools && ./configure && cd testcases/kernel/syscalls/chown/
> $ make clean; make
>
> make -C "/home/pvorel/install/src/ltp.git/lib" -f "/src/ltp/lib/Makefile" all
> make[1]: Entering directory '/src/ltp/lib'
> make[2]: Nothing to be done for 'all'.
> make[2]: Nothing to be done for 'all'.
> make[1]: Leaving directory '/src/ltp/lib'
> CC testcases/kernel/syscalls/chown/chown01.o
> LD testcases/kernel/syscalls/chown/chown01
> CC testcases/kernel/syscalls/chown/chown02.o
> LD testcases/kernel/syscalls/chown/chown02
> CC testcases/kernel/syscalls/chown/chown03.o
> LD testcases/kernel/syscalls/chown/chown03
> CC testcases/kernel/syscalls/chown/chown04.o
> LD testcases/kernel/syscalls/chown/chown04
> CC testcases/kernel/syscalls/chown/chown05.o
> LD testcases/kernel/syscalls/chown/chown05
> make: *** No rule to make target 'chown01_16.c', needed by 'chown01_16'.  Stop.
> rm chown01.o chown03.o chown02.o chown05.o chown04.o
>
> This is a newly introduced failure caused by some change in include/mk/ in this
> commit.

I guess if Cyril likes the overall approach and doesn't spot what is
causing this, then I will try fixing it.

>
> Could we have also make check in the top level Makefile?

Yes, I didn't try it for the RFC though.

>
> $ make check
> make: *** No rule to make target 'check'.  Stop.
>
> $ cd lib && make check
> CHECK lib/cloner.c
> CHECK lib/get_path.c
> CHECK lib/parse_opts.c
> CHECK lib/random_range.c
> CHECK lib/safe_file_ops.c
> CHECK lib/safe_macros.c
> CHECK lib/safe_net.c
> CHECK lib/safe_pthread.c
> CHECK lib/safe_stdio.c
> CHECK lib/self_exec.c
> CHECK lib/tlibio.c
> tst_af_alg.c:16:2: CHECK ERROR: TEST() macro should not be used in library
> tst_af_alg.c:27:2: CHECK ERROR: TEST() macro should not be used in library
> tst_af_alg.c:74:2: CHECK ERROR: TEST() macro should not be used in library
> tst_af_alg.c:109:2: CHECK ERROR: TEST() macro should not be used in library
> tst_af_alg.c:119:2: CHECK ERROR: TEST() macro should not be used in library
> make: *** [../include/mk/rules.mk:46: check-tst_af_alg] Error 1
>
> Similarly what I added to my patchset which also adds new make target:
> https://patchwork.ozlabs.org/project/ltp/patch/20210603183827.24339-2-pvorel@suse.cz/
> Although my code has duplicate issue:
> ../include/mk/generic_trunk_target.inc:105: warning: overriding recipe for target 'check-c'
> ../include/mk/generic_leaf_target.inc:110: warning: ignoring old recipe for target 'check-c'
> ../include/mk/generic_trunk_target.inc:105: warning: overriding recipe for target 'check-shell'
> ../include/mk/generic_leaf_target.inc:118: warning: ignoring old recipe for target 'check-shell'
>
> Also make check on regular test expect it's a library. IMHO these two must be
> probably separated:
>
> $ cd testcases/kernel/syscalls/fchown/ && make check
> CHECK testcases/kernel/syscalls/fchown/fchown01.c
> CHECK testcases/kernel/syscalls/fchown/fchown02.c
> CHECK testcases/kernel/syscalls/fchown/fchown03.c
> CHECK testcases/kernel/syscalls/fchown/fchown04.c
> fchown05.c:80:4: CHECK ERROR: TEST() macro should not be used in library
> make: *** [../../../../include/mk/rules.mk:46: check-fchown05] Error 1

It fails because it is using the old test API, so there is no struct
tst_test test var. I don't think we need to separate the checker. It can
detect what type of file (translation unit) it is processing. In the
case of old API tests, I would simply disable any checks.

All the old tests and test libraries will have something in common. For
the tests, they all import "test.h" (even if through another header), so
we can identify them by that.

>
> Kind regards,
> Petr
Cyril Hrubis June 4, 2021, 2:33 p.m. UTC | #4
Hi!
> > $ make check
> > make: *** No rule to make target 'check'.  Stop.
> >
> > $ cd lib && make check
> > CHECK lib/cloner.c
> > CHECK lib/get_path.c
> > CHECK lib/parse_opts.c
> > CHECK lib/random_range.c
> > CHECK lib/safe_file_ops.c
> > CHECK lib/safe_macros.c
> > CHECK lib/safe_net.c
> > CHECK lib/safe_pthread.c
> > CHECK lib/safe_stdio.c
> > CHECK lib/self_exec.c
> > CHECK lib/tlibio.c
> > tst_af_alg.c:16:2: CHECK ERROR: TEST() macro should not be used in library
> > tst_af_alg.c:27:2: CHECK ERROR: TEST() macro should not be used in library
> > tst_af_alg.c:74:2: CHECK ERROR: TEST() macro should not be used in library
> > tst_af_alg.c:109:2: CHECK ERROR: TEST() macro should not be used in library
> > tst_af_alg.c:119:2: CHECK ERROR: TEST() macro should not be used in library
> > make: *** [../include/mk/rules.mk:46: check-tst_af_alg] Error 1
> >
> > Similarly what I added to my patchset which also adds new make target:
> > https://patchwork.ozlabs.org/project/ltp/patch/20210603183827.24339-2-pvorel@suse.cz/
> > Although my code has duplicate issue:
> > ../include/mk/generic_trunk_target.inc:105: warning: overriding recipe for target 'check-c'
> > ../include/mk/generic_leaf_target.inc:110: warning: ignoring old recipe for target 'check-c'
> > ../include/mk/generic_trunk_target.inc:105: warning: overriding recipe for target 'check-shell'
> > ../include/mk/generic_leaf_target.inc:118: warning: ignoring old recipe for target 'check-shell'
> >
> > Also make check on regular test expect it's a library. IMHO these two must be
> > probably separated:
> >
> > $ cd testcases/kernel/syscalls/fchown/ && make check
> > CHECK testcases/kernel/syscalls/fchown/fchown01.c
> > CHECK testcases/kernel/syscalls/fchown/fchown02.c
> > CHECK testcases/kernel/syscalls/fchown/fchown03.c
> > CHECK testcases/kernel/syscalls/fchown/fchown04.c
> > fchown05.c:80:4: CHECK ERROR: TEST() macro should not be used in library
> > make: *** [../../../../include/mk/rules.mk:46: check-fchown05] Error 1
> 
> It fails because it is using the old test API, so there is no struct
> tst_test test var. I don't think we need to separate the checker. It can
> detect what type of file (translation unit) it is processing. In the
> case of old API tests, I would simply disable any checks.
> 
> All the old tests and test libraries will have something in common. For
> the tests, they all import "test.h" (even if through another header), so
> we can identify them by that.

For the top level library we pass -DLTPLIB in CFLAGS, not sure if that
could be used to identify library code...
Cyril Hrubis June 7, 2021, 9:12 a.m. UTC | #5
Hi!
> > +include $(top_srcdir)/include/mk/env_pre.mk
> > +include $(top_srcdir)/include/mk/functions.mk
> > +
> > +HOST_MAKE_TARGETS	:= main
> > +HOST_LDFLAGS 		+= -lclang
> If anyone else trying this has problems linking the tool, at least for 
> me, this must be
> HOST_LDLIBS ?????? ?????? += -lclang
> 
> Otherwise the link order is wrong (main.c after -lclang) and all symbols 
> from libclang are undefined.

Thx for report, indeed that has to be fixed.
Joerg Vehlow June 7, 2021, 9:18 a.m. UTC | #6
Hi,

On 6/4/2021 1:14 PM, Richard Palethorpe via ltp wrote:
> diff --git a/tools/clang-check/Makefile b/tools/clang-check/Makefile
> new file mode 100644
> index 000000000..4650d6057
> --- /dev/null
> +++ b/tools/clang-check/Makefile
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2021 SUSE LLC <rpalethorpe@suse.com>
> +# Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz>
> +# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
> +
> +top_srcdir		?= ../..
> +
> +include $(top_srcdir)/include/mk/env_pre.mk
> +include $(top_srcdir)/include/mk/functions.mk
> +
> +HOST_MAKE_TARGETS	:= main
> +HOST_LDFLAGS 		+= -lclang
If anyone else trying this has problems linking the tool, at least for 
me, this must be
HOST_LDLIBS         += -lclang

Otherwise the link order is wrong (main.c after -lclang) and all symbols 
from libclang are undefined.

Jörg
Petr Vorel June 11, 2021, 1:49 p.m. UTC | #7
Hi Richie,

> Allows the user to run 'make check' to check all source files or
> 'make check-<target>' to check one source file corresponding to a
> target.

> Adds makefile pieces for tools/clang-check/main which will be a
> libclang based tool. By default this is ran by 'make check'.

> In theory allows other tools to be specified with
> 'make CHECK=tool CHECK_FLAGS=<args> check...'. e.g. 'make CHECK=sparse
> CHECK_FLAGS= check-tst_cgroup'

one more proposal (addition to Metan's fix [1]):
how about to add top level make check target:

diff --git Makefile Makefile
index 56812d77b..b65315618 100644
--- Makefile
+++ Makefile
@@ -79,6 +79,7 @@ BOOTSTRAP_TARGETS	:= $(sort $(COMMON_TARGETS) $(CLEAN_TARGETS) $(INSTALL_TARGETS
 CLEAN_TARGETS		:= $(addsuffix -clean,$(CLEAN_TARGETS))
 INSTALL_TARGETS		:= $(addsuffix -install,$(INSTALL_TARGETS))
 MAKE_TARGETS		:= $(addsuffix -all,$(filter-out lib,$(COMMON_TARGETS)))
+CHECK_TARGETS		:= $(addsuffix -check,testcases lib)
 
 # There's no reason why we should run `all' twice. Otherwise we're just wasting
 # 3+ mins of useful CPU cycles on a modern machine, and even more time on an
@@ -99,6 +100,11 @@ INSTALL_DIR		:= $(abspath $(INSTALL_DIR))
 $(sort $(addprefix $(abs_top_builddir)/,$(BOOTSTRAP_TARGETS)) $(INSTALL_DIR) $(DESTDIR)/$(bindir)):
 	mkdir -m 00755 -p "$@"
 
+$(CHECK_TARGETS):
+	echo "CHECK_TARGETS: $(CHECK_TARGETS)"; \
+	$(MAKE) -C "$(subst -check,,$@)" \
+		-f "$(abs_top_srcdir)/$(subst -check,,$@)/Makefile" all
+
 ## Pattern based subtarget rules.
 lib-install: lib-all
 
@@ -189,6 +195,9 @@ INSTALL_TARGETS		+= $(addprefix $(DESTDIR)/$(bindir)/,$(BINDIR_INSTALL_SCRIPTS))
 
 $(INSTALL_TARGETS): $(INSTALL_DIR) $(DESTDIR)/$(bindir)
 
+## Check
+check: $(CHECK_TARGETS)
+
 ## Install
 install: $(INSTALL_TARGETS)
 
---

Kind regards,
Petr

[1] https://lists.linux.it/pipermail/ltp/2021-June/023017.html
Petr Vorel June 11, 2021, 2:17 p.m. UTC | #8
Hi Richie,
> Hi Richie,

> one more proposal (addition to Metan's fix [1]):
> how about to add top level make check target:

> diff --git Makefile Makefile
> index 56812d77b..b65315618 100644
> --- Makefile
> +++ Makefile
> @@ -79,6 +79,7 @@ BOOTSTRAP_TARGETS	:= $(sort $(COMMON_TARGETS) $(CLEAN_TARGETS) $(INSTALL_TARGETS
>  CLEAN_TARGETS		:= $(addsuffix -clean,$(CLEAN_TARGETS))
>  INSTALL_TARGETS		:= $(addsuffix -install,$(INSTALL_TARGETS))
>  MAKE_TARGETS		:= $(addsuffix -all,$(filter-out lib,$(COMMON_TARGETS)))
> +CHECK_TARGETS		:= $(addsuffix -check,testcases lib)

>  # There's no reason why we should run `all' twice. Otherwise we're just wasting
>  # 3+ mins of useful CPU cycles on a modern machine, and even more time on an
> @@ -99,6 +100,11 @@ INSTALL_DIR		:= $(abspath $(INSTALL_DIR))
>  $(sort $(addprefix $(abs_top_builddir)/,$(BOOTSTRAP_TARGETS)) $(INSTALL_DIR) $(DESTDIR)/$(bindir)):
>  	mkdir -m 00755 -p "$@"

> +$(CHECK_TARGETS):
> +	echo "CHECK_TARGETS: $(CHECK_TARGETS)"; \
This should be obviously left out (my debug message).
> +	$(MAKE) -C "$(subst -check,,$@)" \
> +		-f "$(abs_top_srcdir)/$(subst -check,,$@)/Makefile" all
This should be check target
		-f "$(abs_top_srcdir)/$(subst -check,,$@)/Makefile" check
> +
>  ## Pattern based subtarget rules.
>  lib-install: lib-all

> @@ -189,6 +195,9 @@ INSTALL_TARGETS		+= $(addprefix $(DESTDIR)/$(bindir)/,$(BINDIR_INSTALL_SCRIPTS))

>  $(INSTALL_TARGETS): $(INSTALL_DIR) $(DESTDIR)/$(bindir)

> +## Check
> +check: $(CHECK_TARGETS)
> +
>  ## Install
>  install: $(INSTALL_TARGETS)

> ---

+ there needs to be check added to RECURSIVE_TARGETS
+++ include/mk/generic_trunk_target.inc
@@ -48,7 +48,7 @@
 
 include $(top_srcdir)/include/mk/functions.mk
 
-RECURSIVE_TARGETS		?= all install
+RECURSIVE_TARGETS		?= all install check
 
 $(eval $(get_make_dirs))
 
---

Kind regards,
Petr
Richard Palethorpe June 14, 2021, 11:09 a.m. UTC | #9
Hello Petr,

Petr Vorel <pvorel@suse.cz> writes:

> Hi Richie,
>> Hi Richie,
>
>> one more proposal (addition to Metan's fix [1]):
>> how about to add top level make check target:
>
>> diff --git Makefile Makefile
>> index 56812d77b..b65315618 100644
>> --- Makefile
>> +++ Makefile
>> @@ -79,6 +79,7 @@ BOOTSTRAP_TARGETS	:= $(sort $(COMMON_TARGETS) $(CLEAN_TARGETS) $(INSTALL_TARGETS
>>  CLEAN_TARGETS		:= $(addsuffix -clean,$(CLEAN_TARGETS))
>>  INSTALL_TARGETS		:= $(addsuffix -install,$(INSTALL_TARGETS))
>>  MAKE_TARGETS		:= $(addsuffix -all,$(filter-out lib,$(COMMON_TARGETS)))
>> +CHECK_TARGETS		:= $(addsuffix -check,testcases lib)
>
>>  # There's no reason why we should run `all' twice. Otherwise we're just wasting
>>  # 3+ mins of useful CPU cycles on a modern machine, and even more time on an
>> @@ -99,6 +100,11 @@ INSTALL_DIR		:= $(abspath $(INSTALL_DIR))
>>  $(sort $(addprefix $(abs_top_builddir)/,$(BOOTSTRAP_TARGETS)) $(INSTALL_DIR) $(DESTDIR)/$(bindir)):
>>  	mkdir -m 00755 -p "$@"
>
>> +$(CHECK_TARGETS):
>> +	echo "CHECK_TARGETS: $(CHECK_TARGETS)"; \
> This should be obviously left out (my debug message).
>> +	$(MAKE) -C "$(subst -check,,$@)" \
>> +		-f "$(abs_top_srcdir)/$(subst -check,,$@)/Makefile" all
> This should be check target
> 		-f "$(abs_top_srcdir)/$(subst -check,,$@)/Makefile" check
>> +
>>  ## Pattern based subtarget rules.
>>  lib-install: lib-all
>
>> @@ -189,6 +195,9 @@ INSTALL_TARGETS		+= $(addprefix $(DESTDIR)/$(bindir)/,$(BINDIR_INSTALL_SCRIPTS))
>
>>  $(INSTALL_TARGETS): $(INSTALL_DIR) $(DESTDIR)/$(bindir)
>
>> +## Check
>> +check: $(CHECK_TARGETS)
>> +
>>  ## Install
>>  install: $(INSTALL_TARGETS)
>
>> ---
>
> + there needs to be check added to RECURSIVE_TARGETS
> +++ include/mk/generic_trunk_target.inc
> @@ -48,7 +48,7 @@
>  
>  include $(top_srcdir)/include/mk/functions.mk
>  
> -RECURSIVE_TARGETS		?= all install
> +RECURSIVE_TARGETS		?= all install check
>  
>  $(eval $(get_make_dirs))
>  
> ---
>
> Kind regards,
> Petr

Thanks. It appears defining trunk-check (similar to check-all) and
"check: trunk-check" in addition to adding check to the recursive
targets seems to work.
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 136d82d09..b37c13c3c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,6 +14,7 @@  AC_CONFIG_FILES([ \
 ])
 
 AC_ARG_VAR(HOSTCC, [The C compiler on the host])
+AC_ARG_VAR(CLANG, [The LLVM Clang C compiler on the host])
 
 AM_MAINTAINER_MODE([enable])
 
@@ -42,6 +43,7 @@  AC_CHECK_DECLS([SEM_STAT_ANY],,,[#include <sys/sem.h>])
 
 AC_CHECK_HEADERS_ONCE([ \
     asm/ldt.h \
+    clang-c/Index.h \
     ifaddrs.h \
     keyutils.h \
     linux/can.h \
diff --git a/include/mk/clang-check.mk b/include/mk/clang-check.mk
new file mode 100644
index 000000000..2ab7b67a1
--- /dev/null
+++ b/include/mk/clang-check.mk
@@ -0,0 +1,9 @@ 
+# Rules to make clang-check tool(s) for inclusion in lib and testcases Makefiles
+
+CLANG_CHECK_DIR:= $(abs_top_builddir)/tools/clang-check
+
+$(CLANG_CHECK_DIR)/main: $(CLANG_CHECK_DIR)
+	$(MAKE) -C "$^" -f "$(CLANG_CHECK_DIR)/Makefile" all
+
+$(CLANG_CHECK_DIR): %:
+	mkdir -p "$@"
diff --git a/include/mk/config.mk.in b/include/mk/config.mk.in
index 218447ef3..361b6a746 100644
--- a/include/mk/config.mk.in
+++ b/include/mk/config.mk.in
@@ -44,6 +44,11 @@  HOSTCC := cc
 endif
 endif
 
+CLANG := @CLANG@
+ifeq ($(strip $(CLANG)),)
+CLANG := clang
+endif
+
 AIO_LIBS		:= @AIO_LIBS@
 CAP_LIBS		:= @CAP_LIBS@
 ACL_LIBS		:= @ACL_LIBS@
diff --git a/include/mk/env_post.mk b/include/mk/env_post.mk
index 1d22f9c53..8903a934d 100644
--- a/include/mk/env_post.mk
+++ b/include/mk/env_post.mk
@@ -89,6 +89,14 @@  $(error You must define $$(prefix) before executing install)
 endif # END $(filter-out install,$(MAKECMDGOALS)),$(MAKECMDGOALS)
 endif
 
+CHECK_TARGETS			?= $(addprefix check-,$(MAKE_TARGETS))
+CHECK				?= $(abs_top_srcdir)/tools/clang-check/main
+CHECK_FLAGS			?= -resource-dir $(shell $(CLANG) -print-resource-dir)
+
+ifeq ($(dir $(CHECK)),$(abs_top_srcdir)/tools/clang-check/)
+CHECK_DEPS			+= $(CHECK)
+endif
+
 include $(top_srcdir)/include/mk/rules.mk
 
 endif
diff --git a/include/mk/generic_leaf_target.inc b/include/mk/generic_leaf_target.inc
index 64953f89a..aa092a5a3 100644
--- a/include/mk/generic_leaf_target.inc
+++ b/include/mk/generic_leaf_target.inc
@@ -92,7 +92,7 @@ 
 # INSTALL_DIR			:= $(libdir)
 #
 
-.PHONY: all clean install
+.PHONY: all clean install check
 
 ifneq ($(strip $(MAKE_TARGETS)),)
 $(MAKE_TARGETS) += $(HOST_MAKE_TARGETS)
@@ -109,4 +109,7 @@  $(INSTALL_FILES): | $(INSTALL_DEPS)
 
 install: $(INSTALL_FILES)
 
+$(CHECK_TARGETS): | $(CHECK_DEPS)
+check: $(CHECK_TARGETS)
+
 # vim: syntax=make
diff --git a/include/mk/lib.mk b/include/mk/lib.mk
index f9b6c0aff..a3961bce5 100644
--- a/include/mk/lib.mk
+++ b/include/mk/lib.mk
@@ -26,6 +26,7 @@ 
 # Makefile to include for libraries.
 
 include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/clang-check.mk
 
 INSTALL_DIR	:= $(libdir)
 
@@ -57,6 +58,8 @@  LIBSRCS		:= $(filter-out $(FILTER_OUT_LIBSRCS),$(LIBSRCS))
 
 LIBOBJS		:= $(LIBSRCS:.c=.o)
 
+CHECK_TARGETS	:= $(addprefix check-,$(notdir $(LIBSRCS:.c=)))
+
 $(LIB): $(notdir $(LIBOBJS))
 	@if [ -z "$(strip $^)" ] ; then \
 		echo "Cowardly refusing to create empty archive"; \
diff --git a/include/mk/rules.mk b/include/mk/rules.mk
index c8f4bbbbe..2a04b2b67 100644
--- a/include/mk/rules.mk
+++ b/include/mk/rules.mk
@@ -37,3 +37,12 @@  else
 	@$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $^ $(LTPLDLIBS) $(LDLIBS) -o $@
 	@echo CC $(target_rel_dir)$@
 endif
+
+.PHONY: $(CHECK_TARGETS)
+$(CHECK_TARGETS): check-%: %.c
+ifdef VERBOSE
+	$(CHECK) $(CHECK_FLAGS) $(CPPFLAGS) $(CFLAGS) $<
+else
+	@$(CHECK) $(CHECK_FLAGS) $(CPPFLAGS) $(CFLAGS) $<
+	@echo CHECK $(target_rel_dir)$<
+endif
diff --git a/include/mk/testcases.mk b/include/mk/testcases.mk
index 1c81773d0..e59899898 100644
--- a/include/mk/testcases.mk
+++ b/include/mk/testcases.mk
@@ -22,6 +22,7 @@ 
 
 include $(top_srcdir)/include/mk/env_pre.mk
 include $(top_srcdir)/include/mk/functions.mk
+include $(top_srcdir)/include/mk/clang-check.mk
 
 APICMDS_DIR	:= $(abs_top_builddir)/tools/apicmds
 
diff --git a/tools/clang-check/.gitignore b/tools/clang-check/.gitignore
new file mode 100644
index 000000000..ba2906d06
--- /dev/null
+++ b/tools/clang-check/.gitignore
@@ -0,0 +1 @@ 
+main
diff --git a/tools/clang-check/Makefile b/tools/clang-check/Makefile
new file mode 100644
index 000000000..4650d6057
--- /dev/null
+++ b/tools/clang-check/Makefile
@@ -0,0 +1,14 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2021 SUSE LLC <rpalethorpe@suse.com>
+# Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz>
+# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
+
+top_srcdir		?= ../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/functions.mk
+
+HOST_MAKE_TARGETS	:= main
+HOST_LDFLAGS 		+= -lclang
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk