Compare commits
2 Commits
1d7bc19965
...
7b6f9ef224
Author | SHA1 | Date | |
---|---|---|---|
7b6f9ef224
|
|||
6ca389d5cb
|
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hdlbuild"
|
name = "hdlbuild"
|
||||||
version = "0.5.3"
|
version = "0.6.0"
|
||||||
description = "Flexible FPGA Build System"
|
description = "Flexible FPGA Build System"
|
||||||
authors = ["0xMax42 <Mail@0xMax42.io>"]
|
authors = ["0xMax42 <Mail@0xMax42.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -19,6 +19,7 @@ pyyaml = "^6.0.2"
|
|||||||
pydantic = "^2.11.3"
|
pydantic = "^2.11.3"
|
||||||
rich = "^14.0.0"
|
rich = "^14.0.0"
|
||||||
gitpython = "^3.1.44"
|
gitpython = "^3.1.44"
|
||||||
|
typer = "^0.16.0"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
twine = "^6.1.0"
|
twine = "^6.1.0"
|
||||||
|
@@ -1,32 +1,32 @@
|
|||||||
import argparse
|
import typer
|
||||||
from importlib.metadata import version, PackageNotFoundError
|
from importlib.metadata import version, PackageNotFoundError
|
||||||
from hdlbuild.commands import register_commands
|
|
||||||
|
|
||||||
def get_version():
|
from hdlbuild.commands.build import cli as build_cli
|
||||||
|
from hdlbuild.commands.clean import cli as clean_cli
|
||||||
|
from hdlbuild.commands.dep import cli as dep_cli
|
||||||
|
from hdlbuild.commands.test import cli as test_cli
|
||||||
|
from hdlbuild.commands.init import cli as init_cli
|
||||||
|
|
||||||
|
def get_version() -> str:
|
||||||
try:
|
try:
|
||||||
return version("hdlbuild") # Paketname aus pyproject.toml
|
return version("hdlbuild")
|
||||||
except PackageNotFoundError:
|
except PackageNotFoundError:
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
|
app = typer.Typer(
|
||||||
|
rich_help_panel="ℹ️ HDLBuild – FPGA‑Build‑Tool",
|
||||||
|
help=f"hdlbuild v{get_version()} – Build‑Management for FPGA projects"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Unter‑Kommandos registrieren (entspricht add_subparsers)
|
||||||
|
app.add_typer(build_cli, name="build", help="Build the project")
|
||||||
|
app.add_typer(clean_cli, name="clean", help="Clean build artifacts")
|
||||||
|
app.add_typer(dep_cli, name="dep", help="Resolve dependencies")
|
||||||
|
app.add_typer(test_cli, name="test", help="Run simulations/testbenches")
|
||||||
|
app.add_typer(init_cli, name="init", help="Initialize project")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
version_str = get_version()
|
app()
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=f"hdlbuild v{version_str} - Build management tool for FPGA projects",
|
|
||||||
formatter_class=argparse.RawTextHelpFormatter
|
|
||||||
)
|
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(
|
|
||||||
title="Commands",
|
|
||||||
description="Available commands",
|
|
||||||
dest="command",
|
|
||||||
required=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# Register all commands
|
|
||||||
register_commands(subparsers)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
args.func(args)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
@@ -1 +0,0 @@
|
|||||||
from .commands import register_commands
|
|
@@ -1,30 +1,34 @@
|
|||||||
from hdlbuild.tools.xilinx_ise.main import xilinx_ise_all, xilinx_ise_synth
|
import typer
|
||||||
from hdlbuild.utils.console_utils import ConsoleUtils
|
|
||||||
from hdlbuild.utils.directory_manager import ensure_directories_exist
|
|
||||||
from hdlbuild.utils.project_loader import load_project_config
|
|
||||||
|
|
||||||
class BuildCommand:
|
from hdlbuild.tools.xilinx_ise.main import xilinx_ise_all, xilinx_ise_synth
|
||||||
def __init__(self):
|
from hdlbuild.utils.console_utils import ConsoleUtils
|
||||||
self.console_utils = ConsoleUtils("hdlbuild")
|
from hdlbuild.utils.directory_manager import ensure_directories_exist
|
||||||
|
from hdlbuild.utils.project_loader import load_project_config
|
||||||
|
|
||||||
def register(self, subparsers):
|
cli = typer.Typer(rich_help_panel="🔨 Build Commands")
|
||||||
parser = subparsers.add_parser("build", help="Start the build process")
|
|
||||||
parser.add_argument(
|
|
||||||
"target",
|
|
||||||
nargs="?",
|
|
||||||
choices=["synth"],
|
|
||||||
help="Specify 'synth' to only synthesize the design (optional)"
|
|
||||||
)
|
|
||||||
parser.set_defaults(func=self.execute)
|
|
||||||
|
|
||||||
def execute(self, args):
|
@cli.callback(invoke_without_command=True)
|
||||||
"""Starts the build process."""
|
def build(
|
||||||
self.project = load_project_config()
|
target: str = typer.Argument(
|
||||||
if args.target == "synth":
|
None,
|
||||||
self.console_utils.print("Starting synth process...")
|
help="Optional: 'synth' to run synthesis only",
|
||||||
ensure_directories_exist(True)
|
show_default=False,
|
||||||
xilinx_ise_synth(self.project)
|
rich_help_panel="🔨 Build Commands",
|
||||||
else:
|
)
|
||||||
self.console_utils.print("Starting build process...")
|
) -> None:
|
||||||
ensure_directories_exist(True)
|
"""
|
||||||
xilinx_ise_all(self.project)
|
Run the full build flow or synthesis only.
|
||||||
|
|
||||||
|
* `hdlbuild build` → full flow
|
||||||
|
* `hdlbuild build synth` → synthesis only
|
||||||
|
"""
|
||||||
|
console = ConsoleUtils("hdlbuild")
|
||||||
|
project = load_project_config()
|
||||||
|
|
||||||
|
ensure_directories_exist(True)
|
||||||
|
if target == "synth":
|
||||||
|
console.print("Starting synthesis …")
|
||||||
|
xilinx_ise_synth(project)
|
||||||
|
else:
|
||||||
|
console.print("Starting full build …")
|
||||||
|
xilinx_ise_all(project)
|
||||||
|
@@ -1,27 +1,35 @@
|
|||||||
from hdlbuild.utils.console_utils import ConsoleUtils
|
import typer
|
||||||
from hdlbuild.utils.directory_manager import clear_build_directories, clear_directories
|
|
||||||
|
|
||||||
class CleanCommand:
|
from hdlbuild.utils.console_utils import ConsoleUtils
|
||||||
def __init__(self):
|
from hdlbuild.utils.directory_manager import clear_build_directories, clear_directories
|
||||||
self.console_utils = ConsoleUtils("hdlbuild")
|
|
||||||
|
|
||||||
def register(self, subparsers):
|
cli = typer.Typer(rich_help_panel="🧹 Clean Commands")
|
||||||
parser = subparsers.add_parser("clean", help="Clean build artifacts")
|
|
||||||
parser.add_argument(
|
|
||||||
"target",
|
|
||||||
nargs="?",
|
|
||||||
choices=["all"],
|
|
||||||
help="Specify 'all' to clean everything (optional)"
|
|
||||||
)
|
|
||||||
parser.set_defaults(func=self.execute)
|
|
||||||
|
|
||||||
def execute(self, args):
|
@cli.callback(invoke_without_command=True)
|
||||||
"""Cleans the build artifacts."""
|
def clean(
|
||||||
if args.target == "all":
|
target: str = typer.Argument(
|
||||||
self.console_utils.print("Starting clean all process...")
|
None,
|
||||||
clear_directories()
|
help="Optional: 'all' → wipe *all* artefacts, otherwise only the build directory",
|
||||||
self.console_utils.print("All cleaned.")
|
show_default=False,
|
||||||
else:
|
)
|
||||||
self.console_utils.print("Clearing build artifacts...")
|
) -> None:
|
||||||
clear_build_directories()
|
"""
|
||||||
self.console_utils.print("Build artifacts cleaned.")
|
Remove build artefacts (`build/*`) or *everything* (`all`).
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
```bash
|
||||||
|
hdlbuild clean # build/* and temporary files only
|
||||||
|
hdlbuild clean all # also caches, logs, etc.
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
console = ConsoleUtils("hdlbuild")
|
||||||
|
|
||||||
|
if target == "all":
|
||||||
|
console.print("Starting clean‑all …")
|
||||||
|
clear_directories()
|
||||||
|
console.print("All artefacts removed.")
|
||||||
|
else:
|
||||||
|
console.print("Removing build artefacts …")
|
||||||
|
clear_build_directories()
|
||||||
|
console.print("Build artefacts removed.")
|
||||||
|
@@ -1,19 +0,0 @@
|
|||||||
from hdlbuild.commands.build import BuildCommand
|
|
||||||
from hdlbuild.commands.clean import CleanCommand
|
|
||||||
from hdlbuild.commands.dep import DepCommand
|
|
||||||
from hdlbuild.commands.init import InitCommand
|
|
||||||
from hdlbuild.commands.test import TestCommand
|
|
||||||
|
|
||||||
|
|
||||||
def register_commands(subparsers):
|
|
||||||
"""Registers all available commands."""
|
|
||||||
commands = [
|
|
||||||
CleanCommand(),
|
|
||||||
BuildCommand(),
|
|
||||||
DepCommand(),
|
|
||||||
TestCommand(),
|
|
||||||
InitCommand(),
|
|
||||||
]
|
|
||||||
|
|
||||||
for command in commands:
|
|
||||||
command.register(subparsers)
|
|
@@ -1,17 +1,23 @@
|
|||||||
from hdlbuild.dependencies.resolver import DependencyResolver
|
import typer
|
||||||
from hdlbuild.utils.console_utils import ConsoleUtils
|
|
||||||
from hdlbuild.utils.project_loader import load_project_config
|
|
||||||
|
|
||||||
class DepCommand:
|
from hdlbuild.dependencies.resolver import DependencyResolver
|
||||||
def __init__(self):
|
from hdlbuild.utils.console_utils import ConsoleUtils
|
||||||
self.console_utils = ConsoleUtils("hdlbuild")
|
from hdlbuild.utils.project_loader import load_project_config
|
||||||
|
|
||||||
def register(self, subparsers):
|
cli = typer.Typer(rich_help_panel="🔗 Dependency Commands")
|
||||||
parser = subparsers.add_parser("dep", help="Start the dependencies process")
|
|
||||||
parser.set_defaults(func=self.execute)
|
|
||||||
|
|
||||||
def execute(self, args):
|
@cli.callback(invoke_without_command=True)
|
||||||
"""Starts the dependencies process."""
|
def dep() -> None:
|
||||||
self.project = load_project_config()
|
"""
|
||||||
self.console_utils.print("Starting dependencies process...")
|
Resolve all project dependencies.
|
||||||
DependencyResolver(self.project).resolve_all()
|
|
||||||
|
```bash
|
||||||
|
hdlbuild dep
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
console = ConsoleUtils("hdlbuild")
|
||||||
|
project = load_project_config()
|
||||||
|
|
||||||
|
console.print("Resolving dependencies …")
|
||||||
|
DependencyResolver(project).resolve_all()
|
||||||
|
console.print("Dependencies resolved.")
|
||||||
|
@@ -1,36 +1,35 @@
|
|||||||
from pathlib import Path
|
|
||||||
import shutil
|
import shutil
|
||||||
from hdlbuild.dependencies.resolver import DependencyResolver
|
from pathlib import Path
|
||||||
|
import typer
|
||||||
|
|
||||||
from hdlbuild.utils.console_utils import ConsoleUtils
|
from hdlbuild.utils.console_utils import ConsoleUtils
|
||||||
|
|
||||||
class InitCommand:
|
cli = typer.Typer(rich_help_panel="🆕 Init Commands")
|
||||||
def __init__(self):
|
|
||||||
self.console_utils = ConsoleUtils("hdlbuild")
|
|
||||||
|
|
||||||
def register(self, subparsers):
|
@cli.callback(invoke_without_command=True)
|
||||||
parser = subparsers.add_parser("init", help="Initialize a new HDLBuild project")
|
def init() -> None:
|
||||||
parser.set_defaults(func=self.execute)
|
"""
|
||||||
|
Initialise a new HDLBuild project in the current directory.
|
||||||
|
|
||||||
def execute(self, args):
|
Copies `.gitignore` and `project.yml` from the template folder.
|
||||||
"""Initialize a new HDLBuild project."""
|
"""
|
||||||
project_dir = Path.cwd()
|
console = ConsoleUtils("hdlbuild")
|
||||||
|
project_dir = Path.cwd()
|
||||||
|
|
||||||
# Correctly resolve path to templates directory
|
script_dir = Path(__file__).parent.resolve()
|
||||||
script_dir = Path(__file__).parent.resolve()
|
template_dir = (script_dir / ".." / "templates").resolve()
|
||||||
template_dir = (script_dir / ".." / "templates").resolve()
|
|
||||||
|
|
||||||
# Files to copy
|
files = [
|
||||||
files = [
|
("gitignore.template", ".gitignore"),
|
||||||
("gitignore.template", ".gitignore"),
|
("project.yml.template", "project.yml"),
|
||||||
("project.yml.template", "project.yml"),
|
]
|
||||||
]
|
|
||||||
|
|
||||||
for template_name, target_name in files:
|
for template_name, target_name in files:
|
||||||
template_path = template_dir / template_name
|
template_path = template_dir / template_name
|
||||||
target_path = project_dir / target_name
|
target_path = project_dir / target_name
|
||||||
|
|
||||||
if not target_path.exists():
|
if not target_path.exists():
|
||||||
shutil.copy(template_path, target_path)
|
shutil.copy(template_path, target_path)
|
||||||
self.console_utils.print(f"Created {target_name}")
|
console.print(f"Created {target_name}")
|
||||||
else:
|
else:
|
||||||
self.console_utils.print(f"{target_name} already exists, skipping.")
|
console.print(f"{target_name} already exists – skipping.")
|
||||||
|
@@ -1,23 +1,31 @@
|
|||||||
from hdlbuild.tools.xilinx_ise.isim import build_testbench, run_testbench
|
import typer
|
||||||
from hdlbuild.utils.console_utils import ConsoleUtils
|
|
||||||
from hdlbuild.utils.project_loader import load_project_config
|
|
||||||
|
|
||||||
class TestCommand:
|
from hdlbuild.tools.xilinx_ise.isim import build_testbench, run_testbench
|
||||||
def __init__(self):
|
from hdlbuild.utils.console_utils import ConsoleUtils
|
||||||
self.console_utils = ConsoleUtils("hdlbuild")
|
from hdlbuild.utils.project_loader import load_project_config
|
||||||
|
|
||||||
def register(self, subparsers):
|
cli = typer.Typer(rich_help_panel="🧪 Test Commands")
|
||||||
parser = subparsers.add_parser("test", help="Start the Tests process")
|
|
||||||
parser.add_argument(
|
|
||||||
"target",
|
|
||||||
nargs="?",
|
|
||||||
help="Select the target to test"
|
|
||||||
)
|
|
||||||
parser.set_defaults(func=self.execute)
|
|
||||||
|
|
||||||
def execute(self, args):
|
@cli.callback(invoke_without_command=True)
|
||||||
"""Starts the test process."""
|
def test(
|
||||||
self.project = load_project_config()
|
target: str = typer.Argument(
|
||||||
self.console_utils.print("Starting test process...")
|
None,
|
||||||
build_testbench(self.project, args.target)
|
help="Name of the test target (leave empty to run all)",
|
||||||
run_testbench(self.project, args.target)
|
show_default=False,
|
||||||
|
)
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Build and run testbenches.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hdlbuild test # run all TBs
|
||||||
|
hdlbuild test alu # run TB 'alu' only
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
console = ConsoleUtils("hdlbuild")
|
||||||
|
project = load_project_config()
|
||||||
|
|
||||||
|
console.print("Starting test flow …")
|
||||||
|
build_testbench(project, target)
|
||||||
|
run_testbench(project, target)
|
||||||
|
console.print("Tests finished.")
|
||||||
|
Reference in New Issue
Block a user