Commit 7712401ae9006fc9d9b9a3e7861dc73781429a89

Authored by Sam Ravnborg
1 parent 88181ec30f

kbuild: optimize headers_* targets

Move the core functionality of headers_install
and headers_check to two small perl scripts.
The makefile is adapted to use the perl scrip and
changed to operate on all files in a directory.
So if one file is changed then all files in the
directory is processed.

perl were chosen for the helper scripts because this
is pure text processing which perl is good at and
especially the headers_check.pl script are expected to
see changes / new checks implmented.

The speed is ~300% faster on this box.
And the output generated to the screen is now down to
two lines per directory (one for install, one for check)
so it is easier to scroll back after a kernel build.

The perl scripts has been brought to sanity by patient
feedback from: Vegard Nossum <vegard.nossum@gmail.com>

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>

Showing 4 changed files with 161 additions and 92 deletions Side-by-side Diff

scripts/Makefile.headersinst
1 1 # ==========================================================================
2 2 # Installing headers
3 3 #
4   -# header-y files will be installed verbatim
5   -# unifdef-y are the files where unifdef will be run before installing files
6   -# objhdr-y are generated files that will be installed verbatim
  4 +# header-y - list files to be installed. They are preprocessed
  5 +# to remove __KERNEL__ section of the file
  6 +# unifdef-y - Same as header-y. Obsolete
  7 +# objhdr-y - Same as header-y but for generated files
7 8 #
8 9 # ==========================================================================
9 10  
10   -UNIFDEF := scripts/unifdef -U__KERNEL__
11   -
12   -# Eliminate the contents of (and inclusions of) compiler.h
13   -HDRSED := sed -e "s/ inline / __inline__ /g" \
14   - -e "s/[[:space:]]__user[[:space:]]\{1,\}/ /g" \
15   - -e "s/(__user[[:space:]]\{1,\}/ (/g" \
16   - -e "s/[[:space:]]__force[[:space:]]\{1,\}/ /g" \
17   - -e "s/(__force[[:space:]]\{1,\}/ (/g" \
18   - -e "s/[[:space:]]__iomem[[:space:]]\{1,\}/ /g" \
19   - -e "s/(__iomem[[:space:]]\{1,\}/ (/g" \
20   - -e "s/[[:space:]]__attribute_const__[[:space:]]\{1,\}/\ /g" \
21   - -e "s/[[:space:]]__attribute_const__$$//" \
22   - -e "/^\#include <linux\/compiler.h>/d"
23   -
  11 +# called may set destination dir (when installing to asm/)
24 12 _dst := $(if $(dst),$(dst),$(obj))
25 13  
26 14 kbuild-file := $(srctree)/$(obj)/Kbuild
27 15  
28 16  
29 17  
30 18  
31 19  
32 20  
33 21  
34 22  
35 23  
36 24  
37 25  
38 26  
39 27  
40 28  
41 29  
42 30  
43 31  
44 32  
45 33  
46 34  
... ... @@ -28,90 +16,83 @@
28 16  
29 17 include scripts/Kbuild.include
30 18  
31   -install := $(INSTALL_HDR_PATH)/$(_dst)
  19 +install := $(INSTALL_HDR_PATH)/$(_dst)
32 20  
33   -header-y := $(sort $(header-y) $(unifdef-y))
34   -subdir-y := $(patsubst %/,%,$(filter %/, $(header-y)))
35   -header-y := $(filter-out %/, $(header-y))
  21 +header-y := $(sort $(header-y) $(unifdef-y))
  22 +subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
  23 +header-y := $(filter-out %/, $(header-y))
36 24  
37   -# stamp files for header checks
38   -check-y := $(patsubst %,.check.%,$(header-y) $(objhdr-y))
  25 +# files used to track state of install/check
  26 +install-file := $(install)/.install
  27 +check-file := $(install)/.check
39 28  
  29 +# all headers files for this dir
  30 +all-files := $(header-y) $(objhdr-y)
  31 +input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \
  32 + $(addprefix $(objtree)/$(obj)/,$(objhdr-y))
  33 +output-files := $(addprefix $(install)/, $(all-files))
  34 +
40 35 # Work out what needs to be removed
41   -oldheaders := $(patsubst $(install)/%,%,$(wildcard $(install)/*.h))
42   -unwanted := $(filter-out $(header-y) $(objhdr-y),$(oldheaders))
  36 +oldheaders := $(patsubst $(install)/%,%,$(wildcard $(install)/*.h))
  37 +unwanted := $(filter-out $(all-files),$(oldheaders))
43 38  
44   -oldcheckstamps := $(patsubst $(install)/%,%,$(wildcard $(install)/.check.*.h))
45   -unwanted += $(filter-out $(check-y),$(oldcheckstamps))
  39 +# Prefix unwanted with full paths to $(INSTALL_HDR_PATH)
  40 +unwanted-file := $(addprefix $(install)/, $(unwanted))
46 41  
47   -# Prefix them all with full paths to $(INSTALL_HDR_PATH)
48   -header-y := $(patsubst %,$(install)/%,$(header-y))
49   -objhdr-y := $(patsubst %,$(install)/%,$(objhdr-y))
50   -check-y := $(patsubst %,$(install)/%,$(check-y))
  42 +printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@))
51 43  
52   -quiet_cmd_o_hdr_install = INSTALL $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
53   - cmd_o_hdr_install = cp $(patsubst $(install)/%,$(objtree)/$(obj)/%,$@) \
54   - $(install)
  44 +quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
  45 + file$(if $(word 2, $(all-files)),s))
  46 + cmd_install = $(PERL) $< $(srctree)/$(obj) $(install) $(header-y); \
  47 + $(PERL) $< $(objtree)/$(obj) $(install) $(objhdr-y); \
  48 + touch $@
55 49  
56   -quiet_cmd_unifdef = UNIFDEF $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
57   - cmd_unifdef = $(UNIFDEF) $(patsubst $(install)/%,$(srctree)/$(obj)/%,$@)\
58   - | $(HDRSED) > $@ || :
  50 +quiet_cmd_remove = REMOVE $(unwanted)
  51 + cmd_remove = rm -f $(unwanted-file)
59 52  
60   -quiet_cmd_check = CHECK $(patsubst $(install)/.check.%,$(_dst)/%,$@)
61   - cmd_check = $(CONFIG_SHELL) $(srctree)/scripts/hdrcheck.sh \
62   - $(INSTALL_HDR_PATH)/include $(subst /.check.,/,$@) $@
  53 +quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files)
  54 + cmd_check = $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH) \
  55 + $(addprefix $(install)/, $(all-files)); \
  56 + touch $@
63 57  
64   -quiet_cmd_remove = REMOVE $(_dst)/$@
65   - cmd_remove = rm -f $(install)/$@
  58 +PHONY += __headersinst __headerscheck
66 59  
67   -quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
68   - cmd_mkdir = mkdir -p $@
  60 +ifndef HDRCHECK
  61 +# Rules for installing headers
  62 +__headersinst: $(subdirs) $(install-file)
  63 + @:
69 64  
70   -.PHONY: __headersinst __headerscheck
  65 +targets += $(install-file)
  66 +$(install-file): scripts/headers_install.pl $(input-files) FORCE
  67 + $(if $(unwanted),$(call cmd,remove),)
  68 + $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
  69 + $(call if_changed,install)
71 70  
72   -ifdef HDRCHECK
73   -__headerscheck: $(subdir-y) $(check-y)
74   - @true
75   -
76   -$(check-y) : $(install)/.check.%.h : $(install)/%.h
77   - $(call cmd,check)
78   -
79   -# Other dependencies for $(check-y)
80   -include /dev/null $(wildcard $(check-y))
81   -
82   -# but leave $(check-y) as .PHONY for now until those
83   -# deps are actually correct.
84   -.PHONY: $(check-y)
85   -
86 71 else
87   -# Rules for installing headers
88   -__headersinst: $(subdir-y) $(header-y) $(objhdr-y)
89   - @true
  72 +__headerscheck: $(subdirs) $(check-file)
  73 + @:
90 74  
91   -$(objhdr-y) $(subdir-y) $(header-y): | $(install) $(unwanted)
  75 +targets += $(check-file)
  76 +$(check-file): scripts/headers_check.pl $(output-files) FORCE
  77 + $(call if_changed,check)
92 78  
93   -$(install):
94   - $(call cmd,mkdir)
  79 +endif
95 80  
96   -# Rules for removing unwanted header files
97   -.PHONY: $(unwanted)
98   -$(unwanted):
99   - $(call cmd,remove)
  81 +# Recursion
  82 +hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj
  83 +.PHONY: $(subdirs)
  84 +$(subdirs):
  85 + $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
100 86  
101   -# Install generated files
102   -$(objhdr-y): $(install)/%.h: $(objtree)/$(obj)/%.h $(kbuild-file)
103   - $(call cmd,o_hdr_install)
  87 +targets := $(wildcard $(sort $(targets)))
  88 +cmd_files := $(wildcard \
  89 + $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
104 90  
105   -# Unifdef header files and install them
106   -$(header-y): $(install)/%.h: $(srctree)/$(obj)/%.h $(kbuild-file)
107   - $(call cmd,unifdef)
108   -
  91 +ifneq ($(cmd_files),)
  92 + include $(cmd_files)
109 93 endif
110 94  
111   -hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj
112   -
113   -# Recursion
114   -.PHONY: $(subdir-y)
115   -$(subdir-y):
116   - $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
  95 +.PHONY: $(PHONY)
  96 +PHONY += FORCE
  97 +FORCE: ;
scripts/hdrcheck.sh
1   -#!/bin/sh
2   -
3   -for FILE in `grep '^[ \t]*#[ \t]*include[ \t]*<' $2 | cut -f2 -d\< | cut -f1 -d\> | egrep ^linux\|^asm` ; do
4   - if [ ! -r $1/$FILE ]; then
5   - echo $2 requires $FILE, which does not exist in exported headers
6   - exit 1
7   - fi
8   -done
9   -# FIXME: List dependencies into $3
10   -touch $3
scripts/headers_check.pl
  1 +#!/usr/bin/perl
  2 +#
  3 +# headers_check.pl execute a number of trivial consistency checks
  4 +#
  5 +# Usage: headers_check.pl dir [files...]
  6 +# dir: dir to look for included files
  7 +# arch: architecture
  8 +# files: list of files to check
  9 +#
  10 +# The script reads the supplied files line by line and:
  11 +#
  12 +# 1) for each include statement it checks if the
  13 +# included file actually exists.
  14 +# Only include files located in asm* and linux* are checked.
  15 +# The rest are assumed to be system include files.
  16 +#
  17 +# 2) TODO: check for leaked CONFIG_ symbols
  18 +
  19 +use strict;
  20 +use warnings;
  21 +
  22 +my ($dir, $arch, @files) = @ARGV;
  23 +
  24 +my $ret = 0;
  25 +my $line;
  26 +my $lineno = 0;
  27 +my $filename;
  28 +
  29 +foreach my $file (@files) {
  30 + $filename = $file;
  31 + open(my $fh, '<', "$filename") or die "$filename: $!\n";
  32 + $lineno = 0;
  33 + while ($line = <$fh>) {
  34 + $lineno++;
  35 + check_include();
  36 + }
  37 + close $fh;
  38 +}
  39 +exit $ret;
  40 +
  41 +sub check_include
  42 +{
  43 + if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) {
  44 + my $inc = $1;
  45 + my $found;
  46 + $found = stat($dir . "/" . $inc);
  47 + if (!$found) {
  48 + $inc =~ s#asm/#asm-$arch/#;
  49 + $found = stat($dir . "/" . $inc);
  50 + }
  51 + if (!$found) {
  52 + printf STDERR "$filename:$lineno: included file '$inc' is not exported\n";
  53 + $ret = 1;
  54 + }
  55 + }
  56 +}
scripts/headers_install.pl
  1 +#!/usr/bin/perl
  2 +#
  3 +# headers_install prepare the listed header files for use in
  4 +# user space and copy the files to their destination.
  5 +#
  6 +# Usage: headers_install.pl odir installdir [files...]
  7 +# odir: dir to open files
  8 +# install: dir to install the files
  9 +# files: list of files to check
  10 +#
  11 +# Step in preparation for users space:
  12 +# 1) Drop all use of compiler.h definitions
  13 +# 2) Drop include of compiler.h
  14 +# 3) Drop all sections defined out by __KERNEL__ (using unifdef)
  15 +
  16 +use strict;
  17 +use warnings;
  18 +
  19 +my ($readdir, $installdir, @files) = @ARGV;
  20 +
  21 +my $unifdef = "scripts/unifdef -U__KERNEL__";
  22 +
  23 +foreach my $file (@files) {
  24 + my $tmpfile = "$installdir/$file.tmp";
  25 + open(my $infile, '<', "$readdir/$file")
  26 + or die "$readdir/$file: $!\n";
  27 + open(my $outfile, '>', "$tmpfile") or die "$tmpfile: $!\n";
  28 + while (my $line = <$infile>) {
  29 + $line =~ s/([\s(])__user\s/$1/g;
  30 + $line =~ s/([\s(])__force\s/$1/g;
  31 + $line =~ s/([\s(])__iomem\s/$1/g;
  32 + $line =~ s/\s__attribute_const__\s/ /g;
  33 + $line =~ s/\s__attribute_const__$//g;
  34 + $line =~ s/^#include <linux\/compiler.h>//;
  35 + printf $outfile "%s", $line;
  36 + }
  37 + close $outfile;
  38 + close $infile;
  39 + system $unifdef . " $tmpfile > $installdir/$file";
  40 + unlink $tmpfile;
  41 +}
  42 +exit 0;