Skip to content

Commit 8ff92d1

Browse files
authored
Merge pull request #275 from jameshilliard/install-scripts-rustbin
Fix RustBin setuptools install
2 parents 5be25fe + 76800a6 commit 8ff92d1

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
### Changed
55
- Locate cdylib artifacts by handling messages from cargo instead of searching target dir (fixes build on MSYS2). [#267](https://github.com/PyO3/setuptools-rust/pull/267)
66
- Fix RustBin build without wheel. [#273](https://github.com/PyO3/setuptools-rust/pull/273)
7+
- Fix RustBin setuptools install. [#275](https://github.com/PyO3/setuptools-rust/pull/275)
78

89

910
## 1.4.1 (2022-07-05)

examples/hello-world/noxfile.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,12 @@ def test(session: nox.Session):
1010
session.install(SETUPTOOLS_RUST)
1111
session.install("--no-build-isolation", ".")
1212
session.run("hello-world", *session.posargs)
13+
14+
15+
@nox.session()
16+
def setuptools_install(session: nox.Session):
17+
session.install("setuptools")
18+
with session.chdir(SETUPTOOLS_RUST):
19+
session.run("python", "setup.py", "install")
20+
session.run("python", "setup.py", "install")
21+
session.run("hello-world", *session.posargs)

setuptools_rust/setuptools_ext.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import os
22
import subprocess
3+
import sysconfig
34
from distutils import log
45
from distutils.command.clean import clean
56
from typing import List, Set, Tuple, Type, cast
67

78
from setuptools.command.build_ext import build_ext
89
from setuptools.command.install import install
10+
from setuptools.command.install_lib import install_lib
11+
from setuptools.command.install_scripts import install_scripts
912
from setuptools.command.sdist import sdist
1013
from setuptools.dist import Distribution
1114
from typing_extensions import Literal
1215

13-
from .extension import RustExtension
16+
from .extension import RustBin, RustExtension
1417

1518
try:
1619
from wheel.bdist_wheel import bdist_wheel
@@ -189,8 +192,64 @@ def finalize_options(self) -> None:
189192
# restore ext_modules
190193
self.distribution.ext_modules = ext_modules
191194

195+
def run(self) -> None:
196+
install_base_class.run(self)
197+
install_rustbin = False
198+
if self.distribution.rust_extensions:
199+
for ext in self.distribution.rust_extensions:
200+
if isinstance(ext, RustBin):
201+
install_rustbin = True
202+
if install_rustbin:
203+
self.run_command("install_scripts")
204+
192205
dist.cmdclass["install"] = install_rust_extension
193206

207+
install_lib_base_class = cast(
208+
Type[install_lib], dist.cmdclass.get("install_lib", install_lib)
209+
)
210+
211+
# prevent RustBin from being installed to data_dir
212+
class install_lib_rust_extension(install_lib_base_class): # type: ignore[misc,valid-type]
213+
def get_exclusions(self) -> Set[str]:
214+
exclusions: Set[str] = install_lib_base_class.get_exclusions(self)
215+
build_rust = self.get_finalized_command("build_rust")
216+
scripts_path = os.path.join(
217+
self.install_dir, build_rust.data_dir, "scripts"
218+
)
219+
if self.distribution.rust_extensions:
220+
exe = sysconfig.get_config_var("EXE")
221+
for ext in self.distribution.rust_extensions:
222+
executable_name = ext.name
223+
if exe is not None:
224+
executable_name += exe
225+
if isinstance(ext, RustBin):
226+
exclusions.add(os.path.join(scripts_path, executable_name))
227+
return exclusions
228+
229+
dist.cmdclass["install_lib"] = install_lib_rust_extension
230+
231+
install_scripts_base_class = cast(
232+
Type[install_scripts], dist.cmdclass.get("install_scripts", install_scripts)
233+
)
234+
235+
# this is required to make install_scripts compatible with RustBin
236+
class install_scripts_rust_extension(install_scripts_base_class): # type: ignore[misc,valid-type]
237+
def run(self) -> None:
238+
install_scripts_base_class.run(self)
239+
build_ext = self.get_finalized_command("build_ext")
240+
build_rust = self.get_finalized_command("build_rust")
241+
scripts_path = os.path.join(
242+
build_ext.build_lib, build_rust.data_dir, "scripts"
243+
)
244+
if os.path.isdir(scripts_path):
245+
for file in os.listdir(scripts_path):
246+
script_path = os.path.join(scripts_path, file)
247+
if os.path.isfile(script_path):
248+
with open(os.path.join(script_path), "rb") as script_reader:
249+
self.write_script(file, script_reader.read(), mode="b")
250+
251+
dist.cmdclass["install_scripts"] = install_scripts_rust_extension
252+
194253
if bdist_wheel is not None:
195254
bdist_wheel_base_class = cast( # type: ignore[no-any-unimported]
196255
Type[bdist_wheel], dist.cmdclass.get("bdist_wheel", bdist_wheel)

0 commit comments

Comments
 (0)