diff --git a/.github/actions/setup-kicad/setup.sh b/.github/actions/setup-kicad/setup.sh index 4ea291c5..d4b8133d 100755 --- a/.github/actions/setup-kicad/setup.sh +++ b/.github/actions/setup-kicad/setup.sh @@ -4,104 +4,153 @@ set -e case $1 in 'v5') - sudo add-apt-repository --yes ppa:kicad/kicad-5.1-releases + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-5.1-releases sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad + kicad_PYTHONPATH=/usr/lib/python3/dist-packages + sudo ln -srf "${kicad_PYTHONPATH}"/_pcbnew.*.so "${kicad_PYTHONPATH}/_pcbnew.so" ;; 'v6') - sudo add-apt-repository --yes ppa:kicad/kicad-6.0-releases + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-6.0-releases sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; 'v7') - sudo add-apt-repository --yes ppa:kicad/kicad-7.0-releases + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-7.0-releases sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad - # The Pcbnew module is located in - # - /usr/lib/kicad/lib/python3/dist-packages - # - instead of /usr/lib/python3/dist-packages/pcbnew.py - # Let's add it to PYTHONPATH and also set LD_LIBRARY_PATH - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages:${PYTHONPATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; 'v7-testing') - sudo add-apt-repository --yes ppa:kicad/kicad-7.0-nightly + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-7.0-nightly sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad - # The Pcbnew module is located in - # - /usr/lib/kicad/lib/python3/dist-packages - # - instead of /usr/lib/python3/dist-packages/pcbnew.py - # Let's add it to PYTHONPATH and also set LD_LIBRARY_PATH - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages:${PYTHONPATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; + 'v8') - sudo add-apt-repository --yes ppa:kicad/kicad-8.0-releases + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-8.0-releases sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad - # The Pcbnew module is located in - # - /usr/lib/kicad/lib/python3/dist-packages - # - instead of /usr/lib/python3/dist-packages/pcbnew.py - # Let's add it to PYTHONPATH and also set LD_LIBRARY_PATH - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages:${PYTHONPATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}" >> $GITHUB_ENV - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages/:/usr/lib/kicad/local/lib/python3.10/dist-packages:/usr/lib/kicad/local/lib/python3.11/dist-packages:/usr/lib/kicad/local/lib/python3.12/dist-packages" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu:/usr/lib/kicad/lib/" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; 'v8-testing') - sudo add-apt-repository --yes ppa:kicad/kicad-8.0-nightly + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-8.0-nightly sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad - # The Pcbnew module is located in - # - /usr/lib/kicad/lib/python3/dist-packages - # - instead of /usr/lib/python3/dist-packages/pcbnew.py - # Let's add it to PYTHONPATH and also set LD_LIBRARY_PATH - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages:${PYTHONPATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}" >> $GITHUB_ENV - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages/:/usr/lib/kicad/local/lib/python3.10/dist-packages:/usr/lib/kicad/local/lib/python3.11/dist-packages:/usr/lib/kicad/local/lib/python3.12/dist-packages" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu:/usr/lib/kicad/lib/" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; + 'v9') - sudo add-apt-repository --yes ppa:kicad/kicad-9.0-releases + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-9.0-releases sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad - # The Pcbnew module is located in - # - /usr/lib/kicad/lib/python3/dist-packages - # - instead of /usr/lib/python3/dist-packages/pcbnew.py - # Let's add it to PYTHONPATH and also set LD_LIBRARY_PATH - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages:${PYTHONPATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}" >> $GITHUB_ENV - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages/:/usr/lib/kicad/local/lib/python3.10/dist-packages:/usr/lib/kicad/local/lib/python3.11/dist-packages:/usr/lib/kicad/local/lib/python3.12/dist-packages" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu:/usr/lib/kicad/lib/" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; 'v9-testing') - sudo add-apt-repository --yes ppa:kicad/kicad-9.0-nightly + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-9.0-nightly sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad - # The Pcbnew module is located in - # - /usr/lib/kicad/lib/python3/dist-packages - # - instead of /usr/lib/python3/dist-packages/pcbnew.py - # Let's add it to PYTHONPATH and also set LD_LIBRARY_PATH - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages:${PYTHONPATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu/:${LD_LIBRARY_PATH}" >> $GITHUB_ENV - echo "PYTHONPATH=/usr/lib/kicad/lib/python3/dist-packages/:/usr/lib/kicad/local/lib/python3.10/dist-packages:/usr/lib/kicad/local/lib/python3.11/dist-packages:/usr/lib/kicad/local/lib/python3.12/dist-packages" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad/lib/x86_64-linux-gnu:/usr/lib/kicad/lib/" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/python3/dist-packages ;; + 'nightly') - sudo add-apt-repository --yes ppa:kicad/kicad-dev-nightly + sudo add-apt-repository --yes --enable-source ppa:kicad/kicad-dev-nightly sudo apt-get update sudo apt-get install --yes --no-install-recommends kicad-nightly - echo "PYTHONPATH=/usr/lib/kicad-nightly/lib/python3/dist-packages/:/usr/lib/kicad-nightly/local/lib/python3.10/dist-packages:/usr/lib/kicad-nightly/local/lib/python3.11/dist-packages:/usr/lib/kicad-nightly/local/lib/python3.12/dist-packages" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/kicad-nightly/lib/x86_64-linux-gnu:/usr/lib/kicad-nightly/lib/" >> $GITHUB_ENV + kicad_PYTHONPATH=/usr/lib/kicad-nightly/lib/python3/dist-packages + kicad_LIBRARY_PATH=/usr/lib/kicad-nightly/lib/x86_64-linux-gnu for bin in kicad pcbnew eeschema kicad-cli; do sudo ln -s /usr/bin/${bin}-nightly /usr/bin/${bin} done ;; *) - echo "Invalid version '$1' passed. Only 'v5', 'v6', 'v7', 'v7-testing', 'v8', 'v8-testing' and 'nightly' supported" >&2 + echo "Invalid version '$1' passed. Only 'v5', 'v6', 'v7', 'v7-testing', 'v8', 'v8-testing', 'v9', 'v9-testing' and 'nightly' supported" >&2 exit 1 ;; esac + +if ! [[ -f "$kicad_PYTHONPATH/pcbnew.py" && -f "$kicad_PYTHONPATH/_pcbnew.so" ]]; then + echo "setup-kicad/setup.sh seems to have the wrong location for where KiCad installs pcbnew.py or _pcbnew.so, and needs updated" >&2 + find /usr /opt \( -name pcbnew.py -o -name _pcbnew.so \) -print >&2 + exit 1 +fi +if sudo python3 -c 'import sys; sys.exit(1 if sys.argv[1] in sys.path else 0)' "$kicad_PYTHONPATH"; then + sys_PYTHONPATH=$(sudo python3 -c 'import sys; print(next(p for p in sys.path if "site-packages" in p))') + sudo ln -sf "$kicad_PYTHONPATH/pcbnew.py" "$kicad_PYTHONPATH/_pcbnew.so" "$sys_PYTHONPATH" +fi +if python3 -c 'import sys; sys.exit(1 if sys.argv[1] in sys.path else 0)' "$kicad_PYTHONPATH"; then + user_PYTHONPATH=$(python3 -c 'import sys; print(next(p for p in sys.path if "site-packages" in p))') + ln -sf "$kicad_PYTHONPATH/pcbnew.py" "$kicad_PYTHONPATH/_pcbnew.so" "$user_PYTHONPATH" +fi +# KiCad pulled in wxPython for the APT Python, but if that's not what +# `python3` is (probably because it's from `actions/setup-python`) +# then we need to install wxPython ourselves. +if ! python3 -c 'import wx'; then + mkdir ~/wx + pushd ~/wx + sudo apt-get build-dep wxpython4.0 + if python3 -c 'import sys; sys.exit(0 if sys.version_info.minor < 12 else 1)'; then + wxPython_version=4.2.1 + + curl -LO "https://files.pythonhosted.org/packages/source/w/wxPython/wxPython-${wxPython_version}.tar.gz" + tar xaf "wxPython-${wxPython_version}.tar.gz" + cd "wxPython-${wxPython_version}" + else + # 4.2.3 is the minimum version to not-segfault with Python 3.12. + wxPython_version=4.2.3 + python3 -m pip install setuptools + + # We need to re-generate files; the generated files shipped + # with 4.2.3 need newer wxWidgets than what the system has. + if [[ "$(wx-config --version)" != 3.2.1 ]]; then + echo "setup-kicad/setup.sh needs updated for a different wxWidgets version" >&2 + exit 1 + fi + # To do this, we'll get wxPython from Git instead of from a + # tarball, so that we can easily roll back ext/wxWidgets to + # the version we need. (So actually we won't be + # "re-"generating the files, since the generated files aren't + # checked into Git in the first place!) + + git clone --branch="wxPython-${wxPython_version}" https://github.com/wxWidgets/Phoenix wxPython + cd wxPython + git submodule update --init + + # Adjust which wxWidgets version we generate against. + git show a1c9554bbf10f88cb0ca3602e3011d9977854ae5 -- etg/window.py | patch -p1 -R # 2024-05-16, needs v3.2.5 + git revert --no-commit 7a198b8cae9a81cec4d25a0c6c5cc65ad8822bb2 # 2023-11-20, needs v3.2.3 + git revert --no-commit 1236562af55be1d8064d851e58dd1db3699040de # 2023-06-27, needs v3.2.3 + git revert --no-commit 371101db7a010d679d214fde617dae9de02008d9 # 2023-07-14, needs v3.2.3 + git -C ext/wxWidgets checkout "v$(wx-config --version)" + + # NB: Currently APT's sip-tools is 6.7.5, and wxPython + # 4.2.3 requires sip>=6.8, so it is important that we get + # it from pip instead of from apt. + python3 -m pip install sip requests + + # Generate the files. + # `sip` needs the `etg` output, and `etg` needs the `dox` output. + python3 build.py --jobs=$(nproc) --use_syswx --nodoc --release dox + python3 build.py --jobs=$(nproc) --use_syswx --nodoc --release etg + python3 build.py --jobs=$(nproc) --use_syswx --nodoc --release sip + fi + # Build. + python3 build.py --jobs=$(nproc) --use_syswx --nodoc --release build + # Install. + python3 build.py --jobs=$(nproc) --use_syswx --nodoc --release install + popd +fi + +if [[ -n "$kicad_LIBRARY_PATH" ]]; then + if [[ ! -f "$kicad_LIBRARY_PATH/libkicad_3dsg.so" ]]; then + echo "setup-kicad/setup.sh seems to have the wrong location for where KiCad installs libkicad_3dsg.so, and needs updated" >&2 + find /usr /opt -name 'libkicad*' -print >&2 + exit 1 + fi + echo "LD_LIBRARY_PATH=${kicad_LIBRARY_PATH}${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV +fi diff --git a/.github/workflows/test-kikit.yml b/.github/workflows/test-kikit.yml index 226844af..0e0eb2c4 100644 --- a/.github/workflows/test-kikit.yml +++ b/.github/workflows/test-kikit.yml @@ -12,24 +12,42 @@ jobs: strategy: matrix: kicad-version: [v8, v9, v9-testing] + # setup.py says `python_requires='>=3.8'` + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + fail-fast: false steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/setup-kicad + - name: Install Python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: setup.py + - name: Install KiCad + uses: ./.github/actions/setup-kicad with: kicad-version: ${{ matrix.kicad-version }} - - name: KiCAD version - run: python3 -c 'import pcbnew; print(pcbnew.GetBuildVersion())' - - name: Install dependencies and KiKit + - name: Show Python and KiCad versions + run: | + set -x + python3 --version + python3 -c 'import pcbnew; print(pcbnew.GetBuildVersion())' + - name: Install other dependencies run: | sudo apt-get -qq install --yes --no-install-recommends \ zip inkscape make git libmagickwand-dev \ libgraphicsmagick1-dev libmagickcore-dev \ openscad bats - sudo python -m pip install PcbDraw - sudo env PYTHONPATH=$PYTHONPATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH \ - python -m pip install -e .\[dev\] + # PcbDraw doesn't support Python 3.13 yet (because it uses + # an old Pillow that didn't support Python 3.13 yet, so use + # `sudo` to use the older system Python instead of whatever + # we installed with `actions/setup-python`. + sudo python3 -m pip install PcbDraw + - name: Install KiKit + run: | + python3 -m pip install -e .\[dev\] - run: make test - - run: sudo env PYTHONPATH=$PYTHONPATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH make package + - run: make package build-pcm: name: Build PCM packages runs-on: ubuntu-24.04 diff --git a/Dockerfile b/Dockerfile index 5ccfe561..eeed0fb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,7 +43,7 @@ FROM base AS build COPY . /src/kikit WORKDIR /src/kikit -RUN python3 setup.py install +RUN python3 -m pip install . # the final stage only takes the installed packages from dist-packages # and ignores the src directories diff --git a/Makefile b/Makefile index 858c1e69..632202b0 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ docs/panelization/examples.md: scripts/exampleDoc.py docs/resources/conn.png package: rm -f dist/* - python3 setup.py sdist bdist_wheel + python3 -m build install: package pip3 install --no-deps --force dist/*.whl diff --git a/kikit/ui.py b/kikit/ui.py index 09a41980..ad6dc604 100644 --- a/kikit/ui.py +++ b/kikit/ui.py @@ -2,8 +2,29 @@ from kikit import (panelize_ui, export_ui, present_ui, stencil_ui, modify_ui, fab_ui, drc_ui) from kikit import __version__ +import os import sys +try: + import pcbnew +except ImportError: + if os.name == "nt": + message = "No Pcbnew Python module found.\n" + \ + "Please make sure that you use KiCAD command prompt, " + \ + "not the standard Command Prompt or Power Shell\n" + \ + "See https://github.com/yaqwsx/KiKit/blob/master/doc/installation.md#installation-on-windows" + else: + message = "No Pcbnew Python module found for the current Python interpreter.\n" + \ + "First, make sure that KiCAD is actually installed\n." + \ + "Then, make sure that you use the same Python interpreter as KiCAD uses.\n" + \ + "Usually a good way is to invoke 'python3 -m pip install kikit'." + delimiter = 100 * "=" + "\n" + 100 * "=" + "\n" + sys.stderr.write( + delimiter + f"** Cannot run KiKit**\n{message}\n" + delimiter) + raise RuntimeError("Cannot run KiKit, see error message above") from None +except AttributeError: + raise RuntimeError("KiCAD v5 is no longer supported for KiKit. Version v1.0.x is the last one that supports KiCAD 5.") + @click.group(context_settings={"help_option_names": ["-h", "--help"]}) @click.version_option(__version__) def cli(): diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..9f6f97b7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,10 @@ +[build-system] +requires = ["setuptools", "versioneer[toml]"] +build-backend = "setuptools.build_meta" + +[tool.versioneer] +VCS = "git" +style = "pep440" +versionfile_source = "kikit/_version.py" +versionfile_build = "kikit/_version.py" +tag_prefix = "v" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 1bb5b60f..00000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[versioneer] -VCS = git -style = pep440 -versionfile_source = kikit/_version.py -versionfile_build = kikit/_version.py -tag_prefix = v -parentdir_prefix = None diff --git a/setup.py b/setup.py index 9351fc9d..dd1641ac 100644 --- a/setup.py +++ b/setup.py @@ -2,46 +2,13 @@ import setuptools import versioneer -import os -import sys - -# Some packages on Linux for v7 change the location of the pcbnew module, let's -# add the new location to path: -import os -if os.name != "nt": - sys.path.append("/usr/lib/kicad/lib/python3/dist-packages") - try: - from ctypes import cdll - cdll.LoadLibrary("/usr/lib/kicad/lib/x86_64-linux-gnu/libkicad_3dsg.so.2.0.0") - except Exception: - pass # Ignore any errors as the library just might not exists here - -try: - import pcbnew -except ImportError: - if os.name == "nt": - message = "No Pcbnew Python module found.\n" + \ - "Please make sure that you use KiCAD command prompt, " + \ - "not the standard Command Prompt or Power Shell\n" + \ - "See https://github.com/yaqwsx/KiKit/blob/master/doc/installation.md#installation-on-windows" - else: - message = "No Pcbnew Python module found for the current Python interpreter.\n" + \ - "First, make sure that KiCAD is actually installed\n." + \ - "Then, make sure that you use the same Python interpreter as KiCAD uses.\n" + \ - "Usually a good way is to invoke 'python3 -m pip install kikit'." - delimiter = 100 * "=" + "\n" + 100 * "=" + "\n" - sys.stderr.write( - delimiter + f"** Cannot install KiKit**\n{message}\n" + delimiter) - raise RuntimeError("Cannot install KiKit, see error message above") from None -except AttributeError: - raise RuntimeError("KiCAD v5 is no longer supported for KiKit. Version v1.0.x is the last one that supports KiCAD 5.") with open("README.md", "r") as fh: long_description = fh.read() setuptools.setup( name="KiKit", - python_requires='>=3.7', + python_requires='>=3.8', # if you bump this, be sure to also adjust the matrix in .github/workflows/test-kikit.yml version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), author="Jan Mrázek", @@ -50,10 +17,10 @@ long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/yaqwsx/KiKit", - packages=setuptools.find_packages(), + packages=setuptools.find_namespace_packages(include=["kikit"]), + license = "MIT", classifiers=[ "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], install_requires=[ @@ -70,7 +37,11 @@ "versioneer" ], extras_require={ - "dev": ["pytest"], + "dev": [ + "pytest", + "build", + "wheel", + ], }, zip_safe=False, include_package_data=True,