Package zeroinstall :: Package injector :: Module arch
[frames] | no frames]

Source Code for Module zeroinstall.injector.arch

  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  # Copyright (C) 2009, Thomas Leonard 
 18  # See the README file for details, or visit http://0install.net. 
 19   
 20  from zeroinstall import _ 
 21  import os 
 22   
 23  # TODO: "import platform"? 
 24   
 25  # os_ranks and mapping are mappings from names to how good they are. 
 26  # 1 => Native (best) 
 27  # Higher numbers are worse but usable. 
 28  try: 
 29          _uname = os.uname() 
 30          # On Darwin, machine is wrong. 
 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          # No uname. Probably Windows. 
 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   
50 -def canonicalize_os(os_):
51 if os_.startswith('CYGWIN_NT'): 52 os_ = 'Cygwin' 53 elif os_ == 'SunOS': 54 os_ = 'Solaris' 55 return os_
56
57 -def _get_os_ranks(target_os):
58 target_os = canonicalize_os(target_os) 59 60 if target_os == 'Darwin': 61 # Special case Mac OS X, to separate it from Darwin/X 62 # (Mac OS X also includes the closed Apple frameworks) 63 if os.path.exists('/System/Library/Frameworks/Carbon.framework'): 64 target_os = 'MacOSX' 65 66 # Binaries compiled for _this_ OS are best... 67 os_ranks = {target_os : 1} 68 69 # If target_os appears in the first column of this table, all 70 # following OS types on the line will also run on this one 71 # (earlier ones preferred): 72 _os_matrix = { 73 'Cygwin': ['Windows'], 74 'MacOSX': ['Darwin'], 75 } 76 77 for supported in _os_matrix.get(target_os, []): 78 os_ranks[supported] = len(os_ranks) + 1 79 80 # At the lowest priority, try an OS-independent implementation 81 os_ranks[None] = len(os_ranks) + 1 82 return os_ranks
83 84 os_ranks = _get_os_ranks(_uname[0]) 85 86 # All chosen machine-specific implementations must come from the same group 87 # Unlisted archs are in group 0 88 machine_groups = { 89 'x86_64': 64, 90 'ppc64': 64, 91 } 92
93 -def canonicalize_machine(machine):
94 if machine == 'x86': 95 machine = 'i386' 96 elif machine == 'amd64': 97 machine = 'x86_64' 98 elif machine == 'Power Macintosh': 99 machine = 'ppc' 100 elif machine == 'i86pc': 101 machine = 'i686' 102 return machine
103
104 -def _get_machine_ranks(target_machine):
105 target_machine = canonicalize_machine(target_machine) 106 107 # Binaries compiled for _this_machine are best... 108 machine_ranks = {target_machine : 0} 109 110 # If target_machine appears in the first column of this table, all 111 # following machine types on the line will also run on this one 112 # (earlier ones preferred): 113 _machine_matrix = { 114 'i486': ['i386'], 115 'i586': ['i486', 'i386'], 116 'i686': ['i586', 'i486', 'i386'], 117 'x86_64': ['i686', 'i586', 'i486', 'i386'], 118 'ppc': ['ppc32'], 119 'ppc64': ['ppc'], 120 } 121 for supported in _machine_matrix.get(target_machine, []): 122 machine_ranks[supported] = len(machine_ranks) 123 124 # At the lowest priority, try a machine-independant implementation 125 machine_ranks[None] = len(machine_ranks) 126 return machine_ranks
127 128 machine_ranks = _get_machine_ranks(_uname[-1]) 129
130 -class Architecture:
131 """A description of an architecture. Use by L{solver} to make sure it chooses 132 compatible versions. 133 @ivar os_ranks: supported operating systems and their desirability 134 @type os_ranks: {str: int} 135 @ivar machine_ranks: supported CPU types and their desirability 136 @type machine_ranks: {str: int} 137 @ivar child_arch: architecture for dependencies (usually C{self}) 138 @type child_arch: L{Architecture} 139 @ivar use: matching values for <requires use='...'>; otherwise the dependency is ignored 140 @type use: set(str) 141 """ 142 143 use = frozenset([None]) 144
145 - def __init__(self, os_ranks, machine_ranks):
146 self.os_ranks = os_ranks 147 self.machine_ranks = machine_ranks 148 self.child_arch = self
149
150 - def __str__(self):
151 return _("<Arch: %(os_ranks)s %(machine_ranks)s>") % {'os_ranks': self.os_ranks, 'machine_ranks': self.machine_ranks}
152
153 -class SourceArchitecture(Architecture):
154 """Matches source code that creates binaries for a particular architecture. 155 Note that the L{child_arch} here is the binary; source code depends on binary tools, 156 not on other source packages. 157 """
158 - def __init__(self, binary_arch):
159 Architecture.__init__(self, binary_arch.os_ranks, {'src': 1}) 160 self.child_arch = binary_arch
161
162 -def get_host_architecture():
163 """Get an Architecture that matches implementations that will run on the host machine. 164 @rtype: L{Architecture}""" 165 return Architecture(os_ranks, machine_ranks)
166
167 -def get_architecture(os, machine):
168 """Get an Architecture that matches binaries that will work on the given system. 169 @param os: OS type, or None for host's type 170 @param machine: CPU type, or None for host's type 171 @return: an Architecture object 172 @rtype: L{Architecture}""" 173 174 if os is None: 175 target_os_ranks = os_ranks 176 else: 177 target_os_ranks = _get_os_ranks(os) 178 if machine is None: 179 target_machine_ranks = machine_ranks 180 else: 181 target_machine_ranks = _get_machine_ranks(machine) 182 183 return Architecture(target_os_ranks, target_machine_ranks)
184