msysutils.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 = {}
  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()[:2]
  37. )
  38. if nativePath != 'none':
  39. mounts[mountPoint] = nativePath
  40. finally:
  41. inp.close()
  42. except IOError, ex:
  43. print >> sys.stderr, 'Failed to read MSYS fstab:', ex
  44. except ValueError, ex:
  45. print >> sys.stderr, 'Failed to parse MSYS fstab:', ex
  46. mounts['/'] = msysRoot + '/'
  47. return mounts
  48. def msysPathToNative(path):
  49. if path.startswith('/'):
  50. if len(path) == 2 or (len(path) > 2 and path[2] == '/'):
  51. # Support drive letters as top-level dirs.
  52. return '%s:/%s' % (path[1], path[3 : ])
  53. longestMatch = ''
  54. for mountPoint in msysMounts.iterkeys():
  55. if path.startswith(mountPoint):
  56. if len(mountPoint) > len(longestMatch):
  57. longestMatch = mountPoint
  58. return msysMounts[longestMatch] + path[len(longestMatch) : ]
  59. else:
  60. return path
  61. def msysActive():
  62. return environ.get('OSTYPE') == 'msys' or 'MSYSCON' in environ
  63. def msysShell():
  64. return environ.get('SHELL') or 'sh.exe'
  65. if msysActive():
  66. msysMounts = _determineMounts()
  67. else:
  68. msysMounts = None
  69. if __name__ == '__main__':
  70. print 'MSYS mounts:', msysMounts