0
# Build Commands
1
2
Custom setuptools command classes that extend standard distutils/setuptools commands with CMake integration. These commands handle the build process orchestration between Python packaging and CMake, providing seamless integration of compiled extensions into Python packages.
3
4
## Capabilities
5
6
### Command Mixin
7
8
Base mixin class that provides common functionality for overriding setuptools command behavior.
9
10
```python { .api }
11
class set_build_base_mixin:
12
"""
13
Mixin class for overriding distutils and setuptools commands.
14
15
Provides functionality to modify build_base directory and other
16
common command behaviors across different setuptools commands.
17
"""
18
```
19
20
### Core Build Commands
21
22
Extended versions of core setuptools build commands with CMake integration for handling compiled extensions.
23
24
```python { .api }
25
class build:
26
"""
27
Custom build command with CMake integration.
28
29
Extends distutils.command.build to coordinate CMake builds with
30
Python package building, handling the overall build orchestration.
31
"""
32
33
class build_py:
34
"""
35
Custom build_py command for Python modules.
36
37
Extends setuptools build_py to handle Python modules alongside
38
CMake-built extensions, ensuring proper integration of pure Python
39
and compiled components.
40
"""
41
42
class build_ext:
43
"""
44
Custom build_ext command for C/C++ extensions.
45
46
Replaces the standard setuptools build_ext with CMake-based building,
47
allowing complex C/C++/Fortran extensions to be built using CMake
48
instead of distutils compilation.
49
"""
50
```
51
52
### Installation Commands
53
54
Enhanced installation commands that handle both Python packages and CMake-built extensions.
55
56
```python { .api }
57
class install:
58
"""
59
Custom install command with CMake support.
60
61
Extends setuptools install command to handle installation of
62
CMake-built extensions alongside Python packages, managing
63
the complete installation process.
64
"""
65
66
class install_lib:
67
"""
68
Custom install_lib command for library installation.
69
70
Handles installation of Python libraries and CMake-built shared
71
libraries, ensuring proper placement and permissions.
72
"""
73
74
class install_scripts:
75
"""
76
Custom install_scripts command for script installation.
77
78
Manages installation of Python scripts and any executable files
79
generated by the CMake build process.
80
"""
81
```
82
83
### Distribution Commands
84
85
Commands for creating distributable packages that include CMake-built components.
86
87
```python { .api }
88
class sdist:
89
"""
90
Custom sdist command for source distributions.
91
92
Creates source distributions that include CMake files, build
93
configurations, and all necessary components for building
94
extensions from source.
95
"""
96
97
class bdist:
98
"""
99
Custom bdist command for binary distributions.
100
101
Creates binary distributions containing pre-built extensions
102
and properly configured Python packages.
103
"""
104
105
class bdist_wheel:
106
"""
107
Custom bdist_wheel command for wheel distributions.
108
109
Generates wheel files that include CMake-built extensions with
110
proper platform tags and dependency information.
111
"""
112
```
113
114
### Maintenance Commands
115
116
Commands for cleaning build artifacts and managing project state.
117
118
```python { .api }
119
class clean:
120
"""
121
Custom clean command for build cleanup.
122
123
Removes CMake build directories, generated files, and other
124
build artifacts in addition to standard Python build cleanup.
125
"""
126
```
127
128
### Package Information Commands
129
130
Commands for generating package metadata and information.
131
132
```python { .api }
133
class egg_info:
134
"""
135
Custom egg_info command for package metadata.
136
137
Generates package metadata that includes information about
138
CMake-built extensions and their dependencies.
139
"""
140
141
class generate_source_manifest:
142
"""
143
Custom command for generating source manifest files.
144
145
Creates manifest files that track all source files including
146
CMake configuration, build scripts, and extension sources.
147
"""
148
```
149
150
## Usage Examples
151
152
### Direct Command Usage
153
154
```python
155
from skbuild.command import build, clean
156
from setuptools import Distribution
157
158
# Create a distribution for command execution
159
dist = Distribution({
160
'name': 'my-extension',
161
'cmake_source_dir': 'src'
162
})
163
164
# Execute build command
165
build_cmd = build(dist)
166
build_cmd.finalize_options()
167
build_cmd.run()
168
169
# Execute clean command
170
clean_cmd = clean(dist)
171
clean_cmd.finalize_options()
172
clean_cmd.run()
173
```
174
175
### Custom Command Integration
176
177
```python
178
from skbuild import setup
179
from skbuild.command import build_ext
180
181
class CustomBuildExt(build_ext):
182
"""Custom build_ext with additional functionality."""
183
184
def run(self):
185
# Custom pre-build steps
186
print("Performing custom pre-build operations...")
187
188
# Call parent build_ext
189
super().run()
190
191
# Custom post-build steps
192
print("Performing custom post-build operations...")
193
194
setup(
195
name="custom-extension",
196
cmdclass={'build_ext': CustomBuildExt},
197
cmake_source_dir="native"
198
)
199
```
200
201
### Command-Line Integration
202
203
Commands can be invoked directly from the command line when using scikit-build:
204
205
```bash
206
# Build the project
207
python setup.py build
208
209
# Build only extensions
210
python setup.py build_ext
211
212
# Clean build artifacts
213
python setup.py clean --all
214
215
# Create source distribution
216
python setup.py sdist
217
218
# Create wheel distribution
219
python setup.py bdist_wheel
220
221
# Install the package
222
python setup.py install
223
```
224
225
### Advanced Command Configuration
226
227
```python
228
from skbuild import setup
229
230
setup(
231
name="advanced-extension",
232
233
# Command class customization
234
cmdclass={
235
'build': CustomBuild,
236
'clean': CustomClean,
237
},
238
239
# Command options
240
options={
241
'build': {
242
'build_base': 'custom_build',
243
},
244
'build_ext': {
245
'parallel': 4, # Parallel builds
246
},
247
'bdist_wheel': {
248
'universal': False, # Platform-specific wheels
249
}
250
},
251
252
cmake_source_dir="src",
253
cmake_args=["-DCMAKE_BUILD_TYPE=Release"]
254
)
255
```
256
257
### Command Dependency Management
258
259
```python
260
from skbuild.command import build, build_ext, install
261
from setuptools import Distribution
262
263
class CoordinatedBuild:
264
"""Coordinate multiple build commands."""
265
266
def __init__(self, dist):
267
self.dist = dist
268
269
def build_all(self):
270
"""Execute build commands in proper order."""
271
272
# Build Python modules first
273
build_py_cmd = self.dist.get_command_class('build_py')(self.dist)
274
build_py_cmd.ensure_finalized()
275
build_py_cmd.run()
276
277
# Build extensions
278
build_ext_cmd = build_ext(self.dist)
279
build_ext_cmd.ensure_finalized()
280
build_ext_cmd.run()
281
282
# Overall build coordination
283
build_cmd = build(self.dist)
284
build_cmd.ensure_finalized()
285
build_cmd.run()
286
287
# Usage
288
dist = Distribution({'name': 'coordinated-build'})
289
builder = CoordinatedBuild(dist)
290
builder.build_all()
291
```
292
293
### Error Handling in Commands
294
295
```python
296
from skbuild.command import build_ext
297
from skbuild.exceptions import SKBuildError
298
299
class SafeBuildExt(build_ext):
300
"""Build command with comprehensive error handling."""
301
302
def run(self):
303
try:
304
super().run()
305
except SKBuildError as e:
306
print(f"Build failed: {e}")
307
308
# Attempt recovery or provide helpful messages
309
if "generator" in str(e).lower():
310
print("Try: python setup.py build_ext --generator 'Unix Makefiles'")
311
elif "cmake" in str(e).lower():
312
print("Try: python setup.py build_ext --cmake-executable /path/to/cmake")
313
314
raise
315
except Exception as e:
316
print(f"Unexpected error during build: {e}")
317
print("Please check CMakeLists.txt and build configuration")
318
raise
319
320
setup(
321
name="safe-extension",
322
cmdclass={'build_ext': SafeBuildExt}
323
)
324
```