How to package a plugin that will work on MacOS
Special actions need to be taken in order for binary plug-ins work on the macOS version of GIMP. Specifically, they should be packaged as .pkg. This is due to Apple security restrictions, for example. From start, they needs:
- properly linked and codesigned binaries
- distribution.xml file
- .pkg notarization
Ensuring macOS linking and codesigning
Since the GIMP .dmg is generated from a choosen MACOSX_DEPLOYMENT_TARGET,
binary plug-ins should be built accordingly to ensure the right symbols.
The devel-docs/os-support.txt file on GIMP source is the reference but
you may need to double-check the https://gimp.org/downloads page to safe.
Additionally, for x86_64 cross compile, use these commands when invoking gimptool:
softwareupdate --install-rosetta --agree-to-license
arch -x86_64 /path_to/gimptoolIf you want to make your plug-in available for both x86_64 and arm64 macOS you can build them individually and then “glue” the two binaries together into a “universal binary”. After building the two binaries run:
lipo -create -arch x86_64 /path_to/x86_64/plug-in -arch arm64 /path_to/arm64/plug-in -output /path_to/where_you_want_it_stored/plug-inAfter compiling, codesign the plug-in binaries. To codesign run the below command.
codesign -s "Developer ID Application" --timestamp --options runtime --entitlements /path_to/entitlements.plist /path_to/plug-inReplace Developer ID Application with your developer ID (you need a paid developer account).
You will also need to codesign with hardened runtime which will also require you to point to an entitlements.plist file. This is the file that GIMP uses, which may or may not be right for a plugin: Hardening entitlements. Codesigning is only needed for distributing your plug-in.
Creating a PKG installer
The best way to install your plugin is using a PKG package.
Change GIMP-APP-VERSION, DEV-NAME, PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES appropriately below.
First, create a folder structure in folder called package, with your plugin in a subfolder named gimp_plugin.
In another subfolder called script place a file called postinstall with the following content:
#!/bin/sh
mkdir -p $HOME/Library/Application\ Support/GIMP/GIMP-APP-VERSION/plug-ins/PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES
cp -pf /tmp/gimp_plugin/* $HOME/Library/Application\ Support/GIMP/GIMP-APP-VERSION/plug-ins/PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACESChange the file script/postinstall file to be executable (chmod +x ./script/postinstall).
Finally, create a file called distributions.xml in the folder package with the content:
<?xml version="1.0" encoding="utf8"?>
<installer-gui-script minSpecVersion="2">
<title>PLUG-IN-NAME</title>>
<options customize="never"/>
<domains enable_anywhere="false" enable_currentUserHome="true" enable_localSystem="false"/>
<choices-outline>
<line choice="plug-in"/>
</choices-outline>
<choice id="plug-in" visible="false" customLocation="/tmp/gimp_plugin">
<pkg-ref id="org.DEV-NAME.PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES.pkg" version="0" onConclusion="none">temp_plugin.pkg</pkg-ref>
</choice>
</installer-gui-script>Inside the package folder, run:
pkgbuild --nopayload --identifier org.DEV-NAME.PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES.pkg --scripts ./script --root ./gimp_plugin/ temp_plugin.pkgThen sign the package:
productbuild --distribution ./distribution.xml --sign "Developer ID Installer: YOUR NAME" --timestamp --package-path temp_plugin.pkg ./PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES.pkg- Use
productbuild --distribution ./distribution.xml --package-path temp_plugin.pkg ./plugin_name.pkgif you don’t sign.
You can now delete the temp_plugin.pkg, it was only a temporary file.
Short breakdown of what this all does:
Pkgbuild packages your plugin and sets up the script. Productbuild uses this package, sets it to run as the installing user (enable_currentUserHome="true") and to install the plugin to a temporary folder /tmp/gimp_plugin.
When you run the installer, the plugin gets installed to /tmp/gimp_plugin and the script copies it over to $HOME/Library/Application\ Support/GIMP/GIMP-APP-VERSION/plug-ins/PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES.
Notarization
To notarize your plug-in with Apple, after packaging your codesigned plug-in package (PKG), run:
xcrun notarytool submit --wait --keychain-profile 'cert_container' PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES.pkg
xcrun stapler staple PLUG-IN-NAME-WITHOUT-SYMBOLS-OR-SPACES.pkgGetting cert_container ready will require a certain amount of setup (maybe it’s already done
with the certificates you used for codesigning) but follow Apple’s instructions.
Here is some links with information on the code that does notarization for GIMP: