summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile25
-rw-r--r--scripts/Makefile.build21
3 files changed, 46 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 9875120ea7bd..948c760b2704 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@
*.gcno
*.gcda
*.gz
+*.header-check
*.i
*.ko
*.lex.c
diff --git a/Makefile b/Makefile
index c496d1639103..28502178746f 100644
--- a/Makefile
+++ b/Makefile
@@ -302,7 +302,7 @@ no-dot-config-targets := $(clean-targets) \
run-command
no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \
image_name
-single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/
+single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.header-check %/
config-build :=
mixed-build :=
@@ -1545,6 +1545,26 @@ scripts_gen_packed_field_checks: scripts_basic
$(Q)$(MAKE) $(build)=scripts scripts/gen_packed_field_checks
# ---------------------------------------------------------------------------
+# Header check
+
+# Check the headers in HEADER_CHECK=(headers|dirs)
+PHONY += headercheck
+
+ifneq ($(HEADER_CHECK),)
+
+header-check-dirs := $(filter-out %.h,$(HEADER_CHECK))
+header-check-files := $(filter %.h,$(HEADER_CHECK)) $(if $(header-check-dirs),$(shell cd $(srctree) && find $(header-check-dirs) -name '*.h' 2>/dev/null))
+header-check-targets := $(patsubst %.h,%.header-check,$(sort $(header-check-files)))
+
+headercheck:
+ $(if $(header-check-targets),,$(error $@ found no headers in HEADER_CHECK="$(HEADER_CHECK)"))
+ $(Q)$(MAKE) $(header-check-targets)
+else
+headercheck:
+ $(error $@ requires HEADER_CHECK=(headers|dirs))
+endif
+
+# ---------------------------------------------------------------------------
# Install
# Many distributions have the custom install script, /sbin/installkernel.
@@ -1890,6 +1910,8 @@ help:
@echo ' versioncheck - Sanity check on version.h usage'
@echo ' includecheck - Check for duplicate included header files'
@echo ' headerdep - Detect inclusion cycles in headers'
+ @echo ' headercheck - Check headers in HEADER_CHECK=(headers|dirs) are'
+ @echo ' self-contained, have header guards, and pass kernel-doc.'
@echo ' coccicheck - Check with Coccinelle'
@echo ' kconfig-sym-check - Check for dangling Kconfig symbol references'
@echo ' clang-analyzer - Check with clang static analyzer'
@@ -2255,6 +2277,7 @@ clean: $(clean-dirs)
-o -name '*.ll' \
-o -name '*.gcno' \
-o -name '*.long-type-*.txt' \
+ -o -name '*.header-check' \
\) -type f -print \
-o -name '.tmp_*' -print \
| xargs rm -rf
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 4349108e75e1..6127feb970c6 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -306,6 +306,27 @@ quiet_cmd_cc_lst_c = MKLST $@
$(obj)/%.lst: $(obj)/%.c FORCE
$(call if_changed_dep,cc_lst_c)
+# Compile C headers (.h) for header check
+# ---------------------------------------------------------------------------
+
+# Check a header is self-contained, has header guards, and passes kernel-doc.
+#
+# This is for 'make HEADER_CHECK=(headers|dirs) headercheck'. Not to be confused
+# with CONFIG_UAPI_HEADER_TEST.
+#
+# Please do *not* plug %.header-check into any configurable targets, unless you
+# also figure out a way to completely hide the %.header-check artefacts.
+
+quiet_cmd_header_check = HDRCHK $(patsubst %.header-check,%.h,$@)
+ cmd_header_check = \
+ $(CC) $(c_flags) -fsyntax-only -x c /dev/null -include $< -include $<; \
+ PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none $(KDOCFLAGS) \
+ $(if $(findstring e, $(KBUILD_EXTRA_WARN))$(CONFIG_WERROR),-Werror) $<; \
+ touch $@
+
+$(obj)/%.header-check: $(obj)/%.h FORCE
+ $(call if_changed_dep,header_check)
+
# Compile Rust sources (.rs)
# ---------------------------------------------------------------------------