1 """
2 Information about the current system's architecture.
3
4 This module provides information about the current system. It is used to determine
5 whether an implementation is suitable for this machine, and to compare different implementations.
6
7 For example, it will indicate that:
8
9 - An i486 machine cannot run an i686 binary.
10 - An i686 machine can run an i486 binary, but would prefer an i586 one.
11 - A Windows binary cannot run on a Linux machine.
12
13 Each dictionary maps from a supported architecture type to a preference level. Lower numbers are
14 better, Unsupported architectures are not listed at all.
15 """
16
17
18
19
20 from zeroinstall import _
21 import os
22
23
24
25
26
27
28 try:
29 _uname = os.uname()
30
31 if _uname[0] == 'Darwin' and _uname[-1] == 'i386':
32 _cpu64 = os.popen('sysctl -n hw.cpu64bit_capable 2>&1').next().strip()
33 if _cpu64 == '1':
34 _uname = tuple(list(_uname[:-1])+['x86_64'])
35 except AttributeError:
36
37 import sys
38 p = sys.platform
39 if p == 'win64':
40 _uname = ('Windows', 'x86_64')
41 elif p == 'win32':
42 from win32process import IsWow64Process
43 if IsWow64Process():
44 _uname = ('Windows', 'x86_64')
45 else:
46 _uname = ('Windows', 'i486')
47 else:
48 _uname = (p, 'i486')
49
51 """@type os_: str
52 @rtype: str"""
53 if os_.startswith('CYGWIN_NT'):
54 os_ = 'Cygwin'
55 elif os_ == 'SunOS':
56 os_ = 'Solaris'
57 return os_
58
60 """@type target_os: str"""
61 target_os = canonicalize_os(target_os)
62
63 if target_os == 'Darwin':
64
65
66 if os.path.exists('/System/Library/Frameworks/Carbon.framework'):
67 target_os = 'MacOSX'
68
69
70 os_ranks = {target_os : 1}
71
72
73
74 if target_os != 'Windows':
75 os_ranks['POSIX'] = len(os_ranks) + 1
76
77
78
79
80 _os_matrix = {
81 'Cygwin': ['Windows'],
82 'MacOSX': ['Darwin'],
83 }
84
85 for supported in _os_matrix.get(target_os, []):
86 os_ranks[supported] = len(os_ranks) + 1
87
88
89 os_ranks[None] = len(os_ranks) + 1
90 return os_ranks
91
92 os_ranks = _get_os_ranks(_uname[0])
93
94
95
96 machine_groups = {
97 'x86_64': 64,
98 'ppc64': 64,
99 }
100
102 """@type machine_: str
103 @rtype: str"""
104 machine = machine_.lower()
105 if machine == 'x86':
106 machine = 'i386'
107 elif machine == 'amd64':
108 machine = 'x86_64'
109 elif machine == 'Power Macintosh':
110 machine = 'ppc'
111 elif machine == 'i86pc':
112 machine = 'i686'
113 return machine
114
116 """@type target_machine: str"""
117 target_machine = canonicalize_machine(target_machine)
118
119
120 machine_ranks = {target_machine : 0}
121
122
123
124
125 _machine_matrix = {
126 'i486': ['i386'],
127 'i586': ['i486', 'i386'],
128 'i686': ['i586', 'i486', 'i386'],
129 'x86_64': ['i686', 'i586', 'i486', 'i386'],
130 'ppc': ['ppc32'],
131 'ppc64': ['ppc'],
132 }
133 for supported in _machine_matrix.get(target_machine, []):
134 machine_ranks[supported] = len(machine_ranks)
135
136
137 machine_ranks[None] = len(machine_ranks)
138 return machine_ranks
139
140 machine_ranks = _get_machine_ranks(_uname[-1])
141
143 """A description of an architecture. Use by L{solver} to make sure it chooses
144 compatible versions.
145 @ivar os_ranks: supported operating systems and their desirability
146 @type os_ranks: {str: int}
147 @ivar machine_ranks: supported CPU types and their desirability
148 @type machine_ranks: {str: int}
149 @ivar child_arch: architecture for dependencies (usually C{self})
150 @type child_arch: L{Architecture}
151 @ivar use: matching values for <requires use='...'>; otherwise the dependency is ignored
152 @type use: set(str)
153 """
154
155 use = frozenset([None])
156
157 - def __init__(self, os_ranks, machine_ranks):
161
163 """@rtype: str"""
164 return _("<Arch: %(os_ranks)s %(machine_ranks)s>") % {'os_ranks': self.os_ranks, 'machine_ranks': self.machine_ranks}
165
167 """Matches source code that creates binaries for a particular architecture.
168 Note that the L{child_arch} here is the binary; source code depends on binary tools,
169 not on other source packages.
170 """
172 """@type binary_arch: L{Architecture}"""
173 Architecture.__init__(self, binary_arch.os_ranks, {'src': 1})
174 self.child_arch = binary_arch
175
177 """Get an Architecture that matches implementations that will run on the host machine.
178 @rtype: L{Architecture}"""
179 return Architecture(os_ranks, machine_ranks)
180
182 """Get an Architecture that matches binaries that will work on the given system.
183 @param os: OS type, or None for host's type
184 @type os: str
185 @param machine: CPU type, or None for host's type
186 @type machine: str
187 @return: an Architecture object
188 @rtype: L{Architecture}"""
189
190 if os is None:
191 target_os_ranks = os_ranks
192 else:
193 target_os_ranks = _get_os_ranks(os)
194 if machine is None:
195 target_machine_ranks = machine_ranks
196 else:
197 target_machine_ranks = _get_machine_ranks(machine)
198
199 return Architecture(target_os_ranks, target_machine_ranks)
200