diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c291ee6..8d6acb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,6 +84,13 @@ jobs: --install-dir "$PWD/.pycircuit_out/toolchain/install" \ --out-dir "$PWD/dist" + - name: Check wheel tag + shell: bash + run: | + set -euxo pipefail + wheel="$(basename dist/*.whl)" + [[ "${wheel}" == pycircuit_hisi-*-py3-none-*.whl ]] + - name: Run examples run: | export PYC_TOOLCHAIN_ROOT="$PWD/.pycircuit_out/toolchain/install" @@ -178,6 +185,13 @@ jobs: --install-dir "$PWD/.pycircuit_out/toolchain/install" \ --out-dir "$PWD/dist" + - name: Check wheel tag + shell: bash + run: | + set -euxo pipefail + wheel="$(basename dist/*.whl)" + [[ "${wheel}" == pycircuit_hisi-*-py3-none-*.whl ]] + - name: Run example compile gate run: | export PYC_TOOLCHAIN_ROOT="$PWD/.pycircuit_out/toolchain/install" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 46fbfe0..31a3344 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,7 @@ on: permissions: contents: write packages: write + id-token: write jobs: build-packages: @@ -103,6 +104,12 @@ jobs: dist/*.tar.gz dist/*.whl + - name: Check wheel metadata + run: | + set -euxo pipefail + python3 -m pip install twine + python3 -m twine check dist/*.whl + github-packages: needs: [build-packages] runs-on: ubuntu-latest @@ -156,3 +163,22 @@ jobs: files: | dist/*.tar.gz dist/*.whl + + pypi-publish: + needs: [build-packages] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') && vars.PYC_PUBLISH_PYPI == '1' + environment: + name: pypi + steps: + - name: Download wheel artifacts + uses: actions/download-artifact@v4 + with: + path: dist + merge-multiple: true + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + skip-existing: true diff --git a/README.md b/README.md index d96e274..4b976b0 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,12 @@

License - Python + Python MLIR CI + Release + Latest Release + PyPI Package

pyCircuit is a Python-based hardware construction DSL that compiles Python @@ -37,13 +40,35 @@ The staged toolchain is installed under `.pycircuit_out/toolchain/install/` by d Install a release wheel instead of building locally: ```bash -python3 -m pip install pycircuit--.whl +python3 -m pip install /path/to/pycircuit_hisi--py3-none-.whl pycc --version ``` The platform wheel bundles the matching `pycc` toolchain under the `pycircuit` package, so `pycircuit.cli` and the `pycc` wrapper use the same installed source -tree and do not require a separate repo-local build. +tree and do not require a separate repo-local build. The wheel must match both +your OS/architecture and Python 3.10+. + +Published package install command: + +```bash +python3 -m pip install pycircuit-hisi +``` + +The distribution name is `pycircuit-hisi` to avoid the existing unrelated +`pycircuit` package on PyPI. The Python import path remains `pycircuit`, and +the installed compiler command remains `pycc`. + +Install the frontend from source for development: + +```bash +python3 -m pip install -e . +python3 -m pycircuit.cli --help +``` + +Editable source install is frontend-only. It does not install `pycc`; build the +toolchain with `bash flows/scripts/pyc build` and point `PYC_TOOLCHAIN_ROOT` at +`.pycircuit_out/toolchain/install`, or use a release wheel. Run the smoke gates: diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 0e3590b..c5ebe7e 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -4,7 +4,7 @@ Welcome to the pyCircuit getting started guide! This section will help you set u ## Prerequisites -- Python 3.9 or later +- Python 3.10 or later - LLVM/MLIR 19 (for compiler backend) - CMake 3.20+ - Ninja build system @@ -39,12 +39,21 @@ bash flows/scripts/pyc build ```bash # Install Python package -pip install -e . +python3 -m pip install -e . # Use the frontend to emit MLIR PYTHONPATH=compiler/frontend python -m pycircuit.cli emit your_design.py ``` +### Option 3: Published PyPI Wheel + +```bash +python3 -m pip install pycircuit-hisi +``` + +The distribution name is `pycircuit-hisi` to avoid the unrelated `pycircuit` +project that already exists on PyPI. The import path remains `pycircuit`. + ## Next Steps Once you have pyCircuit installed, proceed to the [Quickstart](quickstart.md) guide to build and run your first design! diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 725be0b..9130e15 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -6,7 +6,7 @@ This guide covers setting up the pyCircuit development environment. | Component | Minimum Version | Recommended Version | |-----------|---------------|---------------------| -| Python | 3.9 | 3.10+ | +| Python | 3.10 | 3.14 | | LLVM | 19 | 19 | | CMake | 3.20 | 3.28+ | | Ninja | 1.10 | Latest | @@ -87,7 +87,7 @@ bash flows/scripts/pyc build ## Alternative: Install a Release Wheel ```bash -python3 -m pip install pycircuit--.whl +python3 -m pip install /path/to/pycircuit_hisi--py3-none-.whl # The wheel ships the matching toolchain inside site-packages. pycc --version @@ -96,18 +96,33 @@ python3 -m pycircuit.cli --help The wheel is platform-specific because it embeds `pycc`, the runtime archive, and the required LLVM/MLIR shared libraries. Use the wheel that matches your -OS and architecture. +OS and architecture. A single wheel now covers Python 3.10+ on that platform. + +Published package install command: + +```bash +python3 -m pip install pycircuit-hisi +``` + +The distribution name is `pycircuit-hisi` to avoid the existing unrelated +`pycircuit` package on PyPI. The import path remains `pycircuit`, and the CLI +entrypoints remain `pycircuit`, `pycc`, and `pyc-opt`. ## Install Python Package ```bash -# Install pycircuit in development mode -pip install -e . +# Install the frontend package in development mode +python3 -m pip install -e . # Verify installation -python -c "import pycircuit; print(pycircuit.__version__)" +python3 -c "import pycircuit; print(pycircuit.__version__)" ``` +Editable install is frontend-only. It does not provide `pycc` on `PATH`; build +the toolchain with `bash flows/scripts/pyc build` and export +`PYC_TOOLCHAIN_ROOT="$PWD/.pycircuit_out/toolchain/install"`, or install a +release wheel instead. + ## Verify Your Setup ```bash @@ -134,7 +149,7 @@ cmake -G Ninja -S . -B .pycircuit_out/toolchain/build ... ### Python Version Issues -pyCircuit requires Python 3.9+. Check your version: +pyCircuit requires Python 3.10+. Check your version: ```bash python3 --version diff --git a/packaging/wheel/setup.py b/packaging/wheel/setup.py index 20590b9..d99f8b8 100644 --- a/packaging/wheel/setup.py +++ b/packaging/wheel/setup.py @@ -4,6 +4,7 @@ from pathlib import Path from setuptools import Distribution, find_namespace_packages, setup +from wheel.bdist_wheel import bdist_wheel as _bdist_wheel def package_files(root: Path, package_root: Path) -> list[str]: @@ -21,17 +22,35 @@ def has_ext_modules(self) -> bool: return True +class PlatformBinaryWheel(_bdist_wheel): + def finalize_options(self) -> None: + super().finalize_options() + self.root_is_pure = False + + def get_tag(self) -> tuple[str, str, str]: + _python, _abi, plat = super().get_tag() + return ("py3", "none", plat) + + ROOT = Path(__file__).resolve().parent PACKAGE_ROOT = ROOT / "pycircuit" setup( - name="pycircuit", + name="pycircuit-hisi", version=os.environ["PYC_WHEEL_VERSION"], description="A Python-based hardware description framework that compiles Python to RTL through MLIR", long_description=(ROOT / "README.md").read_text(encoding="utf-8"), long_description_content_type="text/markdown", license="MIT", - python_requires=">=3.9", + author="LinxISA Contributors", + author_email="contact@linxisa.org", + url="https://github.com/LinxISA/pyCircuit", + project_urls={ + "Repository": "https://github.com/LinxISA/pyCircuit", + "Issues": "https://github.com/LinxISA/pyCircuit/issues", + "Releases": "https://github.com/LinxISA/pyCircuit/releases", + }, + python_requires=">=3.10", install_requires=[ "click>=8.0.0", "pyyaml>=6.0", @@ -50,5 +69,6 @@ def has_ext_modules(self) -> bool: "pyc-opt=pycircuit.packaged_toolchain:pyc_opt_main", ] }, + cmdclass={"bdist_wheel": PlatformBinaryWheel}, distclass=BinaryDistribution, ) diff --git a/pyproject.toml b/pyproject.toml index 91ce48b..36ab3e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "pycircuit" +name = "pycircuit-hisi" version = "0.1.0" description = "A Python-based hardware description framework that compiles Python to RTL through MLIR" readme = "README.md" @@ -11,7 +11,7 @@ license = { file = "LICENSE" } authors = [ { name = "LinxISA Contributors", email = "contact@linxisa.org" } ] -requires-python = ">=3.9" +requires-python = ">=3.10" keywords = ["hardware", "rtl", "verilog", "mlir", "hdl", "fpga", "asic"] classifiers = [ "Development Status :: 3 - Alpha", @@ -19,10 +19,21 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Code Generators", "Topic :: Electronic Design Automation (EDA)", ] +[project.urls] +Homepage = "https://github.com/LinxISA/pyCircuit" +Repository = "https://github.com/LinxISA/pyCircuit" +Issues = "https://github.com/LinxISA/pyCircuit/issues" +Releases = "https://github.com/LinxISA/pyCircuit/releases" + dependencies = [ "click>=8.0.0", "pyyaml>=6.0", @@ -53,16 +64,16 @@ pycircuit = ["**/*.py", "**/*.md"] [tool.black] line-length = 88 -target-version = ["py39", "py310", "py311", "py312"] +target-version = ["py310", "py311", "py312", "py313", "py314"] [tool.ruff] line-length = 88 -target-version = "py39" +target-version = "py310" select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "T20"] ignore = ["E501"] [tool.mypy] -python_version = "3.9" +python_version = "3.10" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = false