This is a fix I considered making to our build system. It would not be that
hard to cygwin-ify our executable calls (there's not that many we call).

I don't think that is an optimal solution, because our build system is kind
of a sprawling, out of control thing. Nobody is really in charge of it. So,
at some point, someone will go and add another call to a windows-style
program. Unless I can somehow cause _only_ POSIX paths to work -- and give
an error if someone calls c:/moc.exe -- I won't be entirely happy. But your
solution is basically how I would do the conversion.

I do want to correct you: GNU make _does_ know that it is being used with
Cygwin. When you build GNU make on Windows, you have to specify, in
config.h.W32, that it is going to be calling the Cygwin shell. It is based
on that compiler option that it knows, for example, that nested double
quotes should be escaped as "" instead of \". Here's a quote
/*
 * Define if you have the Cygnus "Cygwin" GNU Windows32 tool set.
 * Do NOT define BATCH_MODE_ONLY_SHELL if you define HAVE_CYGWIN_SHELL
 */
/*#define HAVE_CYGWIN_SHELL 1 */


There is a possibility that is perhaps a little more annoying - if Cygwin's
behavior changes between versions.


On Fri, Mar 18, 2011 at 4:02 AM, tom honermann <[email protected]>wrote:

> As you noted, this is not a defect in GNU make, but rather a defect in
> Cygwin (CYGWIN=noglob doesn't work as documented - I've come across this as
> well), and, essentially, incorrectly written makefiles.
>
> Cygwin is an implementation of POSIX for Windows and therefore uses POSIX
> style path names.  It does have limited support for handling Windows native
> path names, but you'll likely have limited success getting your makefiles
> working well using native path names.  I recommend you make use of the
> 'cygpath' utility to convert path names to what Cygwin expects.  I've seen
> this done with make variables like the following:
>
>   N2PP=$(foreach path,$(1),$(shell $(CYGWIN_HOME)/bin/cygpath.exe -u
>   $(subst \,\\,$(path))))
>
> N2PP stands for "Native to POSIX Path".  Assuming you are using the Win32
> GNU make port (not the Cygwin port), this can be used something like:
>
>   target:
>        $(call N2PP,c:\foo) 1 "2 3" 4
>
> Note that GNU make does not assume or know that the shell being used is the
> Cygwin shell, so a patch may not be appropriate.
>
> Tom.
>
>
> On 3/17/2011 6:26 PM, Alex Khripin wrote:
>
>> Hi guys,
>> Short summary: there's a bug (I blame Cygwin, but want to fix make) in
>> running commands that start with a drive letter when using Windows make and
>> Cygwin sh
>>
>> I've run into a problem running in our environment.
>>
>> We run windows make (3.82) and use Cygwin (our make is compiled
>> appropriately)
>>
>> In this situation, normally, when make invokes a command, like
>> foo 1 "2 3" 4
>> It runs it like this:
>> sh.exe -c "foo 1 ""2 3"" 4"
>>
>> This is passed to the cygwin sh binary, where the loader takes the command
>> line and turns it into argv. Everything works great.
>>
>> Unless the command is
>> c:/foo 1 "2 3" 4
>> In which case, it still gets called the same way
>> sh.exe -c "c:/foo 1 ""2 3"" 4"
>>
>> The cygwin loader, though, doesn't treat this case the same way - for
>> reasons explained below, this runs the equivalent of
>> c:/foo 1 2 "3 4"
>>
>> I'd call this a cygwin problem - but they're not going to change how their
>> loader works. There's probably many programs that rely on that behavior.
>> First, a test to show exactly what is going on - let's try a simple Cygwin
>> program:
>> #include <stdio.h>
>> int main(int argc, char **argv) {
>>    int i;
>>    for (i = 1; i < argc; i++) printf("%d : %s\n", i, argv[i]);
>>    return 0;
>> }
>>
>> **************** Normal program name *****************
>> c:\cygwin\home\akhripin>args "foo 1 ""2 3"" 4"
>> 1 : foo 1 "2 3" 4
>> ***************** DOS'y program name ****************
>> c:\cygwin\home\akhripin>args "c:/foo 1 ""2 3"" 4"
>> 1 : c:/foo 1 \2 3\ 4
>>
>> Look at those random \'s that appear! I've done some cygwin source
>> reading, and apparently, parameters that start with letter-colon get treated
>> differently.
>>
>> My first attempt was to try setting CYGWIN=noglob But with that enabled,
>> you can't get a double quote through to sh.exe at all - no kind of escaping
>> will do
>>
>> After extensive experimentation and source reading, I've determined that
>> you cannot get the same method of escaping " and \ to work both for
>> parameters that start with a drive letter and those that do not. Thus, I
>> propose the following.
>>
>> **************** Proposed fix **************
>> When building the command line for cygwin (to be passed tinto
>> CreateProcess), look for arguments that start with a drive letter, and
>> escape them using a different method. I'm still trying to come up with the
>> bulletproof approach - at this point, I am considering the following:
>> 1) Enclose every argument with " or \ in double quotes
>> 2) Turn every " into "'"'" and every \ into "\" (outer double quotes
>> included). This essentially closes the current " pair, outputs a \ or a "
>>  (surrounded by ' to escape it) then resumes a new " pair.
>> Once I'm happy with this, I'll email a patch
>>
>> Thoughts/suggestions?
>>
>>
>> _______________________________________________
>> Make-w32 mailing list
>> [email protected]
>> http://lists.gnu.org/mailman/listinfo/make-w32
>>
>
_______________________________________________
Make-w32 mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/make-w32

Reply via email to