1import os
2from .utils import *
3from .pythons import *
4
5class ExtendedConfig:
6    '''Global configuration that specifies what the entire process will do.
7
8    Unlike Config, this class contains also various derived properties
9    for convenience.
10    '''
11
12    def __init__(self, user_config, **kwargs):
13        for k in user_config:
14            self.__dict__[k] = user_config[k]
15        for k in kwargs:
16            setattr(self, k, kwargs[k])
17
18    # These are defaults, overrides can be specified as vc_paths in Config above
19    default_vc_paths = {
20        # where msvc 9 is installed, for python 2.6-3.2
21        'vc9': [
22            'c:/program files (x86)/microsoft visual studio 9.0',
23            'c:/program files/microsoft visual studio 9.0',
24        ],
25        # where msvc 10 is installed, for python 3.3-3.4
26        'vc10': [
27            'c:/program files (x86)/microsoft visual studio 10.0',
28            'c:/program files/microsoft visual studio 10.0',
29        ],
30        # where msvc 14 is installed, for python 3.5-3.9
31        'vc14': [
32            'c:/program files (x86)/microsoft visual studio 14.0',
33            'c:/program files/microsoft visual studio 14.0',
34        ],
35    }
36
37    @property
38    def nasm_path(self):
39        return select_existing_path(self.__dict__['nasm_path'])
40
41    @property
42    def activestate_perl_path(self):
43        return select_existing_path(self.__dict__['activestate_perl_path'])
44
45    @property
46    def archives_path(self):
47        return os.path.join(self.root, 'archives')
48
49    @property
50    def state_path(self):
51        return os.path.join(self.root, 'state')
52
53    @property
54    def git_bin_path(self):
55        #git_bin_path = os.path.join(git_root, 'bin')
56        return ''
57
58    @property
59    def git_path(self):
60        return os.path.join(self.git_bin_path, 'git')
61
62    @property
63    def rm_path(self):
64        return find_in_paths('rm', self.msysgit_bin_paths)
65
66    @property
67    def cp_path(self):
68        return find_in_paths('cp', self.msysgit_bin_paths)
69
70    @property
71    def sed_path(self):
72        return find_in_paths('sed', self.msysgit_bin_paths)
73
74    @property
75    def tar_path(self):
76        return find_in_paths('tar', self.msysgit_bin_paths)
77
78    @property
79    def activestate_perl_bin_path(self):
80        return os.path.join(self.activestate_perl_path, 'bin')
81
82    @property
83    def winbuild_patch_root(self):
84        return os.path.join(self.winbuild_root, 'winbuild')
85
86    @property
87    def openssl_version_tuple(self):
88        return tuple(
89            int(part) if part < 'a' else part
90            for part in re.sub(r'([a-z])', r'.\1', self.openssl_version).split('.')
91        )
92
93    @property
94    def libssh2_version_tuple(self):
95        return tuple(int(part) for part in self.libssh2_version.split('.'))
96
97    @property
98    def cares_version_tuple(self):
99        return tuple(int(part) for part in self.cares_version.split('.'))
100
101    @property
102    def libcurl_version_tuple(self):
103        return tuple(int(part) for part in self.libcurl_version.split('.'))
104
105    @property
106    def python_releases(self):
107        return [PythonRelease('.'.join(version.split('.')[:2]))
108            for version in self.python_versions]
109
110    @property
111    def extra_bin_paths(self):
112        paths = {32: {}, 64: {}}
113
114        # When using visual studio 2019 community, rc.exe is not in path for whatever reason - handle this manually.
115        paths[32]['rc_bin'] = os.path.dirname(glob_first('c:/{program files,program files (x86)}/windows kits/*/bin/*/x86/rc.exe'))
116        paths[64]['rc_bin'] = os.path.dirname(glob_first('c:/{program files,program files (x86)}/windows kits/*/bin/*/x64/rc.exe'))
117
118        return paths
119
120BITNESSES = (32, 64)
121
122PYTHON_VC_VERSIONS = {
123    '2.6': 'vc9',
124    '2.7': 'vc9',
125    '3.2': 'vc9',
126    '3.3': 'vc10',
127    '3.4': 'vc10',
128    '3.5': 'vc14',
129    '3.6': 'vc14',
130    '3.7': 'vc14',
131    '3.8': 'vc14',
132    '3.9': 'vc14',
133}
134
135class BuildConfig:
136    '''Parameters for a particular build configuration.
137
138    Unlike ExtendedConfig, this class fixes bitness and Python version.
139    '''
140
141    def __init__(self, ext_config, **kwargs):
142        for k in dir(ext_config):
143            if k.startswith('_'):
144                continue
145            self.__dict__[k] = getattr(ext_config, k)
146        for k in kwargs:
147            setattr(self, k, kwargs[k])
148
149        assert self.bitness
150        assert self.bitness in (32, 64)
151        assert self.vc_version
152
153    @property
154    def vc_tag(self):
155        return '%s-%s' % (self.vc_version, self.bitness)
156