Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 34 additions & 25 deletions setuptools_rust/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class build_rust(Command):
"Force debug to false for all rust extensions "),
('qbuild', None,
"Force enable quiet option for all rust extensions "),
('build-temp', 't',
"directory for temporary files (cargo 'target' directory) "),
]
boolean_options = ['inplace', 'debug', 'release', 'qbuild']

Expand All @@ -37,24 +39,38 @@ def initialize_options(self):
self.debug = None
self.release = None
self.qbuild = None
self.build_temp = None

def finalize_options(self):
self.extensions = [ext for ext in self.distribution.rust_extensions
if isinstance(ext, RustExtension)]

# Inherit settings from the `build_ext` command
self.set_undefined_options('build_ext',
('build_temp', 'build_temp'),
('debug', 'debug'),
('inplace', 'inplace'),
)

def build_extension(self, ext):
executable = ext.binding == Binding.Exec

# Make sure that if pythonXX-sys is used, it builds against the current
# executing python interpreter.
bindir = os.path.dirname(sys.executable)

# Find where to put the temporary build files created by `cargo`
targetdir = os.environ.get('CARGO_TARGET_DIR') \
or os.path.join(self.build_temp, self.distribution.get_name())

env = os.environ.copy()
env.update({
'CARGO_TARGET_DIR': targetdir,

# disables rust's pkg-config seeking for specified packages,
# which causes pythonXX-sys to fall back to detecting the
# interpreter from the path.
"PATH": bindir + os.pathsep + os.environ.get("PATH", "")
"PATH": os.path.join(bindir, os.environ.get("PATH", "")),
})

if not os.path.exists(ext.path):
Expand All @@ -64,11 +80,7 @@ def build_extension(self, ext):
features = set(ext.features)
features.update(cpython_feature(binding=ext.binding))

if ext.debug is None:
debug_build = self.inplace
else:
debug_build = ext.debug

debug_build = ext.debug if ext.debug is not None else self.inplace
debug_build = self.debug if self.debug is not None else debug_build
if self.release:
debug_build = False
Expand Down Expand Up @@ -136,20 +148,14 @@ def build_extension(self, ext):
else:
suffix = "release"

# location of files
dir = os.environ.get('CARGO_TARGET_DIR', '').strip()
if dir:
target_dir = os.path.join(dir, suffix)
else:
target_dir = os.path.join(
os.path.dirname(ext.path), "target/", suffix)

# location of cargo compiled files
artifactsdir = os.path.join(targetdir, suffix)
dylib_paths = []

if executable:
for name, dest in ext.target.items():
if name:
path = os.path.join(target_dir, name)
path = os.path.join(artifactsdir, name)
if os.access(path, os.X_OK):
dylib_paths.append((dest, path))
continue
Expand All @@ -160,8 +166,8 @@ def build_extension(self, ext):
name, target_dir))
else:
# search executable
for name in os.listdir(target_dir):
path = os.path.join(target_dir, name)
for name in os.listdir(artifactsdir):
path = os.path.join(artifactsdir, name)
if name.startswith(".") or not os.path.isfile(path):
continue

Expand All @@ -175,20 +181,23 @@ def build_extension(self, ext):
target_dir)
else:
if sys.platform == "win32":
wildcard_so = "*.dll"
dylib_ext = "dll"
elif sys.platform == "darwin":
wildcard_so = "*.dylib"
dylib_ext = "dylib"
else:
wildcard_so = "*.so"
dylib_ext = "so"

wildcard_so = "*{}.{}".format(ext.get_lib_name(), dylib_ext)

try:
dylib_paths.append(
(ext.name, glob.glob(
os.path.join(target_dir, wildcard_so))[0]))
except IndexError:
dylib_paths.append((
ext.name,
next(glob.iglob(os.path.join(artifactsdir, wildcard_so)))
))
except StopIteration:
raise DistutilsExecError(
"rust build failed; unable to find any %s in %s" %
(wildcard_so, target_dir))
(wildcard_so, artifactsdir))

# Ask build_ext where the shared library would go if it had built it,
# then copy it there.
Expand Down
10 changes: 10 additions & 0 deletions setuptools_rust/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
from distutils.errors import DistutilsSetupError
from .utils import Binding, Strip

try:
import configparser
except ImportError:
import ConfigParser as configparser


import semantic_version

Expand Down Expand Up @@ -91,6 +96,11 @@ def __init__(self, target, path,

self.path = path

def get_lib_name(self):
cfg = configparser.ConfigParser()
cfg.read(self.path)
return cfg.get('lib', 'name').strip('"')

def get_rust_version(self):
if self.rust_version is None:
return None
Expand Down