OXYGENHUB
◆ main openmsx / build / detectsys.py
4.0 KiB · Python · last changed chore(): initial commit 1 month ago source blame history raw
1
# Detect the native CPU and OS.
2
# Actually we rely on the Python "platform" module and map its output to names
3
# that the openMSX build understands.
4
5
from executils import captureStdout
6
7
from platform import architecture, machine, system
8
from subprocess import PIPE, STDOUT, Popen
9
import sys
10
11
def detectCPU():
12
	'''Detects the CPU family (not the CPU model) of the machine were are
13
	running on.
14
	Raises ValueError if no known CPU is detected.
15
	'''
16
	cpu = machine().lower()
17
	dashIndex = cpu.find('-')
18
	if dashIndex != -1:
19
		# Hurd returns "cputype-cpusubtype" instead of just "cputype".
20
		cpu = cpu[ : dashIndex]
21
	if cpu in ('x86_64', 'amd64'):
22
		return 'x86_64'
23
	elif cpu in ('x86', 'i386', 'i486', 'i586', 'i686'):
24
		return 'x86'
25
	elif cpu == 'ppc64le':
26
		return 'ppc64le'
27
	elif cpu.startswith('ppc') or cpu.endswith('ppc') or cpu.startswith('power'):
28
		return 'ppc64' if cpu.endswith('64') else 'ppc'
29
	elif cpu == 'arm64':
30
		# Darwin uses "arm64", unlike Linux.
31
		return 'aarch64'
32
	elif cpu.startswith('arm'):
33
		return 'arm'
34
	elif cpu == 'aarch64':
35
		return 'aarch64'
36
	elif cpu == 'aarch64_be':
37
		return 'aarch64_be'
38
	elif cpu.startswith('mips') or cpu == 'sgi':
39
		return 'mipsel' if cpu.endswith('el') else 'mips'
40
	elif cpu == 'm68k':
41
		return 'm68k'
42
	elif cpu == 'ia64':
43
		return 'ia64'
44
	elif cpu.startswith('alpha'):
45
		return 'alpha'
46
	elif cpu.startswith('hppa') or cpu.startswith('parisc'):
47
		return 'hppa'
48
	elif cpu.startswith('s390'):
49
		return 's390'
50
	elif cpu.startswith('sparc') or cpu.startswith('sun4u'):
51
		return 'sparc'
52
	elif cpu.startswith('sh'):
53
		return 'sheb' if cpu.endswith('eb') else 'sh'
54
	elif cpu == 'avr32':
55
		return 'avr32'
56
	elif cpu == 'riscv64':
57
		return 'riscv64'
58
	elif cpu == 'loongarch64':
59
		return 'loongarch64'
60
	elif cpu == '':
61
		# Python couldn't figure it out.
62
		os = system().lower()
63
		if os == 'windows':
64
			# Relatively safe bet.
65
			return 'x86'
66
		raise ValueError('Unable to detect CPU')
67
	else:
68
		raise ValueError('Unsupported or unrecognised CPU "%s"' % cpu)
69
70
def detectOS():
71
	'''Detects the operating system of the machine were are running on.
72
	Raises ValueError if no known OS is detected.
73
	'''
74
	os = system().lower()
75
	if os in (
76
		'linux', 'darwin', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'gnu'
77
		):
78
		return os
79
	elif os.startswith('gnu/'):
80
		# GNU userland on non-Hurd kernel, for example Debian GNU/kFreeBSD.
81
		# For openMSX the kernel is not really relevant, so treat it like
82
		# a generic GNU system.
83
		return 'gnu'
84
	elif os.startswith('mingw') or os == 'windows':
85
		return 'mingw-w64'
86
	elif os == 'sunos':
87
		return 'solaris'
88
	elif os == '':
89
		# Python couldn't figure it out.
90
		raise ValueError('Unable to detect OS')
91
	else:
92
		raise ValueError('Unsupported or unrecognised OS "%s"' % os)
93
94
def getCompilerMachine():
95
	# Note: Recent GCC and Clang versions support this option.
96
	machine = captureStdout(sys.stderr, 'cc -dumpmachine')
97
	if machine is not None:
98
		machineParts = machine.split('-')
99
		if len(machineParts) >= 3:
100
			return machineParts[0], machineParts[2]
101
	return None, None
102
103
if __name__ == '__main__':
104
	try:
105
		hostCPU = detectCPU()
106
		if hostCPU == 'mips':
107
			# Little endian MIPS is reported as just "mips" by Linux Python.
108
			compilerCPU, compilerOS = getCompilerMachine()
109
			if compilerCPU == 'mips':
110
				pass
111
			elif compilerCPU == 'mipsel':
112
				hostCPU = compilerCPU
113
			else:
114
				print(
115
					'Warning: Unabling to determine endianess; '
116
					'compiling for big endian',
117
					file=sys.stderr
118
					)
119
120
		hostOS = detectOS()
121
		if hostOS == 'mingw32' and hostCPU == 'x86_64':
122
			# It is possible to run MinGW on 64-bit Windows, but producing
123
			# 64-bit code is not supported yet.
124
			hostCPU = 'x86'
125
		elif hostOS == 'darwin' and hostCPU == 'x86':
126
			# If Python is 64-bit, both the CPU and OS support it, so we can
127
			# compile openMSX for x86-64. Compiling in 32-bit mode might seem
128
			# safer, but will fail if using MacPorts on a 64-bit capable system.
129
			if architecture()[0] == '64bit':
130
				hostCPU = 'x86_64'
131
132
		print(hostCPU, hostOS)
133
	except ValueError as ex:
134
		print(ex, file=sys.stderr)
135
		sys.exit(1)