#!/bin/bash # GIMP 3.x.x Update/Build script for Porteus # Version 2026-03-28 (Unified Minimal/Full) # Copyright 2023-2030, Blaze, Dankov, Russia # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Root check if [ "$(whoami)" != "root" ]; then echo -e "\nYou need to be root to run this script.\n" exit 1 fi BOLD="\e[1m"; CYAN="\e[96m"; GREEN="\e[92m"; RED="\e[31m"; RESET="\e[0m" PRGNAM=${PRGNAM:-gimp} BUILD=${BUILD:-1} ARCH=$( uname -m ) TMPDIR=/tmp/portch PKG=$TMPDIR/package-$PRGNAM PKGINFO=$PKG/var/lib/pkgtools/packages ICON=$PKG/usr/share/applications/gimp.desktop OUTPUT=${OUTPUT:-/tmp} LIBDIRSUFFIX=$([ "$ARCH" = "x86_64" ] && echo "64" || echo "") # Detect latest GIMP version from mirror GIMP_TREE=$(echo 'https://www.nic.funet.fi/pub/mirrors/ftp.gimp.org/pub/gimp') GIMP_MAJOR=$(curl -skL -A "Mozilla/5.0" ${GIMP_TREE} | grep -oP 'v\d+\.\d+(?=/)' | tail -1) VERSION=$(lynx -source "${GIMP_TREE}/${GIMP_MAJOR}/SHA256SUMS" | grep -oP '(?<=gimp-)\d+\.\d+\.\d+(?=\.tar\.)' | tail -1) # Check installed version if [[ -f "/usr/bin/gimp" ]]; then MYVER=${MYVER:-$(basename /var/lib/pkgtools/packages/gimp* | tail -1 | cut -d'-' -f2)} fi if [ "$MYVER" == "$VERSION" ]; then echo -e "You already have the latest ${GREEN}$MYVER${RESET} version of $PRGNAM" sleep 2 && exit fi read -p "$(echo -e "Would you like to build $PRGNAM ${GREEN}$VERSION${RESET} xzm module? [y/n]: ")" -n 1 -r -s && echo [[ $REPLY =~ ^[Yy]$ ]] || exit # Build mode selection echo -e "${BOLD}Select GIMP build mode:${RESET}" echo "1) Full (Standard: Includes OpenCL, JS scripts, Python, advanced filters)" echo "2) Minimal (Lightweight: No JS scripts, advanced filters, etc...)" read -p "Your choice [1/2]: " B_MODE if [ "$B_MODE" == "2" ]; then MODE="minimal" echo -e "Selected mode: ${CYAN}MINIMAL${RESET}" else MODE="full" echo -e "Selected mode: ${GREEN}FULL${RESET}" fi cleanup(){ [ -d $TMPDIR ] && rm -rf $TMPDIR [ -d $PKG ] && rm -rf $PKG rm -f ${OUTPUT}/*.txz exit } rm -rf $PKG ${OUTPUT}/*.txz mkdir -p $TMPDIR $PKG cd $PKG # Auto-detect Desktop Environment (for su/root cases) if [ -z "$XDG_CURRENT_DESKTOP" ]; then if pgrep -x "cinnamon" > /dev/null; then XDG_CURRENT_DESKTOP="X-Cinnamon" elif pgrep -x "cosmic-session" > /dev/null; then XDG_CURRENT_DESKTOP="COSMIC" elif pgrep -x "gnome-session" > /dev/null; then XDG_CURRENT_DESKTOP="GNOME" elif pgrep -x "ksmserver" > /dev/null; then XDG_CURRENT_DESKTOP="KDE" elif pgrep -x "lxsession" > /dev/null; then XDG_CURRENT_DESKTOP="LXDE" elif pgrep -x "lxqt-session" > /dev/null; then XDG_CURRENT_DESKTOP="LXQt" elif pgrep -x "mate-session" > /dev/null; then XDG_CURRENT_DESKTOP="MATE" elif pgrep -x "openbox" > /dev/null; then XDG_CURRENT_DESKTOP="OPENBOX" elif pgrep -x "xfce4-session" > /dev/null; then XDG_CURRENT_DESKTOP="XFCE" fi fi export XDG_CURRENT_DESKTOP # Package Fetching Logic (DE Awareness) # !!! Minimal version !!! if [ "$MODE" == "minimal" ]; then if [[ "$XDG_CURRENT_DESKTOP" == "X-Cinnamon" || "$XDG_CURRENT_DESKTOP" == "MATE" ]]; then getpkg -q gimp appstream gegl gexiv2 libfyaml libmypaint libxmlb llvm elif [[ "$XDG_CURRENT_DESKTOP" == "GNOME" || "$XDG_CURRENT_DESKTOP" == "KDE" || "$XDG_CURRENT_DESKTOP" == "LXDE" || "$XDG_CURRENT_DESKTOP" == "LXQt" || "$XDG_DESKTOP_SESSION" == "openbox" || "$XDG_CURRENT_DESKTOP" == "XFCE" ]]; then # add babl getpkg -q gimp appstream babl gegl gexiv2 libfyaml libmypaint libxmlb llvm else getpkg -q gimp appstream babl gegl gexiv2 libfyaml libmypaint libxmlb llvm fi else # !!! Full version !!! if [[ "$XDG_CURRENT_DESKTOP" == "X-Cinnamon" || "$XDG_CURRENT_DESKTOP" == "MATE" ]]; then getpkg -q gimp appstream cfitsio gcc-gfortran gegl gexiv2 gjs Imath lensfun libfyaml libmypaint libwmf libxmlb llvm LibRaw mozjs140 openblas openexr openjph suitesparse elif [[ "$XDG_CURRENT_DESKTOP" == "GNOME" || "$XDG_CURRENT_DESKTOP" == "KDE" || "$XDG_CURRENT_DESKTOP" == "LXDE" || "$XDG_CURRENT_DESKTOP" == "LXQt" || "$XDG_DESKTOP_SESSION" == "openbox" || "$XDG_CURRENT_DESKTOP" == "XFCE" ]]; then # add babl getpkg -q gimp appstream babl cfitsio gcc-gfortran gegl gexiv2 gjs Imath lensfun libfyaml libmypaint libwmf libxmlb llvm LibRaw mozjs140 openblas openexr openjph suitesparse else getpkg -q gimp appstream babl cfitsio gcc-gfortran gegl gexiv2 gjs Imath lensfun libfyaml libmypaint libwmf libxmlb llvm LibRaw mozjs140 openblas openexr openjph suitesparse fi fi # Library Extraction (LLVM is now extracted in BOTH modes) echo "Extracting Clang library..." [ -f "${OUTPUT}"/llvm-*.txz ] && tar -xf "${OUTPUT}"/llvm-*.txz -C "$PKG" --wildcards "usr/lib${LIBDIRSUFFIX}/libclang.so*" if [ "$MODE" == "full" ]; then echo "Extracting extra libraries for Full mode..." [ -f "${OUTPUT}"/gcc-gfortran-*.txz ] && tar -xf "${OUTPUT}"/gcc-gfortran-*.txz -C "$PKG" --wildcards "usr/lib${LIBDIRSUFFIX}/libgfortran.so.*" [ -f "${OUTPUT}"/mozjs*-*.txz ] && tar -xf "${OUTPUT}"/mozjs*-*.txz -C "$PKG" --wildcards "usr/lib${LIBDIRSUFFIX}/libmozjs-*.so*" fi # Symlink creation cd "$PKG/usr/lib${LIBDIRSUFFIX}" # CLANG symlinks REAL_CLANG=$(ls -S libclang.so.* 2>/dev/null | head -n 1) [ -n "$REAL_CLANG" ] && { ln -sf "$REAL_CLANG" "$(echo $REAL_CLANG | cut -d. -f1-4)"; ln -sf "$REAL_CLANG" "libclang.so"; } if [ "$MODE" == "full" ]; then # GFortran symlinks REAL_GFORTRAN=$(ls -S libgfortran.so.* 2>/dev/null | head -n 1) [ -n "$REAL_GFORTRAN" ] && { ln -sf "$REAL_GFORTRAN" "libgfortran.so.$(echo $REAL_GFORTRAN | cut -d. -f3)"; ln -sf "$REAL_GFORTRAN" "libgfortran.so"; } # MozJS symlinks REAL_MOZJS=$(ls -S libmozjs-*.so.*.* 2>/dev/null | head -n 1) [ -n "$REAL_MOZJS" ] && { ln -sf "$REAL_MOZJS" "$(echo $REAL_MOZJS | rev | cut -d. -f3- | rev)"; } fi cd $PKG # Install downloaded .txz files to the package root rm -f ${OUTPUT}/{gcc-gfortran,mozjs*-*,llvm}-*.txz for i in $(ls ${OUTPUT}/*.txz | sort); do ROOT=$PKG installpkg $i >/dev/null; done # Cleanup echo "Cleaning up unnecessary files..." rm -rf $PKG/usr/{doc,include,man} rm -rf $PKG/usr/lib${LIBDIRSUFFIX}/{cmake,pkgconfig} rm -rf $PKG/usr/libexec rm -rf $PKG/usr/share/{appstream,bash-completion,doc,gettext,ghostscript,gir-1.0,gjs-1.0,gtk-doc,installed-tests,libwmf,metainfo,vala} rm -rf $PKG/var/lib/pkgtools/scripts/* # Binary filtering find "$PKG/usr/bin" -maxdepth 1 \( -type f -o -type l \) \ ! -name "gimp*" \ ! -name "gegl*" \ ! -name "babl*" \ -delete # Remove MimeTypes sed -i 's|application/pdf;||' ${ICON} sed -i 's|image/dds;image/g3-fax;||' ${ICON} sed -i 's|image/gif;||' ${ICON} sed -i 's|image/jp2;image/jpeg;||' ${ICON} sed -i 's|image/bmp;||' ${ICON} sed -i 's|image/png;||' ${ICON} sed -i 's|image/svg+xml;||' ${ICON} sed -i 's|image/tiff;||' ${ICON} sed -i 's|image/vnd.wap.wbmp;image/webp;||' ${ICON} sed -i 's|image/x-dcm;image/x-dcx;image/x-eps;||' ${ICON} sed -i 's|image/x-fits;image/x-flic;image/x-icns;image/x-ico;||' ${ICON} sed -i 's|image/x-jp2-codestream;image/x-pcx;||' ${ICON} sed -i 's|image/x-pixmap;image/x-portable-anymap;image/x-portable-arbitrarymap;||' ${ICON} sed -i 's|image/x-portable-bitmap;image/x-portable-floatmap;image/x-portable-graymap;image/x-portable-pixmap;||' ${ICON} sed -i 's|image/x-psp;image/x-sgi;image/x-sun-raster;image/x-tga;image/x-wmf;||' ${ICON} sed -i 's|image/x-xbitmap;image/x-xwindowdump||' ${ICON} # Add Russian translation sed -i 's|Name\[ru\]\=GNU Image Manipulation Program|Name\[ru\]\=Редактор изображений GIMP|' $PKG/usr/share/applications/gimp.desktop # Locale selection and filtering function array_menu(){ echo -e "\n$1" echo "$2" select CHOICE in ${RESULT[@]}; do # If no choice is made, default to en_US [ -z "$CHOICE" ] && CHOICE="en_US" echo -e "${BOLD}${CYAN}${CHOICE}${RESET} locale chosen"; break done } RESULT=(af am ar as ast az be bg bn br bs ca 'ca@valencia' ckb cs csb da de dz el en_CA en_GB en_US eo es et eu fa fi fr fur fy ga gd gl gu he hi hr hu hy id is it ja ka kab kk km kn ko ky lt lv mai mk ml mn mr ms my nb nds ne nl nn nn_NO oc pa pl pt pt_BR ro ru rw sc se si sk sl sq sr 'sr@latin' sv ta te tg th tr tt uk uz vi wa xh yi zh_CN zh_HK zh_TW) array_menu "Select a locale from the list:" "Note: en_US and your choice will be kept. All other locales will be removed." find $PKG/usr/share/locale/ -maxdepth 1 -type d ! -name 'locale' | grep -Ev "(${CHOICE}|en_US)" | xargs -i rm -rf {} find $PKG/usr/share/locale -type f ! -name 'gimp30*.mo' -delete # Apply the same logic to GIMP extensions locales if they exist if [ -d $PKG/usr/lib${LIBDIRSUFFIX}/gimp ]; then find $PKG/usr/lib${LIBDIRSUFFIX}/gimp/*.*/extensions/org.gimp.extension.goat-exercises/locale -maxdepth 1 -type d ! -name 'locale' 2>/dev/null | grep -Ev "(${CHOICE}|en_US)" | xargs -i rm -rf {} fi dir2xzm $PKG $OUTPUT/$PRGNAM-$VERSION-$CHOICE-$MODE-$ARCH-$BUILD.xzm # Check on GIMP 3.x.x xzm file exists in /tmp if [ -f "${OUTPUT}/${PRGNAM}-${VERSION}-${CHOICE}-${MODE}-${ARCH}-${BUILD}.xzm" ]; then echo -e "\n${BOLD}Your ${PRGNAM} module is at: ${GREEN}${BOLD}${OUTPUT}/${PRGNAM}-${VERSION}-${CHOICE}-${MODE}-${ARCH}-${BUILD}.xzm${RESET}\n${BOLD}Please copy it to your modules folder to survive a reboot.${RESET}\n" else echo -e "\n${RED}${BOLD}Faile. Your $PRGNAM module is not built.${RESET}\n" fi cleanup