Skip Menu |

This queue is for tickets about the ExtUtils-MakeMaker CPAN distribution.

Report information
The Basics
Id: 68679
Status: resolved
Worked: 45 min
Priority: 0/
Queue: ExtUtils-MakeMaker

People
Owner: ETJ [...] cpan.org
Requestors: alex [...] earth.li
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 7.05_06



Subject: dmake on win32 (strawberry) doesn't like escaped CCFLAGS
Date: Tue, 7 Jun 2011 11:34:14 +0100
To: bug-ExtUtils-MakeMaker [...] rt.cpan.org
From: Alex Gough <alex [...] earth.li>
I'm trying to build a module which links to libraries which get installed under c:\program files (x86)\blah\include but cannot do so under strawberry perl as the brackets get escaped, then passed complete with escapes to gcc, which croaks. The following patch fixes this, but in a violent way: --- /c/strawberry/perl/lib/ExtUtils/MM_Unix.pm Tue Jun 7 22:20:12 2011 +++ /c/users/alex/Downloads/ExtUtils-MakeMaker-6.57_11/lib/ExtUtils/MM_Unix.pm Tue Jun 7 22:17:59 2011 @@ -264,7 +264,7 @@ $pollute = '$(PERL_MALLOC_DEF)'; } - $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}) unless $Config{make} eq 'dmake'; + $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); return $self->{CFLAGS} = qq{
On Tue Jun 07 06:34:23 2011, alex@earth.li wrote: Show quoted text
> I'm trying to build a module which links to libraries which get > installed under c:\program files (x86)\blah\include but cannot do so > under strawberry perl as the brackets get escaped, then passed > complete with escapes to gcc, which croaks. The following patch fixes > this, but in a violent way:
This is a less violent way as it leaves alone () not in quotes, which I think is sensible, it should manage to only mess with quoted stuff, I also have some tests for the included little function(below the patch), but I'm not sure which test file to put them in. --- ExtUtils-MakeMaker-6.57_11/lib/ExtUtils/MM_Unix.pm Fri May 20 12:27:11 2011 +++ ../ExtUtils-MakeMaker-6.57_11/lib/ExtUtils/MM_Unix.pm Tue Jun 7 23:23:52 2011 @@ -264,8 +264,14 @@ $pollute = '$(PERL_MALLOC_DEF)'; } - $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); - $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); + if ($Config{make} eq 'dmake') { + $self->{CCFLAGS} = quote_paren_not_quoted($self->{CCFLAGS}); + $self->{OPTIMIZE} = quote_paren_not_quoted($self->{OPTIMIZE}); + } + else { + $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); + $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); + } return $self->{CFLAGS} = qq{ CCFLAGS = $self->{CCFLAGS} @@ -3089,6 +3095,31 @@ $arg =~ s{(?<!\\)([()])}{\\$1}g; # quote unprotected $arg =~ s{\$\\\\\((.+?)\\\\\)}{\$($1)}g; # unprotect $(...) return $arg; +} + +=item quote_paren_not_quoted + +Backslashes parentheses C<()> in command line arguments. +Doesn't handle recursive Makefile C<$(...)> constructs, +but handles simple ones. Leaves alone anything in unprotected +quotes. + +=cut + +sub quote_paren_not_quoted { + my $arg = shift; + my @parts = split(/(?<!\\)(")/, $arg); + push(@parts, '') if (substr($arg, -1, 1) eq q{"}); + + if (@parts == 1) { + return quote_paren($arg); + } + else { + for my $i (0..@parts-1) { + $parts[$i] = quote_paren($parts[$i]) if $i % 4 == 0; + } + return join(q{}, @parts); + } } =item replace_manpage_separator ############################ Tests: is(quote_paren_not_quoted(q{}), q{}); is(quote_paren_not_quoted(q{()}), q{\\(\\)}); is(quote_paren_not_quoted(q{"()"}), q{"()"}); is(quote_paren_not_quoted(q{()""()}), q{\\(\\)""\\(\\)}); is(quote_paren_not_quoted(q{"()""()"}), q{"()""()"}); is(quote_paren_not_quoted(q{"()" ("}), q{"()" \\("}); is(quote_paren_not_quoted(q{"\\""}), q{"\\""}); is(quote_paren_not_quoted(q{"(\\"("}), q{"(\\"("}); is(quote_paren_not_quoted(q{"(\\"(" ( ""}), q{"(\\"(" \\( ""}); is(quote_paren_not_quoted(q{\\" () \\"}), q{\\" \\(\\) \\"}); is(quote_paren_not_quoted(q{"\\" () \\""}), q{"\\" () \\""});
Sorry, that lost the whitespace, maybe, so patch here also as a file. is(quote_paren_not_quoted(q{}), q{}); is(quote_paren_not_quoted(q{()}), q{\\(\\)}); is(quote_paren_not_quoted(q{"()"}), q{"()"}); is(quote_paren_not_quoted(q{()""()}), q{\\(\\)""\\(\\)}); is(quote_paren_not_quoted(q{"()""()"}), q{"()""()"}); is(quote_paren_not_quoted(q{"()" ("}), q{"()" \\("}); is(quote_paren_not_quoted(q{"\\""}), q{"\\""}); is(quote_paren_not_quoted(q{"(\\"("}), q{"(\\"("}); is(quote_paren_not_quoted(q{"(\\"(" ( ""}), q{"(\\"(" \\( ""}); is(quote_paren_not_quoted(q{\\" () \\"}), q{\\" \\(\\) \\"}); is(quote_paren_not_quoted(q{"\\" () \\""}), q{"\\" () \\""});
Subject: diff.txt
--- ExtUtils-MakeMaker-6.57_11/lib/ExtUtils/MM_Unix.pm Fri May 20 12:27:11 2011 +++ ../ExtUtils-MakeMaker-6.57_11/lib/ExtUtils/MM_Unix.pm Tue Jun 7 23:23:52 2011 @@ -264,8 +264,14 @@ $pollute = '$(PERL_MALLOC_DEF)'; } - $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); - $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); + if ($Config{make} eq 'dmake') { + $self->{CCFLAGS} = quote_paren_not_quoted($self->{CCFLAGS}); + $self->{OPTIMIZE} = quote_paren_not_quoted($self->{OPTIMIZE}); + } + else { + $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); + $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); + } return $self->{CFLAGS} = qq{ CCFLAGS = $self->{CCFLAGS} @@ -3089,6 +3095,31 @@ $arg =~ s{(?<!\\)([()])}{\\$1}g; # quote unprotected $arg =~ s{\$\\\\\((.+?)\\\\\)}{\$($1)}g; # unprotect $(...) return $arg; +} + +=item quote_paren_not_quoted + +Backslashes parentheses C<()> in command line arguments. +Doesn't handle recursive Makefile C<$(...)> constructs, +but handles simple ones. Leaves alone anything in unprotected +quotes. + +=cut + +sub quote_paren_not_quoted { + my $arg = shift; + my @parts = split(/(?<!\\)(")/, $arg); + push(@parts, '') if (substr($arg, -1, 1) eq q{"}); + + if (@parts == 1) { + return quote_paren($arg); + } + else { + for my $i (0..@parts-1) { + $parts[$i] = quote_paren($parts[$i]) if $i % 4 == 0; + } + return join(q{}, @parts); + } } =item replace_manpage_separator
6.61_01 contains a major overhaul to the quoting routines on Windows. Please give it a shot? https://metacpan.org/release/MSCHWERN/ExtUtils-MakeMaker-6.61_01/
From: alex-perlbug [...] earth.li
On Sun Sep 25 02:11:30 2011, MSCHWERN wrote: Show quoted text
> 6.61_01 contains a major overhaul to the quoting routines on Windows. > Please give it a shot? > https://metacpan.org/release/MSCHWERN/ExtUtils-MakeMaker-6.61_01/
That still has the problem, I'll see if I have time to investigate further later. This isn't a showstopper as the obvious workaround is to install my libraries in a path without spaces. perl -MExtUtils::MakeMaker -E "say $ExtUtils::MakeMaker::VERSION" 6.6101 (With Parallel::MPI::Simple) perl MakeFile.PL ... ok dmake .... C:\strawberry\perl\bin\perl.exe C:\strawberry\perl\lib\ExtUtils\xsubpp -typemap C:\strawberry\perl\lib\ExtUtils\typemap Simple.xs > Simple .xsc && C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e mv -- Simple.xsc Simple.c gcc -c "-IC:\Program Files \(x86\)\MPICH2\include" "- LC:\Program Files \(x86\)\MPICH2\lib" -lmpi -s -O2 - DVERSION=\"0.10\" -DXS_VERSION=\"0.10\" "-IC:\strawberry\perl\lib\CORE" Simple.c Simple.xs:8:18: error: mpi.h: No such file or directory
From: alex-perlbug [...] earth.li
The problem is that dmake doesn't like quoted escaped brackets, the approach I took before fixes it again, here's a fresh patch against 61_01. On Sun Sep 25 21:21:49 2011, quidity wrote: Show quoted text
> On Sun Sep 25 02:11:30 2011, MSCHWERN wrote:
> > 6.61_01 contains a major overhaul to the quoting routines on
Windows. Show quoted text
> > That still has the problem, I'll see if I have time to investigate > further later. This isn't a showstopper as the obvious workaround is
to Show quoted text
> install my libraries in a path without spaces. > > perl -MExtUtils::MakeMaker -E "say $ExtUtils::MakeMaker::VERSION" > 6.6101 > > (With Parallel::MPI::Simple) > perl MakeFile.PL ... ok > dmake > .... > C:\strawberry\perl\bin\perl.exe C:\strawberry\perl\lib\ExtUtils\xsubpp > -typemap C:\strawberry\perl\lib\ExtUtils\typemap Simple.xs > Simple > .xsc && C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e mv -- > Simple.xsc Simple.c > gcc -c "-IC:\Program Files \(x86\)\MPICH2\include" "- > LC:\Program Files \(x86\)\MPICH2\lib" -lmpi -s -O2 - > DVERSION=\"0.10\" > -DXS_VERSION=\"0.10\" "-IC:\strawberry\perl\lib\CORE" > Simple.c > Simple.xs:8:18: error: mpi.h: No such file or directory
Subject: mm_patch.txt
--- ExtUtils-MakeMaker-6.61_01/lib/ExtUtils/MM_Unix.pm Sun Sep 25 18:16:36 2011 +++ ExtUtils-MakeMaker-6.61_01-changed/lib/ExtUtils/MM_Unix.pm Mon Sep 26 14:36:20 2011 @@ -264,8 +264,14 @@ $pollute = '$(PERL_MALLOC_DEF)'; } - $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); - $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); + if ($Config{make} eq 'dmake') { + $self->{CCFLAGS} = quote_paren_if_not_quoted($self->{CCFLAGS}); + $self->{OPTIMIZE} = quote_paren_if_not_quoted($self->{OPTIMIZE}); + } + else { + $self->{CCFLAGS} = quote_paren($self->{CCFLAGS}); + $self->{OPTIMIZE} = quote_paren($self->{OPTIMIZE}); + } return $self->{CFLAGS} = qq{ CCFLAGS = $self->{CCFLAGS} @@ -3089,6 +3095,31 @@ $arg =~ s{(?<!\\)([()])}{\\$1}g; # quote unprotected $arg =~ s{\$\\\\\((.+?)\\\\\)}{\$($1)}g; # unprotect $(...) return $arg; +} + +=item quote_paren_if_not_quoted + +Backslashes parentheses C<()> in command line arguments. +Doesn't handle recursive Makefile C<$(...)> constructs, +but handles simple ones. Leaves alone anything in unprotected +quotes. + +=cut + +sub quote_paren_if_not_quoted { + my $arg = shift; + my @parts = split(/(?<!\\)(")/, $arg); + push(@parts, '') if (substr($arg, -1, 1) eq q{"}); + + if (@parts == 1) { + return quote_paren($arg); + } + else { + for my $i (0..@parts-1) { + $parts[$i] = quote_paren($parts[$i]) if $i % 4 == 0; + } + return join(q{}, @parts); + } } =item replace_manpage_separator
RT-Send-CC: shay [...] cpan.org
Thanks for checking it out and the repatch. Let me see if our Resident Expert on Windows quoting will weigh in, otherwise ping the bug in a few days and I'll patch it in.
On Tue Sep 27 21:57:22 2011, MSCHWERN wrote: Show quoted text
> Thanks for checking it out and the repatch. Let me see if our Resident > Expert on Windows quoting will weigh in, otherwise ping the bug in a few > days and I'll patch it in.
I will take a look in the next day or two. I've downloaded 6.61_01 as a reminder to myself. I didn't realize that EU-MM even supported paths with a space in them, but this bug could affect more than just that anyway. (Btw, I see that the 6.61_01 tarball is made in such a way that WinZip doesn't handle it correctly on Windows -- it has the same problem which I reported recently for the Apache-Singleton distro in #68532. I realize it's a WinZip "feature", but many Windows users would appreciate it if you could make your tarballs compatible with WinZip.)
Subject: Re: [rt.cpan.org #68679] dmake on win32 (strawberry) doesn't like escaped CCFLAGS
Date: Wed, 28 Sep 2011 20:43:15 -0700
To: bug-ExtUtils-MakeMaker [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
On 2011.9.28 3:43 PM, Steve Hay via RT wrote: Show quoted text
> On Tue Sep 27 21:57:22 2011, MSCHWERN wrote:
>> Thanks for checking it out and the repatch. Let me see if our Resident >> Expert on Windows quoting will weigh in, otherwise ping the bug in a few >> days and I'll patch it in.
> > I will take a look in the next day or two. I've downloaded 6.61_01 as a > reminder to myself. I didn't realize that EU-MM even supported paths > with a space in them, but this bug could affect more than just that anyway.
Paths with spaces in them are caveat emptor, but a user has less control over where C libraries are located on Windows than where Perl is so I'm a bit more sympathetic. Show quoted text
> (Btw, I see that the 6.61_01 tarball is made in such a way that WinZip > doesn't handle it correctly on Windows -- it has the same problem which > I reported recently for the Apache-Singleton distro in #68532. I realize > it's a WinZip "feature", but many Windows users would appreciate it if > you could make your tarballs compatible with WinZip.)
I'm opening this as a separate issue. https://rt.cpan.org/Ticket/Display.html?id=71325 -- Anyway, last I saw him, the TPF goons were pouring concrete around him, leaving only one hole each for air, tea, and power. No ethernet, because he's using git. -- Eric Wilhelm on one of my disappearances
On Wed Sep 28 23:43:23 2011, schwern@pobox.com wrote: Show quoted text
> On 2011.9.28 3:43 PM, Steve Hay via RT wrote:
> > On Tue Sep 27 21:57:22 2011, MSCHWERN wrote:
> >> Thanks for checking it out and the repatch. Let me see if our
> Resident
> >> Expert on Windows quoting will weigh in, otherwise ping the bug in
> a few
> >> days and I'll patch it in.
> > > > I will take a look in the next day or two. I've downloaded 6.61_01
> as a
> > reminder to myself. I didn't realize that EU-MM even supported paths > > with a space in them, but this bug could affect more than just that
> anyway. > > Paths with spaces in them are caveat emptor, but a user has less > control over > where C libraries are located on Windows than where Perl is so I'm a > bit more > sympathetic.
Good point. I've had a look, and I don't believe the problem is specifically with dmake. According to the documentation which I cited when I overhauled the quoting of oneliners, parentheses may need to be escaped for the cmd.exe shell if they're not in a double-quoted part of the command-line, so the approach taken by the suggested patch should be correct for Windows generally (i.e. nmake as well as dmake). Sure enough, when I tried an example with nmake, I got an error from the cl.exe compiler, complaining that it couldn't find a header file located in an incorrectly-escaped path with parentheses: C:\Temp\Filter-Crypto-1.31>nmake [snip] cl -c -nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_ST RICT -DHAVE_DES_FCRYPT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DPERL_DEBUGGING_MSTATS -DPERL_IMPLICIT_CONTEXT -DUSE_PERLIO "-IC:\Program Files \(x86\)\openssl\include" -MD -Zi -DNDEBUG -O1 -DVERSION=\"1.18\" -DXS_VERSION=\"1.18\" "-IC:\perl5\lib\CORE" -DFILTER_CRYPTO_OPENSSL_VERSION=1000001 CryptFile.c CryptFile.c c:\temp\filter-crypto-1.31\cryptfile\../CryptoCommon-c.inc(67) : fatal error C1083: Cannot open include file: 'openssl/err.h': No such file or directory NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\cl.EXE"' : return code '0x2' Stop. NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\nmake.EXE"' : return code '0x2' Stop. (And just typing the cl.exe command-line above directly into the cmd.exe shell also produces the same error -- it's purely a shell quoting issue, nothing to do with either make program.) Extending the suggested patch to cover nmake as well as dmake fixes the problem.
Subject: Re: [rt.cpan.org #68679] dmake on win32 (strawberry) doesn't like escaped CCFLAGS
Date: Fri, 30 Sep 2011 23:57:16 -0700
To: bug-ExtUtils-MakeMaker [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Thanks for the analysis. Patching it in, I've noticed this applies to MM_Unix, so it will affect all platforms. Is that safe? The basic logic makes sense, escape parens unless it's quoted, but the quotes are different on Unix which I can account for in the patch. Also, what's doing the quoting? Are they already quoted in $Config{ccflags}?
Subject: Re: [rt.cpan.org #68679] dmake on win32 (strawberry) doesn't like escaped CCFLAGS
Date: Sat, 1 Oct 2011 11:16:31 +0100
To: Michael G Schwern via RT <bug-ExtUtils-MakeMaker [...] rt.cpan.org>
From: Alex Gough <alex [...] earth.li>
#### [Sat, Oct 01, 2011 at 02:57:34AM -0400: Michael G Schwern via RT] Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=68679 > > > Thanks for the analysis. > > Patching it in, I've noticed this applies to MM_Unix, so it will affect all > platforms. Is that safe? The basic logic makes sense, escape parens unless > it's quoted, but the quotes are different on Unix which I can account for in > the patch.
Yes, I decided that patching MM_Unix meant changing less code to fix the problem, and that guarding with 'dmake' should make that safe. If other make's are involved as well, which could be on unices, then it may make sense to factor the quoting routine out and have a different one in each class. Alex -- #!perl $.=bless ["Just another Perl hacker\n"]; 19800829 .. 20020829; use overload '0+' => sub {print @{$_[0]}};
On Sat Oct 01 02:57:33 2011, schwern@pobox.com wrote: Show quoted text
> Thanks for the analysis. > > Patching it in, I've noticed this applies to MM_Unix, so it will > affect all > platforms. Is that safe? The basic logic makes sense, escape parens > unless > it's quoted, but the quotes are different on Unix which I can account > for in > the patch.
I have no idea about other platforms, so I can't help there :-( Show quoted text
> > Also, what's doing the quoting? Are they already quoted in > $Config{ccflags}?
In the test case that I hacked together I explicitly passed CCFLAGS => with a string already containing quotes (double-quotes in my case, on Windows) to the WriteMakefile() call. Alex's Parallel-MPI-Simple distro did likewise (see http://cpansearch.perl.org/src/AJGOUGH/Parallel-MPI-Simple-0.10/Makefile.PL). So MM_Unix.pm's $self->{CCFLAGS} is certainly already quoted in these cases, but I don't know about $Config{ccflags}... My Config_heavy.pl contains ccflags='-nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX' It has no -I or -L include or library paths that might need quoting. I thought we were only talking about the paths of libraries that extension modules may need to link against, so why would such paths ever appear in $Config{ccflags}? Surely that would only ever contain paths related to the original perl build, which should never need quoting since we do not support paths with spaces for that. Btw, I find the function names quote_paren() and quote_paren_if_not_quoted() rather confusing -- especially the latter! Are they really "quoting" parentheses? To my mind "quoting" something is adding double-quotes (") or single-quotes (') around it; what we're doing here is *escaping* parentheses with a preceding backslash. Perhaps escape_paren() and escape_paren_unless_quoted() would be better names?
Alex, Could you try the latest (7.04) EUMM and see if the EUMM7 "perl in space" changes fixed this for you? Ed
On Wed Jan 07 22:01:23 2015, ETJ wrote: Show quoted text
> As of https://github.com/Perl-Toolchain-Gang/ExtUtils- > MakeMaker/commit/0c7aa72f8216b06b2224345e72ee993573d11848 this now > works.