0
# Distutils Integration
1
2
Nuitka provides seamless integration with Python's distutils and setuptools build systems, enabling automatic compilation of Python packages during installation. This integration supports PEP 517 build backends, custom distutils commands, and setup.py configuration keywords.
3
4
## Capabilities
5
6
### Setup Configuration
7
8
Core functions for configuring Nuitka integration in setup.py files.
9
10
```python { .api }
11
def setupNuitkaDistutilsCommands(dist, keyword, value):
12
"""
13
Configure distutils integration for Nuitka.
14
15
Sets up Nuitka compilation commands and options within the distutils
16
framework. Called automatically when build_with_nuitka=True is used
17
in setup.py.
18
19
Args:
20
dist: Distribution object from setuptools
21
keyword (str): Setup keyword that triggered this function
22
value: Value associated with the keyword
23
24
Returns:
25
None: Modifies distribution configuration in-place
26
"""
27
28
def addToPythonPath(python_path: str, in_front: bool = False):
29
"""
30
Modify Python path for compilation.
31
32
Adds directories to the Python path during compilation to ensure
33
proper module resolution and imports.
34
35
Args:
36
python_path (str): Path to add to PYTHONPATH
37
in_front (bool): Whether to add at beginning of path
38
39
Returns:
40
None: Modifies sys.path
41
"""
42
```
43
44
**Usage Example:**
45
46
```python
47
from nuitka.distutils.DistutilCommands import setupNuitkaDistutilsCommands
48
from setuptools import setup
49
50
# Basic setup.py with Nuitka integration
51
setup(
52
name="mypackage",
53
version="1.0.0",
54
py_modules=["mymodule"],
55
build_with_nuitka=True, # Triggers setupNuitkaDistutilsCommands
56
# Standard setup parameters
57
)
58
```
59
60
### Custom Build Commands
61
62
Distutils command classes for Nuitka-enabled building and installation.
63
64
```python { .api }
65
class build:
66
"""
67
Custom build command with Nuitka support.
68
69
Extends the standard distutils build command to include Nuitka
70
compilation of Python modules and packages during the build process.
71
72
Attributes:
73
nuitka_options (list): Compilation options for Nuitka
74
build_lib (str): Directory for built modules
75
build_temp (str): Temporary build directory
76
"""
77
78
class install:
79
"""
80
Custom install command with Nuitka support.
81
82
Extends the standard distutils install command to handle installation
83
of Nuitka-compiled modules and executables.
84
85
Attributes:
86
nuitka_compiled (bool): Whether modules were compiled with Nuitka
87
install_lib (str): Installation directory for modules
88
"""
89
90
class bdist_nuitka:
91
"""
92
Binary distribution command class.
93
94
Creates binary distributions (wheels) containing Nuitka-compiled
95
modules instead of Python source code.
96
97
Attributes:
98
dist_dir (str): Directory for distribution files
99
format (str): Distribution format
100
plat_name (str): Platform name for distribution
101
"""
102
```
103
104
**Usage Example:**
105
106
```python
107
from setuptools import setup
108
from nuitka.distutils.DistutilCommands import build, install, bdist_nuitka
109
110
setup(
111
name="mypackage",
112
cmdclass={
113
'build': build,
114
'install': install,
115
'bdist_nuitka': bdist_nuitka,
116
},
117
build_with_nuitka=True,
118
)
119
```
120
121
### PEP 517 Build Backend
122
123
Modern build backend support for pip and other PEP 517 compliant tools.
124
125
```python { .api }
126
class NuitkaBuildMetaBackend:
127
"""
128
PEP 517 build backend implementation.
129
130
Provides a modern build backend interface that enables pip and other
131
tools to build packages with Nuitka compilation automatically.
132
133
Methods:
134
build_wheel: Build a wheel distribution
135
build_sdist: Build a source distribution
136
get_requires_for_build_wheel: Get build requirements
137
get_requires_for_build_sdist: Get source build requirements
138
"""
139
```
140
141
**Usage Example:**
142
143
Create `pyproject.toml`:
144
```toml
145
[build-system]
146
requires = ["setuptools", "nuitka"]
147
build-backend = "nuitka.distutils.Build:NuitkaBuildMetaBackend"
148
149
[tool.nuitka]
150
standalone = true
151
include-packages = ["requests", "numpy"]
152
```
153
154
## Setup.py Integration
155
156
### Basic Integration
157
158
Simple setup.py integration with automatic Nuitka compilation.
159
160
```python
161
from setuptools import setup, find_packages
162
163
setup(
164
name="myapp",
165
version="1.0.0",
166
packages=find_packages(),
167
168
# Enable Nuitka compilation
169
build_with_nuitka=True,
170
171
# Standard metadata
172
author="Your Name",
173
description="My Python application",
174
install_requires=[
175
"requests>=2.25.0",
176
"numpy>=1.20.0",
177
],
178
)
179
```
180
181
### Advanced Configuration
182
183
Advanced setup.py with custom Nuitka options and selective compilation.
184
185
```python
186
from setuptools import setup, find_packages
187
188
# Custom configuration for Nuitka compilation
189
nuitka_config = {
190
'standalone': True,
191
'include_packages': ['requests', 'numpy'],
192
'plugins': ['numpy', 'tk-inter'],
193
'optimize': True,
194
'show_progress': True,
195
}
196
197
setup(
198
name="advanced_app",
199
version="2.0.0",
200
packages=find_packages(exclude=['tests*']),
201
202
# Nuitka integration
203
build_with_nuitka=True,
204
nuitka_options=nuitka_config,
205
206
# Entry points for executables
207
entry_points={
208
'console_scripts': [
209
'myapp=myapp.main:main',
210
],
211
},
212
213
# Dependencies
214
install_requires=[
215
'requests>=2.25.0',
216
'numpy>=1.20.0',
217
'tkinter-tooltip>=2.0.0',
218
],
219
220
# Metadata
221
author="Developer",
222
author_email="dev@example.com",
223
description="Advanced Python application with Nuitka compilation",
224
long_description=open('README.md').read(),
225
long_description_content_type="text/markdown",
226
url="https://github.com/user/advanced_app",
227
classifiers=[
228
"Programming Language :: Python :: 3",
229
"License :: OSI Approved :: MIT License",
230
"Operating System :: OS Independent",
231
],
232
python_requires='>=3.7',
233
)
234
```
235
236
### Conditional Compilation
237
238
Conditionally enable Nuitka based on environment or user choice.
239
240
```python
241
import os
242
import sys
243
from setuptools import setup
244
245
# Check if Nuitka should be used
246
use_nuitka = (
247
os.getenv('USE_NUITKA', '').lower() in ('1', 'true', 'yes') or
248
'--nuitka' in sys.argv
249
)
250
251
if '--nuitka' in sys.argv:
252
sys.argv.remove('--nuitka')
253
254
setup_kwargs = {
255
'name': 'conditional_app',
256
'version': '1.0.0',
257
'py_modules': ['app'],
258
}
259
260
# Add Nuitka configuration if enabled
261
if use_nuitka:
262
setup_kwargs.update({
263
'build_with_nuitka': True,
264
'nuitka_options': {
265
'standalone': True,
266
'optimize': True,
267
}
268
})
269
print("Building with Nuitka compilation enabled")
270
else:
271
print("Building with standard Python interpretation")
272
273
setup(**setup_kwargs)
274
```
275
276
## Build Process Integration
277
278
### Custom Build Steps
279
280
Integrate custom build steps with Nuitka compilation.
281
282
```python
283
from setuptools import setup
284
from setuptools.command.build_py import build_py
285
from nuitka.distutils.DistutilCommands import build as nuitka_build
286
287
class CustomBuild(nuitka_build):
288
"""Custom build command with pre/post processing."""
289
290
def run(self):
291
"""Execute custom build process."""
292
# Pre-compilation steps
293
self.pre_compile()
294
295
# Run Nuitka compilation
296
super().run()
297
298
# Post-compilation steps
299
self.post_compile()
300
301
def pre_compile(self):
302
"""Steps to run before Nuitka compilation."""
303
print("Running pre-compilation setup...")
304
# Generate configuration files
305
# Process templates
306
# Validate dependencies
307
308
def post_compile(self):
309
"""Steps to run after Nuitka compilation."""
310
print("Running post-compilation cleanup...")
311
# Copy additional resources
312
# Generate documentation
313
# Create distribution packages
314
315
setup(
316
name="custom_build_app",
317
cmdclass={'build': CustomBuild},
318
build_with_nuitka=True,
319
)
320
```
321
322
### Resource Management
323
324
Handle data files and resources during Nuitka compilation.
325
326
```python
327
from setuptools import setup
328
import os
329
330
def find_data_files(directory):
331
"""Find all data files in directory structure."""
332
data_files = []
333
for root, dirs, files in os.walk(directory):
334
for file in files:
335
if not file.endswith(('.pyc', '__pycache__')):
336
data_files.append(os.path.join(root, file))
337
return data_files
338
339
setup(
340
name="resource_app",
341
packages=['myapp'],
342
343
# Include data files
344
package_data={
345
'myapp': [
346
'data/*.json',
347
'templates/*.html',
348
'static/*/*.css',
349
'config/*.ini',
350
]
351
},
352
353
# Additional data files
354
data_files=[
355
('docs', find_data_files('docs')),
356
('examples', find_data_files('examples')),
357
],
358
359
# Nuitka configuration with resource inclusion
360
build_with_nuitka=True,
361
nuitka_options={
362
'standalone': True,
363
'include_data_files': [
364
'myapp/data/',
365
'myapp/templates/',
366
'myapp/static/',
367
],
368
},
369
)
370
```
371
372
## Development Workflow
373
374
### Development vs Production Builds
375
376
Different configurations for development and production environments.
377
378
```python
379
import os
380
from setuptools import setup
381
382
# Detect environment
383
is_production = os.getenv('ENVIRONMENT') == 'production'
384
is_development = os.getenv('ENVIRONMENT') == 'development'
385
386
# Base configuration
387
base_config = {
388
'name': 'workflow_app',
389
'version': '1.0.0',
390
'packages': ['myapp'],
391
'install_requires': ['requests', 'click'],
392
}
393
394
# Environment-specific configuration
395
if is_production:
396
# Production: Full optimization
397
base_config.update({
398
'build_with_nuitka': True,
399
'nuitka_options': {
400
'standalone': True,
401
'optimize': True,
402
'lto': True,
403
'remove_output': True,
404
'show_progress': False,
405
}
406
})
407
408
elif is_development:
409
# Development: Fast compilation with debug info
410
base_config.update({
411
'build_with_nuitka': True,
412
'nuitka_options': {
413
'module': True,
414
'debug': True,
415
'verbose': True,
416
'show_progress': True,
417
}
418
})
419
420
else:
421
# Default: Standard Python installation
422
print("Using standard Python installation (set ENVIRONMENT=production or ENVIRONMENT=development for Nuitka)")
423
424
setup(**base_config)
425
```
426
427
### Testing Integration
428
429
Integrate testing with Nuitka-compiled modules.
430
431
```python
432
from setuptools import setup
433
from setuptools.command.test import test as TestCommand
434
435
class NuitkaTest(TestCommand):
436
"""Custom test command for Nuitka-compiled modules."""
437
438
def run_tests(self):
439
"""Run tests against compiled modules."""
440
import pytest
441
442
# First, ensure modules are compiled
443
self.run_command('build')
444
445
# Add build directory to Python path
446
build_lib = self.get_finalized_command('build').build_lib
447
import sys
448
sys.path.insert(0, build_lib)
449
450
# Run tests
451
pytest.main(['tests/'])
452
453
setup(
454
name="tested_app",
455
packages=['myapp'],
456
457
# Test configuration
458
cmdclass={'test': NuitkaTest},
459
tests_require=['pytest', 'pytest-cov'],
460
461
# Nuitka compilation
462
build_with_nuitka=True,
463
nuitka_options={
464
'module': True,
465
'debug': True, # Keep debug info for testing
466
},
467
)
468
```
469
470
## Error Handling
471
472
### Build Error Management
473
474
Handle common build and integration errors.
475
476
```python
477
from setuptools import setup
478
from nuitka.distutils.DistutilCommands import build
479
import sys
480
481
class SafeNuitkaBuild(build):
482
"""Build command with comprehensive error handling."""
483
484
def run(self):
485
"""Execute build with error handling."""
486
try:
487
super().run()
488
489
except ImportError as e:
490
print(f"Import error during build: {e}")
491
print("Consider adding missing packages to install_requires")
492
sys.exit(1)
493
494
except OSError as e:
495
print(f"File system error: {e}")
496
print("Check permissions and available disk space")
497
sys.exit(1)
498
499
except Exception as e:
500
print(f"Build failed: {e}")
501
print("Use --verbose for detailed error information")
502
sys.exit(1)
503
504
def safe_setup(**kwargs):
505
"""Setup with error handling."""
506
try:
507
setup(**kwargs)
508
except Exception as e:
509
print(f"Setup failed: {e}")
510
sys.exit(1)
511
512
# Usage
513
safe_setup(
514
name="safe_app",
515
cmdclass={'build': SafeNuitkaBuild},
516
build_with_nuitka=True,
517
)
518
```
519
520
## Types
521
522
```python { .api }
523
# Distribution types
524
DistributionObject = Any # setuptools.Distribution
525
SetupKeyword = str
526
SetupValue = Any
527
528
# Build command types
529
BuildCommand = Any # distutils.cmd.Command subclass
530
BuildOptions = dict[str, Any]
531
532
# PEP 517 types
533
BuildBackend = Any
534
WheelMetadata = dict[str, str]
535
BuildRequirements = list[str]
536
537
# Configuration types
538
NuitkaOptions = dict[str, Any]
539
PackageData = dict[str, list[str]]
540
DataFiles = list[tuple[str, list[str]]]
541
```