[Distutils] distutils - Filenames/Pathnames with spaces under WinNT

Jonathan M. Gilligan jonathan.gilligan@vanderbilt.edu
Thu, 09 Mar 2000 02:11:09 -0600


I'm new on this list, so please forgive me if I'm treading on familiar 
ground, but I didn't see this issue raised when I browsed through the last 
month or so of archives.

Distutils for Windows NT,9x,2K seems to have a big hole in the way it forms 
command-lines for the compiler and friends: it doesn't account for the fact 
that filenames and pathnames may have spaces in them and thus may need to 
be quoted on the command-line passed to external tools (compiler, linker). 
Given that the standard Python 1.5.2 distribution installs itself on 
"C:\Program Files\Python" this leads to potentially problematic 
command-lines of the form

    cl -IC:\Program Files\Python\include
    link C:\Program Files\Python\Libs\python15.lib

Both of these command lines will fail, because cl can't find the directory 
"C:\Program" and can't find "Files\Python\include.obj" and link can't find 
"C:\Program" or "Files\Python\Libs\python15.lib". CL and LINK both reparse 
the command-line so even if "-IC:/Program Files/Python/include" is passed 
as a single argument to os.spawnv(), it is split into two by cl's 
command-line parser:

    Python 1.5.2 (#0, Feb  2 2000, 22:07:42) [MSC 32 bit (Intel)] on win32
    Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
    >>> from distutils.spawn import *
    >>> spawn(['cl','-c','-IC:/Program Files/Python/include','client.cpp'])
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

    Command line warning D4024 : unrecognized source file type 
'Files/Python/include', object file assumed
    Command line warning D4027 : source file 'Files/Python/include' ignored
    client.cpp
    client.cpp(7) : fatal error C1083: Cannot open include file: 
'python.h': No such file or directory
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
      File "C:\Program Files\python\python-1.5.2\distutils\spawn.py", line 
37, in spawn
        _spawn_nt (cmd, search_path, verbose, dry_run)
      File "C:\Program Files\python\python-1.5.2\distutils\spawn.py", line 
74, in _spawn_nt
        raise DistutilsExecError, \
    distutils.errors.DistutilsExecError: command 'cl' failed with exit status 2
    >>>

The command-lines should be:

    cl -I"C:\Program Files\Python\include"
    link "C:\Program Files\Python\Libs\python15.lib"

which work:

    Python 1.5.2 (#0, Feb  2 2000, 22:07:42) [MSC 32 bit (Intel)] on win32
    Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
    >>> from distutils.spawn import *
    >>> spawn(['cl','-c','-I"C:/Program Files/Python/include"','client.cpp'])
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

    client.cpp
    >>>

I started hacking at the msvccompiler.py source to put quotes around 
filenames passed as arguments, but then realized that it would probably be 
better to implement a "wrapfilename(fname)" method in the ccompiler class 
and then subclass it appropriately for *ix (return fname) and WinNT (return 
'"%s"' % fname). Then every time a filename or path gets added to a 
command-line it must be processed with wrapfilename(). For instance:

    inputOpt = fileOpt + wrapfilename(srcFile)

Does this sound like a reasonable approach? Am I missing a boat somewhere?

Implementing this looks as thought it will require modifying (slightly) a 
number functions in ccompiler.py and msvccompiler.py, so I would like 
feedback from all of you more experienced folks on this list before I spend 
any time at it. I also might not be the best person to try, being a 
greenhorn and thus less prone to catch where such a modification would 
break existing code, but I am willing to make a pass at it if others don't 
have the time.

Alternately, one could modify _spawn_nt to wrap each of its arguments in 
double-quotes, but that seems potentially more problematic (Some programs 
may not transparently discard quotation marks on command-line arguments. 
Consider the behavior of the find command.).

Thanks for listening,
Jonathan Gilligan