diff mbox series

[RFC] modpost: compile constant module information only once

Message ID 20240824-modinfo-const-v1-1-485f9c64b868@weissschuh.net (mailing list archive)
State New
Headers show
Series [RFC] modpost: compile constant module information only once | expand

Commit Message

Thomas Weißschuh Aug. 24, 2024, 5:44 p.m. UTC
Various information about modules is compiled into the info sections.
For that a dedicated .mod.c file is generated by modpost for each module
and then linked into the module.
However most of the information in the .mod.c is the same for all
modules, internal and external.
Split the shared information into a dedicated source file that is
compiled once and then linked into all modules.

This avoids frequent rebuilds for all .mod.c files when using
CONFIG_LOCALVERSION_AUTO because the local version ends up in .mod.c
through UTS_RELEASE and VERMAGIC_STRING.
The modules are still relinked in this case.

The code is also easier to maintain as it's now in a proper source file
instead of an inline string literal.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
I came up with this while investigating something different.
Not sure it's worth the effort.
---
 scripts/Makefile.modfinal            |  9 +++++++--
 scripts/mod/modinfo.c                | 25 +++++++++++++++++++++++++
 scripts/mod/modpost.c                | 23 -----------------------
 scripts/package/install-extmod-build |  3 ++-
 4 files changed, 34 insertions(+), 26 deletions(-)


---
base-commit: 184a282d540c3da03f6a229f4792a5f72d3dfc2a
change-id: 20240824-modinfo-const-6f0d67e2b301

Best regards,

Comments

Masahiro Yamada Sept. 1, 2024, 3:33 p.m. UTC | #1
On Sun, Aug 25, 2024 at 2:44 AM Thomas Weißschuh <linux@weissschuh.net> wrote:
>
> Various information about modules is compiled into the info sections.
> For that a dedicated .mod.c file is generated by modpost for each module
> and then linked into the module.
> However most of the information in the .mod.c is the same for all
> modules, internal and external.
> Split the shared information into a dedicated source file that is
> compiled once and then linked into all modules.
>
> This avoids frequent rebuilds for all .mod.c files when using
> CONFIG_LOCALVERSION_AUTO because the local version ends up in .mod.c
> through UTS_RELEASE and VERMAGIC_STRING.
> The modules are still relinked in this case.
>
> The code is also easier to maintain as it's now in a proper source file
> instead of an inline string literal.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> I came up with this while investigating something different.
> Not sure it's worth the effort.
> ---
>  scripts/Makefile.modfinal            |  9 +++++++--
>  scripts/mod/modinfo.c                | 25 +++++++++++++++++++++++++
>  scripts/mod/modpost.c                | 23 -----------------------
>  scripts/package/install-extmod-build |  3 ++-
>  4 files changed, 34 insertions(+), 26 deletions(-)
>
> diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
> index 306a6bb86e4d..dde09dc4ba11 100644
> --- a/scripts/Makefile.modfinal
> +++ b/scripts/Makefile.modfinal
> @@ -30,6 +30,11 @@ quiet_cmd_cc_o_c = CC [M]  $@
>  %.mod.o: %.mod.c FORCE
>         $(call if_changed_dep,cc_o_c)
>
> +ifeq ($(KBUILD_EXTMOD),)
> +scripts/mod/modinfo.o: scripts/mod/modinfo.c FORCE
> +       $(call if_changed_dep,cc_o_c)
> +endif
> +
>  quiet_cmd_ld_ko_o = LD [M]  $@
>        cmd_ld_ko_o +=                                                   \
>         $(LD) -r $(KBUILD_LDFLAGS)                                      \
> @@ -54,13 +59,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check),      \
>         printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
>
>  # Re-generate module BTFs if either module's .ko or vmlinux changed
> -%.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
> +%.ko: %.o %.mod.o scripts/module.lds scripts/mod/modinfo.o $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
>         +$(call if_changed_except,ld_ko_o,vmlinux)
>  ifdef CONFIG_DEBUG_INFO_BTF_MODULES
>         +$(if $(newer-prereqs),$(call cmd,btf_ko))
>  endif
>
> -targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o)
> +targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) scripts/mod/modinfo.o
>
>  # Add FORCE to the prerequisites of a target to force it to be always rebuilt.
>  # ---------------------------------------------------------------------------
> diff --git a/scripts/mod/modinfo.c b/scripts/mod/modinfo.c
> new file mode 100644
> index 000000000000..12fbc6d3aae8
> --- /dev/null
> +++ b/scripts/mod/modinfo.c
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/module.h>
> +/*
> + * Include build-salt.h after module.h in order to
> + * inherit the definitions.
> + */
> +#define INCLUDE_VERMAGIC
> +#include <linux/build-salt.h>
> +#include <linux/elfnote-lto.h>
> +#include <linux/vermagic.h>
> +
> +#ifdef CONFIG_UNWINDER_ORC
> +#include <asm/orc_header.h>
> +ORC_HEADER;
> +#endif
> +
> +BUILD_SALT;
> +BUILD_LTO_INFO;
> +
> +MODULE_INFO(vermagic, VERMAGIC_STRING);
> +
> +#ifdef CONFIG_MITIGATION_RETPOLINE
> +MODULE_INFO(retpoline, "Y");
> +#endif
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index c8cd5d822bb6..107393a8c48a 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1755,26 +1755,9 @@ static void check_modname_len(struct module *mod)
>  static void add_header(struct buffer *b, struct module *mod)
>  {
>         buf_printf(b, "#include <linux/module.h>\n");
> -       /*
> -        * Include build-salt.h after module.h in order to
> -        * inherit the definitions.
> -        */
> -       buf_printf(b, "#define INCLUDE_VERMAGIC\n");
> -       buf_printf(b, "#include <linux/build-salt.h>\n");
> -       buf_printf(b, "#include <linux/elfnote-lto.h>\n");
>         buf_printf(b, "#include <linux/export-internal.h>\n");
> -       buf_printf(b, "#include <linux/vermagic.h>\n");
>         buf_printf(b, "#include <linux/compiler.h>\n");
>         buf_printf(b, "\n");
> -       buf_printf(b, "#ifdef CONFIG_UNWINDER_ORC\n");
> -       buf_printf(b, "#include <asm/orc_header.h>\n");
> -       buf_printf(b, "ORC_HEADER;\n");
> -       buf_printf(b, "#endif\n");
> -       buf_printf(b, "\n");
> -       buf_printf(b, "BUILD_SALT;\n");
> -       buf_printf(b, "BUILD_LTO_INFO;\n");
> -       buf_printf(b, "\n");
> -       buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
>         buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
>         buf_printf(b, "\n");
>         buf_printf(b, "__visible struct module __this_module\n");
> @@ -1792,12 +1775,6 @@ static void add_header(struct buffer *b, struct module *mod)
>         if (!external_module)
>                 buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
>
> -       buf_printf(b,
> -                  "\n"
> -                  "#ifdef CONFIG_MITIGATION_RETPOLINE\n"
> -                  "MODULE_INFO(retpoline, \"Y\");\n"
> -                  "#endif\n");
> -
>         if (strstarts(mod->name, "drivers/staging"))
>                 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
>
> diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build
> index d2c9cacecc0c..15fab6d5dd56 100755
> --- a/scripts/package/install-extmod-build
> +++ b/scripts/package/install-extmod-build
> @@ -37,6 +37,7 @@ mkdir -p "${destdir}"
>         echo include/config/auto.conf
>         echo include/config/kernel.release
>         echo include/generated
> +       echo scripts/mod/modinfo.o
>         find_in_scripts
>
>         if is_enabled CONFIG_GCC_PLUGINS; then
> @@ -78,4 +79,4 @@ if [ "${CC}" != "${HOSTCC}" ] && is_enabled CONFIG_CC_CAN_LINK; then
>         rm -f "${destdir}/Kbuild" "${destdir}/scripts/Kbuild"
>  fi
>
> -find "${destdir}" \( -name '.*.cmd' -o -name '*.o' \) -delete
> +find "${destdir}" \( -name '.*.cmd' -o \( -name '*.o' -a -! -path '*/scripts/mod/modinfo.o' \) \) -delete


This is not an enough hack because scripts/mod/modinfo.o
is a new requirement for building external modules.

'make clean' would need a similar treatment.

'make help' goes:

  clean   - Remove most generated files but keep the config and
            enough build support to build external modules






Or, another approach is to generate a different object
when building external modules.

A patch attached (on top of this).





>
> ---
> base-commit: 184a282d540c3da03f6a229f4792a5f72d3dfc2a
> change-id: 20240824-modinfo-const-6f0d67e2b301
>
> Best regards,
> --
> Thomas Weißschuh <linux@weissschuh.net>
>
Masahiro Yamada Sept. 1, 2024, 3:59 p.m. UTC | #2
On Mon, Sep 2, 2024 at 12:33 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Sun, Aug 25, 2024 at 2:44 AM Thomas Weißschuh <linux@weissschuh.net> wrote:
> >
> > Various information about modules is compiled into the info sections.
> > For that a dedicated .mod.c file is generated by modpost for each module
> > and then linked into the module.
> > However most of the information in the .mod.c is the same for all
> > modules, internal and external.
> > Split the shared information into a dedicated source file that is
> > compiled once and then linked into all modules.
> >
> > This avoids frequent rebuilds for all .mod.c files when using
> > CONFIG_LOCALVERSION_AUTO because the local version ends up in .mod.c
> > through UTS_RELEASE and VERMAGIC_STRING.
> > The modules are still relinked in this case.
> >
> > The code is also easier to maintain as it's now in a proper source file
> > instead of an inline string literal.
> >
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > ---
> > I came up with this while investigating something different.
> > Not sure it's worth the effort.
> > ---
> >  scripts/Makefile.modfinal            |  9 +++++++--
> >  scripts/mod/modinfo.c                | 25 +++++++++++++++++++++++++
> >  scripts/mod/modpost.c                | 23 -----------------------
> >  scripts/package/install-extmod-build |  3 ++-
> >  4 files changed, 34 insertions(+), 26 deletions(-)
> >
> > diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
> > index 306a6bb86e4d..dde09dc4ba11 100644
> > --- a/scripts/Makefile.modfinal
> > +++ b/scripts/Makefile.modfinal
> > @@ -30,6 +30,11 @@ quiet_cmd_cc_o_c = CC [M]  $@
> >  %.mod.o: %.mod.c FORCE
> >         $(call if_changed_dep,cc_o_c)
> >
> > +ifeq ($(KBUILD_EXTMOD),)
> > +scripts/mod/modinfo.o: scripts/mod/modinfo.c FORCE
> > +       $(call if_changed_dep,cc_o_c)
> > +endif
> > +
> >  quiet_cmd_ld_ko_o = LD [M]  $@
> >        cmd_ld_ko_o +=                                                   \
> >         $(LD) -r $(KBUILD_LDFLAGS)                                      \
> > @@ -54,13 +59,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check),      \
> >         printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
> >
> >  # Re-generate module BTFs if either module's .ko or vmlinux changed
> > -%.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
> > +%.ko: %.o %.mod.o scripts/module.lds scripts/mod/modinfo.o $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
> >         +$(call if_changed_except,ld_ko_o,vmlinux)
> >  ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> >         +$(if $(newer-prereqs),$(call cmd,btf_ko))
> >  endif
> >
> > -targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o)
> > +targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) scripts/mod/modinfo.o
> >
> >  # Add FORCE to the prerequisites of a target to force it to be always rebuilt.
> >  # ---------------------------------------------------------------------------
> > diff --git a/scripts/mod/modinfo.c b/scripts/mod/modinfo.c
> > new file mode 100644
> > index 000000000000..12fbc6d3aae8
> > --- /dev/null
> > +++ b/scripts/mod/modinfo.c
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/module.h>
> > +/*
> > + * Include build-salt.h after module.h in order to
> > + * inherit the definitions.
> > + */
> > +#define INCLUDE_VERMAGIC
> > +#include <linux/build-salt.h>
> > +#include <linux/elfnote-lto.h>
> > +#include <linux/vermagic.h>
> > +
> > +#ifdef CONFIG_UNWINDER_ORC
> > +#include <asm/orc_header.h>
> > +ORC_HEADER;
> > +#endif
> > +
> > +BUILD_SALT;
> > +BUILD_LTO_INFO;
> > +
> > +MODULE_INFO(vermagic, VERMAGIC_STRING);
> > +
> > +#ifdef CONFIG_MITIGATION_RETPOLINE
> > +MODULE_INFO(retpoline, "Y");
> > +#endif
> > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> > index c8cd5d822bb6..107393a8c48a 100644
> > --- a/scripts/mod/modpost.c
> > +++ b/scripts/mod/modpost.c
> > @@ -1755,26 +1755,9 @@ static void check_modname_len(struct module *mod)
> >  static void add_header(struct buffer *b, struct module *mod)
> >  {
> >         buf_printf(b, "#include <linux/module.h>\n");
> > -       /*
> > -        * Include build-salt.h after module.h in order to
> > -        * inherit the definitions.
> > -        */
> > -       buf_printf(b, "#define INCLUDE_VERMAGIC\n");
> > -       buf_printf(b, "#include <linux/build-salt.h>\n");
> > -       buf_printf(b, "#include <linux/elfnote-lto.h>\n");
> >         buf_printf(b, "#include <linux/export-internal.h>\n");
> > -       buf_printf(b, "#include <linux/vermagic.h>\n");
> >         buf_printf(b, "#include <linux/compiler.h>\n");
> >         buf_printf(b, "\n");
> > -       buf_printf(b, "#ifdef CONFIG_UNWINDER_ORC\n");
> > -       buf_printf(b, "#include <asm/orc_header.h>\n");
> > -       buf_printf(b, "ORC_HEADER;\n");
> > -       buf_printf(b, "#endif\n");
> > -       buf_printf(b, "\n");
> > -       buf_printf(b, "BUILD_SALT;\n");
> > -       buf_printf(b, "BUILD_LTO_INFO;\n");
> > -       buf_printf(b, "\n");
> > -       buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
> >         buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
> >         buf_printf(b, "\n");
> >         buf_printf(b, "__visible struct module __this_module\n");
> > @@ -1792,12 +1775,6 @@ static void add_header(struct buffer *b, struct module *mod)
> >         if (!external_module)
> >                 buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
> >
> > -       buf_printf(b,
> > -                  "\n"
> > -                  "#ifdef CONFIG_MITIGATION_RETPOLINE\n"
> > -                  "MODULE_INFO(retpoline, \"Y\");\n"
> > -                  "#endif\n");
> > -
> >         if (strstarts(mod->name, "drivers/staging"))
> >                 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
> >
> > diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build
> > index d2c9cacecc0c..15fab6d5dd56 100755
> > --- a/scripts/package/install-extmod-build
> > +++ b/scripts/package/install-extmod-build
> > @@ -37,6 +37,7 @@ mkdir -p "${destdir}"
> >         echo include/config/auto.conf
> >         echo include/config/kernel.release
> >         echo include/generated
> > +       echo scripts/mod/modinfo.o
> >         find_in_scripts
> >
> >         if is_enabled CONFIG_GCC_PLUGINS; then
> > @@ -78,4 +79,4 @@ if [ "${CC}" != "${HOSTCC}" ] && is_enabled CONFIG_CC_CAN_LINK; then
> >         rm -f "${destdir}/Kbuild" "${destdir}/scripts/Kbuild"
> >  fi
> >
> > -find "${destdir}" \( -name '.*.cmd' -o -name '*.o' \) -delete
> > +find "${destdir}" \( -name '.*.cmd' -o \( -name '*.o' -a -! -path '*/scripts/mod/modinfo.o' \) \) -delete
>
>
> This is not an enough hack because scripts/mod/modinfo.o
> is a new requirement for building external modules.
>
> 'make clean' would need a similar treatment.
>
> 'make help' goes:
>
>   clean   - Remove most generated files but keep the config and
>             enough build support to build external modules
>
>
>
>
>
>
> Or, another approach is to generate a different object
> when building external modules.
>
> A patch attached (on top of this).



The previous one was buggy.

Re-attached.
diff mbox series

Patch

diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index 306a6bb86e4d..dde09dc4ba11 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -30,6 +30,11 @@  quiet_cmd_cc_o_c = CC [M]  $@
 %.mod.o: %.mod.c FORCE
 	$(call if_changed_dep,cc_o_c)
 
+ifeq ($(KBUILD_EXTMOD),)
+scripts/mod/modinfo.o: scripts/mod/modinfo.c FORCE
+	$(call if_changed_dep,cc_o_c)
+endif
+
 quiet_cmd_ld_ko_o = LD [M]  $@
       cmd_ld_ko_o +=							\
 	$(LD) -r $(KBUILD_LDFLAGS)					\
@@ -54,13 +59,13 @@  if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check),      \
 	printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
 
 # Re-generate module BTFs if either module's .ko or vmlinux changed
-%.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
+%.ko: %.o %.mod.o scripts/module.lds scripts/mod/modinfo.o $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
 	+$(call if_changed_except,ld_ko_o,vmlinux)
 ifdef CONFIG_DEBUG_INFO_BTF_MODULES
 	+$(if $(newer-prereqs),$(call cmd,btf_ko))
 endif
 
-targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o)
+targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) scripts/mod/modinfo.o
 
 # Add FORCE to the prerequisites of a target to force it to be always rebuilt.
 # ---------------------------------------------------------------------------
diff --git a/scripts/mod/modinfo.c b/scripts/mod/modinfo.c
new file mode 100644
index 000000000000..12fbc6d3aae8
--- /dev/null
+++ b/scripts/mod/modinfo.c
@@ -0,0 +1,25 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/module.h>
+/*
+ * Include build-salt.h after module.h in order to
+ * inherit the definitions.
+ */
+#define INCLUDE_VERMAGIC
+#include <linux/build-salt.h>
+#include <linux/elfnote-lto.h>
+#include <linux/vermagic.h>
+
+#ifdef CONFIG_UNWINDER_ORC
+#include <asm/orc_header.h>
+ORC_HEADER;
+#endif
+
+BUILD_SALT;
+BUILD_LTO_INFO;
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+
+#ifdef CONFIG_MITIGATION_RETPOLINE
+MODULE_INFO(retpoline, "Y");
+#endif
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index c8cd5d822bb6..107393a8c48a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1755,26 +1755,9 @@  static void check_modname_len(struct module *mod)
 static void add_header(struct buffer *b, struct module *mod)
 {
 	buf_printf(b, "#include <linux/module.h>\n");
-	/*
-	 * Include build-salt.h after module.h in order to
-	 * inherit the definitions.
-	 */
-	buf_printf(b, "#define INCLUDE_VERMAGIC\n");
-	buf_printf(b, "#include <linux/build-salt.h>\n");
-	buf_printf(b, "#include <linux/elfnote-lto.h>\n");
 	buf_printf(b, "#include <linux/export-internal.h>\n");
-	buf_printf(b, "#include <linux/vermagic.h>\n");
 	buf_printf(b, "#include <linux/compiler.h>\n");
 	buf_printf(b, "\n");
-	buf_printf(b, "#ifdef CONFIG_UNWINDER_ORC\n");
-	buf_printf(b, "#include <asm/orc_header.h>\n");
-	buf_printf(b, "ORC_HEADER;\n");
-	buf_printf(b, "#endif\n");
-	buf_printf(b, "\n");
-	buf_printf(b, "BUILD_SALT;\n");
-	buf_printf(b, "BUILD_LTO_INFO;\n");
-	buf_printf(b, "\n");
-	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
 	buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
 	buf_printf(b, "\n");
 	buf_printf(b, "__visible struct module __this_module\n");
@@ -1792,12 +1775,6 @@  static void add_header(struct buffer *b, struct module *mod)
 	if (!external_module)
 		buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
 
-	buf_printf(b,
-		   "\n"
-		   "#ifdef CONFIG_MITIGATION_RETPOLINE\n"
-		   "MODULE_INFO(retpoline, \"Y\");\n"
-		   "#endif\n");
-
 	if (strstarts(mod->name, "drivers/staging"))
 		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
 
diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build
index d2c9cacecc0c..15fab6d5dd56 100755
--- a/scripts/package/install-extmod-build
+++ b/scripts/package/install-extmod-build
@@ -37,6 +37,7 @@  mkdir -p "${destdir}"
 	echo include/config/auto.conf
 	echo include/config/kernel.release
 	echo include/generated
+	echo scripts/mod/modinfo.o
 	find_in_scripts
 
 	if is_enabled CONFIG_GCC_PLUGINS; then
@@ -78,4 +79,4 @@  if [ "${CC}" != "${HOSTCC}" ] && is_enabled CONFIG_CC_CAN_LINK; then
 	rm -f "${destdir}/Kbuild" "${destdir}/scripts/Kbuild"
 fi
 
-find "${destdir}" \( -name '.*.cmd' -o -name '*.o' \) -delete
+find "${destdir}" \( -name '.*.cmd' -o \( -name '*.o' -a -! -path '*/scripts/mod/modinfo.o' \) \) -delete