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.
Files changed (49) hide show
  1. relenv/__init__.py +14 -2
  2. relenv/__main__.py +12 -6
  3. relenv/_resources/xz/config.h +148 -0
  4. relenv/_resources/xz/readme.md +4 -0
  5. relenv/build/__init__.py +28 -30
  6. relenv/build/common/__init__.py +50 -0
  7. relenv/build/common/_sysconfigdata_template.py +72 -0
  8. relenv/build/common/builder.py +907 -0
  9. relenv/build/common/builders.py +163 -0
  10. relenv/build/common/download.py +324 -0
  11. relenv/build/common/install.py +609 -0
  12. relenv/build/common/ui.py +432 -0
  13. relenv/build/darwin.py +128 -14
  14. relenv/build/linux.py +296 -78
  15. relenv/build/windows.py +259 -44
  16. relenv/buildenv.py +48 -17
  17. relenv/check.py +10 -5
  18. relenv/common.py +499 -163
  19. relenv/create.py +147 -7
  20. relenv/fetch.py +16 -4
  21. relenv/manifest.py +15 -7
  22. relenv/python-versions.json +329 -0
  23. relenv/pyversions.py +817 -30
  24. relenv/relocate.py +101 -55
  25. relenv/runtime.py +452 -253
  26. relenv/toolchain.py +9 -3
  27. {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/METADATA +1 -1
  28. relenv-0.22.0.dist-info/RECORD +48 -0
  29. tests/__init__.py +2 -0
  30. tests/_pytest_typing.py +45 -0
  31. tests/conftest.py +42 -36
  32. tests/test_build.py +426 -9
  33. tests/test_common.py +311 -48
  34. tests/test_create.py +149 -6
  35. tests/test_downloads.py +19 -15
  36. tests/test_fips_photon.py +6 -3
  37. tests/test_module_imports.py +44 -0
  38. tests/test_pyversions_runtime.py +177 -0
  39. tests/test_relocate.py +45 -39
  40. tests/test_relocate_module.py +257 -0
  41. tests/test_runtime.py +1802 -6
  42. tests/test_verify_build.py +500 -34
  43. relenv/build/common.py +0 -1609
  44. relenv-0.21.1.dist-info/RECORD +0 -35
  45. {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/WHEEL +0 -0
  46. {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/entry_points.txt +0 -0
  47. {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/licenses/LICENSE.md +0 -0
  48. {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/licenses/NOTICE +0 -0
  49. {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 shutil
8
- import sys
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 logging
13
- from .common import runcmd, create_archive, MODULE_DIR, builds, install_runtime
14
- from ..common import arches, WIN32
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 patch_file(path, old, new):
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
- import re
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 path: str
69
+ :type source: str
68
70
  :param old: Regular expression to search for
69
- :type path: str
71
+ :type old: str
70
72
  :param new: Replacement text
71
- :type path: str
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 build_python(env, dirs, logfp):
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
- if env["RELENV_PY_MAJOR_VERSION"] in [
90
- "3.10",
91
- "3.11",
92
- ]:
93
- override_dependency(dirs.source, r"sqlite-\d+.\d+.\d+.\d+", "sqlite-3.50.4.0")
94
- override_dependency(dirs.source, r"xz-\d+.\d+.\d+", "xz-5.6.2")
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 2023-2025 Broadcom.
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
- RelenvException,
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(subparsers):
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(relenv_path=None):
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 RelenvException("Not in a relenv environment")
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 RelenvException("buildenv is only supported on Linux")
66
+ raise PlatformError("buildenv is only supported on Linux")
57
67
 
58
68
  toolchain = get_toolchain()
59
69
  if not toolchain:
60
- raise RelenvException("buildenv is only supported on Linux")
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": f"-I{relenv_path}/include -I{toolchain}/sysroot/usr/include",
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{toolchain}/{triplet}/sysroot/usr/include "
74
- f"-L{relenv_path}/lib -L{toolchain}/{triplet}/sysroot/lib "
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"-I{relenv_path}/include " f"-I{toolchain}/{triplet}/sysroot/usr/include"
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"-I{relenv_path}/include " f"-I{toolchain}/{triplet}/sysroot/usr/include"
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"-L{relenv_path}/lib -L{toolchain}/{triplet}/sysroot/lib "
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 == "dawin":
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 . import relocate
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(subparsers):
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