diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml new file mode 100644 index 000000000..47060d5df --- /dev/null +++ b/.github/workflows/build-wheels.yml @@ -0,0 +1,79 @@ +name: Build Python sdist and wheels + +on: + pull_request: + push: + release: + types: + - published + +jobs: + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-22.04, windows-2022, macos-12] + + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + if: runner.os == 'Linux' + uses: docker/setup-qemu-action@v3 + with: + platforms: all + + - name: Build ${{ matrix.os }} wheels + uses: pypa/cibuildwheel@v2.16.5 + env: + # we only support what's supported by wxPython, therefore we skip: + # * PyPy Python implementation + # * Python 3.6 and 3.7 versions + # * musl C implementation + CIBW_SKIP: "pp* cp36* cp37* *-musllinux*" + # produce ARM wheels on Linux in addition to 32 and 64 bit + CIBW_ARCHS_LINUX: auto aarch64 + # produce wheels for macOS to support both Intel and Apple silicon + CIBW_ARCHS_MACOS: x86_64 universal2 arm64 + + - name: Upload ${{ matrix.os }} wheels + uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: pipx run build --sdist + + - name: Upload sdist + uses: actions/upload-artifact@v4 + with: + name: cibw-sdist + path: dist/*.tar.gz + + upload_pypi: + needs: [build_wheels, build_sdist] + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + if: github.event_name == 'release' && github.event.action == 'published' + steps: + - uses: actions/download-artifact@v4 + with: + # unpack all CIBW artifacts into dist/ + pattern: cibw-* + path: dist + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + # by default, the contents of the `dist/` directory are uploaded + password: ${{ secrets.PYPI_API_KEY }} diff --git a/.github/workflows/buildpackage-mac.yml b/.github/workflows/buildpackage-mac.yml index 203da0f94..bcafa9441 100644 --- a/.github/workflows/buildpackage-mac.yml +++ b/.github/workflows/buildpackage-mac.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - os: [macos-11, macos-12] + os: [macos-12] architecture: [x64] python-version: ['3.10'] @@ -33,11 +33,11 @@ jobs: python setup.py build_ext --inplace - name: Make pyinstaller spec run: | - pyi-makespec --hidden-import="pkg_resources.py2_warn" -F --add-data images/\*:images --add-data \*.png:. --add-data \*.ico:. -w -i P-face.icns pronterface.py + pyi-makespec --hidden-import="pkg_resources.py2_warn" -F --add-data images/\*:images --add-data \*.png:. --add-data \*.ico:. --name Pronterface -w -i P-face.icns pronterface.py # Edit spec file export git_hash=$(git rev-parse --short "$GITHUB_SHA") - sed -i '' '$ s/.$//' pronterface.spec - cat >> pronterface.spec <> Pronterface.spec < **Note for Ubuntu/Debian**: You might need to install `python3-venv` first. > **Note for Ubuntu/Debian**: If you get `python: command not found` use -> `python3` instead of just `python` on all commands below. +> `python3 -m venv venv` instead. -#### 4. Install dependencies +#### 4. Install Printrun -Dependencies for running Printrun are laid out in the [`requirements.txt`][5] -file. Once activated your virtual environment, install required dependencies -with: +Once activated your virtual environment, install Printrun' source code with: ``` -(venv) $ python -m pip install -r requirements.txt # install the rest of dependencies +(venv) $ python -m pip install . ``` > **Note for Linux users**: wxPython4 doesn't have Linux wheels available from @@ -186,32 +184,15 @@ with: > (venv) $ python -m pip install https://extras.wxpython.org/wxPython4/extras/linux/gtk3/fedora-27/wxPython-4.0.1-cp36-cp36m-linux_x86_64.whl # replace the link with yours > ``` -[5]: requirements.txt [6]: https://extras.wxpython.org/wxPython4/extras/linux/gtk3 -#### 5. (Optional) Cython-based G-Code parser - -Printrun default G-Code parser is quite memory hungry, but we also provide a -much lighter one which just needs an extra build-time dependency (Cython). The -warning message `WARNING:root:Memory-efficient GCoder implementation -unavailable: No module named gcoder_line` means that this optimized G-Code -parser hasn't been compiled. To get rid of it and benefit from the better -implementation, install Cython and build the extension with the following -commands: - -```console -(venv) $ python -m pip install Cython -(venv) $ python setup.py build_ext --inplace -``` - - -#### 6. Run Printrun +#### 5. Run Printrun With your virtual environment still active, invoke the app you need like: ```shell -(venv) $ python pronterface.py # or `pronsole.py` or `plater.py` +(venv) $ pronterface.py # or `pronsole.py` or `plater.py` ``` diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..fb7c4da78 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["setuptools", "cython"] +build-backend = "setuptools.build_meta" + +[project] +name = "Printrun" +description = "Host software for 3D printers" +authors = [ + {name = "Kliment Yanev"}, + {name = "Guillaume Seguin"}, +] +readme = "README.md" +requires-python=">=3.8" +classifiers=[ + "Environment :: X11 Applications :: GTK", + "Intended Audience :: End Users/Desktop", + "Intended Audience :: Manufacturing", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Printing", +] +dynamic = [ # these variables are dynamically set at `setup.py` + "version", + "scripts", +] + +[project.urls] +Homepage = "https://github.com/kliment/Printrun/" +Issues = "https://github.com/kliment/Printrun/issues" +Changelog = "https://github.com/kliment/Printrun/blob/master/NEWS.md" \ No newline at end of file diff --git a/setup.py b/setup.py index c507b0622..fc27da308 100755 --- a/setup.py +++ b/setup.py @@ -17,32 +17,20 @@ import ast import glob -from setuptools import setup -from setuptools import find_packages +from setuptools import Extension, find_packages, setup -try: - from Cython.Build import cythonize - extensions = cythonize("printrun/gcoder_line.pyx") - from Cython.Distutils import build_ext -except ImportError as e: - print("WARNING: Failed to cythonize: %s" % e) - # Debug helper: uncomment these: - # import traceback - # traceback.print_exc() - extensions = None - build_ext = None +def get_install_requires(): + with open('requirements.txt') as f: + install_requires = f.readlines() -with open('README.md', encoding='utf-8') as f: - long_description = f.read() -with open('requirements.txt') as f: - install_requires = f.readlines() - -with open('printrun/printcore.py') as f: - for line in f.readlines(): - if line.startswith("__version__"): - __version__ = ast.literal_eval(line.split("=")[1].strip()) +def get_version(): + with open('printrun/printcore.py', encoding="utf-8") as f: + for line in f.readlines(): + if line.startswith("__version__"): + return ast.literal_eval(line.split("=")[1].strip()) + return "unknown" def multiglob(*globs): @@ -52,49 +40,35 @@ def multiglob(*globs): return paths -data_files = [ - ('share/pixmaps', multiglob('*.png')), - ('share/applications', multiglob('*.desktop')), - ('share/metainfo', multiglob('*.appdata.xml')), - ('share/pronterface/images', multiglob('images/*.png', - 'images/*.svg')), -] +def get_data_files(): + data_files = [ + ('share/pixmaps', multiglob('*.png')), + ('share/applications', multiglob('*.desktop')), + ('share/metainfo', multiglob('*.appdata.xml')), + ('share/pronterface/images', multiglob('images/*.png', + 'images/*.svg')), + ] + + for locale in glob.glob('locale/*/LC_MESSAGES/'): + data_files.append((f'share/{locale}', glob.glob(f'{locale}/*.mo'))) + + return data_files + -for locale in glob.glob('locale/*/LC_MESSAGES/'): - data_files.append((f'share/{locale}', glob.glob(f'{locale}/*.mo'))) +def get_extensions(): + extensions = [ + Extension(name="printrun.gcoder_line", + sources=["printrun/gcoder_line.pyx"]) + ] + return extensions setup( - name="Printrun", - version=__version__, - description="Host software for 3D printers", - author="Kliment Yanev, Guillaume Seguin and others", - long_description=long_description, - long_description_content_type="text/markdown", - url="http://github.com/kliment/Printrun/", - license="GPLv3+", - data_files=data_files, + version=get_version(), + data_files=get_data_files(), packages=find_packages(), scripts=["pronsole.py", "pronterface.py", "plater.py", "printcore.py"], - ext_modules=extensions, - python_requires=">=3.7", - install_requires=install_requires, - setup_requires=["Cython"], - classifiers=[ - "Environment :: X11 Applications :: GTK", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: Manufacturing", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Topic :: Printing", - ], + ext_modules=get_extensions(), + install_requires=get_install_requires(), zip_safe=False, )