devlab-fpga 0.1.0__tar.gz → 0.1.2__tar.gz
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.
- {devlab_fpga-0.1.0/devlab_fpga.egg-info → devlab_fpga-0.1.2}/PKG-INFO +19 -1
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/README.md +18 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/__init__.py +1 -2
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/cli.py +12 -2
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/toolchain.py +67 -22
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2/devlab_fpga.egg-info}/PKG-INFO +19 -1
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/pyproject.toml +1 -1
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/LICENSE +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/MANIFEST.in +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/__main__.py +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/errors.py +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/platforms.py +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab/project.py +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab_fpga.egg-info/SOURCES.txt +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab_fpga.egg-info/dependency_links.txt +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab_fpga.egg-info/entry_points.txt +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab_fpga.egg-info/requires.txt +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/devlab_fpga.egg-info/top_level.txt +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/setup.cfg +0 -0
- {devlab_fpga-0.1.0 → devlab_fpga-0.1.2}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devlab-fpga
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: FPGA development helper for installing OSS CAD Suite and running build/flash flows.
|
|
5
5
|
Author-email: Mrju10 <name@email.com>
|
|
6
6
|
License: MIT
|
|
@@ -64,6 +64,24 @@ YosysHQ. The installer selects the correct asset for:
|
|
|
64
64
|
The default install location is `~/.devlab`. Set `DEVLAB_HOME` to use a
|
|
65
65
|
different directory.
|
|
66
66
|
|
|
67
|
+
On Windows, OSS CAD Suite may be distributed as a 7-Zip self-extracting `.exe`
|
|
68
|
+
archive. `devlab install` extracts it automatically into `~/.devlab/toolchains`
|
|
69
|
+
without opening an installer:
|
|
70
|
+
|
|
71
|
+
```powershell
|
|
72
|
+
devlab install
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The installed tree keeps the official OSS CAD Suite layout:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
~/.devlab/toolchains/oss-cad-suite-2026-07-06-windows-x64/
|
|
79
|
+
oss-cad-suite/
|
|
80
|
+
bin/
|
|
81
|
+
environment.bat
|
|
82
|
+
environment.ps1
|
|
83
|
+
```
|
|
84
|
+
|
|
67
85
|
## OSS CAD Suite Source
|
|
68
86
|
|
|
69
87
|
Default release:
|
|
@@ -40,6 +40,24 @@ YosysHQ. The installer selects the correct asset for:
|
|
|
40
40
|
The default install location is `~/.devlab`. Set `DEVLAB_HOME` to use a
|
|
41
41
|
different directory.
|
|
42
42
|
|
|
43
|
+
On Windows, OSS CAD Suite may be distributed as a 7-Zip self-extracting `.exe`
|
|
44
|
+
archive. `devlab install` extracts it automatically into `~/.devlab/toolchains`
|
|
45
|
+
without opening an installer:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
devlab install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The installed tree keeps the official OSS CAD Suite layout:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
~/.devlab/toolchains/oss-cad-suite-2026-07-06-windows-x64/
|
|
55
|
+
oss-cad-suite/
|
|
56
|
+
bin/
|
|
57
|
+
environment.bat
|
|
58
|
+
environment.ps1
|
|
59
|
+
```
|
|
60
|
+
|
|
43
61
|
## OSS CAD Suite Source
|
|
44
62
|
|
|
45
63
|
Default release:
|
|
@@ -24,8 +24,13 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
24
24
|
description="Install FPGA toolchains and run local FPGA build flows.",
|
|
25
25
|
)
|
|
26
26
|
parser.add_argument("--version", action="version", version=f"devlab {__version__}")
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
"--run-installer",
|
|
29
|
+
action="store_true",
|
|
30
|
+
help="Deprecated compatibility flag. Windows install is automatic.",
|
|
31
|
+
)
|
|
27
32
|
|
|
28
|
-
commands = parser.add_subparsers(dest="command"
|
|
33
|
+
commands = parser.add_subparsers(dest="command")
|
|
29
34
|
|
|
30
35
|
doctor_parser = commands.add_parser("doctor", help="Check local FPGA tools.")
|
|
31
36
|
doctor_parser.add_argument(
|
|
@@ -40,7 +45,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
40
45
|
install_parser.add_argument(
|
|
41
46
|
"--run-installer",
|
|
42
47
|
action="store_true",
|
|
43
|
-
help="
|
|
48
|
+
help="Deprecated compatibility flag. Windows install is automatic.",
|
|
44
49
|
)
|
|
45
50
|
install_parser.set_defaults(func=_install)
|
|
46
51
|
|
|
@@ -105,6 +110,11 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
105
110
|
parser = build_parser()
|
|
106
111
|
args = parser.parse_args(argv)
|
|
107
112
|
try:
|
|
113
|
+
if args.command is None:
|
|
114
|
+
if args.run_installer:
|
|
115
|
+
args.force = False
|
|
116
|
+
return _install(args)
|
|
117
|
+
parser.error("the following arguments are required: command")
|
|
108
118
|
return args.func(args)
|
|
109
119
|
except DevlabError as exc:
|
|
110
120
|
parser.exit(2, f"devlab: error: {exc}\n")
|
|
@@ -9,6 +9,7 @@ import sys
|
|
|
9
9
|
import tarfile
|
|
10
10
|
import tempfile
|
|
11
11
|
import urllib.request
|
|
12
|
+
import zipfile
|
|
12
13
|
from dataclasses import dataclass
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
|
|
@@ -104,13 +105,18 @@ def archive_path(asset: ToolchainAsset | None = None, home: Path | None = None)
|
|
|
104
105
|
|
|
105
106
|
def bin_dir(path: Path | None = None) -> Path:
|
|
106
107
|
path = path or install_path()
|
|
107
|
-
return path / "bin"
|
|
108
|
+
return path / "oss-cad-suite" / "bin"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def bin_dirs(path: Path | None = None) -> list[Path]:
|
|
112
|
+
path = path or install_path()
|
|
113
|
+
return [path / "oss-cad-suite" / "bin", path / "bin"]
|
|
108
114
|
|
|
109
115
|
|
|
110
116
|
def env_with_toolchain(path: Path | None = None) -> dict[str, str]:
|
|
111
117
|
env = os.environ.copy()
|
|
112
|
-
|
|
113
|
-
env["PATH"] =
|
|
118
|
+
binary_dirs = os.pathsep.join(str(candidate) for candidate in bin_dirs(path))
|
|
119
|
+
env["PATH"] = binary_dirs + os.pathsep + env.get("PATH", "")
|
|
114
120
|
return env
|
|
115
121
|
|
|
116
122
|
|
|
@@ -120,9 +126,9 @@ def find_executable(name: str, path: Path | None = None) -> str | None:
|
|
|
120
126
|
suffixes = [".exe", ".bat", ".cmd", ""]
|
|
121
127
|
|
|
122
128
|
candidates: list[str] = []
|
|
123
|
-
binary_dir
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
for binary_dir in bin_dirs(path):
|
|
130
|
+
for suffix in suffixes:
|
|
131
|
+
candidates.append(str(binary_dir / f"{name}{suffix}"))
|
|
126
132
|
|
|
127
133
|
for candidate in candidates:
|
|
128
134
|
if Path(candidate).exists():
|
|
@@ -179,45 +185,75 @@ def install_oss_cad_suite(
|
|
|
179
185
|
asset = select_asset()
|
|
180
186
|
destination = install_path(asset, home)
|
|
181
187
|
|
|
182
|
-
if destination.exists() and not force:
|
|
188
|
+
if destination.exists() and find_executable("yosys", destination) and not force:
|
|
183
189
|
return destination
|
|
184
190
|
|
|
185
191
|
archive = download_asset(asset, archive_path(asset, home), force=force)
|
|
186
192
|
|
|
187
193
|
if asset.name.endswith(".exe"):
|
|
188
|
-
|
|
194
|
+
_extract_windows_sfx(archive, destination, force=force)
|
|
195
|
+
if not find_executable("yosys", destination):
|
|
189
196
|
raise DevlabError(
|
|
190
|
-
"Windows
|
|
191
|
-
|
|
192
|
-
"
|
|
197
|
+
"The Windows OSS CAD Suite archive was extracted, "
|
|
198
|
+
"but yosys was not found in "
|
|
199
|
+
f"{destination}\\oss-cad-suite\\bin or {destination}\\bin. "
|
|
200
|
+
"Check the extracted files, then run `devlab doctor`."
|
|
193
201
|
)
|
|
194
|
-
|
|
202
|
+
return destination
|
|
203
|
+
|
|
204
|
+
if asset.name.endswith(".zip"):
|
|
205
|
+
_extract_zip(archive, destination, force=force)
|
|
195
206
|
return destination
|
|
196
207
|
|
|
197
208
|
_extract_tarball(archive, destination, force=force)
|
|
198
|
-
|
|
209
|
+
for binary_dir in bin_dirs(destination):
|
|
210
|
+
_mark_executables(binary_dir)
|
|
199
211
|
return destination
|
|
200
212
|
|
|
201
213
|
|
|
202
|
-
def
|
|
214
|
+
def _move_extracted_tree(source: Path, destination: Path, force: bool) -> None:
|
|
203
215
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
204
216
|
if destination.exists():
|
|
205
|
-
if not force:
|
|
217
|
+
if not force and find_executable("yosys", destination):
|
|
206
218
|
raise DevlabError(f"Install destination already exists: {destination}")
|
|
207
219
|
shutil.rmtree(destination)
|
|
208
220
|
|
|
221
|
+
destination.mkdir(parents=True)
|
|
222
|
+
for child in source.iterdir():
|
|
223
|
+
shutil.move(str(child), destination / child.name)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _extract_windows_sfx(archive: Path, destination: Path, force: bool) -> None:
|
|
227
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
228
|
+
with tempfile.TemporaryDirectory(
|
|
229
|
+
prefix="devlab-oss-cad-suite-", dir=destination.parent
|
|
230
|
+
) as tmp:
|
|
231
|
+
tmp_path = Path(tmp)
|
|
232
|
+
try:
|
|
233
|
+
subprocess.check_call([str(archive), f"-o{tmp_path}", "-y"], cwd=tmp_path)
|
|
234
|
+
except subprocess.CalledProcessError as exc:
|
|
235
|
+
raise DevlabError(
|
|
236
|
+
f"Could not extract Windows OSS CAD Suite archive: {exc}"
|
|
237
|
+
) from exc
|
|
238
|
+
_move_extracted_tree(tmp_path, destination, force=force)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _extract_zip(archive: Path, destination: Path, force: bool) -> None:
|
|
242
|
+
with tempfile.TemporaryDirectory(prefix="devlab-oss-cad-suite-") as tmp:
|
|
243
|
+
tmp_path = Path(tmp)
|
|
244
|
+
with zipfile.ZipFile(archive) as zip_file:
|
|
245
|
+
_safe_extract_zip(zip_file, tmp_path)
|
|
246
|
+
|
|
247
|
+
_move_extracted_tree(tmp_path, destination, force=force)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _extract_tarball(archive: Path, destination: Path, force: bool) -> None:
|
|
209
251
|
with tempfile.TemporaryDirectory(prefix="devlab-oss-cad-suite-") as tmp:
|
|
210
252
|
tmp_path = Path(tmp)
|
|
211
253
|
with tarfile.open(archive, "r:gz") as tar:
|
|
212
254
|
_safe_extract(tar, tmp_path)
|
|
213
255
|
|
|
214
|
-
|
|
215
|
-
if len(children) == 1 and children[0].is_dir():
|
|
216
|
-
shutil.move(str(children[0]), destination)
|
|
217
|
-
else:
|
|
218
|
-
destination.mkdir(parents=True)
|
|
219
|
-
for child in children:
|
|
220
|
-
shutil.move(str(child), destination / child.name)
|
|
256
|
+
_move_extracted_tree(tmp_path, destination, force=force)
|
|
221
257
|
|
|
222
258
|
|
|
223
259
|
def _safe_extract(tar: tarfile.TarFile, destination: Path) -> None:
|
|
@@ -232,6 +268,15 @@ def _safe_extract(tar: tarfile.TarFile, destination: Path) -> None:
|
|
|
232
268
|
tar.extractall(destination)
|
|
233
269
|
|
|
234
270
|
|
|
271
|
+
def _safe_extract_zip(zip_file: zipfile.ZipFile, destination: Path) -> None:
|
|
272
|
+
destination = destination.resolve()
|
|
273
|
+
for member in zip_file.infolist():
|
|
274
|
+
target = (destination / member.filename).resolve()
|
|
275
|
+
if destination != target and destination not in target.parents:
|
|
276
|
+
raise DevlabError(f"Unsafe path in archive: {member.filename}")
|
|
277
|
+
zip_file.extractall(destination)
|
|
278
|
+
|
|
279
|
+
|
|
235
280
|
def _mark_executables(path: Path) -> None:
|
|
236
281
|
if not path.exists():
|
|
237
282
|
return
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devlab-fpga
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: FPGA development helper for installing OSS CAD Suite and running build/flash flows.
|
|
5
5
|
Author-email: Mrju10 <name@email.com>
|
|
6
6
|
License: MIT
|
|
@@ -64,6 +64,24 @@ YosysHQ. The installer selects the correct asset for:
|
|
|
64
64
|
The default install location is `~/.devlab`. Set `DEVLAB_HOME` to use a
|
|
65
65
|
different directory.
|
|
66
66
|
|
|
67
|
+
On Windows, OSS CAD Suite may be distributed as a 7-Zip self-extracting `.exe`
|
|
68
|
+
archive. `devlab install` extracts it automatically into `~/.devlab/toolchains`
|
|
69
|
+
without opening an installer:
|
|
70
|
+
|
|
71
|
+
```powershell
|
|
72
|
+
devlab install
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The installed tree keeps the official OSS CAD Suite layout:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
~/.devlab/toolchains/oss-cad-suite-2026-07-06-windows-x64/
|
|
79
|
+
oss-cad-suite/
|
|
80
|
+
bin/
|
|
81
|
+
environment.bat
|
|
82
|
+
environment.ps1
|
|
83
|
+
```
|
|
84
|
+
|
|
67
85
|
## OSS CAD Suite Source
|
|
68
86
|
|
|
69
87
|
Default release:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "devlab-fpga"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "FPGA development helper for installing OSS CAD Suite and running build/flash flows."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|