Import _ into each module rather than using a builtin
[zeroinstall/zeroinstall-rsl.git] / zeroinstall / injector / arch.py
blob855d9cb67776641389d186df66cb5bfc46f28780
1 """
2 Information about the current system's architecture.
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.
7 For example, it will indicate that:
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.
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 """
17 # Copyright (C) 2009, Thomas Leonard
18 # See the README file for details, or visit http://0install.net.
20 from zeroinstall import _
21 import os
23 # os_ranks and mapping are mappings from names to how good they are.
24 # 1 => Native (best)
25 # Higher numbers are worse but usable.
26 try:
27 _uname = os.uname()
28 except AttributeError:
29 # No uname. Probably Windows (untested).
30 import sys
31 p = sys.platform
32 if p == 'win32':
33 _uname = ('Windows', 'i486')
34 elif p == 'win64':
35 _uname = ('Windows', 'x86_64')
36 else:
37 _uname = (p, 'i486')
39 os_ranks = {
40 # 'Linux' : 3, # Linux (lots of systems support emulation)
41 None : 2, # Any OS
42 _uname[0] : 1, # Current OS
45 # All chosen machine-specific implementations must come from the same group
46 # Unlisted archs are in group 0
47 machine_groups = {
48 'x86_64': 64,
49 'ppc64': 64,
52 def _get_machine_ranks(target_machine):
53 # Binaries compiled for _this_machine are best...
54 machine_ranks = {target_machine : 0}
56 # If target_machine appears in the first column of this table, all
57 # following machine types on the line will also run on this one
58 # (earlier ones preferred):
59 _machine_matrix = {
60 'i486': ['i386'],
61 'i586': ['i486', 'i386'],
62 'i686': ['i586', 'i486', 'i386'],
63 'x86_64': ['i686', 'i586', 'i486', 'i386'],
64 'ppc64': ['ppc32'],
66 for supported in _machine_matrix.get(target_machine, []):
67 machine_ranks[supported] = len(machine_ranks)
69 # At the lowest priority, try a machine-independant implementation
70 machine_ranks[None] = len(machine_ranks)
71 return machine_ranks
73 machine_ranks = _get_machine_ranks(_uname[-1])
74 #print machine_ranks
76 class Architecture:
77 """A description of an architecture. Use by L{solver} to make sure it chooses
78 compatible versions.
79 @ivar os_ranks: supported operating systems and their desirability
80 @type os_ranks: {str: int}
81 @ivar machine_ranks: supported CPU types and their desirability
82 @type machine_ranks: {str: int}
83 @ivar child_arch: architecture for dependencies (usually C{self})
84 @type child_arch: L{Architecture}"""
85 def __init__(self, os_ranks, machine_ranks):
86 self.os_ranks = os_ranks
87 self.machine_ranks = machine_ranks
88 self.child_arch = self
90 def __str__(self):
91 return _("<Arch: %(os_ranks)s %(machine_ranks)s>") % {'os_ranks': self.os_ranks, 'machine_ranks': self.machine_ranks}
93 class SourceArchitecture(Architecture):
94 """Matches source code that creates binaries for a particular architecture.
95 Note that the L{child_arch} here is the binary; source code depends on binary tools,
96 not on other source packages.
97 """
98 def __init__(self, binary_arch):
99 Architecture.__init__(self, binary_arch.os_ranks, {'src': 1})
100 self.child_arch = binary_arch
102 def get_host_architecture():
103 """Get an Architecture that matches implementations that will run on the host machine.
104 @rtype: L{Architecture}"""
105 return Architecture(os_ranks, machine_ranks)
107 def get_architecture(os, machine):
108 """Get an Architecture that matches binaries that will work on the given system.
109 @param os: OS type, or None for host's type
110 @param machine: CPU type, or None for host's type
111 @return: an Architecture object
112 @rtype: L{Architecture}"""
114 if os:
115 target_os_ranks = {
116 os : 1, # Perfer binaries for target OS
117 None : 2, # Otherwise, generic OS is fine
119 else:
120 target_os_ranks = os_ranks
121 if machine:
122 target_machine_ranks = _get_machine_ranks(machine)
123 else:
124 target_machine_ranks = machine_ranks
125 return Architecture(target_os_ranks, target_machine_ranks)