win32.py
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:12k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. """SCons.Platform.win32
  2. Platform-specific initialization for Win32 systems.
  3. There normally shouldn't be any need to import this module directly.  It
  4. will usually be imported through the generic SCons.Platform.Platform()
  5. selection method.
  6. """
  7. #
  8. # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
  9. #
  10. # Permission is hereby granted, free of charge, to any person obtaining
  11. # a copy of this software and associated documentation files (the
  12. # "Software"), to deal in the Software without restriction, including
  13. # without limitation the rights to use, copy, modify, merge, publish,
  14. # distribute, sublicense, and/or sell copies of the Software, and to
  15. # permit persons to whom the Software is furnished to do so, subject to
  16. # the following conditions:
  17. #
  18. # The above copyright notice and this permission notice shall be included
  19. # in all copies or substantial portions of the Software.
  20. #
  21. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  22. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  23. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. #
  29. __revision__ = "src/engine/SCons/Platform/win32.py 3057 2008/06/09 22:21:00 knight"
  30. import os
  31. import os.path
  32. import string
  33. import sys
  34. import tempfile
  35. from SCons.Platform.posix import exitvalmap
  36. from SCons.Platform import TempFileMunge
  37. import SCons.Util
  38. try:
  39.     import msvcrt
  40.     import win32api
  41.     import win32con
  42.     msvcrt.get_osfhandle
  43.     win32api.SetHandleInformation
  44.     win32con.HANDLE_FLAG_INHERIT
  45. except ImportError:
  46.     parallel_msg = 
  47.         "you do not seem to have the pywin32 extensions installed;n" + 
  48.         "tparallel (-j) builds may not work reliably with open Python files."
  49. except AttributeError:
  50.     parallel_msg = 
  51.         "your pywin32 extensions do not support file handle operations;n" + 
  52.         "tparallel (-j) builds may not work reliably with open Python files."
  53. else:
  54.     parallel_msg = None
  55.     import __builtin__
  56.     _builtin_file = __builtin__.file
  57.     _builtin_open = __builtin__.open
  58.     def _scons_file(*args, **kw):
  59.         fp = apply(_builtin_file, args, kw)
  60.         win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
  61.                                       win32con.HANDLE_FLAG_INHERIT,
  62.                                       0)
  63.         return fp
  64.     def _scons_open(*args, **kw):
  65.         fp = apply(_builtin_open, args, kw)
  66.         win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
  67.                                       win32con.HANDLE_FLAG_INHERIT,
  68.                                       0)
  69.         return fp
  70.     __builtin__.file = _scons_file
  71.     __builtin__.open = _scons_open
  72. # The upshot of all this is that, if you are using Python 1.5.2,
  73. # you had better have cmd or command.com in your PATH when you run
  74. # scons.
  75. def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
  76.     # There is no direct way to do that in python. What we do
  77.     # here should work for most cases:
  78.     #   In case stdout (stderr) is not redirected to a file,
  79.     #   we redirect it into a temporary file tmpFileStdout
  80.     #   (tmpFileStderr) and copy the contents of this file
  81.     #   to stdout (stderr) given in the argument
  82.     if not sh:
  83.         sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?n")
  84.         return 127
  85.     else:
  86.         # one temporary file for stdout and stderr
  87.         tmpFileStdout = os.path.normpath(tempfile.mktemp())
  88.         tmpFileStderr = os.path.normpath(tempfile.mktemp())
  89.         # check if output is redirected
  90.         stdoutRedirected = 0
  91.         stderrRedirected = 0
  92.         for arg in args:
  93.             # are there more possibilities to redirect stdout ?
  94.             if (string.find( arg, ">", 0, 1 ) != -1 or
  95.                 string.find( arg, "1>", 0, 2 ) != -1):
  96.                 stdoutRedirected = 1
  97.             # are there more possibilities to redirect stderr ?
  98.             if string.find( arg, "2>", 0, 2 ) != -1:
  99.                 stderrRedirected = 1
  100.         # redirect output of non-redirected streams to our tempfiles
  101.         if stdoutRedirected == 0:
  102.             args.append(">" + str(tmpFileStdout))
  103.         if stderrRedirected == 0:
  104.             args.append("2>" + str(tmpFileStderr))
  105.         # actually do the spawn
  106.         try:
  107.             args = [sh, '/C', escape(string.join(args)) ]
  108.             ret = os.spawnve(os.P_WAIT, sh, args, env)
  109.         except OSError, e:
  110.             # catch any error
  111.             try:
  112.                 ret = exitvalmap[e[0]]
  113.             except KeyError:
  114.                 sys.stderr.write("scons: unknown OSError exception code %d - %s: %sn" % (e[0], cmd, e[1]))
  115.             if stderr != None:
  116.                 stderr.write("scons: %s: %sn" % (cmd, e[1]))
  117.         # copy child output from tempfiles to our streams
  118.         # and do clean up stuff
  119.         if stdout != None and stdoutRedirected == 0:
  120.             try:
  121.                 stdout.write(open( tmpFileStdout, "r" ).read())
  122.                 os.remove( tmpFileStdout )
  123.             except (IOError, OSError):
  124.                 pass
  125.         if stderr != None and stderrRedirected == 0:
  126.             try:
  127.                 stderr.write(open( tmpFileStderr, "r" ).read())
  128.                 os.remove( tmpFileStderr )
  129.             except (IOError, OSError):
  130.                 pass
  131.         return ret
  132. def exec_spawn(l, env):
  133.     try:
  134.         result = os.spawnve(os.P_WAIT, l[0], l, env)
  135.     except OSError, e:
  136.         try:
  137.             result = exitvalmap[e[0]]
  138.             sys.stderr.write("scons: %s: %sn" % (l[0], e[1]))
  139.         except KeyError:
  140.             result = 127
  141.             if len(l) > 2:
  142.                 if len(l[2]) < 1000:
  143.                     command = string.join(l[0:3])
  144.                 else:
  145.                     command = l[0]
  146.             else:
  147.                 command = l[0]
  148.             sys.stderr.write("scons: unknown OSError exception code %d - '%s': %sn" % (e[0], command, e[1]))
  149.     return result
  150. def spawn(sh, escape, cmd, args, env):
  151.     if not sh:
  152.         sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?n")
  153.         return 127
  154.     return exec_spawn([sh, '/C', escape(string.join(args))], env)
  155. # Windows does not allow special characters in file names anyway, so no
  156. # need for a complex escape function, we will just quote the arg, except
  157. # that "cmd /c" requires that if an argument ends with a backslash it
  158. # needs to be escaped so as not to interfere with closing double quote
  159. # that we add.
  160. def escape(x):
  161.     if x[-1] == '\':
  162.         x = x + '\'
  163.     return '"' + x + '"'
  164. # Get the windows system directory name
  165. def get_system_root():
  166.     # A resonable default if we can't read the registry
  167.     try:
  168.         val = os.environ['SYSTEMROOT']
  169.     except KeyError:
  170.         val = "C:/WINDOWS"
  171.         pass
  172.     # First see if we can look in the registry...
  173.     if SCons.Util.can_read_reg:
  174.         try:
  175.             # Look for Windows NT system root
  176.             k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
  177.                                       'Software\Microsoft\Windows NT\CurrentVersion')
  178.             val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot')
  179.         except SCons.Util.RegError:
  180.             try:
  181.                 # Okay, try the Windows 9x system root
  182.                 k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
  183.                                           'Software\Microsoft\Windows\CurrentVersion')
  184.                 val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot')
  185.             except KeyboardInterrupt:
  186.                 raise
  187.             except:
  188.                 pass
  189.     return val
  190. # Get the location of the program files directory
  191. def get_program_files_dir():
  192.     # Now see if we can look in the registry...
  193.     val = ''
  194.     if SCons.Util.can_read_reg:
  195.         try:
  196.             # Look for Windows Program Files directory
  197.             k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
  198.                                       'Software\Microsoft\Windows\CurrentVersion')
  199.             val, tok = SCons.Util.RegQueryValueEx(k, 'ProgramFilesDir')
  200.         except SCons.Util.RegError:
  201.             val = ''
  202.             pass
  203.     if val == '':
  204.         # A reasonable default if we can't read the registry
  205.         # (Actually, it's pretty reasonable even if we can :-)
  206.         val = os.path.join(os.path.dirname(get_system_root()),"Program Files")
  207.         
  208.     return val
  209. def generate(env):
  210.     # Attempt to find cmd.exe (for WinNT/2k/XP) or
  211.     # command.com for Win9x
  212.     cmd_interp = ''
  213.     # First see if we can look in the registry...
  214.     if SCons.Util.can_read_reg:
  215.         try:
  216.             # Look for Windows NT system root
  217.             k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
  218.                                           'Software\Microsoft\Windows NT\CurrentVersion')
  219.             val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot')
  220.             cmd_interp = os.path.join(val, 'System32\cmd.exe')
  221.         except SCons.Util.RegError:
  222.             try:
  223.                 # Okay, try the Windows 9x system root
  224.                 k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
  225.                                               'Software\Microsoft\Windows\CurrentVersion')
  226.                 val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot')
  227.                 cmd_interp = os.path.join(val, 'command.com')
  228.             except KeyboardInterrupt:
  229.                 raise
  230.             except:
  231.                 pass
  232.     # For the special case of not having access to the registry, we
  233.     # use a temporary path and pathext to attempt to find the command
  234.     # interpreter.  If we fail, we try to find the interpreter through
  235.     # the env's PATH.  The problem with that is that it might not
  236.     # contain an ENV and a PATH.
  237.     if not cmd_interp:
  238.         systemroot = r'C:Windows'
  239.         if os.environ.has_key('SYSTEMROOT'):
  240.             systemroot = os.environ['SYSTEMROOT']
  241.         tmp_path = systemroot + os.pathsep + 
  242.                    os.path.join(systemroot,'System32')
  243.         tmp_pathext = '.com;.exe;.bat;.cmd'
  244.         if os.environ.has_key('PATHEXT'):
  245.             tmp_pathext = os.environ['PATHEXT'] 
  246.         cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext)
  247.         if not cmd_interp:
  248.             cmd_interp = SCons.Util.WhereIs('command', tmp_path, tmp_pathext)
  249.     if not cmd_interp:
  250.         cmd_interp = env.Detect('cmd')
  251.         if not cmd_interp:
  252.             cmd_interp = env.Detect('command')
  253.     
  254.     if not env.has_key('ENV'):
  255.         env['ENV']        = {}
  256.     # Import things from the external environment to the construction
  257.     # environment's ENV.  This is a potential slippery slope, because we
  258.     # *don't* want to make builds dependent on the user's environment by
  259.     # default.  We're doing this for SYSTEMROOT, though, because it's
  260.     # needed for anything that uses sockets, and seldom changes, and
  261.     # for SYSTEMDRIVE because it's related.
  262.     #
  263.     # Weigh the impact carefully before adding other variables to this list.
  264.     import_env = [ 'SYSTEMDRIVE', 'SYSTEMROOT', 'TEMP', 'TMP' ]
  265.     for var in import_env:
  266.         v = os.environ.get(var)
  267.         if v:
  268.             env['ENV'][var] = v
  269.     env['ENV']['PATHEXT'] = '.COM;.EXE;.BAT;.CMD'
  270.     env['OBJPREFIX']      = ''
  271.     env['OBJSUFFIX']      = '.obj'
  272.     env['SHOBJPREFIX']    = '$OBJPREFIX'
  273.     env['SHOBJSUFFIX']    = '$OBJSUFFIX'
  274.     env['PROGPREFIX']     = ''
  275.     env['PROGSUFFIX']     = '.exe'
  276.     env['LIBPREFIX']      = ''
  277.     env['LIBSUFFIX']      = '.lib'
  278.     env['SHLIBPREFIX']    = ''
  279.     env['SHLIBSUFFIX']    = '.dll'
  280.     env['LIBPREFIXES']    = [ '$LIBPREFIX' ]
  281.     env['LIBSUFFIXES']    = [ '$LIBSUFFIX' ]
  282.     env['PSPAWN']         = piped_spawn
  283.     env['SPAWN']          = spawn
  284.     env['SHELL']          = cmd_interp
  285.     env['TEMPFILE']       = TempFileMunge
  286.     env['TEMPFILEPREFIX'] = '@'
  287.     env['MAXLINELENGTH']  = 2048
  288.     env['ESCAPE']         = escape