Skip to content

Commit ef8fef1

Browse files
committed
Enable debug builds for inplace builds, otherwise build release; simplify monkey patch
1 parent a686ad9 commit ef8fef1

File tree

5 files changed

+87
-93
lines changed

5 files changed

+87
-93
lines changed

CHANGES.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
CHANGES
22
=======
33

4+
0.4 (2017-03-xx)
5+
----------------
6+
7+
- Use absolute path to cargo manifest
8+
9+
- Enable debug builds for inplace builds, otherwise build release
10+
11+
- Simplify monkey patches
12+
13+
414
0.3.1 (2017-03-09)
515
------------------
616

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from setuptools import setup
22

3-
version = '0.3.1'
3+
version = '0.4'
44

55

66
setup(
@@ -33,6 +33,7 @@
3333
],
3434
entry_points="""
3535
[distutils.commands]
36+
build_ext=setuptools_rust:build_ext
3637
build_rust=setuptools_rust:build_rust
3738
"""
3839
)

setuptools_rust/__init__.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
import semantic_version
1313

1414
from . import patch # noqa
15+
from .build_ext import build_ext
1516

16-
__all__ = ('RustExtension', 'build_rust')
17+
__all__ = ('RustExtension', 'build_ext', 'build_rust')
18+
19+
patch.monkey_patch_dist(build_ext)
1720

1821

1922
class RustExtension:
@@ -35,14 +38,15 @@ class RustExtension:
3538
quiet : bool
3639
If True, doesn't echo cargo's output.
3740
debug : bool
38-
Controls whether --debug or --release is passed to cargo.
41+
Controls whether --debug or --release is passed to cargo. If set to
42+
None then build type is auto-detect. Inplace build is debug build
43+
otherwise release. Default: None
3944
"""
4045

4146
def __init__(self, name, path,
4247
args=None, features=None, rust_version=None,
43-
quiet=False, debug=False):
48+
quiet=False, debug=None):
4449
self.name = name
45-
self.path = path
4650
self.args = args
4751
self.rust_version = rust_version
4852
self.quiet = quiet
@@ -53,6 +57,17 @@ def __init__(self, name, path,
5357

5458
self.features = [s.strip() for s in features]
5559

60+
# get absolute path to Cargo manifest file
61+
file = sys._getframe(1).f_globals.get('__file__')
62+
if file:
63+
dirname = os.path.dirname(file)
64+
cwd = os.getcwd()
65+
os.chdir(dirname)
66+
path = os.path.abspath(path)
67+
os.chdir(cwd)
68+
69+
self.path = path
70+
5671
def get_rust_version(self):
5772
if self.rust_version is None:
5873
return None
@@ -79,6 +94,8 @@ def get_rust_version():
7994
class build_rust(Command):
8095
""" Command for building rust crates via cargo. """
8196

97+
description = "build Rust extensions (compile/link to build directory)"
98+
8299
user_options = [
83100
('inplace', 'i',
84101
"ignore build-lib and put compiled extensions into the source " +
@@ -124,11 +141,16 @@ def build_extension(self, ext):
124141
features = set(ext.features)
125142
features.update(self._cpython_feature())
126143

144+
if ext.debug is None:
145+
debug_build = self.inplace
146+
else:
147+
debug_build = ext.debug
148+
127149
# build cargo command
128150
args = (["cargo", "rustc", "--lib", "--manifest-path", ext.path,
129151
"--features", " ".join(features)]
130152
+ list(ext.args or []))
131-
if not ext.debug:
153+
if not debug_build:
132154
args.append("--release")
133155

134156
args.extend(["--", '--crate-type', 'cdylib'])
@@ -159,7 +181,7 @@ def build_extension(self, ext):
159181

160182
# Find the shared library that cargo hopefully produced and copy
161183
# it into the build directory as if it were produced by build_ext.
162-
if ext.debug:
184+
if debug_build:
163185
suffix = "debug"
164186
else:
165187
suffix = "release"
@@ -186,10 +208,10 @@ def build_extension(self, ext):
186208
build_ext.inplace = self.inplace
187209
target_fname = ext.name
188210
if target_fname is None:
189-
target_fname = os.path.splitext(
190-
os.path.basename(dylib_path)[3:])[0]
211+
target_fname = os.path.basename(os.path.splitext(
212+
os.path.basename(dylib_path)[3:])[0])
191213

192-
ext_path = build_ext.get_ext_fullpath(os.path.basename(target_fname))
214+
ext_path = build_ext.get_ext_fullpath(target_fname)
193215
try:
194216
os.makedirs(os.path.dirname(ext_path))
195217
except OSError:

setuptools_rust/build_ext.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from distutils import log
2+
from setuptools.command.build_ext import build_ext as _build_ext
3+
4+
5+
class build_ext(_build_ext):
6+
7+
def __init__(self, *args):
8+
_build_ext.__init__(self, *args)
9+
10+
def has_rust_extensions(self):
11+
return (self.distribution.rust_extensions and
12+
len(self.distribution.rust_extensions) > 0)
13+
14+
def check_extensions_list(self, extensions):
15+
if extensions:
16+
_build_ext.check_extensions_list(extensions)
17+
18+
def run(self):
19+
"""Run build_rust sub command """
20+
if self.has_rust_extensions():
21+
log.info("running build_rust")
22+
build_rust = self.get_finalized_command('build_rust')
23+
build_rust.inplace = self.inplace
24+
build_rust.run()
25+
26+
_build_ext.run(self)

setuptools_rust/patch.py

Lines changed: 18 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,27 @@
1-
from distutils.dist import Distribution
2-
from distutils.command.build import build as Build
3-
from setuptools.command import develop
1+
from setuptools.dist import Distribution
42

5-
try:
6-
from setuptools.command.py36compat import sdist_add_defaults
7-
has_py36compat = True
8-
except ImportError:
9-
has_py36compat = False
103

4+
def monkey_patch_dist(build_ext):
5+
# allow to use 'rust_extensions' parameter for setup() call
6+
Distribution.rust_extensions = ()
117

12-
# allow to use 'rust_extensions' parameter for setup() call
13-
Distribution.rust_extensions = ()
8+
# replace setuptools build_ext
9+
Distribution.orig_get_command_class = Distribution.get_command_class
1410

11+
def get_command_class(self, command):
12+
if command == 'build_ext':
13+
if command not in self.cmdclass:
14+
self.cmdclass[command] = build_ext
1515

16-
orig_has_ext_modules = Distribution.has_ext_modules
16+
return self.orig_get_command_class(command)
1717

18-
def has_ext_modules(self):
19-
return (self.ext_modules and len(self.ext_modules) > 0 or
20-
self.rust_extensions and len(self.rust_extensions) > 0)
18+
Distribution.get_command_class = get_command_class
2119

20+
# use custom has_ext_modules
21+
Distribution.orig_has_ext_modules = Distribution.has_ext_modules
2222

23-
Distribution.has_ext_modules = has_ext_modules
23+
def has_ext_modules(self):
24+
return (self.ext_modules and len(self.ext_modules) > 0 or
25+
self.rust_extensions and len(self.rust_extensions) > 0)
2426

25-
26-
# add support for build_rust sub-command
27-
def has_rust_extensions(self):
28-
return (self.distribution.rust_extensions and
29-
len(self.distribution.rust_extensions) > 0)
30-
31-
32-
Build.has_rust_extensions = has_rust_extensions
33-
Build.sub_commands.append(('build_rust', Build.has_rust_extensions))
34-
35-
# monkey patch "develop" command
36-
orig_run_command = develop.develop.run_command
37-
38-
39-
def monkey_run_command(self, cmd):
40-
orig_run_command(self, cmd)
41-
42-
if cmd == 'build_ext':
43-
self.reinitialize_command('build_rust', inplace=1)
44-
orig_run_command(self, 'build_rust')
45-
46-
47-
develop.develop.run_command = monkey_run_command
48-
49-
50-
if has_py36compat:
51-
# monkey patch "sdist_add_defaults"
52-
53-
def _add_defaults_ext(self):
54-
if (self.distribution.ext_modules and
55-
len(self.distribution.ext_modules) > 0):
56-
build_ext = self.get_finalized_command('build_ext')
57-
self.filelist.extend(build_ext.get_source_files())
58-
59-
sdist_add_defaults._add_defaults_ext = _add_defaults_ext
60-
else:
61-
from distutils.command.build_ext import build_ext
62-
from setuptools.command.bdist_egg import bdist_egg
63-
64-
orig_get_source_files = build_ext.get_source_files
65-
66-
def get_source_files(self):
67-
if self.extensions:
68-
return orig_get_source_files(self)
69-
else:
70-
return []
71-
72-
build_ext.get_source_files = get_source_files
73-
74-
orig_get_ext_outputs = bdist_egg.get_ext_outputs
75-
76-
def get_ext_outputs(self):
77-
Distribution.has_ext_modules = orig_has_ext_modules
78-
try:
79-
return orig_get_ext_outputs(self)
80-
finally:
81-
Distribution.has_ext_modules = has_ext_modules
82-
83-
84-
bdist_egg.get_ext_outputs = get_ext_outputs
85-
86-
orig_run = bdist_egg.run
87-
88-
def run(self):
89-
self.run_command("build_rust")
90-
orig_run(self)
91-
92-
bdist_egg.run = run
27+
Distribution.has_ext_modules = has_ext_modules

0 commit comments

Comments
 (0)