blob: fcb50df4e49e1356b16090dad2870b7eaf06e0d0 [file] [log] [blame]
Tarek Ziade1231a4e2011-05-19 13:07:25 +02001"""Main build command, which calls the other build_* commands."""
2
3import sys
4import os
5
6from packaging.util import get_platform
7from packaging.command.cmd import Command
8from packaging.errors import PackagingOptionError
9from packaging.compiler import show_compilers
10
11
12class build(Command):
13
14 description = "build everything needed to install"
15
16 user_options = [
17 ('build-base=', 'b',
18 "base directory for build library"),
19 ('build-purelib=', None,
20 "build directory for platform-neutral distributions"),
21 ('build-platlib=', None,
22 "build directory for platform-specific distributions"),
23 ('build-lib=', None,
24 "build directory for all distribution (defaults to either " +
25 "build-purelib or build-platlib"),
26 ('build-scripts=', None,
27 "build directory for scripts"),
28 ('build-temp=', 't',
29 "temporary build directory"),
30 ('plat-name=', 'p',
31 "platform name to build for, if supported "
32 "(default: %s)" % get_platform()),
33 ('compiler=', 'c',
34 "specify the compiler type"),
35 ('debug', 'g',
36 "compile extensions and libraries with debugging information"),
37 ('force', 'f',
38 "forcibly build everything (ignore file timestamps)"),
39 ('executable=', 'e',
40 "specify final destination interpreter path (build.py)"),
41 ('use-2to3', None,
42 "use 2to3 to make source python 3.x compatible"),
43 ('convert-2to3-doctests', None,
Éric Araujo9ad81a32011-11-03 00:13:05 +010044 "use 2to3 to convert doctests in separate text files"),
Tarek Ziade1231a4e2011-05-19 13:07:25 +020045 ('use-2to3-fixers', None,
46 "list additional fixers opted for during 2to3 conversion"),
47 ]
48
49 boolean_options = ['debug', 'force']
50
51 help_options = [
52 ('help-compiler', None,
53 "list available compilers", show_compilers),
54 ]
55
56 def initialize_options(self):
57 self.build_base = 'build'
58 # these are decided only after 'build_base' has its final value
59 # (unless overridden by the user or client)
60 self.build_purelib = None
61 self.build_platlib = None
62 self.build_lib = None
63 self.build_temp = None
64 self.build_scripts = None
65 self.compiler = None
66 self.plat_name = None
67 self.debug = None
68 self.force = False
69 self.executable = None
70 self.use_2to3 = False
71 self.convert_2to3_doctests = None
72 self.use_2to3_fixers = None
73
74 def finalize_options(self):
75 if self.plat_name is None:
76 self.plat_name = get_platform()
77 else:
78 # plat-name only supported for windows (other platforms are
79 # supported via ./configure flags, if at all). Avoid misleading
80 # other platforms.
81 if os.name != 'nt':
82 raise PackagingOptionError(
83 "--plat-name only supported on Windows (try "
84 "using './configure --help' on your platform)")
Éric Araujo9f90a732012-02-10 05:20:53 +010085 pyversion = '%s.%s' % sys.version_info[:2]
86 plat_specifier = ".%s-%s" % (self.plat_name, pyversion)
Tarek Ziade1231a4e2011-05-19 13:07:25 +020087
88 # Make it so Python 2.x and Python 2.x with --with-pydebug don't
89 # share the same build directories. Doing so confuses the build
90 # process for C modules
91 if hasattr(sys, 'gettotalrefcount'):
92 plat_specifier += '-pydebug'
93
94 # 'build_purelib' and 'build_platlib' just default to 'lib' and
95 # 'lib.<plat>' under the base build directory. We only use one of
96 # them for a given distribution, though --
97 if self.build_purelib is None:
98 self.build_purelib = os.path.join(self.build_base, 'lib')
99 if self.build_platlib is None:
100 self.build_platlib = os.path.join(self.build_base,
101 'lib' + plat_specifier)
102
103 # 'build_lib' is the actual directory that we will use for this
104 # particular module distribution -- if user didn't supply it, pick
105 # one of 'build_purelib' or 'build_platlib'.
106 if self.build_lib is None:
107 if self.distribution.ext_modules:
108 self.build_lib = self.build_platlib
109 else:
110 self.build_lib = self.build_purelib
111
112 # 'build_temp' -- temporary directory for compiler turds,
113 # "build/temp.<plat>"
114 if self.build_temp is None:
115 self.build_temp = os.path.join(self.build_base,
116 'temp' + plat_specifier)
117 if self.build_scripts is None:
118 self.build_scripts = os.path.join(self.build_base,
Éric Araujo9f90a732012-02-10 05:20:53 +0100119 'scripts-' + pyversion)
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200120
121 if self.executable is None:
122 self.executable = os.path.normpath(sys.executable)
123
124 def run(self):
125 # Run all relevant sub-commands. This will be some subset of:
126 # - build_py - pure Python modules
127 # - build_clib - standalone C libraries
128 # - build_ext - Python extension modules
129 # - build_scripts - Python scripts
130 for cmd_name in self.get_sub_commands():
131 self.run_command(cmd_name)
132
133 # -- Predicates for the sub-command list ---------------------------
134
135 def has_pure_modules(self):
136 return self.distribution.has_pure_modules()
137
138 def has_c_libraries(self):
139 return self.distribution.has_c_libraries()
140
141 def has_ext_modules(self):
142 return self.distribution.has_ext_modules()
143
144 def has_scripts(self):
145 return self.distribution.has_scripts()
146
147 sub_commands = [('build_py', has_pure_modules),
148 ('build_clib', has_c_libraries),
149 ('build_ext', has_ext_modules),
150 ('build_scripts', has_scripts),
151 ]