selftests: add build/cross-build dependency check script
Subsystems (3)
Shuah Khan
maintainerPATCH 1/1 selftests: add build/cross-build dependency check script
Add build/cross-build dependency check script kselftest_deps.sh This script does the following:
Usage: ./kselftest_deps.sh -[p] <compiler> [test_name]
kselftest_deps.sh [-p] gcc kselftest_deps.sh [-p] gcc vm kselftest_deps.sh [-p] aarch64-linux-gnu-gcc kselftest_deps.sh [-p] aarch64-linux-gnu-gcc vm
- Should be run in selftests directory in the kernel repo.
- Checks if Kselftests can be built/cross-built on a system.
- Parses all test/sub-test Makefile to find library dependencies.
- Runs compile test on a trivial C file with LDLIBS specified in the test Makefiles to identify missing library dependencies.
- Prints suggested target list for a system filtering out tests failed the build dependency check from the TARGETS in Selftests the main Makefile when optional -p is specified.
- Prints pass/fail dependency check for each tests/sub-test.
- Prints pass/fail targets and libraries.
- Default: runs dependency checks on all tests.
- Optional test name can be specified to check dependencies for it.
To make LDLIBS parsing easier
- change gpio and memfd Makefiles to use the same temporary variable used to find and add libraries to LDLIBS.
- simlify LDLIBS append logic in intel_pstate/Makefile.
Results from run on x86_64 system (trimmed detailed pass/fail list):
========================================================
Kselftest Dependency Check for [./kselftest_deps.sh gcc ] results...
========================================================
Checked tests defining LDLIBS dependencies
--------------------------------------------------------
Total tests with Dependencies:
55 Pass: 53 Fail: 2
--------------------------------------------------------
Targets passed build dependency check on system:
bpf capabilities filesystems futex gpio intel_pstate membarrier memfd mqueue net powerpc ptp rseq rtc safesetid timens timers vDSO vm
--------------------------------------------------------
FAIL: netfilter/Makefile dependency check: -lmnl
FAIL: gpio/Makefile dependency check: -lmount
--------------------------------------------------------
Targets failed build dependency check on system:
gpio netfilter
--------------------------------------------------------
Missing libraries system
-lmnl -lmount
--------------------------------------------------------
========================================================
Results from run on x86_64 system with aarch64-linux-gnu-gcc:
(trimmed detailed pass/fail list):
========================================================
Kselftest Dependency Check for [./kselftest_deps.sh aarch64-linux-gnu-gcc ] results...
========================================================
Checked tests defining LDLIBS dependencies
--------------------------------------------------------
Total tests with Dependencies:
55 Pass: 41 Fail: 14
--------------------------------------------------------
Targets failed build dependency check on system:
bpf capabilities filesystems futex gpio intel_pstate membarrier memfd mqueue net powerpc ptp rseq rtc timens timers vDSO vm
--------------------------------------------------------
--------------------------------------------------------
Targets failed build dependency check on system:
bpf capabilities gpio memfd mqueue net netfilter safesetid vm
--------------------------------------------------------
Missing libraries system
-lcap -lcap-ng -lelf -lfuse -lmnl -lmount -lnuma -lpopt -lz
--------------------------------------------------------
========================================================
--- tools/testing/selftests/gpio/Makefile | 12 +- tools/testing/selftests/intel_pstate/Makefile | 2 +- tools/testing/selftests/kselftest_deps.sh | 272 ++++++++++++++++++ tools/testing/selftests/memfd/Makefile | 14 +- 4 files changed, 291 insertions(+), 9 deletions(-) create mode 100755 tools/testing/selftests/kselftest_deps.sh
tools/testing/selftests/gpio/Makefile +6 -6
@@ -1,13 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 -MOUNT_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) -MOUNT_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) -ifeq ($(MOUNT_LDLIBS),) -MOUNT_LDLIBS := -lmount -I/usr/include/libmount +VAR_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) +VAR_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) +ifeq ($(VAR_LDLIBS),) +VAR_LDLIBS := -lmount -I/usr/include/libmount endif -CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) -LDLIBS += $(MOUNT_LDLIBS) +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) +LDLIBS += $(VAR_LDLIBS) TEST_PROGS := gpio-mockup.sh TEST_FILES := gpio-mockup-sysfs.sh
tools/testing/selftests/intel_pstate/Makefile +1 -1
@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE -LDLIBS := $(LDLIBS) -lm +LDLIBS += -lm uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
tools/testing/selftests/kselftest_deps.sh new file +272 -0
272 lines not on this page · raw message
tools/testing/selftests/memfd/Makefile +12 -2
@@ -8,11 +8,21 @@ TEST_GEN_PROGS := memfd_test TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh TEST_GEN_FILES := fuse_test fuse_mnt -fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) +VAR_CFLAGS := $(shell pkg-config fuse --cflags 2>/dev/null) +ifeq ($(VAR_CFLAGS),) +VAR_CFLAGS := -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse +endif + +VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) +ifeq ($(VAR_LDLIBS),) +VAR_LDLIBS := -lfuse -pthread +endif + +fuse_mnt.o: CFLAGS += $(VAR_CFLAGS) include ../lib.mk -$(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) +$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) $(OUTPUT)/memfd_test: memfd_test.c common.c $(OUTPUT)/fuse_test: fuse_test.c common.c
Signature · 1 line
2.20.1
Hi,
tools/testing/selftests/gpio/Makefile line 10
Quoted 4 lines · Shuah Khan
tools/testing/selftests/gpio/Makefile +2
-2-CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) -LDLIBS += $(MOUNT_LDLIBS) +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) +LDLIBS += $(VAR_LDLIBS)
(1) Can that series of ../../../.. be replaced by $(objtree)? If so, that would be much cleaner IMO.
(2) I can't find anything that checks that ../../../../usr/include exists (or has been installed via 'make headers_install'). Or anything that requires that CONFIG_HEADERS_INSTALL be set/enabled. Well, other than a Makefile error, but that's not a nice way to find out.
Preferably we would have some Kconfig check/enforcement or at least some documentation.
Thoughts?
thanks.
Signature · 1 line
~Randy
Shuah Khan
maintainerQuoted 12 lines · Randy Dunlap
Hi,
tools/testing/selftests/gpio/Makefile line 10
Quoted 4 lines · Shuah Khan
tools/testing/selftests/gpio/Makefile +2
-2-CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) -LDLIBS += $(MOUNT_LDLIBS) +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) +LDLIBS += $(VAR_LDLIBS)(1) Can that series of ../../../.. be replaced by $(objtree)? If so, that would be much cleaner IMO.
Agreed. It can be done in a separate patch. We have other tests that do similar hard coded header paths.
Quoted 5 lines
(2) I can't find anything that checks that ../../../../usr/include exists (or has been installed via 'make
headers_install'). Or anything that requires thatCONFIG_HEADERS_INSTALLbe set/enabled. Well, other than aMakefileerror, but that's not a nice way to find out.
At the moment no. When this Makefile is fixed, that is another check to add. It is addressed by headers install during selftest make.
Headers are installed as part of selftests make since selftests are often dependent on recent headers and headers install is a necessary step.
You are right. There are several tests that need cleanup for such hard coded values and this dependency check script in this patch currently does libs check. My plan is to extend this to check for headers installed or not and flag headers as missing dependency.
I can do that in my next version of this dependency check script.
thanks,
-- Shuah
Quoted 4 lines
-----Original Message-----
From: [email protected] <[email protected]> On Behalf Of Randy DunlapOn 4/14/20 2:22 PM, Shuah Khan wrote:
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +2
-2-CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) -LDLIBS += $(MOUNT_LDLIBS) +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) +LDLIBS += $(VAR_LDLIBS)(1) Can that series of ../../../.. be replaced by $(objtree)? If so, that would be much cleaner IMO.
kselftests doesn't set $(objtree) when it is run directly (ie make -C tools/testing/selftests)
I had my own solution which was to use KBUILD_OUTPUT, like so:
This was a patch in my queue, that I didn't send in because I wasn't very happy with it. I was still considering alternatives.
---------------- (patch)
Subject: [PATCH] selftests/vm: use includes from KBUILD_OUTPUT directory
The Makefile for the vm tests was specifying a relative path (in the source directory) for accessing include files. This doesn't work when the headers files are placed in another directory (with O= or KBUILD_OUTPUT). It may appear to work, but ends up using includes from the host machine, which may not match the kernel source being compiled against.
Without this change, when the program userfaultfd.c was compiled, it generated errors like the following:
userfaultfd.c:267:21: error: 'UFFD_API_RANGE_IOCTLS_BASIC' undeclared here (not in a function)
.expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC,
^~~~~~~~~~~~~~~~~~~~~~~~~~~
userfaultfd.c: In function 'uffd_poll_thread':
userfaultfd.c:529:8: error: 'UFFD_EVENT_FORK' undeclared (first use in this function)
case UFFD_EVENT_FORK:
^~~~~~~~~~~~~~~
userfaultfd.c:529:8: note: each undeclared identifier is reported only once for each function it appears in
userfaultfd.c:531:18: error: 'union <anonymous>' has no member named 'fork'
uffd = msg.arg.fork.ufd;
^
Change the CFLAGS definition in the Makefile to reference KBUILD_OUTPUT.
--- tools/testing/selftests/vm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/vm/Makefile +1 -1
@@ -3,7 +3,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/') -CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) +CFLAGS = -Wall -I $(KBUILD_OUTPUT)/usr/include $(EXTRA_CFLAGS) LDLIBS = -lrt TEST_GEN_FILES = compaction_test TEST_GEN_FILES += gup_benchmark
Signature · 7 lines
2.1.4 -------- (end patch) The reason I wasn't happy is that this required another patch to tools/testing/Makefile to make sure KBUILD_OUTPUT was always set. I got sidetracked on the make headers_install issue, and didn't finish this up. Sorry about that. (See below for the headers_install issue).
Quoted 5 lines
(2) I can't find anything that checks that ../../../../usr/include exists (or has been installed via 'make
headers_install'). Or anything that requires thatCONFIG_HEADERS_INSTALLbe set/enabled. Well, other than aMakefileerror, but that's not a nice way to find out.
The kselftest handling of headers_install is quite confusing. There is a dependency in the top-level Makefile that ends up causing a vmlinux build, even if you just finished doing a headers_install recently (at least the way that it is called by kselftest, and in certain build configurations that I am seeing with my testing.)
I suspect that we don't have clean separation of kernel headers for the kernel under test, from the host machine's kernel header files, for builds of kselftest programs. But I ran out of time to tease this out.
-- Tim
Quoted 9 lines
Preferably we would have some
Kconfigcheck/enforcement or at least some documentation.Thoughts?
thanks.
--
~Randy
Shuah Khan
maintainerQuoted 63 lines · Tim
Quoted 4 lines
-----Original Message-----
From: [email protected] <[email protected]> On Behalf Of Randy DunlapOn 4/14/20 2:22 PM, Shuah Khan wrote:
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +2
-2-CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) -LDLIBS += $(MOUNT_LDLIBS) +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) +LDLIBS += $(VAR_LDLIBS)(1) Can that series of ../../../.. be replaced by $(objtree)? If so, that would be much cleaner IMO.
kselftests doesn't set $(objtree) when it is run directly (ie make -C
tools/testing/selftests)I had my own solution which was to use
KBUILD_OUTPUT, like so:
This was a patch in my queue, that I didn't send in because I wasn't very happy with it. I was still considering alternatives.---------------- (patch)
Subject: [PATCH] selftests/vm: use includes fromKBUILD_OUTPUTdirectoryThe
Makefilefor the vm tests was specifying a relative path (in the source directory) for accessing include files. This doesn't work when the headers files are placed in another directory (with O= orKBUILD_OUTPUT). It may appear to work, but ends up using includes from the host machine, which may not match the kernel source being compiled against.Without this change, when the program
userfaultfd.cwas compiled, it generated errors like the following:userfaultfd.c:267:21: error: '
UFFD_API_RANGE_IOCTLS_BASIC' undeclared here (not in a function)
.expected_ioctls =UFFD_API_RANGE_IOCTLS_BASIC,
^~~~~~~~~~~~~~~~~~~~~~~~~~~
userfaultfd.c: In function 'uffd_poll_thread':
userfaultfd.c:529:8: error: 'UFFD_EVENT_FORK' undeclared (first use in this function)
caseUFFD_EVENT_FORK:
^~~~~~~~~~~~~~~
userfaultfd.c:529:8: note: each undeclared identifier is reported only once for each function it appears in
userfaultfd.c:531:18: error: 'union <anonymous>' has no member named 'fork'
uffd = msg.arg.fork.ufd;
^Change the CFLAGS definition in the
Makefileto referenceKBUILD_OUTPUT.Signed-off-by Tim Bird <[email protected]>--- tools/testing/selftests/vm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)tools/testing/selftests/vm/Makefile +0
-0
tools/testing/selftests/vm/Makefile line 9
Quoted 8 lines
tools/testing/selftests/vm/Makefile +1
-1@@ -3,7 +3,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/') -CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) +CFLAGS = -Wall -I $(KBUILD_OUTPUT)/usr/include $(EXTRA_CFLAGS) LDLIBS = -lrt TEST_GEN_FILES = compaction_test TEST_GEN_FILES += gup_benchmark
This should be $(OUTPUT) instead of $(KBUILD_OUTPUT). OUTPUT is set by selftests Makefile and lib.mk which is common for all tests even when make -C is used for compile.
Using KBUILD_OUTPUT will break other use-cases.
Send me the patch when you are ready.
kselftest Makefile invokes headers_install from the main Makefile.
This sequence doesn't install headers again when kselftest make is done:
Main directory:
# make headers_install [headers_install runs]
# make headers_install INSTALL ./usr/include [does nothing - headers are there]
make kselftest-all
make --no-builtin-rules ARCH=x86 -C ../../.. headers_install make[2]: Entering directory '/home/shuah/lkml/linux_5.7'
INSTALL ./usr/include
[Same here - headers aren't installed]
I didn't check O= and KBUILD_OUTPUT cases though.
thanks,
-- Shuah