PKGBUILD for UnstableFusion (stable diffusion gui) nvidia cuda only

I couldn’t find UnstableFusion in the AUR so I put together a PKGBUILD for it. Perhaps someone with experience as package maintainer could publish this to AUR. This package is only for nvidia gpus with cuda support. If anyone knows how to adapt this PKGBUILD to support all gpus please post the changes needed.

Caution: If your bandwidth is limited you may not want to install this package. It can take upwards of 9gb to download the dependencies and runtimes (downloaded when you generate first image). Run it from your console the first time to view download progress.

pkgname=unstablefusion
pkgver=1.0
pkgrel=1
pkgdesc="A Stable Diffusion desktop frontend with inpainting, img2img and more"
arch=('x86_64')
url="https://github.com/ahrm/UnstableFusion"
license=('GPLv3')
depends=(
  'numactl'
  'python-pyqt5'
  'python-numpy'
  'python-pytorch-cuda'
  'python-pillow'
  'python-requests'
  'python-flask'
  'protobuf'
  'python-qasync'
  'python-httpx'
  'python-pip'
  'python-setuptools'
)
makedepends=('imagemagick')
conflicts=('python-opencv')
source=(
  "${pkgname}.tar.gz::${url}/archive/refs/tags/v1.tar.gz"
)
sha256sums=(
  '8101c362802d0c4ccaa2b75a82ff86087b03cdaf0219037943376145f377f824'
)

prepare() {
  pip install accelerate diffusers transformers opencv-python-headless
  echo -ne "#!/bin/bash\n\npython /usr/lib/python3.10/${pkgname}/${pkgname}.py" > "${srcdir}/UnstableFusion-1/${pkgname}"
  echo -ne "[Desktop Entry]\nName=UnstableFusion\nComment=${pkgdesc}\nExec=${pkgname}\nIcon=${pkgname}\nStartupNotify=false\nTerminal=false\nType=Application\nCategories=Graphics;2DGraphics;" > "${srcdir}/UnstableFusion-1/${pkgname}.desktop"
  convert "${srcdir}/UnstableFusion-1/icons/${pkgname}.png" -resize 32x32 "${srcdir}/UnstableFusion-1/icons/${pkgname}32.png"
}

package() {
  cd "${srcdir}/UnstableFusion-1"
  for f in ./*; do
    if [ -f "$f" ]; then
      bf=$(basename -- "${f}")
      install -Dm644 "${f}" "${pkgdir}/usr/lib/python3.10/${pkgname}/${bf}"
    fi
  done

  for f in ./icons/*; do
    bf=$(basename -- "${f}")
    install -Dm644 "${f}" "${pkgdir}/usr/lib/python3.10/${pkgname}/icons/${bf}"
  done

  install -Dm644 "${srcdir}/UnstableFusion-1/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
  install -Dm644 "${srcdir}/UnstableFusion-1/${pkgname}.desktop" "${pkgdir}/usr/share/applications/${pkgname}.desktop"
  install -Dm644 "${srcdir}/UnstableFusion-1/icons/${pkgname}32.png" "${pkgdir}/usr/share/icons/hicolor/32x32/apps/${pkgname}.png"
  install -Dm755 "${srcdir}/UnstableFusion-1/${pkgname}" "${pkgdir}/usr/bin/${pkgname}"
}

Great - a couple of notes …

Never use pip to install system wide packages

assuming a specific version of python is usually doomed to create issues

The pip line was necessary since those packages aren’t in the manjaro repo. Not sure how to list them in the depends array so pip was a last resort.

I know the python3.10 folder is not ideal. I could check the python version during install and then insert the version into the path. But even that might break after a python upgrade. Which folder would you use for the python scripts?

All the pip installed packages is available in the repo as

python-<pkgname>

So add them to the depends=() array

There is this page Python package guidelines - ArchWiki

Using python version

Sometimes during preparing, building, testing or installation it is required to refer to the system’s major and minor Python version. Do not hardcode this (e.g. 3.9 or 3.10) and instead use a call to the Python interpreter to retrieve the information and store it in a local variable:

check() { 
    local python_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
    ... 
}
1 Like

All but opencv-python-headless are in the AUR.

PKGBUILD critique:

  • The pkgver is 1, not 1.0
  • The arch is ‘any’, there are no ELF files
  • The license is named GPL3, not GPLv3. Common licenses are already installed via the licenses package
  • The source tarball needs to include the pkgver to be a unique filename for each new version
  • Include the desktop file and script as source files
  • Install loose files to /opt/, see Arch package guidelines
  • The script is meant to be run locally, not installed to site-packages. If it was installed to site-packages, Python would know where to find it.
  • There is no need to add a shebang to Python scripts. Run them with python -m <script>.py.
  • Why resize the icon to 32x32? That’s quite small. The icon is less than 500 KB, and can be installed to /usr/share/pixmaps/

See the following example:

PKGBUILD
pkgname=unstablefusion
pkgver=1
pkgrel=1
pkgdesc="A Stable Diffusion desktop frontend with inpainting, img2img and more"
arch=('any')
url="https://github.com/ahrm/UnstableFusion"
license=('GPL3')
depends=(
  'numactl'
  'python-pyqt5'
  'python-numpy'
  'python-pytorch-cuda'
  'python-pillow'
  'python-requests'
  'python-flask'
  'protobuf'
  'python-qasync'
  'python-httpx'

  # AUR packages
  'python-accelerate'
  'python-diffusers'
  'python-transformers'

  # Not in repos or AUR
  'opencv-python-headless'
)
source=(
  "${pkgname}-${pkgver}.tar.gz::${url}/archive/refs/tags/v${pkgver}.tar.gz"
  "${pkgname}.desktop"
  "${pkgname}.sh"
)
sha256sums=('8101c362802d0c4ccaa2b75a82ff86087b03cdaf0219037943376145f377f824'
            '815181cddf8d5069095a8937155d0680a07fe0244062db12ef14049ca52b6877'
            '70b850d0783ea9a9f97eaefa0e7e05c50cf20c37f20c953eb155c9e162472ec0')

package() {
  cd "UnstableFusion-${pkgver}"
  install -Dm644 *.py keys.json mods.txt UnstableFusionServer.ipynb -t \
    "${pkgdir}/opt/${pkgname}/"
  cp -r icons "${pkgdir}/opt/${pkgname}/"

  install -d "${pkgdir}/usr/share/pixmaps"
  ln -s "/opt/${pkgname}/icons/${pkgname}.png" "${pkgdir}/usr/share/pixmaps/"

  install -Dm644 "${srcdir}/${pkgname}.desktop" -t "${pkgdir}/usr/share/applications/"
  install -Dm755 "${srcdir}/${pkgname}.sh" "${pkgdir}/usr/bin/${pkgname}"
}
unstablefusion.desktop
[Desktop Entry]
Name=UnstableFusion
Comment=A Stable Diffusion desktop frontend with inpainting, img2img and more
Exec=unstablefusion
Icon=unstablefusion
StartupNotify=false
Terminal=false
Type=Application
Categories=Graphics;2DGraphics;
unstablefusion.sh
#!/bin/bash

python -m /opt/unstablefusion/unstablefusion.py