{ stdenv, lib, fetchurl, replaceVars, meson, ninja, pkg-config, babl, bash-completion, cfitsio, gegl, gtk3, glib, gdk-pixbuf, graphviz, isocodes, pango, cairo, libarchive, luajit, freetype, fontconfig, lcms, libpng, libiff, libilbm, libjpeg, libjxl, poppler, poppler_data, libtiff, libmng, librsvg, libwmf, zlib, xz, libzip, ghostscript, aalib, shared-mime-info, python3, libexif, gettext, glibcLocales, wrapGAppsHook3, libxslt, gobject-introspection, vala, gi-docgen, perl, appstream, desktop-file-utils, libxpm, libxmu, glib-networking, json-glib, libmypaint, llvmPackages, gexiv2_0_10, harfbuzz, makeFontsConf, mypaint-brushes, libwebp, libheif, gjs, libgudev, openexr, xvfb-run, dbus, adwaita-icon-theme, alsa-lib, desktopToDarwinBundle, qoi, }: let python = python3.withPackages ( pp: with pp; [ pygobject3 ] ); in stdenv.mkDerivation (finalAttrs: { pname = "gimp"; version = "3.2.6"; outputs = [ "out" "dev" "devdoc" "man" ]; src = fetchurl { url = "https://download.gimp.org/gimp/v${lib.versions.majorMinor finalAttrs.version}/gimp-${finalAttrs.version}.tar.xz"; hash = "sha256-QLFekK0MDGMbdto8Rn6phH+lwk83QTrFtJKASGCijNg="; }; patches = [ # to remove compiler from the runtime closure, reference was retained via # gimp --version --verbose output (replaceVars ./remove-cc-reference.patch { cc_version = stdenv.cc.cc.name; }) # Use absolute paths instead of relying on PATH # to make sure plug-ins are loaded by the correct interpreter. # TODO: This now only appears to be used on Windows. (replaceVars ./hardcode-plugin-interpreters.patch { python_interpreter = python.interpreter; PYTHON_EXE = null; }) # D-Bus configuration is not available in the build sandbox # so we need to pick up the one from the package. (replaceVars ./tests-dbus-conf.patch { session_conf = "${dbus.out}/share/dbus-1/session.conf"; }) ]; nativeBuildInputs = [ meson ninja pkg-config gettext glibcLocales wrapGAppsHook3 libxslt # for xsltproc gobject-introspection perl python vala # for docs gi-docgen # for tests desktop-file-utils ] ++ lib.optionals stdenv.hostPlatform.isLinux [ dbus xvfb-run ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ desktopToDarwinBundle ]; buildInputs = [ appstream # for library babl bash-completion cfitsio gegl gtk3 glib gdk-pixbuf pango cairo libarchive gexiv2_0_10 harfbuzz isocodes freetype fontconfig lcms libpng libiff libilbm libjpeg libjxl poppler poppler_data libtiff openexr libmng librsvg libwmf zlib xz libzip ghostscript aalib shared-mime-info json-glib libwebp libheif python libexif libxpm libxmu glib-networking libmypaint mypaint-brushes qoi # New file dialogue crashes with “Icon 'image-missing' not present in theme Symbolic” without an icon theme. adwaita-icon-theme ] # for Lua plug-ins; LuaJIT is unavailable on riscv64 # https://github.com/LuaJIT/LuaJIT/issues/628 ++ lib.optionals (lib.meta.availableOn stdenv.hostPlatform luajit) [ (luajit.withPackages (pp: [ pp.lgi ])) ] ++ lib.optionals stdenv.hostPlatform.isLinux [ alsa-lib # for JavaScript plug-ins gjs ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ llvmPackages.openmp ] ++ lib.optionals stdenv.hostPlatform.isLinux [ libgudev ]; propagatedBuildInputs = [ # needed by gimp-3.0.pc gegl cairo pango gexiv2_0_10 ]; strictDeps = true; mesonFlags = [ "-Dbug-report-url=https://github.com/NixOS/nixpkgs/issues/new" "-Dicc-directory=/run/current-system/sw/share/color/icc" "-Dcheck-update=no" (lib.mesonEnable "gudev" stdenv.hostPlatform.isLinux) (lib.mesonEnable "headless-tests" stdenv.hostPlatform.isLinux) (lib.mesonEnable "linux-input" stdenv.hostPlatform.isLinux) # Not very important to do downstream, save a dependency. "-Dappdata-test=disabled" ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ "-Dalsa=disabled" "-Djavascript=disabled" ]; doCheck = true; env = { # The check runs before glib-networking is registered GIO_EXTRA_MODULES = "${glib-networking}/lib/gio/modules"; NIX_CFLAGS_COMPILE = lib.optionalString stdenv.hostPlatform.isDarwin "-DGDK_OSX_BIG_SUR=16"; # Check if librsvg was built with --disable-pixbuf-loader. PKG_CONFIG_GDK_PIXBUF_2_0_GDK_PIXBUF_MODULEDIR = "${librsvg}/${gdk-pixbuf.moduleDir}"; # Silence fontconfig warnings about missing config during tests FONTCONFIG_FILE = makeFontsConf { fontDirectories = [ ]; }; }; postPatch = '' patchShebangs tools/gimp-mkenums # GIMP is executed at build time so we need to fix this. # TODO: Look into if we can fix the interp thing. chmod +x plug-ins/python/{colorxhtml,file-openraster,foggify,gradients-save-as-css,histogram-export,palette-export-as-kpl,palette-offset,palette-sort,palette-to-gradient,python-eval,spyro-plus}.py patchShebangs \ plug-ins/python/{colorxhtml,file-openraster,foggify,gradients-save-as-css,histogram-export,palette-export-as-kpl,palette-offset,palette-sort,palette-to-gradient,python-eval,spyro-plus}.py ''; preBuild = let librarySuffix = if stdenv.hostPlatform.extensions.library == ".so" then "3.0.so.0" else if stdenv.hostPlatform.extensions.library == ".dylib" then "3.0.0.dylib" else throw "Unsupported library extension ‘${stdenv.hostPlatform.extensions.library}’"; in '' # Our gobject-introspection patches make the shared library paths absolute # in the GIR files. When running GIMP in build or check phase, it will try # to use plug-ins, which import GIMP introspection files which will try # to load the GIMP libraries which will not be installed yet. # So we need to replace the absolute path with a local one. # We are using a symlink that will be overridden during installation. mkdir -p "$out/lib" ln -s "$PWD/libgimp/libgimp-${librarySuffix}" \ "$PWD/libgimpbase/libgimpbase-${librarySuffix}" \ "$PWD/libgimpcolor/libgimpcolor-${librarySuffix}" \ "$PWD/libgimpconfig/libgimpconfig-${librarySuffix}" \ "$PWD/libgimpmath/libgimpmath-${librarySuffix}" \ "$PWD/libgimpmodule/libgimpmodule-${librarySuffix}" \ "$out/lib/" ''; preCheck = '' # Avoid “Error retrieving accessibility bus address” export NO_AT_BRIDGE=1 # Fix storing recent file list in tests export HOME="$TMPDIR" export XDG_DATA_DIRS="${glib.getSchemaDataDirPath gtk3}:${adwaita-icon-theme}/share:$XDG_DATA_DIRS" ''; preFixup = '' gappsWrapperArgs+=(--prefix PATH : "${ lib.makeBinPath [ # for dot for gegl:introspect (Debug » Show Image Graph, hidden by default on stable release) graphviz # for gimp-script-fu-interpreter-3.0 invoked by shebang of some plug-ins "$out" ] }" --suffix XDG_DATA_DIRS : "${adwaita-icon-theme}/share") ''; postFixup = '' # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back. moveToOutput "share/doc" "$devdoc" ''; passthru = { # The declarations for `gimp-with-plugins` wrapper, # used for determining plug-in installation paths apiVersion = "${ toString ( lib.toInt (lib.versions.major finalAttrs.version) + (if lib.versions.minor finalAttrs.version == "99" then 1 else 0) ) }.0"; appVersion = lib.versions.majorMinor finalAttrs.version; majorVersion = lib.warn "gimp.majorVersion is deprecated in favour of gimp.apiVersion and gimp.appVersion" finalAttrs.passthru.apiVersion; targetLibDir = "lib/gimp/${finalAttrs.passthru.apiVersion}"; targetDataDir = "share/gimp/${finalAttrs.passthru.apiVersion}"; targetPluginDir = "${finalAttrs.passthru.targetLibDir}/plug-ins"; targetScriptDir = "${finalAttrs.passthru.targetDataDir}/scripts"; # probably its a good idea to use the same gtk in plugins ? gtk = gtk3; }; meta = { description = "GNU Image Manipulation Program"; homepage = "https://www.gimp.org/"; donationPage = "https://www.gimp.org/donating/"; maintainers = with lib.maintainers; [ jtojnar bddvlpr ]; license = lib.licenses.gpl3Plus; platforms = lib.platforms.linux; # Build invokes built binary to convert assets, binary hangs during plugin loading on big-endian platforms (s390x, ppc64) # https://gitlab.gnome.org/GNOME/gimp/-/issues/12522 broken = stdenv.hostPlatform.isBigEndian; mainProgram = "gimp"; }; })