msysutils.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. from os import environ
  2. from os.path import isfile
  3. from subprocess import PIPE, Popen
  4. import sys
  5. def _determineMounts():
  6. # The MSYS shell provides a Unix-like file system by translating paths on
  7. # the command line to Windows paths. Usually this is transparent, but not
  8. # for us since we call GCC without going through the shell.
  9. # Figure out the root directory of MSYS.
  10. proc = Popen(
  11. [ msysShell(), '-c', '"%s" -c \'import sys ; print sys.argv[1]\' /'
  12. % sys.executable.replace('\\', '\\\\') ],
  13. stdin = None,
  14. stdout = PIPE,
  15. stderr = PIPE,
  16. )
  17. stdoutdata, stderrdata = proc.communicate()
  18. if stderrdata or proc.returncode:
  19. if stderrdata:
  20. print >> sys.stderr, 'Error determining MSYS root:', stderrdata
  21. if proc.returncode:
  22. print >> sys.stderr, 'Exit code %d' % proc.returncode
  23. raise IOError('Error determining MSYS root')
  24. msysRoot = stdoutdata.strip()
  25. # Figure out all mount points of MSYS.
  26. mounts = { '/': msysRoot + '/' }
  27. fstab = msysRoot + '/etc/fstab'
  28. if isfile(fstab):
  29. try:
  30. inp = open(fstab, 'r')
  31. try:
  32. for line in inp:
  33. line = line.strip()
  34. if line and not line.startswith('#'):
  35. nativePath, mountPoint = (
  36. path.rstrip('/') + '/' for path in line.split()
  37. )
  38. mounts[mountPoint] = nativePath
  39. finally:
  40. inp.close()
  41. except IOError, ex:
  42. print >> sys.stderr, 'Failed to read MSYS fstab:', ex
  43. except ValueError, ex:
  44. print >> sys.stderr, 'Failed to parse MSYS fstab:', ex
  45. return mounts
  46. def msysPathToNative(path):
  47. if path.startswith('/'):
  48. if len(path) == 2 or (len(path) > 2 and path[2] == '/'):
  49. # Support drive letters as top-level dirs.
  50. return '%s:/%s' % (path[1], path[3 : ])
  51. longestMatch = ''
  52. for mountPoint in msysMounts.iterkeys():
  53. if path.startswith(mountPoint):
  54. if len(mountPoint) > len(longestMatch):
  55. longestMatch = mountPoint
  56. return msysMounts[longestMatch] + path[len(longestMatch) : ]
  57. else:
  58. return path
  59. def msysActive():
  60. return environ.get('OSTYPE') == 'msys' or 'MSYSCON' in environ
  61. def msysShell():
  62. return environ.get('MSYSCON') or environ.get('SHELL') or 'sh.exe'
  63. if msysActive():
  64. msysMounts = _determineMounts()
  65. else:
  66. msysMounts = None
  67. if __name__ == '__main__':
  68. print 'MSYS mounts:', msysMounts