1b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# -*- coding: ascii -*-
2b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
3b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Copyright 2007, 2008, 2009, 2010, 2011
4b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Andr\xe9 Malo or his licensors, as applicable
5b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
6b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Licensed under the Apache License, Version 2.0 (the "License");
7b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# you may not use this file except in compliance with the License.
8b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# You may obtain a copy of the License at
9b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
10b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#     http://www.apache.org/licenses/LICENSE-2.0
11b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
12b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Unless required by applicable law or agreed to in writing, software
13b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# distributed under the License is distributed on an "AS IS" BASIS,
14b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# See the License for the specific language governing permissions and
16b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# limitations under the License.
17b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
18b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang===================
19b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Command extenders
20b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang===================
21b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
22b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei WangCommand extenders.
23b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
24b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__author__ = "Andr\xe9 Malo"
25b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__docformat__ = "restructuredtext en"
26b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__test__ = False
27b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
28b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils import fancy_getopt as _fancy_getopt
29b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils import log
30b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils.command import build as _build
31b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils.command import build_ext as _build_ext
32b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils.command import install as _install
33b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils.command import install_data as _install_data
34b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangfrom distutils.command import install_lib as _install_lib
35b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport os as _os
36b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
37b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang_option_defaults = {}
38b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang_option_inherits = {}
39b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang_option_finalizers = {}
40b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang_command_mapping = {
41b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    'install': 'Install',
42b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    'install_data': 'InstallData',
43b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    'install_lib': 'InstallLib',
44b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    'build': 'Build',
45b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    'build_ext': 'BuildExt',
46b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang}
47b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
48b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
49b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef add_option(command, long_name, help_text, short_name=None, default=None,
50b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang               inherit=None):
51b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Add an option """
52b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
53b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        command_class = globals()[_command_mapping[command]]
54b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except KeyError:
55b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        raise ValueError("Unknown command %r" % (command,))
56b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for opt in command_class.user_options:
57b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if opt[0] == long_name:
58b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            break
59b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    else:
60b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        opt = (long_name, short_name, help_text)
61b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        command_class.user_options.append(opt)
62b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if not long_name.endswith('='):
63b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            command_class.boolean_options.append(long_name)
64b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            attr_name = _fancy_getopt.translate_longopt(long_name)
65b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        else:
66b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            attr_name = _fancy_getopt.translate_longopt(long_name[:-1])
67b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if command not in _option_defaults:
68b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            _option_defaults[command] = []
69b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if inherit is not None:
70b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if isinstance(inherit, str):
71b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                inherit = [inherit]
72b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for i_inherit in inherit:
73b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                add_option(
74b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    i_inherit, long_name, help_text, short_name, default
75b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                )
76b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            default = None
77b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if command not in _option_inherits:
78b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                _option_inherits[command] = []
79b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for i_inherit in inherit:
80b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                for i_command, opt_name in _option_inherits[command]:
81b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    if i_command == i_inherit and opt_name == attr_name:
82b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        break
83b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                else:
84b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    _option_inherits[command].append((i_inherit, attr_name))
85b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _option_defaults[command].append((attr_name, default))
86b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
87b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
88b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef add_finalizer(command, key, func):
89b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Add finalizer """
90b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if command not in _option_finalizers:
91b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _option_finalizers[command] = {}
92b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if key not in _option_finalizers[command]:
93b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _option_finalizers[command][key] = func
94b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
95b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
96b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangclass Install(_install.install):
97b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Extended installer to reflect the additional data options """
98b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    user_options = _install.install.user_options + [
99b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ('single-version-externally-managed', None,
100b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            "Compat option. Does not a thing."),
101b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    ]
102b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    boolean_options = _install.install.boolean_options + [
103b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        'single-version-externally-managed'
104b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    ]
105b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
106b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def initialize_options(self):
107b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Prepare for new options """
108b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _install.install.initialize_options(self)
109b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        self.single_version_externally_managed = None
110b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install' in _option_defaults:
111b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for opt_name, default in _option_defaults['install']:
112b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                setattr(self, opt_name, default)
113b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
114b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def finalize_options(self):
115b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Finalize options """
116b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _install.install.finalize_options(self)
117b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install' in _option_inherits:
118b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for parent, opt_name in _option_inherits['install']:
119b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self.set_undefined_options(parent, (opt_name, opt_name))
120b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install' in _option_finalizers:
121b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for func in list(_option_finalizers['install'].values()):
122b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                func(self)
123b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
124b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
125b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangclass InstallData(_install_data.install_data):
126b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Extended data installer """
127b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    user_options = _install_data.install_data.user_options + []
128b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    boolean_options = _install_data.install_data.boolean_options + []
129b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
130b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def initialize_options(self):
131b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Prepare for new options """
132b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _install_data.install_data.initialize_options(self)
133b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install_data' in _option_defaults:
134b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for opt_name, default in _option_defaults['install_data']:
135b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                setattr(self, opt_name, default)
136b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
137b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def finalize_options(self):
138b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Finalize options """
139b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _install_data.install_data.finalize_options(self)
140b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install_data' in _option_inherits:
141b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for parent, opt_name in _option_inherits['install_data']:
142b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self.set_undefined_options(parent, (opt_name, opt_name))
143b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install_data' in _option_finalizers:
144b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for func in list(_option_finalizers['install_data'].values()):
145b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                func(self)
146b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
147b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
148b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangclass InstallLib(_install_lib.install_lib):
149b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Extended lib installer """
150b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    user_options = _install_lib.install_lib.user_options + []
151b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    boolean_options = _install_lib.install_lib.boolean_options + []
152b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
153b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def initialize_options(self):
154b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Prepare for new options """
155b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _install_lib.install_lib.initialize_options(self)
156b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install_lib' in _option_defaults:
157b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for opt_name, default in _option_defaults['install_lib']:
158b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                setattr(self, opt_name, default)
159b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
160b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def finalize_options(self):
161b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Finalize options """
162b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _install_lib.install_lib.finalize_options(self)
163b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install_lib' in _option_inherits:
164b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for parent, opt_name in _option_inherits['install_lib']:
165b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self.set_undefined_options(parent, (opt_name, opt_name))
166b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'install_lib' in _option_finalizers:
167b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for func in list(_option_finalizers['install_lib'].values()):
168b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                func(self)
169b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
170b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
171b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangclass BuildExt(_build_ext.build_ext):
172b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
173b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Extended extension builder class
174b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
175b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    This class allows extensions to provide a ``check_prerequisites`` method
176b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    which is called before actually building it. The method takes the
177b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    `BuildExt` instance and returns whether the extension should be skipped or
178b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    not.
179b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
180b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
181b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def initialize_options(self):
182b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Prepare for new options """
183b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _build_ext.build_ext.initialize_options(self)
184b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'build_ext' in _option_defaults:
185b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for opt_name, default in _option_defaults['build_ext']:
186b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                setattr(self, opt_name, default)
187b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
188b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def finalize_options(self):
189b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Finalize options """
190b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _build_ext.build_ext.finalize_options(self)
191b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'build_ext' in _option_inherits:
192b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for parent, opt_name in _option_inherits['build_ext']:
193b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self.set_undefined_options(parent, (opt_name, opt_name))
194b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'build_ext' in _option_finalizers:
195b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for func in list(_option_finalizers['build_ext'].values()):
196b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                func(self)
197b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
198b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def build_extension(self, ext):
199b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """
200b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        Build C extension - with extended functionality
201b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
202b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        The following features are added here:
203b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
204b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        - ``ext.check_prerequisites`` is called before the extension is being
205b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang          built. See `Extension` for details. If the method does not exist,
206b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang          simply no check will be run.
207b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        - The macros ``EXT_PACKAGE`` and ``EXT_MODULE`` will be filled (or
208b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang          unset) depending on the extensions name, but only if they are not
209b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang          already defined.
210b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
211b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        :Parameters:
212b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang          `ext` : `Extension`
213b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            The extension to build. If it's a pure
214b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ``distutils.core.Extension``, simply no prequisites check is
215b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            applied.
216b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
217b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        :Return: whatever ``distutils.command.build_ext.build_ext`` returns
218b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        :Rtype: any
219b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """
220b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        # handle name macros
221b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        macros = dict(ext.define_macros or ())
222b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        tup = ext.name.split('.')
223b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if len(tup) == 1:
224b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            pkg, mod = None, tup[0]
225b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        else:
226b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            pkg, mod = '.'.join(tup[:-1]), tup[-1]
227b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if pkg is not None and 'EXT_PACKAGE' not in macros:
228b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ext.define_macros.append(('EXT_PACKAGE', pkg))
229b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'EXT_MODULE' not in macros:
230b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ext.define_macros.append(('EXT_MODULE', mod))
231b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if pkg is None:
232b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            macros = dict(ext.undef_macros or ())
233b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if 'EXT_PACKAGE' not in macros:
234b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                ext.undef_macros.append('EXT_PACKAGE')
235b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
236b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        # handle prereq checks
237b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
238b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            checker = ext.check_prerequisites
239b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        except AttributeError:
240b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            pass
241b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        else:
242b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if checker(self):
243b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                log.info("Skipping %s extension" % ext.name)
244b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                return
245b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
246b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        return _build_ext.build_ext.build_extension(self, ext)
247b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
248b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
249b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangclass Build(_build.build):
250b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
251b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def initialize_options(self):
252b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Prepare for new options """
253b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _build.build.initialize_options(self)
254b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'build' in _option_defaults:
255b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for opt_name, default in _option_defaults['build']:
256b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                setattr(self, opt_name, default)
257b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
258b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def finalize_options(self):
259b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Finalize options """
260b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _build.build.finalize_options(self)
261b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'build' in _option_inherits:
262b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for parent, opt_name in _option_inherits['build']:
263b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self.set_undefined_options(parent, (opt_name, opt_name))
264b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if 'build' in _option_finalizers:
265b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for func in list(_option_finalizers['build'].values()):
266b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                func(self)
267