0
# Extension Building
1
2
Configuration and building of Rust extensions as Python modules or standalone binaries. setuptools-rust provides comprehensive support for different binding types, cross-compilation, build customization, and integration with the Python packaging ecosystem.
3
4
## Capabilities
5
6
### Extension Configuration
7
8
Define Rust extensions that will be built as Python modules, with full control over build options, features, and binding types.
9
10
```python { .api }
11
class RustExtension:
12
def __init__(
13
self,
14
target: Union[str, Dict[str, str]],
15
path: str = "Cargo.toml",
16
args: Optional[Sequence[str]] = (),
17
cargo_manifest_args: Optional[Sequence[str]] = (),
18
features: Optional[Sequence[str]] = (),
19
rustc_flags: Optional[Sequence[str]] = (),
20
rust_version: Optional[str] = None,
21
quiet: bool = False,
22
debug: Optional[bool] = None,
23
binding: Binding = Binding.PyO3,
24
strip: Strip = Strip.No,
25
script: bool = False,
26
native: bool = False,
27
optional: bool = False,
28
py_limited_api: Literal["auto", True, False] = "auto",
29
env: Optional[Dict[str, str]] = None,
30
):
31
"""
32
Configure a Rust extension for building as a Python module.
33
34
Parameters:
35
- target: Extension target name or dict mapping target to module name
36
- path: Path to Cargo.toml file (default: "Cargo.toml")
37
- args: Additional arguments passed to cargo build
38
- cargo_manifest_args: Arguments passed to cargo for manifest operations
39
- features: List of Cargo features to enable
40
- rustc_flags: Additional flags passed to rustc
41
- rust_version: Minimum required Rust version
42
- quiet: Suppress cargo output during build
43
- debug: Enable debug build (None uses setuptools debug setting)
44
- binding: Binding type (PyO3, RustCPython, NoBinding, Exec)
45
- strip: Symbol stripping mode (No, Debug, All)
46
- script: Install as console script
47
- native: Use native target (no cross-compilation)
48
- optional: Mark extension as optional (build failures won't stop installation)
49
- py_limited_api: Python limited API compatibility
50
- env: Environment variables for the build process
51
"""
52
53
def get_lib_name(self, *, quiet: bool) -> str:
54
"""
55
Parse Cargo.toml to get the shared library name.
56
57
Parameters:
58
- quiet: Suppress output during parsing
59
60
Returns:
61
str: The shared library name from Cargo.toml
62
"""
63
64
def get_rust_version(self) -> Optional[SimpleSpec]:
65
"""
66
Get parsed Rust version requirement.
67
68
Returns:
69
Optional[SimpleSpec]: Parsed version requirement or None
70
"""
71
72
def get_cargo_profile(self) -> Optional[str]:
73
"""
74
Extract cargo profile from build arguments.
75
76
Returns:
77
Optional[str]: Cargo profile name or None
78
"""
79
80
def entry_points(self) -> List[str]:
81
"""
82
Generate console script entry points for the extension.
83
84
Returns:
85
List[str]: List of entry point specifications
86
"""
87
88
def install_script(self, module_name: str, exe_path: str) -> None:
89
"""
90
Install console script for the extension.
91
92
Parameters:
93
- module_name: Name of the Python module
94
- exe_path: Path to the executable
95
"""
96
97
def metadata(self, *, quiet: bool) -> CargoMetadata:
98
"""
99
Get cargo metadata for the extension (cached).
100
101
Parameters:
102
- quiet: Suppress cargo output
103
104
Returns:
105
CargoMetadata: Cargo metadata dictionary
106
"""
107
```
108
109
### Binary Configuration
110
111
Define Rust binaries that will be built as standalone executables, inheriting most functionality from RustExtension but with binary-specific behavior.
112
113
```python { .api }
114
class RustBin(RustExtension):
115
def __init__(
116
self,
117
target: Union[str, Dict[str, str]],
118
path: str = "Cargo.toml",
119
args: Optional[Sequence[str]] = (),
120
cargo_manifest_args: Optional[Sequence[str]] = (),
121
features: Optional[Sequence[str]] = (),
122
rust_version: Optional[str] = None,
123
quiet: bool = False,
124
debug: Optional[bool] = None,
125
strip: Strip = Strip.No,
126
optional: bool = False,
127
env: Optional[dict[str, str]] = None,
128
):
129
"""
130
Configure a Rust binary for building as a standalone executable.
131
132
Parameters: Same as RustExtension except:
133
- No binding parameter (always uses Exec binding)
134
- No script, native, or py_limited_api parameters
135
"""
136
137
def entry_points(self) -> List[str]:
138
"""
139
Generate entry points for binary (returns empty list).
140
141
Returns:
142
List[str]: Empty list (binaries don't create console scripts)
143
"""
144
```
145
146
### Binding Types
147
148
Enumeration of supported Rust-Python binding types, determining how the Rust code interfaces with Python.
149
150
```python { .api }
151
class Binding(IntEnum):
152
PyO3 = auto() # Extension built using PyO3 bindings
153
RustCPython = auto() # Extension built using rust-cpython bindings
154
NoBinding = auto() # Bring your own bindings
155
Exec = auto() # Build executable instead of extension
156
157
def __repr__(self) -> str:
158
"""String representation of the binding type."""
159
```
160
161
### Symbol Stripping
162
163
Control symbol stripping in built extensions for size optimization and debugging.
164
165
```python { .api }
166
class Strip(IntEnum):
167
No = auto() # Do not strip symbols
168
Debug = auto() # Strip debug symbols only
169
All = auto() # Strip all symbols
170
171
def __repr__(self) -> str:
172
"""String representation of the stripping mode."""
173
```
174
175
## Usage Examples
176
177
### Basic PyO3 Extension
178
179
```python
180
from setuptools import setup
181
from setuptools_rust import RustExtension, Binding
182
183
setup(
184
name="my-pyo3-extension",
185
rust_extensions=[
186
RustExtension(
187
"my_package.rust_module",
188
path="rust/Cargo.toml",
189
binding=Binding.PyO3,
190
features=["python-extension"],
191
)
192
],
193
zip_safe=False,
194
)
195
```
196
197
### Cross-compilation Setup
198
199
```python
200
RustExtension(
201
"my_package.cross_compiled",
202
path="Cargo.toml",
203
args=["--target", "x86_64-pc-windows-gnu"],
204
env={"CARGO_BUILD_TARGET": "x86_64-pc-windows-gnu"},
205
)
206
```
207
208
### Debug Build with Custom Features
209
210
```python
211
RustExtension(
212
"my_package.debug_module",
213
path="Cargo.toml",
214
debug=True,
215
features=["debugging", "profiling"],
216
rustc_flags=["-C", "debuginfo=2"],
217
)
218
```
219
220
### Optional Extension
221
222
```python
223
RustExtension(
224
"my_package.optional_rust",
225
path="optional/Cargo.toml",
226
optional=True, # Build failure won't stop installation
227
quiet=True, # Suppress cargo output
228
)
229
```
230
231
### Standalone Binary
232
233
```python
234
from setuptools import setup
235
from setuptools_rust import RustBin, Strip
236
237
setup(
238
name="my-rust-tools",
239
rust_extensions=[
240
RustBin(
241
"my-cli-tool",
242
path="cli/Cargo.toml",
243
strip=Strip.All, # Strip all symbols for smaller binary
244
)
245
],
246
)
247
```
248
249
## Type Definitions
250
251
```python { .api }
252
from typing import Union, Dict, List, Optional, Sequence, Literal, Any, NewType
253
from enum import IntEnum, auto
254
255
CargoMetadata = NewType("CargoMetadata", Dict[str, Any])
256
257
class SimpleSpec:
258
"""Parsed Rust version requirement specification."""
259
260
class _BuiltModule:
261
"""Internal type representing a built module."""
262
```