0
# Environment Handling
1
2
Cibuildwheel provides advanced environment variable parsing with bash syntax support and context-aware evaluation for comprehensive build customization.
3
4
## Capabilities
5
6
### Environment Parsing
7
8
Parse environment variable specifications from configuration strings.
9
10
```python { .api }
11
def parse_environment(env_string: str) -> ParsedEnvironment:
12
"""
13
Parse environment variable specification string.
14
15
Args:
16
env_string: Environment specification (e.g., "VAR1=value1 VAR2=value2")
17
18
Returns:
19
ParsedEnvironment object containing parsed assignments
20
21
Raises:
22
EnvironmentParseError: If parsing fails due to syntax errors
23
"""
24
```
25
26
### Parsed Environment Container
27
28
Container for environment variable assignments with evaluation capabilities.
29
30
```python { .api }
31
@dataclasses.dataclass(kw_only=True)
32
class ParsedEnvironment:
33
assignments: list[EnvironmentAssignment]
34
35
def as_dictionary(
36
self,
37
prev_environment: Mapping[str, str],
38
executor: bashlex_eval.EnvironmentExecutor | None = None
39
) -> dict[str, str]:
40
"""
41
Convert parsed environment to a dictionary with evaluated values.
42
43
Args:
44
prev_environment: Existing environment variables for context
45
executor: Optional bash expression executor
46
47
Returns:
48
Dictionary of environment variable names to evaluated values
49
"""
50
51
def add(self, name: str, value: str, prepend: bool = False) -> None:
52
"""
53
Add a new environment variable assignment.
54
55
Args:
56
name: Variable name
57
value: Variable value (can contain expressions)
58
prepend: If True, add to beginning of assignments list
59
"""
60
```
61
62
### Environment Assignment Interface
63
64
Protocol defining how environment assignments are evaluated.
65
66
```python { .api }
67
class EnvironmentAssignment(Protocol):
68
name: str
69
70
def evaluated_value(
71
self,
72
*,
73
environment: Mapping[str, str],
74
executor: bashlex_eval.EnvironmentExecutor | None = None
75
) -> str:
76
"""
77
Evaluate the assignment value in the given environment context.
78
79
Args:
80
environment: Current environment variables
81
executor: Optional bash expression executor
82
83
Returns:
84
Evaluated string value
85
"""
86
```
87
88
### Assignment Types
89
90
Different types of environment variable assignments.
91
92
```python { .api }
93
class EnvironmentAssignmentRaw:
94
"""Simple string assignment without expression evaluation."""
95
name: str
96
value: str
97
98
class EnvironmentAssignmentBash:
99
"""Assignment with bash expression evaluation support."""
100
name: str
101
value: str
102
```
103
104
### Environment Parse Error
105
106
Exception raised when environment parsing fails.
107
108
```python { .api }
109
class EnvironmentParseError(Exception):
110
"""Raised when environment variable parsing fails."""
111
```
112
113
## Environment Specification Syntax
114
115
### Simple Assignments
116
117
```python
118
# Basic key=value pairs
119
env_string = "CFLAGS=-O2 LDFLAGS=-s DEBUG=1"
120
121
# With quotes for values containing spaces
122
env_string = 'CFLAGS="-O2 -g" DESCRIPTION="My Package"'
123
```
124
125
### Bash Expression Support
126
127
```python
128
# Variable expansion
129
env_string = "PATH=$PATH:/usr/local/bin HOME_BIN=$HOME/bin"
130
131
# Command substitution
132
env_string = "VERSION=$(python setup.py --version) BUILD_DATE=$(date)"
133
134
# Conditional expressions
135
env_string = "CFLAGS=${CFLAGS:--O2} DEBUG=${DEBUG:-0}"
136
```
137
138
### Multi-line Specifications
139
140
```python
141
# Line continuation
142
env_string = """
143
CFLAGS=-O2 \\
144
LDFLAGS=-s \\
145
DEBUG=1
146
"""
147
148
# Multiple assignments
149
env_string = """
150
CC=gcc
151
CXX=g++
152
CFLAGS=-O2 -g
153
LDFLAGS=-s
154
"""
155
```
156
157
## Configuration Methods
158
159
### TOML Configuration
160
161
```toml
162
[tool.cibuildwheel]
163
# Simple environment variables
164
environment = {CFLAGS = "-O2", LDFLAGS = "-s", DEBUG = "1"}
165
166
# With bash expressions
167
environment = {
168
PATH = "$PATH:/usr/local/bin",
169
VERSION = "$(python setup.py --version)",
170
BUILD_TYPE = "${BUILD_TYPE:-release}"
171
}
172
173
# Platform-specific environments
174
[tool.cibuildwheel.linux]
175
environment = {
176
CC = "gcc",
177
CXX = "g++",
178
CFLAGS = "-O2 -fPIC"
179
}
180
181
[tool.cibuildwheel.windows]
182
environment = {
183
CC = "cl.exe",
184
CXX = "cl.exe",
185
CFLAGS = "/O2"
186
}
187
```
188
189
### Environment Variables
190
191
```bash
192
# Single assignment
193
export CIBW_ENVIRONMENT="CFLAGS=-O2"
194
195
# Multiple assignments
196
export CIBW_ENVIRONMENT="CFLAGS=-O2 LDFLAGS=-s DEBUG=1"
197
198
# With bash expressions
199
export CIBW_ENVIRONMENT="PATH=\$PATH:/usr/local/bin VERSION=\$(python setup.py --version)"
200
201
# Platform-specific
202
export CIBW_ENVIRONMENT_LINUX="CC=gcc CXX=g++"
203
export CIBW_ENVIRONMENT_WINDOWS="CC=cl.exe CXX=cl.exe"
204
```
205
206
### String Format
207
208
```python
209
# Space-separated key=value pairs
210
"CFLAGS=-O2 LDFLAGS=-s DEBUG=1"
211
212
# Quoted values for spaces
213
'CFLAGS="-O2 -g" DESCRIPTION="My Package"'
214
215
# Bash expressions
216
"PATH=$PATH:/usr/local/bin VERSION=$(python setup.py --version)"
217
```
218
219
## Environment Pass-Through
220
221
### Host Environment Variables
222
223
Pass specific environment variables from the host to the build environment:
224
225
```toml
226
[tool.cibuildwheel]
227
# Pass through authentication tokens
228
environment-pass = ["API_TOKEN", "SECRET_KEY", "GITHUB_TOKEN"]
229
230
# Platform-specific pass-through
231
[tool.cibuildwheel.linux]
232
environment-pass = ["DOCKER_HOST", "DOCKER_CERT_PATH"]
233
```
234
235
```bash
236
# Via environment variable
237
export CIBW_ENVIRONMENT_PASS="API_TOKEN SECRET_KEY GITHUB_TOKEN"
238
export CIBW_ENVIRONMENT_PASS_LINUX="DOCKER_HOST DOCKER_CERT_PATH"
239
```
240
241
### CI Environment Detection
242
243
Automatically pass common CI environment variables:
244
245
```python
246
# Common CI variables that are often needed:
247
CI_VARS = [
248
"CI", "GITHUB_ACTIONS", "GITHUB_TOKEN", "GITHUB_REF",
249
"TRAVIS", "TRAVIS_TAG", "TRAVIS_BRANCH",
250
"APPVEYOR", "APPVEYOR_REPO_TAG_NAME",
251
"AZURE_PIPELINES", "BUILD_SOURCEBRANCH"
252
]
253
```
254
255
## Advanced Environment Features
256
257
### Dynamic Environment Generation
258
259
```python
260
import os
261
from cibuildwheel.environment import parse_environment
262
263
# Generate environment based on conditions
264
if os.environ.get("DEBUG"):
265
env_string = "CFLAGS=-g -O0 DEBUG=1"
266
else:
267
env_string = "CFLAGS=-O2 -DNDEBUG DEBUG=0"
268
269
parsed_env = parse_environment(env_string)
270
```
271
272
### Environment Inheritance and Merging
273
274
```python
275
# Base environment
276
base_env = parse_environment("CC=gcc CFLAGS=-O2")
277
278
# Add platform-specific variables
279
if platform == "linux":
280
base_env.add("LDFLAGS", "-s")
281
elif platform == "windows":
282
base_env.add("CC", "cl.exe")
283
```
284
285
### Build-Specific Environment Variables
286
287
Cibuildwheel provides special variables during builds:
288
289
- `{project}`: Path to the project being built
290
- `{package}`: Path to the package directory
291
- `{wheel}`: Path to the built wheel (in repair commands)
292
- `{dest_dir}`: Destination directory for repaired wheels
293
294
```toml
295
[tool.cibuildwheel]
296
# Use in test commands
297
test-command = "cd {project} && python -m pytest tests/"
298
299
# Use in repair commands
300
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}"
301
```
302
303
## Usage Examples
304
305
### Basic Environment Setup
306
307
```python
308
from cibuildwheel.environment import parse_environment
309
310
# Parse simple environment
311
env = parse_environment("CFLAGS=-O2 LDFLAGS=-s")
312
env_dict = env.as_dictionary({})
313
# Result: {"CFLAGS": "-O2", "LDFLAGS": "-s"}
314
```
315
316
### Bash Expression Evaluation
317
318
```python
319
import os
320
from cibuildwheel.environment import parse_environment
321
322
# Environment with expressions
323
env_string = "PATH=$PATH:/usr/local/bin HOME_BIN=$HOME/bin"
324
env = parse_environment(env_string)
325
326
# Evaluate with current environment
327
current_env = dict(os.environ)
328
evaluated = env.as_dictionary(current_env)
329
# Result: {"PATH": "/usr/bin:/usr/local/bin", "HOME_BIN": "/home/user/bin"}
330
```
331
332
### Platform-Specific Configuration
333
334
```toml
335
[tool.cibuildwheel]
336
# Base environment for all platforms
337
environment = {DEBUG = "0", OPTIMIZE = "1"}
338
339
[tool.cibuildwheel.linux]
340
# Linux-specific compiler settings
341
environment = {
342
CC = "gcc",
343
CXX = "g++",
344
CFLAGS = "-O2 -fPIC",
345
LDFLAGS = "-s"
346
}
347
348
[tool.cibuildwheel.windows]
349
# Windows-specific compiler settings
350
environment = {
351
CC = "cl.exe",
352
CXX = "cl.exe",
353
CFLAGS = "/O2 /MD",
354
LDFLAGS = "/LTCG"
355
}
356
357
[tool.cibuildwheel.macos]
358
# macOS-specific settings
359
environment = {
360
CC = "clang",
361
CXX = "clang++",
362
CFLAGS = "-O2 -arch x86_64 -arch arm64",
363
MACOSX_DEPLOYMENT_TARGET = "10.14"
364
}
365
```
366
367
### Complex Build Environment
368
369
```toml
370
[tool.cibuildwheel]
371
environment = {
372
# Build configuration
373
BUILD_TYPE = "${BUILD_TYPE:-Release}",
374
CMAKE_BUILD_PARALLEL_LEVEL = "${CMAKE_BUILD_PARALLEL_LEVEL:-4}",
375
376
# Compiler flags
377
CFLAGS = "${CFLAGS:--O2} -DVERSION=$(python setup.py --version)",
378
CXXFLAGS = "${CXXFLAGS:--O2} -std=c++17",
379
380
# Paths
381
PKG_CONFIG_PATH = "/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH",
382
LD_LIBRARY_PATH = "/usr/local/lib:$LD_LIBRARY_PATH"
383
}
384
385
# Pass through CI variables
386
environment-pass = [
387
"GITHUB_TOKEN", "CI", "GITHUB_ACTIONS",
388
"TRAVIS", "APPVEYOR", "AZURE_PIPELINES"
389
]
390
```
391
392
### Error Handling
393
394
```python
395
from cibuildwheel.environment import parse_environment, EnvironmentParseError
396
397
try:
398
# This might fail due to syntax errors
399
env = parse_environment("INVALID SYNTAX")
400
except EnvironmentParseError as e:
401
print(f"Environment parsing failed: {e}")
402
```