diff mbox

make headers_install fail when path is too long

Message ID 51376E6C.4040903@6wind.com (mailing list archive)
State New, archived
Headers show

Commit Message

Nicolas Dichtel March 6, 2013, 4:27 p.m. UTC
Le 06/03/2013 17:10, Sam Ravnborg a écrit :
> On Wed, Mar 06, 2013 at 12:16:33PM +0100, Nicolas Dichtel wrote:
>> This problem has probably already been reported, but I don't find the fix
>> in a kernel.org tree and I don't understand why.
>
> First time I see this bug described - but I may missed it here at kbuild.
It's probably why I didn't find this on a linux kernel mailing list ;-)

> If a patch exists then please include the patch in your mail so we can
> see it and comment on it.
>
> And make sure to have the attribution correct if you consider it to
> be applied.
I'm not the author of the patch, I've found it on the web. Here it is:

 From cb9c811b8f23277de95dc687e87c6859308e68e6 Mon Sep 17 00:00:00 2001
From: Bruce Ashfield <bruce.ashfield@windriver.com>
Date: Wed, 6 Mar 2013 17:23:51 +0100
Subject: [PATCH] scripts/Makefile.headersinst: install headers from scratch
  file

If headers_install is executed from a deep/long directory structure, the
shell's maximum argument length can be execeeded, which breaks the operation
with:

| make[2]: execvp: /bin/sh: Argument list too long
| make[2]: ***

By dumping the input files to a scratch file and using xargs to read the
input list from the scratch file, we can avoid blowing out the maximum
argument size and install headers in a long path name environment.

Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
---
  scripts/Makefile.headersinst | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

          done;                                                           \
@@ -100,7 +100,9 @@ targets += $(install-file)
  $(install-file): scripts/headers_install.pl $(input-files) FORCE
  	$(if $(unwanted),$(call cmd,remove),)
  	$(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
+	@echo $(input-files) > $(INSTALL_HDR_PATH)/.input-files
  	$(call if_changed,install)
+	@rm $(INSTALL_HDR_PATH)/.input-files

  else
  __headerscheck: $(subdirs) $(check-file)

Comments

Bruce Ashfield March 6, 2013, 4:50 p.m. UTC | #1
On 13-03-06 11:27 AM, Nicolas Dichtel wrote:
> Le 06/03/2013 17:10, Sam Ravnborg a écrit :
>> On Wed, Mar 06, 2013 at 12:16:33PM +0100, Nicolas Dichtel wrote:
>>> This problem has probably already been reported, but I don't find the
>>> fix
>>> in a kernel.org tree and I don't understand why.
>>
>> First time I see this bug described - but I may missed it here at kbuild.
> It's probably why I didn't find this on a linux kernel mailing list ;-)

And it's been on my TODO list to float this as a RFC to the kbuild lists
before 3.9 arrived .. a goal that I managed to miss (again).

The patch in question has us up and installing headers on Yocto kernel/
kernel header packages greater than 3.7, so it has received a decent
amount of testing.

As for it being the perfect approach, I only claim that it works in
the environment that I've been using and it is functional.

If this change turns out to be acceptable, that's great. I can also
spend time re-working as appropriate .. or someone else's solution
can be adopted.

In the end it's a win and a fix, and the thread has prompted me to
get the change floated :)

Cheers,

Bruce

>
>> If a patch exists then please include the patch in your mail so we can
>> see it and comment on it.
>>
>> And make sure to have the attribution correct if you consider it to
>> be applied.
> I'm not the author of the patch, I've found it on the web. Here it is:
>
>  From cb9c811b8f23277de95dc687e87c6859308e68e6 Mon Sep 17 00:00:00 2001
> From: Bruce Ashfield <bruce.ashfield@windriver.com>
> Date: Wed, 6 Mar 2013 17:23:51 +0100
> Subject: [PATCH] scripts/Makefile.headersinst: install headers from scratch
>   file
>
> If headers_install is executed from a deep/long directory structure, the
> shell's maximum argument length can be execeeded, which breaks the
> operation
> with:
>
> | make[2]: execvp: /bin/sh: Argument list too long
> | make[2]: ***
>
> By dumping the input files to a scratch file and using xargs to read the
> input list from the scratch file, we can avoid blowing out the maximum
> argument size and install headers in a long path name environment.
>
> Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
> ---
>   scripts/Makefile.headersinst | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
> index 25f216a..c481986 100644
> --- a/scripts/Makefile.headersinst
> +++ b/scripts/Makefile.headersinst
> @@ -71,7 +71,7 @@ printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@))
>   quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
>                               file$(if $(word 2, $(all-files)),s))
>         cmd_install = \
> -        $(PERL) $< $(installdir) $(SRCARCH) $(input-files); \
> +        xargs $(PERL) $< $(installdir) $(SRCARCH) <
> $(INSTALL_HDR_PATH)/.input-files; \
>           for F in $(wrapper-files); do                                   \
>                   echo "\#include <asm-generic/$$F>" >
> $(installdir)/$$F;    \
>           done;                                                           \
> @@ -100,7 +100,9 @@ targets += $(install-file)
>   $(install-file): scripts/headers_install.pl $(input-files) FORCE
>       $(if $(unwanted),$(call cmd,remove),)
>       $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
> +    @echo $(input-files) > $(INSTALL_HDR_PATH)/.input-files
>       $(call if_changed,install)
> +    @rm $(INSTALL_HDR_PATH)/.input-files
>
>   else
>   __headerscheck: $(subdirs) $(check-file)

--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michal Marek March 7, 2013, 8:26 a.m. UTC | #2
Dne 6.3.2013 17:27, Nicolas Dichtel napsal(a):
> -        $(PERL) $< $(installdir) $(SRCARCH) $(input-files); \
[...]
> +    @echo $(input-files) > $(INSTALL_HDR_PATH)/.input-files

Are you sure this is a reliable fix? What make does is to spawn

/bin/sh -c 'echo <long list of files> > usr/include/.input-files'

here. So I guess that it works for you just because "sh -c" is shorter
than "sh -c 'perl scripts/headers_install.pl...'".

Michal
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bruce Ashfield March 7, 2013, 1:28 p.m. UTC | #3
On 13-03-07 03:26 AM, Michal Marek wrote:
> Dne 6.3.2013 17:27, Nicolas Dichtel napsal(a):
>> -        $(PERL) $< $(installdir) $(SRCARCH) $(input-files); \
> [...]
>> +    @echo $(input-files) > $(INSTALL_HDR_PATH)/.input-files
>
> Are you sure this is a reliable fix? What make does is to spawn
>
> /bin/sh -c 'echo <long list of files> > usr/include/.input-files'

It's what I was referencing in my original email. It works here,
and fixes our install of headers in previously failing environments.
But yes, it does shuffle the args enough to get around the limit, but
there's still a way to have even deeper and longer path names that
could cause failures.

I experimented with loops, and other options as well. But any
construct like "for f in $(input-files)", is both slow and explodes
on the argument length limits just like the original.

>
> here. So I guess that it works for you just because "sh -c" is shorter
> than "sh -c 'perl scripts/headers_install.pl...'".

Partly, yes, but we are more than a few characters over the limit
in my testing. So it shouldn't be the whole story.

Cheers,

Bruce

>
> Michal
>

--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 25f216a..c481986 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -71,7 +71,7 @@  printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@))
  quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
                              file$(if $(word 2, $(all-files)),s))
        cmd_install = \
-        $(PERL) $< $(installdir) $(SRCARCH) $(input-files); \
+        xargs $(PERL) $< $(installdir) $(SRCARCH) < 
$(INSTALL_HDR_PATH)/.input-files; \
          for F in $(wrapper-files); do                                   \
                  echo "\#include <asm-generic/$$F>" > $(installdir)/$$F;    \