relenv 0.21.1__py3-none-any.whl → 0.22.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- relenv/__init__.py +14 -2
- relenv/__main__.py +12 -6
- relenv/_resources/xz/config.h +148 -0
- relenv/_resources/xz/readme.md +4 -0
- relenv/build/__init__.py +28 -30
- relenv/build/common/__init__.py +50 -0
- relenv/build/common/_sysconfigdata_template.py +72 -0
- relenv/build/common/builder.py +907 -0
- relenv/build/common/builders.py +163 -0
- relenv/build/common/download.py +324 -0
- relenv/build/common/install.py +609 -0
- relenv/build/common/ui.py +432 -0
- relenv/build/darwin.py +128 -14
- relenv/build/linux.py +296 -78
- relenv/build/windows.py +259 -44
- relenv/buildenv.py +48 -17
- relenv/check.py +10 -5
- relenv/common.py +499 -163
- relenv/create.py +147 -7
- relenv/fetch.py +16 -4
- relenv/manifest.py +15 -7
- relenv/python-versions.json +329 -0
- relenv/pyversions.py +817 -30
- relenv/relocate.py +101 -55
- relenv/runtime.py +452 -253
- relenv/toolchain.py +9 -3
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/METADATA +1 -1
- relenv-0.22.0.dist-info/RECORD +48 -0
- tests/__init__.py +2 -0
- tests/_pytest_typing.py +45 -0
- tests/conftest.py +42 -36
- tests/test_build.py +426 -9
- tests/test_common.py +311 -48
- tests/test_create.py +149 -6
- tests/test_downloads.py +19 -15
- tests/test_fips_photon.py +6 -3
- tests/test_module_imports.py +44 -0
- tests/test_pyversions_runtime.py +177 -0
- tests/test_relocate.py +45 -39
- tests/test_relocate_module.py +257 -0
- tests/test_runtime.py +1802 -6
- tests/test_verify_build.py +500 -34
- relenv/build/common.py +0 -1609
- relenv-0.21.1.dist-info/RECORD +0 -35
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/WHEEL +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/entry_points.txt +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/licenses/LICENSE.md +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/licenses/NOTICE +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/top_level.txt +0 -0
relenv/build/windows.py
CHANGED
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
# Copyright 2022-2025 Broadcom.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2
|
|
3
|
+
# mypy: ignore-errors
|
|
3
4
|
"""
|
|
4
5
|
The windows build process.
|
|
5
6
|
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
6
9
|
import glob
|
|
7
|
-
import
|
|
8
|
-
import
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
9
12
|
import os
|
|
10
13
|
import pathlib
|
|
14
|
+
import shutil
|
|
15
|
+
import sys
|
|
11
16
|
import tarfile
|
|
12
|
-
import
|
|
13
|
-
from
|
|
14
|
-
|
|
17
|
+
import time
|
|
18
|
+
from typing import IO, MutableMapping, Union
|
|
19
|
+
|
|
20
|
+
from .common import (
|
|
21
|
+
Dirs,
|
|
22
|
+
builds,
|
|
23
|
+
create_archive,
|
|
24
|
+
get_dependency_version,
|
|
25
|
+
install_runtime,
|
|
26
|
+
patch_file,
|
|
27
|
+
update_ensurepip,
|
|
28
|
+
update_sbom_checksums,
|
|
29
|
+
)
|
|
30
|
+
from ..common import (
|
|
31
|
+
WIN32,
|
|
32
|
+
arches,
|
|
33
|
+
MODULE_DIR,
|
|
34
|
+
download_url,
|
|
35
|
+
extract_archive,
|
|
36
|
+
runcmd,
|
|
37
|
+
)
|
|
15
38
|
|
|
16
39
|
log = logging.getLogger(__name__)
|
|
17
40
|
|
|
18
41
|
ARCHES = arches[WIN32]
|
|
19
42
|
|
|
43
|
+
EnvMapping = MutableMapping[str, str]
|
|
44
|
+
|
|
20
45
|
if sys.platform == WIN32:
|
|
21
46
|
import ctypes
|
|
22
47
|
|
|
@@ -24,7 +49,7 @@ if sys.platform == WIN32:
|
|
|
24
49
|
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
|
25
50
|
|
|
26
51
|
|
|
27
|
-
def populate_env(env, dirs):
|
|
52
|
+
def populate_env(env: EnvMapping, dirs: Dirs) -> None:
|
|
28
53
|
"""
|
|
29
54
|
Make sure we have the correct environment variables set.
|
|
30
55
|
|
|
@@ -36,45 +61,227 @@ def populate_env(env, dirs):
|
|
|
36
61
|
env["MSBUILDDISABLENODEREUSE"] = "1"
|
|
37
62
|
|
|
38
63
|
|
|
39
|
-
def
|
|
40
|
-
"""
|
|
41
|
-
Search a file line by line for a string to replace.
|
|
42
|
-
|
|
43
|
-
:param path: Location of the file to search
|
|
44
|
-
:type path: str
|
|
45
|
-
:param old: The value that will be replaced
|
|
46
|
-
:type path: str
|
|
47
|
-
:param new: The value that will replace the 'old' value.
|
|
48
|
-
:type path: str
|
|
64
|
+
def update_props(source: pathlib.Path, old: str, new: str) -> None:
|
|
49
65
|
"""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
with open(path, "r") as fp:
|
|
53
|
-
content = fp.read()
|
|
54
|
-
new_content = ""
|
|
55
|
-
for line in content.splitlines():
|
|
56
|
-
re.sub(old, new, line)
|
|
57
|
-
new_content += line + os.linesep
|
|
58
|
-
with open(path, "w") as fp:
|
|
59
|
-
fp.write(new_content)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def override_dependency(source, old, new):
|
|
63
|
-
"""
|
|
64
|
-
Overwrite a dependency string for Windoes PCBuild.
|
|
66
|
+
Overwrite a dependency string for Windows PCBuild.
|
|
65
67
|
|
|
66
68
|
:param source: Python's source directory
|
|
67
|
-
:type
|
|
69
|
+
:type source: str
|
|
68
70
|
:param old: Regular expression to search for
|
|
69
|
-
:type
|
|
71
|
+
:type old: str
|
|
70
72
|
:param new: Replacement text
|
|
71
|
-
:type
|
|
73
|
+
:type new: str
|
|
72
74
|
"""
|
|
73
75
|
patch_file(source / "PCbuild" / "python.props", old, new)
|
|
74
76
|
patch_file(source / "PCbuild" / "get_externals.bat", old, new)
|
|
75
77
|
|
|
76
78
|
|
|
77
|
-
def
|
|
79
|
+
def get_externals_source(externals_dir: pathlib.Path, url: str) -> None:
|
|
80
|
+
"""
|
|
81
|
+
Download external source code dependency.
|
|
82
|
+
|
|
83
|
+
Download source code and extract to the "externals" directory in the root of
|
|
84
|
+
the python source. Only works with a tarball
|
|
85
|
+
"""
|
|
86
|
+
zips_dir = externals_dir / "zips"
|
|
87
|
+
zips_dir.mkdir(parents=True, exist_ok=True)
|
|
88
|
+
local_file = download_url(url=url, dest=str(zips_dir))
|
|
89
|
+
extract_archive(archive=str(local_file), to_dir=str(externals_dir))
|
|
90
|
+
try:
|
|
91
|
+
os.remove(local_file)
|
|
92
|
+
except OSError:
|
|
93
|
+
log.exception("Failed to remove temporary file")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def get_externals_bin(source_root: pathlib.Path, url: str) -> None:
|
|
97
|
+
"""
|
|
98
|
+
Download external binary dependency.
|
|
99
|
+
|
|
100
|
+
Download binaries to the "externals" directory in the root of the python
|
|
101
|
+
source.
|
|
102
|
+
"""
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def update_sqlite(dirs: Dirs, env: EnvMapping) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Update the SQLITE library.
|
|
109
|
+
"""
|
|
110
|
+
# Try to get version from JSON
|
|
111
|
+
sqlite_info = get_dependency_version("sqlite", "win32")
|
|
112
|
+
if sqlite_info:
|
|
113
|
+
version = sqlite_info["version"]
|
|
114
|
+
url_template = sqlite_info["url"]
|
|
115
|
+
sha256 = sqlite_info["sha256"]
|
|
116
|
+
sqliteversion = sqlite_info.get("sqliteversion", "3500400")
|
|
117
|
+
# Format the URL with sqliteversion (the 7-digit version number)
|
|
118
|
+
url = url_template.format(version=sqliteversion)
|
|
119
|
+
else:
|
|
120
|
+
# Fallback to hardcoded values
|
|
121
|
+
version = "3.50.4.0"
|
|
122
|
+
url = "https://sqlite.org/2025/sqlite-autoconf-3500400.tar.gz"
|
|
123
|
+
sha256 = "a3db587a1b92ee5ddac2f66b3edb41b26f9c867275782d46c3a088977d6a5b18"
|
|
124
|
+
sqliteversion = "3500400"
|
|
125
|
+
ref_loc = f"cpe:2.3:a:sqlite:sqlite:{version}:*:*:*:*:*:*:*"
|
|
126
|
+
target_dir = dirs.source / "externals" / f"sqlite-{version}"
|
|
127
|
+
target_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
128
|
+
if not target_dir.exists():
|
|
129
|
+
update_props(dirs.source, r"sqlite-\d+.\d+.\d+.\d+", f"sqlite-{version}")
|
|
130
|
+
get_externals_source(externals_dir=dirs.source / "externals", url=url)
|
|
131
|
+
# # we need to fix the name of the extracted directory
|
|
132
|
+
extracted_dir = dirs.source / "externals" / f"sqlite-autoconf-{sqliteversion}"
|
|
133
|
+
shutil.move(str(extracted_dir), str(target_dir))
|
|
134
|
+
# Update externals.spdx.json with the correct version, url, and hash
|
|
135
|
+
# This became a thing in 3.12
|
|
136
|
+
if env["RELENV_PY_MAJOR_VERSION"] in ["3.12"]:
|
|
137
|
+
spdx_json = dirs.source / "Misc" / "externals.spdx.json"
|
|
138
|
+
with open(str(spdx_json), "r") as f:
|
|
139
|
+
data = json.load(f)
|
|
140
|
+
for pkg in data["packages"]:
|
|
141
|
+
if pkg["name"] == "sqlite":
|
|
142
|
+
pkg["versionInfo"] = version
|
|
143
|
+
pkg["downloadLocation"] = url
|
|
144
|
+
pkg["checksums"][0]["checksumValue"] = sha256
|
|
145
|
+
pkg["externalRefs"][0]["referenceLocator"] = ref_loc
|
|
146
|
+
with open(str(spdx_json), "w") as f:
|
|
147
|
+
json.dump(data, f, indent=2)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def update_xz(dirs: Dirs, env: EnvMapping) -> None:
|
|
151
|
+
"""
|
|
152
|
+
Update the XZ library.
|
|
153
|
+
|
|
154
|
+
COMPATIBILITY NOTE: We use config.h from XZ 5.4.7 for all XZ versions.
|
|
155
|
+
Starting with XZ 5.5.0, the project removed Visual Studio .vcxproj files
|
|
156
|
+
and switched to CMake. Python's build system (PCbuild/liblzma.vcxproj)
|
|
157
|
+
still expects MSBuild-compatible builds, so we maintain a compatibility
|
|
158
|
+
shim at relenv/_resources/xz/config.h.
|
|
159
|
+
|
|
160
|
+
When updating XZ versions, verify compatibility by checking:
|
|
161
|
+
1. Build completes without compiler errors
|
|
162
|
+
2. test_xz_lzma_functionality passes
|
|
163
|
+
3. No new HAVE_* defines required in src/liblzma source files
|
|
164
|
+
4. No removed HAVE_* defines that config.h references
|
|
165
|
+
|
|
166
|
+
If compatibility breaks, you have two options:
|
|
167
|
+
- Use CMake to generate new config.h for Windows (see discussion at
|
|
168
|
+
https://discuss.python.org/t/building-python-from-source-on-windows-using-a-custom-version-of-xz/74717)
|
|
169
|
+
- Update relenv/_resources/xz/config.h manually from newer XZ source
|
|
170
|
+
|
|
171
|
+
See also: relenv/_resources/xz/readme.md
|
|
172
|
+
"""
|
|
173
|
+
# Try to get version from JSON
|
|
174
|
+
# Note: Windows may use a different XZ version than Linux/Darwin due to MSBuild compatibility
|
|
175
|
+
xz_info = get_dependency_version("xz", "win32")
|
|
176
|
+
if xz_info:
|
|
177
|
+
version = xz_info["version"]
|
|
178
|
+
url_template = xz_info["url"]
|
|
179
|
+
sha256 = xz_info["sha256"]
|
|
180
|
+
url = url_template.format(version=version)
|
|
181
|
+
else:
|
|
182
|
+
# Fallback to hardcoded values
|
|
183
|
+
# Note: Using 5.6.2 for MSBuild compatibility (5.5.0+ removed MSBuild support)
|
|
184
|
+
version = "5.6.2"
|
|
185
|
+
url = f"https://github.com/tukaani-project/xz/releases/download/v{version}/xz-{version}.tar.xz"
|
|
186
|
+
sha256 = "8bfd20c0e1d86f0402f2497cfa71c6ab62d4cd35fd704276e3140bfb71414519"
|
|
187
|
+
ref_loc = f"cpe:2.3:a:tukaani:xz:{version}:*:*:*:*:*:*:*"
|
|
188
|
+
target_dir = dirs.source / "externals" / f"xz-{version}"
|
|
189
|
+
target_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
190
|
+
if not target_dir.exists():
|
|
191
|
+
update_props(dirs.source, r"xz-\d+.\d+.\d+", f"xz-{version}")
|
|
192
|
+
get_externals_source(externals_dir=dirs.source / "externals", url=url)
|
|
193
|
+
# Starting with version v5.5.0, XZ-Utils removed the ability to compile
|
|
194
|
+
# with MSBuild. We are bringing the config.h from the last version that
|
|
195
|
+
# had it, 5.4.7
|
|
196
|
+
config_file = target_dir / "src" / "common" / "config.h"
|
|
197
|
+
config_file_source = dirs.root / "_resources" / "xz" / "config.h"
|
|
198
|
+
if not config_file.exists():
|
|
199
|
+
shutil.copy(str(config_file_source), str(config_file))
|
|
200
|
+
# Update externals.spdx.json with the correct version, url, and hash
|
|
201
|
+
# This became a thing in 3.12
|
|
202
|
+
if env["RELENV_PY_MAJOR_VERSION"] in ["3.12", "3.13", "3.14"]:
|
|
203
|
+
spdx_json = dirs.source / "Misc" / "externals.spdx.json"
|
|
204
|
+
with open(str(spdx_json), "r") as f:
|
|
205
|
+
data = json.load(f)
|
|
206
|
+
for pkg in data["packages"]:
|
|
207
|
+
if pkg["name"] == "xz":
|
|
208
|
+
pkg["versionInfo"] = version
|
|
209
|
+
pkg["downloadLocation"] = url
|
|
210
|
+
pkg["checksums"][0]["checksumValue"] = sha256
|
|
211
|
+
pkg["externalRefs"][0]["referenceLocator"] = ref_loc
|
|
212
|
+
with open(str(spdx_json), "w") as f:
|
|
213
|
+
json.dump(data, f, indent=2)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def update_expat(dirs: Dirs, env: EnvMapping) -> None:
|
|
217
|
+
"""
|
|
218
|
+
Update the EXPAT library.
|
|
219
|
+
"""
|
|
220
|
+
# Patch <src>/Modules/expat/refresh.sh. When the SBOM is created, refresh.sh
|
|
221
|
+
# is scanned for the expat version, even though it doesn't run on Windows.
|
|
222
|
+
|
|
223
|
+
# Try to get version from JSON
|
|
224
|
+
expat_info = get_dependency_version("expat", "win32")
|
|
225
|
+
if expat_info:
|
|
226
|
+
version = expat_info["version"]
|
|
227
|
+
hash = expat_info["sha256"]
|
|
228
|
+
else:
|
|
229
|
+
# Fallback to hardcoded values
|
|
230
|
+
version = "2.7.3"
|
|
231
|
+
hash = "821ac9710d2c073eaf13e1b1895a9c9aa66c1157a99635c639fbff65cdbdd732"
|
|
232
|
+
|
|
233
|
+
url = f'https://github.com/libexpat/libexpat/releases/download/R_{version.replace(".", "_")}/expat-{version}.tar.xz'
|
|
234
|
+
bash_refresh = dirs.source / "Modules" / "expat" / "refresh.sh"
|
|
235
|
+
old = r'expected_libexpat_tag="R_\d+_\d+_\d"'
|
|
236
|
+
new = f'expected_libexpat_tag="R_{version.replace(".", "_")}"'
|
|
237
|
+
patch_file(bash_refresh, old=old, new=new)
|
|
238
|
+
old = r'expected_libexpat_version="\d+.\d+.\d"'
|
|
239
|
+
new = f'expected_libexpat_version="{version}"'
|
|
240
|
+
patch_file(bash_refresh, old=old, new=new)
|
|
241
|
+
old = 'expected_libexpat_sha256=".*"'
|
|
242
|
+
new = f'expected_libexpat_sha256="{hash}"'
|
|
243
|
+
patch_file(bash_refresh, old=old, new=new)
|
|
244
|
+
get_externals_source(externals_dir=dirs.source / "Modules" / "expat", url=url)
|
|
245
|
+
# Copy *.h and *.c to expat directory
|
|
246
|
+
expat_lib_dir = dirs.source / "Modules" / "expat" / f"expat-{version}" / "lib"
|
|
247
|
+
expat_dir = dirs.source / "Modules" / "expat"
|
|
248
|
+
updated_files = []
|
|
249
|
+
for file in glob.glob(str(expat_lib_dir / "*.h")):
|
|
250
|
+
target = expat_dir / os.path.basename(file)
|
|
251
|
+
if target.exists():
|
|
252
|
+
target.unlink()
|
|
253
|
+
shutil.move(file, str(expat_dir))
|
|
254
|
+
updated_files.append(target)
|
|
255
|
+
for file in glob.glob(str(expat_lib_dir / "*.c")):
|
|
256
|
+
target = expat_dir / os.path.basename(file)
|
|
257
|
+
if target.exists():
|
|
258
|
+
target.unlink()
|
|
259
|
+
shutil.move(file, str(expat_dir))
|
|
260
|
+
updated_files.append(target)
|
|
261
|
+
|
|
262
|
+
# Touch all updated files to ensure MSBuild rebuilds them
|
|
263
|
+
# (The original files may have newer timestamps)
|
|
264
|
+
now = time.time()
|
|
265
|
+
for target_file in updated_files:
|
|
266
|
+
os.utime(target_file, (now, now))
|
|
267
|
+
|
|
268
|
+
# Update SBOM with correct checksums for updated expat files
|
|
269
|
+
# Map SBOM file names to actual file paths
|
|
270
|
+
files_to_update = {}
|
|
271
|
+
for target_file in updated_files:
|
|
272
|
+
# SBOM uses relative paths from Python source root
|
|
273
|
+
relative_path = f"Modules/expat/{target_file.name}"
|
|
274
|
+
files_to_update[relative_path] = target_file
|
|
275
|
+
|
|
276
|
+
# Also include refresh.sh which was patched
|
|
277
|
+
bash_refresh = dirs.source / "Modules" / "expat" / "refresh.sh"
|
|
278
|
+
if bash_refresh.exists():
|
|
279
|
+
files_to_update["Modules/expat/refresh.sh"] = bash_refresh
|
|
280
|
+
|
|
281
|
+
update_sbom_checksums(dirs.source, files_to_update)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def build_python(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None:
|
|
78
285
|
"""
|
|
79
286
|
Run the commands to build Python.
|
|
80
287
|
|
|
@@ -86,12 +293,16 @@ def build_python(env, dirs, logfp):
|
|
|
86
293
|
:type logfp: file
|
|
87
294
|
"""
|
|
88
295
|
# Override default versions
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
296
|
+
|
|
297
|
+
# Create externals directory
|
|
298
|
+
externals_dir = dirs.source / "externals"
|
|
299
|
+
externals_dir.mkdir(parents=True, exist_ok=True)
|
|
300
|
+
|
|
301
|
+
update_sqlite(dirs=dirs, env=env)
|
|
302
|
+
|
|
303
|
+
update_xz(dirs=dirs, env=env)
|
|
304
|
+
|
|
305
|
+
update_expat(dirs=dirs, env=env)
|
|
95
306
|
|
|
96
307
|
arch_to_plat = {
|
|
97
308
|
"amd64": "x64",
|
|
@@ -106,6 +317,7 @@ def build_python(env, dirs, logfp):
|
|
|
106
317
|
plat,
|
|
107
318
|
"--no-tkinter",
|
|
108
319
|
]
|
|
320
|
+
|
|
109
321
|
log.info("Start PCbuild")
|
|
110
322
|
runcmd(cmd, env=env, stderr=logfp, stdout=logfp)
|
|
111
323
|
log.info("PCbuild finished")
|
|
@@ -189,7 +401,7 @@ build.add(
|
|
|
189
401
|
)
|
|
190
402
|
|
|
191
403
|
|
|
192
|
-
def finalize(env, dirs, logfp):
|
|
404
|
+
def finalize(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None:
|
|
193
405
|
"""
|
|
194
406
|
Finalize sitecustomize, relenv runtime, and pip for Windows.
|
|
195
407
|
|
|
@@ -202,14 +414,16 @@ def finalize(env, dirs, logfp):
|
|
|
202
414
|
"""
|
|
203
415
|
# Lay down site customize
|
|
204
416
|
sitepackages = dirs.prefix / "Lib" / "site-packages"
|
|
205
|
-
|
|
206
417
|
install_runtime(sitepackages)
|
|
207
418
|
|
|
419
|
+
# update ensurepip
|
|
420
|
+
update_ensurepip(dirs.prefix / "Lib")
|
|
421
|
+
|
|
208
422
|
# Install pip
|
|
209
423
|
python = dirs.prefix / "Scripts" / "python.exe"
|
|
210
424
|
runcmd([str(python), "-m", "ensurepip"], env=env, stderr=logfp, stdout=logfp)
|
|
211
425
|
|
|
212
|
-
def runpip(pkg):
|
|
426
|
+
def runpip(pkg: Union[str, os.PathLike[str]]) -> None:
|
|
213
427
|
# XXX Support cross pip installs on windows
|
|
214
428
|
env = os.environ.copy()
|
|
215
429
|
target = None
|
|
@@ -243,6 +457,7 @@ def finalize(env, dirs, logfp):
|
|
|
243
457
|
"*.pyd",
|
|
244
458
|
"*.dll",
|
|
245
459
|
"*.lib",
|
|
460
|
+
"*.whl",
|
|
246
461
|
"/Include/*",
|
|
247
462
|
"/Lib/site-packages/*",
|
|
248
463
|
]
|
relenv/buildenv.py
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2022-2025 Broadcom.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
"""
|
|
4
4
|
Helper for building libraries to install into a relenv environment.
|
|
5
5
|
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
6
9
|
import json
|
|
7
10
|
import logging
|
|
11
|
+
import os
|
|
8
12
|
import sys
|
|
13
|
+
from typing import Any, cast
|
|
9
14
|
|
|
10
15
|
from .common import (
|
|
11
16
|
MACOS_DEVELOPMENT_TARGET,
|
|
12
|
-
|
|
17
|
+
PlatformError,
|
|
18
|
+
RelenvEnvironmentError,
|
|
13
19
|
get_toolchain,
|
|
14
20
|
get_triplet,
|
|
15
21
|
)
|
|
@@ -17,7 +23,9 @@ from .common import (
|
|
|
17
23
|
log = logging.getLogger()
|
|
18
24
|
|
|
19
25
|
|
|
20
|
-
def setup_parser(
|
|
26
|
+
def setup_parser(
|
|
27
|
+
subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
28
|
+
) -> None:
|
|
21
29
|
"""
|
|
22
30
|
Setup the subparser for the ``relenv buildenv`` command.
|
|
23
31
|
|
|
@@ -36,30 +44,33 @@ def setup_parser(subparsers):
|
|
|
36
44
|
)
|
|
37
45
|
|
|
38
46
|
|
|
39
|
-
def is_relenv():
|
|
47
|
+
def is_relenv() -> bool:
|
|
40
48
|
"""
|
|
41
49
|
True when we are in a relenv environment.
|
|
42
50
|
"""
|
|
43
51
|
return hasattr(sys, "RELENV")
|
|
44
52
|
|
|
45
53
|
|
|
46
|
-
def buildenv(
|
|
54
|
+
def buildenv(
|
|
55
|
+
relenv_path: str | os.PathLike[str] | None = None,
|
|
56
|
+
) -> dict[str, str]:
|
|
47
57
|
"""
|
|
48
58
|
Relenv build environment variable mapping.
|
|
49
59
|
"""
|
|
50
60
|
if not relenv_path:
|
|
51
61
|
if not is_relenv():
|
|
52
|
-
raise
|
|
53
|
-
relenv_path = sys.RELENV
|
|
62
|
+
raise RelenvEnvironmentError("Not in a relenv environment")
|
|
63
|
+
relenv_path = cast(str | os.PathLike[str], cast(Any, sys).RELENV)
|
|
54
64
|
|
|
55
65
|
if sys.platform != "linux":
|
|
56
|
-
raise
|
|
66
|
+
raise PlatformError("buildenv is only supported on Linux")
|
|
57
67
|
|
|
58
68
|
toolchain = get_toolchain()
|
|
59
69
|
if not toolchain:
|
|
60
|
-
raise
|
|
70
|
+
raise PlatformError("buildenv is only supported on Linux")
|
|
61
71
|
|
|
62
72
|
triplet = get_triplet()
|
|
73
|
+
sysroot = f"{toolchain}/{triplet}/sysroot"
|
|
63
74
|
env = {
|
|
64
75
|
"RELENV_BUILDENV": "1",
|
|
65
76
|
"TOOLCHAIN_PATH": f"{toolchain}",
|
|
@@ -67,30 +78,50 @@ def buildenv(relenv_path=None):
|
|
|
67
78
|
"RELENV_PATH": f"{relenv_path}",
|
|
68
79
|
"CC": f"{toolchain}/bin/{triplet}-gcc",
|
|
69
80
|
"CXX": f"{toolchain}/bin/{triplet}-g++",
|
|
70
|
-
"CFLAGS":
|
|
81
|
+
"CFLAGS": (
|
|
82
|
+
f"--sysroot={sysroot} "
|
|
83
|
+
f"-fPIC "
|
|
84
|
+
f"-I{relenv_path}/include "
|
|
85
|
+
f"-I{sysroot}/usr/include"
|
|
86
|
+
),
|
|
71
87
|
"CXXFLAGS": (
|
|
88
|
+
f"--sysroot={sysroot} "
|
|
89
|
+
f"-fPIC "
|
|
72
90
|
f"-I{relenv_path}/include "
|
|
73
|
-
f"-I{
|
|
74
|
-
f"-L{relenv_path}/lib -L{
|
|
91
|
+
f"-I{sysroot}/usr/include "
|
|
92
|
+
f"-L{relenv_path}/lib -L{sysroot}/lib "
|
|
75
93
|
f"-Wl,-rpath,{relenv_path}/lib"
|
|
76
94
|
),
|
|
77
95
|
"CPPFLAGS": (
|
|
78
|
-
f"
|
|
96
|
+
f"--sysroot={sysroot} "
|
|
97
|
+
f"-fPIC "
|
|
98
|
+
f"-I{relenv_path}/include "
|
|
99
|
+
f"-I{sysroot}/usr/include"
|
|
79
100
|
),
|
|
80
101
|
"CMAKE_CFLAGS": (
|
|
81
|
-
f"
|
|
102
|
+
f"--sysroot={sysroot} "
|
|
103
|
+
f"-fPIC "
|
|
104
|
+
f"-I{relenv_path}/include "
|
|
105
|
+
f"-I{sysroot}/usr/include"
|
|
82
106
|
),
|
|
83
107
|
"LDFLAGS": (
|
|
84
|
-
f"
|
|
108
|
+
f"--sysroot={sysroot} "
|
|
109
|
+
f"-L{relenv_path}/lib -L{sysroot}/lib "
|
|
85
110
|
f"-Wl,-rpath,{relenv_path}/lib"
|
|
86
111
|
),
|
|
112
|
+
"CRATE_CC_NO_DEFAULTS": "1",
|
|
113
|
+
"OPENSSL_DIR": f"{relenv_path}",
|
|
114
|
+
"OPENSSL_INCLUDE_DIR": f"{relenv_path}/include",
|
|
115
|
+
"OPENSSL_LIB_DIR": f"{relenv_path}/lib",
|
|
116
|
+
"PKG_CONFIG_PATH": f"{relenv_path}/lib/pkgconfig",
|
|
117
|
+
"RUSTFLAGS": f"-L {relenv_path}/lib -C link-arg=-Wl,-rpath,{relenv_path}/lib",
|
|
87
118
|
}
|
|
88
|
-
if sys.platform == "
|
|
119
|
+
if sys.platform == "darwin":
|
|
89
120
|
env["MACOS_DEVELOPMENT_TARGET"] = MACOS_DEVELOPMENT_TARGET
|
|
90
121
|
return env
|
|
91
122
|
|
|
92
123
|
|
|
93
|
-
def main(args):
|
|
124
|
+
def main(args: argparse.Namespace) -> None:
|
|
94
125
|
"""
|
|
95
126
|
The entrypoint into the ``relenv buildenv`` command.
|
|
96
127
|
|
relenv/check.py
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
# Copyright 2025 Broadcom.
|
|
1
|
+
# Copyright 2022-2025 Broadcom.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
"""
|
|
4
4
|
Check the integrety of a relenv environment.
|
|
5
5
|
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
6
9
|
import logging
|
|
7
10
|
import pathlib
|
|
8
11
|
import sys
|
|
9
12
|
|
|
10
|
-
from
|
|
13
|
+
from relenv import relocate
|
|
11
14
|
|
|
12
|
-
log = logging.getLogger()
|
|
15
|
+
log: logging.Logger = logging.getLogger(__name__)
|
|
13
16
|
|
|
14
17
|
|
|
15
|
-
def setup_parser(
|
|
18
|
+
def setup_parser(
|
|
19
|
+
subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
20
|
+
) -> None:
|
|
16
21
|
"""
|
|
17
22
|
Setup the subparser for the ``relenv check`` command.
|
|
18
23
|
|
|
@@ -23,7 +28,7 @@ def setup_parser(subparsers):
|
|
|
23
28
|
subparser.set_defaults(func=main)
|
|
24
29
|
|
|
25
30
|
|
|
26
|
-
def main(args):
|
|
31
|
+
def main(args: argparse.Namespace) -> None:
|
|
27
32
|
"""
|
|
28
33
|
The entrypoint into the ``relenv check`` command.
|
|
29
34
|
|