Skip to content

Conversation

@brainy
Copy link

@brainy brainy commented Jul 2, 2025

The GIMP App on macOS has all the shared libraries that the plugin needs, it just doesn't have the headers. This change uses include paths from pre-built libraries (from Homebrew or MacPorts) and the GIMP source tree (from git or a release tarball) to build the plugin and force it to use the shared libraries that are installed with GIMP.app.

The GIMP App on macOS has all the shared libraries that the plugin
needs, it just doesn't have the headers. This change uses include
paths from pre-built libraries (from Homebrew or MacPorts) and the
GIMP source tree (from git or a release tarball) to build the plugin
and force it to use the shared libraries that are installed with
GIMP.app.
@brainy
Copy link
Author

brainy commented Jul 2, 2025

I use this shell script to build the plugin:

#!/usr/bin/env bash

gimpver=gimp-3.0.4
gimptar=${gimpver}.tar.xz
gimpurl=https://download.gimp.org/gimp/v3.0/$gimptar
resynth=https://github.com/bootchk/resynthesizer.git
srcdir=resynthesizer
builddir=resynth-build
prefix=/opt/gimp
plugins=$prefix/3.0/plug-ins

here="$(cd $(dirname "$0") && pwd)"
abs_gimpsrc="$here/$gimpver"
abs_srcdir="$here/$srcdir"
abs_builddir="$here/$builddir"

set -e
set -x

cd $here

if [ ! -d $gimpver ]; then
    rm -fr $gimpver
    if [ ! -r $gimptar ]; then
        curl -LO $gimpurl
        shasum -c ${gimptar}.sha256
    fi
    xzcat ${gimptar} | tar x

    # Configure the libgimp version header.
    ver=$(sed -E 's/^( +version: +'"'"'([0-9.]+))?.*$/\2/' $gimpver/meson.build)
    vmaj=$(echo $ver | sed -Ee 's/^([0-9]+).*$/\1/')
    vmin=$(echo $ver | sed -Ee 's/^[^.]+\.([0-9]+).*$/\1/')
    vmic=$(echo $ver | sed -Ee 's/^[^.]+\.[^.]+\.([0-9]+).*$/\1/')
    cat $gimpver/libgimpbase/gimpversion.h.in         \
        | sed -e s/@GIMP_MAJOR_VERSION@/$vmaj/        \
              -e s/@GIMP_MINOR_VERSION@/$vmin/        \
              -e s/@GIMP_MICRO_VERSION@/$vmic/        \
              -e s/@GIMP_API_VERSION@/$vmaj.$vmin/    \
              -e s/@GIMP_VERSION@/$vmaj.$vmin.$vmic/  \
        > $gimpver/libgimpbase/gimpversion.h
fi

if [ ! -d $srcdir ]; then
    rm -fr $srcdir
    git clone $resynth --branch resynthesizer3 $srcdir
    (
        cd $srcdir
        git checkout -b macosbuild3
    )
fi

rm -fr $builddir
mkdir $builddir
meson setup \
      --prefix="$prefix" \
      -Dgimp-plugin-dir="$plugins" \
      -Dgimp-source-dir="$abs_gimpsrc" \
      -Dmac-gimp-app="/Applications/GIMP.app" \
      $builddir $srcdir
cd $builddir
meson compile
meson install

@bootchk
Copy link
Owner

bootchk commented Jul 2, 2025

Thanks.

I don't understand. If the resynthesizer doesn't directly call those libraries (I don't think it does) then it doesn't need the headers for those libraries.

I agree that during linking, it must use the same libraries as GIMP. So there is a transitive dependence on those libraries (the libraries themselves, not their headers.)

But I am wondering why meson doesn't do that. Maybe it just doesn't, and parts of your fix are necessary. IOW I hate to make the meson.build more complicated than necessary. I could be wrong, I will need to study it more.

@brainy
Copy link
Author

brainy commented Jul 2, 2025

When you #include <libgimp/gimp.h>, that eventually pulls in headers from all the other packages. Those packages are, in fact if not in intent, part of libgimp's public API.

I considered calling pkg-config --cflags-only-I directly from meson.build instead of using dependency(). It might be better, because it would avoid silently pulling in the actual libraries from the installed packages, which in turn requires all those "unnecessary" cc.find_library() calls that are there only in order to prioritize the libs from GIMP.app for linking.

I'll try that, it might end up simplifying meson.build. I'm not happy with all the bespoke dependency juggling, either.

Unfortunately macOS does not have a common package manager and installer. A mac "app" is just a directory tree with everything the app needs in there, including shared libraries that, on Linux, would normally be separate dependencies installed in /usr.

@brainy
Copy link
Author

brainy commented Jul 2, 2025

When you #include <libgimp/gimp.h>, that eventually pulls in headers from all the other packages. Those packages are, in fact if not in intent, part of libgimp's public API.

In fact you get those include paths automagically on Linux from the dependency('gimp-3.0', version : '>=2.99.0') call. I simply have to make them explicit on macOS.

Rename the option 'mac-gimp-souce' to 'gimp-source-dir'.
@brainy
Copy link
Author

brainy commented Jul 2, 2025

So it turns out that even with the recent commit that uses only the include paths from all the dependent packages, I still have to explicitly list all the shared libs provided in GIMP.app. That's because cc.find_library() doesn't create a transitive tree of all loaded libraries, so the linker needs to be told explicitly where to find the symbols it needs.

Again, this is something what would happen automagically on Linux with the gimp-3.0-dev dependency.

… the

symbols that are available in that version.
@brainy
Copy link
Author

brainy commented Jul 19, 2025

To follow up, with this patch I can build a working resynthesizer plugin on macOS. Tested with GIMP 3.0.2 and 3.0.4 on ARM64 (M3 Max).

$ otool -L /opt/gimp/3.0/plug-ins/resynthesizer/resynthesizer 
/opt/gimp/3.0/plug-ins/resynthesizer/resynthesizer:
	@rpath/lib/libgimp-3.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	@rpath/lib/libglib-2.0.0.dylib (compatibility version 7801.0.0, current version 7801.4.0)
	@rpath/lib/libgobject-2.0.0.dylib (compatibility version 7801.0.0, current version 7801.4.0)
	@rpath/lib/libgegl-0.4.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	@rpath/lib/libbabl-0.1.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	@rpath/lib/libintl.8.dylib (compatibility version 13.0.0, current version 13.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)

and

$ otool -l /opt/gimp/3.0/plug-ins/resynthesizer/resynthesizer | fgrep -C2 RPATH
Load command 21
          cmd LC_RPATH
      cmdsize 56
         path /Applications/GIMP.app/Contents/Resources (offset 12)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants