Problem with mkmf and spaces in directory names?

Hi all,

Ruby 1.8.1
Windows 2000

I installed libexpat in C:\Program Files\Expat and then tried to
install Quixml. I made one modification to the extconf.rb file, using
'have_library("libexpat")' instead of 'have_header('expat.h')...'.
Then I ran this:

C:\ruby\src\QUIXML~1.1>ruby extconf.rb
--with-quixml-include='c:\program files\e
xpat\source\lib' --with-quixml-lib='c:\program files\expat\libs'

But it fails. Here's the mkmf.log output:

have_library: checking for main() in libexpat.lib...
-------------------- no

"cl -nologo -Feconftest -IC:/ruby/lib/ruby/1.8/i386-mswin32
-IC:/ruby/lib/ruby/1.8/i386-mswin32 -Ic:\program
files\expat\source\lib -I. -I./.. -I./../missing -MD -Zi -O2b2xg- -G6
conftest.c msvcrt-ruby18-static.lib libexpat.lib oldnames.lib
user32.lib advapi32.lib wsock32.lib -link -libpath:"C:/ruby/lib"
-libpath:"c:\program files\expat\libs" -stack:0x2000000"
Command line warning D4024 : unrecognized source file type
'files\expat\source\lib', object file assumed
conftest.c
LINK : fatal error LNK1181: cannot open input file
"files\expat\libs.obj"
checked program was:
/* begin */

/*top*/
int main() { return 0; }
int t() { main(); return 0; }
/* end */

"cl -nologo -Feconftest -IC:/ruby/lib/ruby/1.8/i386-mswin32
-IC:/ruby/lib/ruby/1.8/i386-mswin32 -Ic:\program
files\expat\source\lib -I. -I./.. -I./../missing -MD -Zi -O2b2xg- -G6
conftest.c msvcrt-ruby18-static.lib libexpat.lib oldnames.lib
user32.lib advapi32.lib wsock32.lib -link -libpath:"C:/ruby/lib"
-libpath:"c:\program files\expat\libs" -stack:0x2000000"
Command line warning D4024 : unrecognized source file type
'files\expat\source\lib', object file assumed
conftest.c
LINK : fatal error LNK1181: cannot open input file
"files\expat\libs.obj"
checked program was:
/* begin */
#include <winsock2.h>
#include <windows.h>

/*top*/
int main() { return 0; }
int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; }
/* end */

···

--------------------

However, everything works fine if I install expat in c:\expat. So, it
looks like the space in the directory name is causing a problem. Is
this a problem with mkmf.rb or is it a bug in the Windows linker?

Regards,

Dan

Hi,

At Fri, 25 Jun 2004 10:28:06 +0900,
Daniel Berger wrote in [ruby-talk:104505]:

However, everything works fine if I install expat in c:\expat. So, it
looks like the space in the directory name is causing a problem. Is
this a problem with mkmf.rb or is it a bug in the Windows linker?

It's a known restriction, but... it may be nasty. Can you try
this patch?

* lib/mkmf.rb (libpathflag, dir_config): quote directory names if
  necessary. [ruby-talk:104505]

Index: lib/mkmf.rb

···

===================================================================
RCS file: /pub/cvs/ruby/src/ruby/lib/mkmf.rb,v
retrieving revision 1.162.2.13
diff -U2 -p -d -r1.162.2.13 mkmf.rb
--- lib/mkmf.rb 20 May 2004 08:02:11 -0000 1.162.2.13
+++ lib/mkmf.rb 25 Jun 2004 02:30:25 -0000
@@ -251,5 +251,5 @@ end
def libpathflag(libpath=$LIBPATH)
   libpath.map{|x|
- (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x
+ (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x.quote
   }.join
end
@@ -662,5 +662,5 @@ def dir_config(target, idefault=nil, lde
     idirs -= Shellwords.shellwords($CPPFLAGS)
     unless idirs.empty?
- $CPPFLAGS = (idirs << $CPPFLAGS).join(" ")
+ $CPPFLAGS = (idirs << $CPPFLAGS).quote.join(" ")
     end
   end

--
Nobu Nakada

nobu.nokada@softhome.net wrote in message news:<200406250254.i5P2sJtK003642@sharui.nakada.niregi.kanuma.tochigi.jp>...

Hi,

At Fri, 25 Jun 2004 10:28:06 +0900,
Daniel Berger wrote in [ruby-talk:104505]:
> However, everything works fine if I install expat in c:\expat. So, it
> looks like the space in the directory name is causing a problem. Is
> this a problem with mkmf.rb or is it a bug in the Windows linker?

It's a known restriction, but... it may be nasty. Can you try
this patch?

* lib/mkmf.rb (libpathflag, dir_config): quote directory names if
  necessary. [ruby-talk:104505]

Index: lib/mkmf.rb

RCS file: /pub/cvs/ruby/src/ruby/lib/mkmf.rb,v
retrieving revision 1.162.2.13
diff -U2 -p -d -r1.162.2.13 mkmf.rb
--- lib/mkmf.rb 20 May 2004 08:02:11 -0000 1.162.2.13
+++ lib/mkmf.rb 25 Jun 2004 02:30:25 -0000
@@ -251,5 +251,5 @@ end
def libpathflag(libpath=$LIBPATH)
   libpath.map{|x|
- (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x
+ (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x.quote
   }.join
end
@@ -662,5 +662,5 @@ def dir_config(target, idefault=nil, lde
     idirs -= Shellwords.shellwords($CPPFLAGS)
     unless idirs.empty?
- $CPPFLAGS = (idirs << $CPPFLAGS).join(" ")
+ $CPPFLAGS = (idirs << $CPPFLAGS).quote.join(" ")
     end
   end

No luck. The libpathflag method is never actually reached because the
Quixml extconf.rb file doesn't call create_makefile unless the expat
lib is found. As for the change to $CPPFLAGS, it didn't seem to make
any difference. As far as I can tell, using debug prints, the
$CPPFLAGS are escaped properly.

LIBPATHFLAG entered
have_library: checking for main() in libexpat.lib...
-------------------- no

LIBPATHFLAG entered
"cl -nologo -Feconftest -IC:/ruby/lib/ruby/1.8/i386-mswin32
-IC:/ruby/lib/ruby/1
..8/i386-mswin32 "-Ic:\program files\expat\source\lib" "-I. -I./..
-I./../missing
" -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib
libexpat.lib oldna
mes.lib user32.lib advapi32.lib wsock32.lib -link
-libpath:C:/ruby/lib -lib
path:"c:\program files\expat\libs" -stack:0x2000000"
conftest.c
LINK : fatal error LNK1181: cannot open input file
"files\expat\libs.obj"
checked program was:
/* begin */

/*top*/
int main() { return 0; }
int t() { main(); return 0; }
/* end */

"cl -nologo -Feconftest -IC:/ruby/lib/ruby/1.8/i386-mswin32
-IC:/ruby/lib/ruby/1
..8/i386-mswin32 "-Ic:\program files\expat\source\lib" "-I. -I./..
-I./../missing
" -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib
libexpat.lib oldna
mes.lib user32.lib advapi32.lib wsock32.lib -link
-libpath:C:/ruby/lib -lib
path:"c:\program files\expat\libs" -stack:0x2000000"
conftest.c
LINK : fatal error LNK1181: cannot open input file
"files\expat\libs.obj"
checked program was:
/* begin */
#include <winsock2.h>
#include <windows.h>

/*top*/
int main() { return 0; }
int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; }
/* end */

···

--------------------

Any other ideas? Thanks.

Dan

nobu.nokada@softhome.net wrote in message news:<200406250254.i5P2sJtK003642@sharui.nakada.niregi.kanuma.tochigi.jp>...

Hi,

At Fri, 25 Jun 2004 10:28:06 +0900,
Daniel Berger wrote in [ruby-talk:104505]:
> However, everything works fine if I install expat in c:\expat. So, it
> looks like the space in the directory name is causing a problem. Is
> this a problem with mkmf.rb or is it a bug in the Windows linker?

It's a known restriction, but... it may be nasty.

<snip>

Wayne Chin was kind enough to point out that you can specify the short
path name instead as a workaround, e.g. "progra~1" instead of "program
files".

I tested it out and it worked fine. I suppose we could add a patch to
mkmf.rb for windows file names using OLE + WMI. It's up to you.

Regards,

Dan

Hi,

At Fri, 25 Jun 2004 21:38:11 +0900,
Daniel Berger wrote in [ruby-talk:104531]:

No luck. The libpathflag method is never actually reached because the
Quixml extconf.rb file doesn't call create_makefile unless the expat
lib is found. As for the change to $CPPFLAGS, it didn't seem to make
any difference. As far as I can tell, using debug prints, the
$CPPFLAGS are escaped properly.

libpathflag is called from every have_library, via try_link.

"-Ic:\program files\expat\source\lib" "-I. -I./.. -I./../missing"

tells where the patch was wrong:

+ $CPPFLAGS = (idirs << $CPPFLAGS).quote.join(" ")

should be

+ $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")

That is, previous $CPPFLAGS should not be quoted.

But,

-libpath:C:/ruby/lib -libpath:"c:\program files\expat\libs"

-libpath seems quoted properly. Hmmm, cl.exe can't deal with
quotation inside an argument?

Can you try this instead of the previous one?

Index: lib/mkmf.rb

···

===================================================================
RCS file: /pub/cvs/ruby/src/ruby/lib/mkmf.rb,v
retrieving revision 1.162.2.13
diff -u -2 -p -r1.162.2.13 mkmf.rb
--- lib/mkmf.rb 20 May 2004 08:02:11 -0000 1.162.2.13
+++ lib/mkmf.rb 26 Jun 2004 01:34:52 -0000
@@ -252,5 +252,5 @@ def libpathflag(libpath=$LIBPATH)
   libpath.map{|x|
     (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x
- }.join
+ }.quote.join
end

@@ -662,5 +662,5 @@ def dir_config(target, idefault=nil, lde
     idirs -= Shellwords.shellwords($CPPFLAGS)
     unless idirs.empty?
- $CPPFLAGS = (idirs << $CPPFLAGS).join(" ")
+ $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
     end
   end

--
Nobu Nakada

Hi,

At Sat, 26 Jun 2004 10:36:32 +0900,
nobu.nokada@softhome.net wrote in [ruby-talk:104619]:

@@ -252,5 +252,5 @@ def libpathflag(libpath=$LIBPATH)
   libpath.map{|x|
     (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x
- }.join
+ }.quote.join
end

This hunk was wrong, and unnecessary.

And cl.exe apparently doesn't pass arguments with spaces to
link.exe correctly.

  $ cat a.c
  int main(int argc, char **argv)
  {
      return 0;
  }

  $ cat a.bat
  @cl.exe -Fea.exe a.c /link "/libpath:"c:\Program Files""

  $ ./a.bat
  Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
  Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

  a.c
  Microsoft (R) Incremental Linker Version 6.00.8447
  Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

  /out:a.exe
  /libpath:c:\Program
  Files
  a.obj
  LINK : fatal error LNK1181: cannot open input file "Files.obj"

···

--
Nobu Nakada