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