summaryrefslogtreecommitdiffstats
path: root/packaging/macos
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/macos')
-rwxr-xr-xpackaging/macos/110-bootstrap_jhb.sh31
-rwxr-xr-xpackaging/macos/120-build_gtk3.sh37
-rwxr-xr-xpackaging/macos/130-build_inkdeps.sh44
-rwxr-xr-xpackaging/macos/140-build_packaging.sh44
-rwxr-xr-xpackaging/macos/210-inkscape_build.sh90
-rwxr-xr-xpackaging/macos/220-inkscape_package.sh184
-rwxr-xr-xpackaging/macos/230-inkscape_distrib.sh48
-rwxr-xr-xpackaging/macos/310-inkscape_test.sh54
-rw-r--r--packaging/macos/README.md3
-rwxr-xr-xpackaging/macos/build_inkscape.sh33
-rwxr-xr-xpackaging/macos/build_toolset.sh34
-rwxr-xr-xpackaging/macos/install_toolset.sh36
-rw-r--r--packaging/macos/jhb/README.md17
-rw-r--r--packaging/macos/jhb/etc/jhb.conf.sh53
l---------packaging/macos/jhb/etc/jhb.conf/10.sh1
l---------packaging/macos/jhb/etc/jhb.conf/20.sh1
l---------packaging/macos/jhb/etc/jhb.conf/30.sh1
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/README.md12
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/bash_d.sh30
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/ccache.sh49
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/ci.sh42
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/directories.sh83
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/dmgbuild.sh96
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/home.sh24
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/jhbuild.sh229
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/path.sh23
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/pip.sh26
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/release.sh35
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/sdkroot.sh41
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/sys.sh121
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/temp.sh27
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/version.sh24
-rw-r--r--packaging/macos/jhb/etc/jhb.conf/xdg.sh25
-rw-r--r--packaging/macos/jhb/etc/jhbuildrc613
-rw-r--r--packaging/macos/jhb/etc/modulesets/jhb/bootstrap.modules158
-rw-r--r--packaging/macos/jhb/etc/modulesets/jhb/jhb.modules60
-rw-r--r--packaging/macos/jhb/etc/modulesets/jhb/moduleset.dtd240
-rw-r--r--packaging/macos/jhb/etc/modulesets/jhb/moduleset.xsl196
-rw-r--r--packaging/macos/jhb/etc/modulesets/jhb/patches/libtool-apple-sort.patch38
-rw-r--r--packaging/macos/jhb/etc/modulesets/jhb/patches/vasnprintf.patch11
-rwxr-xr-xpackaging/macos/jhb/usr/bin/archive205
-rwxr-xr-xpackaging/macos/jhb/usr/bin/bootstrap135
-rwxr-xr-xpackaging/macos/jhb/usr/bin/jhb63
-rwxr-xr-xpackaging/macos/jhb/usr/bin/run-parts73
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/README.md9
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/ansi.sh76
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/assert.sh42
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/bash_d.sh98
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/echo.sh52
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/error.sh45
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/lib.sh174
-rw-r--r--packaging/macos/jhb/usr/src/bash_d/readlinkf.sh27
-rw-r--r--packaging/macos/modulesets/README.md8
-rw-r--r--packaging/macos/modulesets/gtk-osx-bootstrap.modules119
-rw-r--r--packaging/macos/modulesets/gtk-osx-gtkmm.modules80
-rw-r--r--packaging/macos/modulesets/gtk-osx-network.modules153
-rw-r--r--packaging/macos/modulesets/gtk-osx-python.modules150
-rw-r--r--packaging/macos/modulesets/gtk-osx-random.modules168
-rw-r--r--packaging/macos/modulesets/gtk-osx.modules336
-rw-r--r--packaging/macos/modulesets/inkscape.modules371
-rw-r--r--packaging/macos/modulesets/jhbuildrc4
l---------packaging/macos/modulesets/moduleset.dtd1
l---------packaging/macos/modulesets/moduleset.xsl1
-rw-r--r--packaging/macos/modulesets/patches/Quartz-version-detection-for-macOS-12.patch67
-rw-r--r--packaging/macos/modulesets/patches/README.md3
-rw-r--r--packaging/macos/modulesets/patches/cairo-color_mgmt_perf.patch472
-rw-r--r--packaging/macos/modulesets/patches/cairo-pixman_dithering.patch659
-rw-r--r--packaging/macos/modulesets/patches/cairo-snapshot_leak.patch27
-rw-r--r--packaging/macos/modulesets/patches/enchant-relocatable.patch38
-rw-r--r--packaging/macos/modulesets/patches/frodo-getopt-autotools.patch28
-rw-r--r--packaging/macos/modulesets/patches/gdk-pixbuf-loader-name.patch25
-rw-r--r--packaging/macos/modulesets/patches/ghostscript_configure_libtiff.patch11
-rw-r--r--packaging/macos/modulesets/patches/ghostscript_link_cupsimage.patch11
-rw-r--r--packaging/macos/modulesets/patches/graphviz-remove-rpath.patch55
-rw-r--r--packaging/macos/modulesets/patches/gspell-makefile_objc.patch20
-rw-r--r--packaging/macos/modulesets/patches/gspell-remove_gtkmacintegration.patch59
-rw-r--r--packaging/macos/modulesets/patches/gtk+-scale-absolute-value.patch32
-rw-r--r--packaging/macos/modulesets/patches/gtk-3.24.33-quartz-window-transient-for.patch46
-rw-r--r--packaging/macos/modulesets/patches/gtk-3.24.33-remove-gtk4-update-icon-cache-dependency.patch10
-rw-r--r--packaging/macos/modulesets/patches/gtk-mac-bundler_configure.patch24
-rw-r--r--packaging/macos/modulesets/patches/gtkmm-3-bad-const-property-background.patch13
-rw-r--r--packaging/macos/modulesets/patches/imagemagick_configure_pango.patch18
-rw-r--r--packaging/macos/modulesets/patches/itstool-config-python.patch14
-rw-r--r--packaging/macos/modulesets/patches/libtasn1-inline-fix.patch10
-rw-r--r--packaging/macos/modulesets/patches/libxml2-python-config.patch23
-rw-r--r--packaging/macos/modulesets/patches/pango-coretext-fix-clang-build-failure.patch30
-rw-r--r--packaging/macos/modulesets/patches/rust_cmake_install.patch27
-rw-r--r--packaging/macos/modulesets/patches/shared-mime-info-2.1-freedesktop-generate.patch27
-rw-r--r--packaging/macos/modulesets/patches/tiff-nohtml.patch44
-rw-r--r--packaging/macos/modulesets/patches/xmlto-allow-net-access.patch27
-rw-r--r--packaging/macos/res/Inkscape-Generic.icnsbin0 -> 100381 bytes
-rw-r--r--packaging/macos/res/application-gimp-gradient.icnsbin0 -> 107998 bytes
-rw-r--r--packaging/macos/res/application-illustrator-svg.icnsbin0 -> 111240 bytes
-rw-r--r--packaging/macos/res/application-illustrator.icnsbin0 -> 105960 bytes
-rw-r--r--packaging/macos/res/application-pdf.icnsbin0 -> 108879 bytes
-rw-r--r--packaging/macos/res/application-vnd.corel-draw-compressed.icnsbin0 -> 109979 bytes
-rw-r--r--packaging/macos/res/application-vnd.corel-draw-template.icnsbin0 -> 109021 bytes
-rw-r--r--packaging/macos/res/application-vnd.corel-draw.icnsbin0 -> 109756 bytes
-rw-r--r--packaging/macos/res/application-vnd.ms.xaml.icnsbin0 -> 111445 bytes
-rw-r--r--packaging/macos/res/application-vnd.wordperfect-graphic.icnsbin0 -> 110434 bytes
-rw-r--r--packaging/macos/res/fonts.conf67
-rw-r--r--packaging/macos/res/image-svg+xml-compressed.icnsbin0 -> 109445 bytes
-rw-r--r--packaging/macos/res/image-svg+xml.icnsbin0 -> 110098 bytes
-rw-r--r--packaging/macos/res/image-vnd.dxf.icnsbin0 -> 109423 bytes
-rw-r--r--packaging/macos/res/image-vnd.windows-metafile.icnsbin0 -> 110447 bytes
-rw-r--r--packaging/macos/res/inkscape.plist485
-rw-r--r--packaging/macos/res/mibap_icon.pngbin0 -> 7359 bytes
-rw-r--r--packaging/macos/src/cairosvg.sh38
-rw-r--r--packaging/macos/src/ink.sh329
-rw-r--r--packaging/macos/src/inkscape.bundle181
-rw-r--r--packaging/macos/src/inkscape_dmg.py246
-rw-r--r--packaging/macos/src/jhb-custom.conf.sh41
-rw-r--r--packaging/macos/src/png2icns.sh37
-rw-r--r--packaging/macos/src/svg2icns.sh56
-rwxr-xr-xpackaging/macos/uninstall_toolset.sh58
115 files changed, 8662 insertions, 0 deletions
diff --git a/packaging/macos/110-bootstrap_jhb.sh b/packaging/macos/110-bootstrap_jhb.sh
new file mode 100755
index 0000000..914783d
--- /dev/null
+++ b/packaging/macos/110-bootstrap_jhb.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Bootstrap jhb with our slightly customized configuration. We use our own
+# versioning and naming scheme, making this incompatible with the pre-built
+# bootstrapped jhb archive (everything will be built from scratch here).
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+SELF_DIR=$(dirname "${BASH_SOURCE[0]}")
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+"$SELF_DIR"/jhb/usr/bin/bootstrap "$SELF_DIR"/src/jhb-custom.conf.sh
diff --git a/packaging/macos/120-build_gtk3.sh b/packaging/macos/120-build_gtk3.sh
new file mode 100755
index 0000000..e253440
--- /dev/null
+++ b/packaging/macos/120-build_gtk3.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Install GTK3 libraries and their dependencies.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+### variables ##################################################################
+
+SELF_DIR=$(dirname "$(greadlink -f "$0")")
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+jhb configure "$SELF_DIR"/modulesets/inkscape.modules
+
+jhb build \
+ pygments
+
+jhb build \
+ meta-gtk-osx-bootstrap \
+ meta-gtk-osx-gtk3 \
+ gtkmm3
diff --git a/packaging/macos/130-build_inkdeps.sh b/packaging/macos/130-build_inkdeps.sh
new file mode 100755
index 0000000..c062bcc
--- /dev/null
+++ b/packaging/macos/130-build_inkdeps.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Install remaining Inkscape dependencies, i.e. everything besides the GTK3
+# stack.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+source "$(dirname "${BASH_SOURCE[0]}")"/src/ink.sh
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+#------------------------------------------------------ dependencies besides GTK
+
+jhb build meta-inkscape-dependencies
+
+#------------------------------------------------- run time dependencies: Python
+
+# Download custom Python runtime.
+
+ink_download_python
+
+# Build Python wheels and save them to our package cache.
+
+ink_build_wheels
diff --git a/packaging/macos/140-build_packaging.sh b/packaging/macos/140-build_packaging.sh
new file mode 100755
index 0000000..bb6a3f6
--- /dev/null
+++ b/packaging/macos/140-build_packaging.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Install additional tools that are no direct dependencies of Inkscape but that
+# we need for e.g. packaging the application.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+source "$(dirname "${BASH_SOURCE[0]}")"/src/svg2icns.sh
+
+bash_d_include error
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+if $CI; then # break in CI, otherwise we get interactive prompt by JHBuild
+ error_trace_enable
+fi
+
+#-------------------------------------------- install application bundle creator
+
+jhb build gtkmacbundler
+
+#------------------------------------------------- install svg to icns convertor
+
+svg2icns_install
diff --git a/packaging/macos/210-inkscape_build.sh b/packaging/macos/210-inkscape_build.sh
new file mode 100755
index 0000000..52a555a
--- /dev/null
+++ b/packaging/macos/210-inkscape_build.sh
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Build and install Inkscape. For non-CI builds, this will build Inkscape
+# master branch. Installation prefix is VER_DIR.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+source "$(dirname "${BASH_SOURCE[0]}")"/src/ink.sh
+
+bash_d_include error
+bash_d_include lib
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+error_trace_enable
+
+#----------------------------------------------------------- (re-) configure jhb
+
+# Rerun configuration to adapt to the current system. This will
+# - allow Inkscape to be build against a different SDK than the toolset has
+# been built with
+# - setup ccache
+
+jhb configure
+
+#---------------------------------------------------------------- build Inkscape
+
+# If we're not running in Inkscape CI, use either an existing source directory
+# or clone the sources there.
+if [ "$CI_PROJECT_NAME" != "inkscape" ]; then
+
+ if [ -d "$INK_DIR" ]; then # Sourcecode directory already there?
+ echo_i "using existing source $INK_DIR"
+ else
+ git clone \
+ --branch "$INK_BRANCH" \
+ --depth 10 \
+ --recurse-submodules \
+ --single-branch \
+ "$INK_URL" "$INK_DIR"
+ fi
+
+ # Ensure a clean build by removing files from a previous one if they exist.
+ if [ -d "$INK_BLD_DIR" ]; then
+ rm -rf "$INK_BLD_DIR"
+ fi
+fi
+
+mkdir -p "$INK_BLD_DIR"
+cd "$INK_BLD_DIR" || exit 1
+
+cmake \
+ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
+ -DCMAKE_C_COMPILER_LAUNCHER=ccache \
+ -DCMAKE_PREFIX_PATH="$VER_DIR" \
+ -DCMAKE_INSTALL_PREFIX="$VER_DIR" \
+ -GNinja \
+ "$INK_DIR"
+
+ninja
+ninja install
+
+#----------------------------------- make libraries work for unpackaged Inkscape
+
+# Most libraries are linked to with their fully qualified paths, a few have been
+# linked to using '@rpath'. The Inkscape binary only provides an LC_RPATH
+# setting for its custom library path 'lib/inkscape' at this point, so we need
+# to add the common library path 'lib'.
+
+lib_add_rpath @loader_path/../lib "$BIN_DIR"/inkscape
diff --git a/packaging/macos/220-inkscape_package.sh b/packaging/macos/220-inkscape_package.sh
new file mode 100755
index 0000000..02400dc
--- /dev/null
+++ b/packaging/macos/220-inkscape_package.sh
@@ -0,0 +1,184 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Create the application bundle and make everything relocatable.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+source "$(dirname "${BASH_SOURCE[0]}")"/src/ink.sh
+source "$(dirname "${BASH_SOURCE[0]}")"/src/svg2icns.sh
+
+bash_d_include error
+bash_d_include lib
+
+### variables ##################################################################
+
+SELF_DIR=$(dirname "$(greadlink -f "$0")")
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+error_trace_enable
+
+#----------------------------------------------------- create application bundle
+
+( # run gtk-mac-bundler
+
+ cp "$SELF_DIR"/src/inkscape.bundle "$INK_BLD_DIR"
+ cp "$SELF_DIR"/res/inkscape.plist "$INK_BLD_DIR"
+
+ cd "$INK_BLD_DIR" || exit 1
+ export ARTIFACT_DIR=$ARTIFACT_DIR # referenced in inkscape.bundle
+ jhb run gtk-mac-bundler inkscape.bundle
+)
+
+# Rename to get from lowercase "i" to capitalized "I" as the app bundle name
+# depends on the main binary (and that was lowercase in 0.9x).
+mv "$INK_APP_DIR" "$INK_APP_DIR".tmp # requires case-insensitive filesysystem
+mv "$INK_APP_DIR".tmp "$INK_APP_DIR"
+
+#----------------------------------------------------- adjust library link paths
+
+# Add rpath according to our app bundle structure.
+lib_clear_rpath "$INK_APP_EXE_DIR"/inkscape
+lib_add_rpath @executable_path/../Resources/lib "$INK_APP_EXE_DIR"/inkscape
+lib_add_rpath @executable_path/../Resources/lib/inkscape \
+ "$INK_APP_EXE_DIR"/inkscape
+
+# Libraries in INK_APP_LIB_DIR can reference each other directly.
+lib_change_siblings "$INK_APP_LIB_DIR"
+
+# Point GTK modules towards INK_APP_LIB_DIR using @loader_path.
+lib_change_paths @loader_path/../../.. "$INK_APP_LIB_DIR" \
+ "$INK_APP_LIB_DIR"/gtk-3.0/3.0.0/immodules/*.so \
+ "$INK_APP_LIB_DIR"/gtk-3.0/3.0.0/printbackends/*.so
+
+# Point enchant's applespell plugin towards INK_APP_LIB_DIR using @loader_path.
+lib_change_paths @loader_path/.. "$INK_APP_LIB_DIR" \
+ "$INK_APP_LIB_DIR"/enchant-2/enchant_applespell.so
+
+# Point Ghostscript towards INK_APP_LIB_DIR using @executable_path.
+lib_change_paths \
+ @executable_path/../lib \
+ "$INK_APP_LIB_DIR" \
+ "$INK_APP_BIN_DIR"/gs
+
+#------------------------------------------------------ use rpath in cache files
+
+sed -i '' \
+ 's|@executable_path/../Resources/lib|@rpath|g' \
+ "$INK_APP_LIB_DIR"/gtk-3.0/3.0.0/immodules.cache
+sed -i '' \
+ 's|@executable_path/../Resources/lib|@rpath|g' \
+ "$INK_APP_LIB_DIR"/gdk-pixbuf-2.0/2.10.0/loaders.cache
+
+#------------------------------------------------------------- modify Info.plist
+
+# update Inkscape version information
+/usr/libexec/PlistBuddy \
+ -c "Set CFBundleShortVersionString '$(ink_get_version)'" \
+ "$INK_APP_PLIST"
+/usr/libexec/PlistBuddy \
+ -c "Set CFBundleVersion '$INK_BUILD'" \
+ "$INK_APP_PLIST"
+
+# update minimum system version according to deployment target
+/usr/libexec/PlistBuddy \
+ -c "Set LSMinimumSystemVersion $SYS_SDK_VER" \
+ "$INK_APP_PLIST"
+
+# add some metadata to make CI identifiable
+if $CI_GITLAB; then
+ for var in PROJECT_NAME PROJECT_URL COMMIT_BRANCH COMMIT_SHA COMMIT_SHORT_SHA\
+ JOB_ID JOB_URL JOB_NAME PIPELINE_ID PIPELINE_URL; do
+ # use awk to create camel case strings (e.g. PROJECT_NAME to ProjectName)
+ /usr/libexec/PlistBuddy -c "Add CI$(\
+ echo $var | awk -F _ '{
+ for (i=1; i<=NF; i++)
+ printf "%s", toupper(substr($i,1,1)) tolower(substr($i,2))
+ }'
+ ) string $(eval echo \$CI_$var)" "$INK_APP_PLIST"
+ done
+fi
+
+#----------------------------------------------------- generate application icon
+
+svg2icns \
+ "$INK_DIR"/share/branding/inkscape-mac.svg \
+ "$INK_APP_RES_DIR"/inkscape.icns
+
+#----------------------------------------------------------- add file type icons
+
+cp "$INK_DIR"/packaging/macos/res/*.icns "$INK_APP_RES_DIR"
+
+#------------------------------------------------------- add Python and packages
+
+# Install externally built Python framework.
+ink_install_python
+
+# Add rpath to find libraries.
+lib_add_rpath @executable_path/../../../../../Resources/lib \
+ "$INK_APP_FRA_DIR"/Python.framework/Versions/Current/bin/\
+python"$INK_PYTHON_VER"
+lib_add_rpath @executable_path/../../../../../../../../Resources/lib \
+ "$INK_APP_FRA_DIR"/Python.framework/Versions/Current/Resources/\
+Python.app/Contents/MacOS/Python
+
+# Install wheels.
+ink_pipinstall INK_PYTHON_PKG_APPDIRS # extension manager
+ink_pipinstall INK_PYTHON_PKG_BEAUTIFULSOUP4 # extension manager
+ink_pipinstall INK_PYTHON_PKG_CACHECONTROL # extension manager
+ink_pipinstall INK_PYTHON_PKG_CSSSELECT
+ink_pipinstall INK_PYTHON_PKG_LXML
+ink_pipinstall INK_PYTHON_PKG_NUMPY
+ink_pipinstall INK_PYTHON_PKG_PILLOW # export raster extension
+ink_pipinstall INK_PYTHON_PKG_PYGOBJECT
+ink_pipinstall INK_PYTHON_PKG_PYSERIAL
+ink_pipinstall INK_PYTHON_PKG_SCOUR
+
+#----------------------------------------------------- remove Python cache files
+
+rm -rf "$INK_APP_RES_DIR"/share/glib-2.0/codegen/__pycache__
+
+#-------------------------------------------------- add fontconfig configuration
+
+# Mimic the behavior of having all files under 'share' and linking the
+# active ones to 'etc'.
+cd "$INK_APP_ETC_DIR"/fonts/conf.d || exit 1
+
+for file in ./*.conf; do
+ ln -sf ../../../share/fontconfig/conf.avail/"$(basename "$file")" .
+done
+
+# Our customized version loses all the non-macOS paths and sets a cache
+# directory below '$HOME/Library/Application Support/Inkscape'.
+cp "$SELF_DIR"/res/fonts.conf "$INK_APP_ETC_DIR"/fonts
+
+#-------------------------------- use rpath for GObject introspection repository
+
+for gir in "$INK_APP_RES_DIR"/share/gir-1.0/*.gir; do
+ sed "s|@executable_path/..|@rpath|g" "$gir" > "$TMP_DIR/$(basename "$gir")"
+done
+
+mv "$TMP_DIR"/*.gir "$INK_APP_RES_DIR"/share/gir-1.0
+
+# compile *.gir into *.typelib files
+for gir in "$INK_APP_RES_DIR"/share/gir-1.0/*.gir; do
+ jhb run g-ir-compiler \
+ -o "$INK_APP_LIB_DIR/girepository-1.0/$(basename -s .gir "$gir")".typelib \
+ "$gir"
+done
diff --git a/packaging/macos/230-inkscape_distrib.sh b/packaging/macos/230-inkscape_distrib.sh
new file mode 100755
index 0000000..2836e2b
--- /dev/null
+++ b/packaging/macos/230-inkscape_distrib.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Create a disk image for distribution.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+source "$(dirname "${BASH_SOURCE[0]}")"/src/ink.sh
+
+bash_d_include error
+
+### variables ##################################################################
+
+SELF_DIR=$(dirname "$(greadlink -f "$0")")
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+error_trace_enable
+
+# Create background for development snapshots. This is not meant for
+# official releases, those will be repackaged eventually (they also need
+# to be signed and notarized).
+LD_LIBRARY_PATH=$LIB_DIR convert -size 560x400 xc:transparent \
+ -font Andale-Mono -pointsize 64 -fill black \
+ -draw "text 20,60 'Inkscape'" \
+ -draw "text 20,120 '$(ink_get_version)'" \
+ -draw "text 20,180 'development'" \
+ -draw "text 20,240 'snapshot'" \
+ -draw "text 20,300 '$(ink_get_repo_shorthash)'" \
+ "$SRC_DIR"/inkscape_dmg.png
+
+# Create the disk image.
+dmgbuild_run "$SELF_DIR"/src/inkscape_dmg.py "$INK_APP_PLIST"
diff --git a/packaging/macos/310-inkscape_test.sh b/packaging/macos/310-inkscape_test.sh
new file mode 100755
index 0000000..fa5237e
--- /dev/null
+++ b/packaging/macos/310-inkscape_test.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Build and run the test suite.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh
+
+source "$(dirname "${BASH_SOURCE[0]}")"/src/ink.sh
+
+bash_d_include error
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+error_trace_enable
+
+#----------------------------------------------------------- (re-) configure jhb
+
+# Rerun configuration to adapt to the current system. This will
+# - allow Inkscape to be build against a different SDK than the toolset has
+# been built with
+# - setup ccache
+
+jhb configure
+
+#----------------------------------------------- install additional dependencies
+
+jhb run pip3 install "$PKG_DIR"/lxml*.whl
+
+#--------------------------------------------------------------------- run tests
+
+cd "$INK_BLD_DIR" || exit 1
+
+ninja tests # build tests
+
+ctest -V # run tests
diff --git a/packaging/macos/README.md b/packaging/macos/README.md
new file mode 100644
index 0000000..5103528
--- /dev/null
+++ b/packaging/macos/README.md
@@ -0,0 +1,3 @@
+# macOS build pipeline
+
+This folder contains the scripts that make up the build pipeline for Inkscape on macOS. The upstream project is [mibap](https://gitlab.com/inkscape/devel/mibap) which contains the complete development history. It also provides a disk image with precompiled dependencies so that Inkscape CI can focus on building the application.
diff --git a/packaging/macos/build_inkscape.sh b/packaging/macos/build_inkscape.sh
new file mode 100755
index 0000000..7c2ef59
--- /dev/null
+++ b/packaging/macos/build_inkscape.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Compile and package Inkscape
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+SELF_DIR=$(dirname "${BASH_SOURCE[0]}")
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+set -e
+
+for script in "$SELF_DIR"/2??-*.sh; do
+ $script
+done
diff --git a/packaging/macos/build_toolset.sh b/packaging/macos/build_toolset.sh
new file mode 100755
index 0000000..bf25168
--- /dev/null
+++ b/packaging/macos/build_toolset.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Create our JHBuild-based toolset with all dependencies to be able to
+# compile Inkscape.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+SELF_DIR=$(dirname "${BASH_SOURCE[0]}")
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+set -e
+
+for script in "$SELF_DIR"/1??-*.sh; do
+ $script
+done
diff --git a/packaging/macos/install_toolset.sh b/packaging/macos/install_toolset.sh
new file mode 100755
index 0000000..ec136a5
--- /dev/null
+++ b/packaging/macos/install_toolset.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Install a pre-compiled version of our JHBuild-based toolset and all the
+# required dependencies to build Inkscape.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh \
+ "$(dirname "${BASH_SOURCE[0]}")"/src/jhb-custom.conf.sh
+
+### variables ##################################################################
+
+SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1; pwd)
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+"$SELF_DIR"/jhb/usr/bin/archive install_dmg 3
+
+if [ "$1" = "restore_overlay" ]; then
+ # restore files fronm build stage
+ gtar -C "$VER_DIR" -xpJf "$ARTIFACT_DIR"/toolset_overlay.tar.xz
+fi
diff --git a/packaging/macos/jhb/README.md b/packaging/macos/jhb/README.md
new file mode 100644
index 0000000..04c025e
--- /dev/null
+++ b/packaging/macos/jhb/README.md
@@ -0,0 +1,17 @@
+# bootstrapped JHBuild for macOS
+
+This is my version of setting up JHBuild on macOS. It is inspired by and uses components of [gtk-osx](https://gitlab.gnome.org/GNOME/gtk-osx), but deviates from it in a few significant ways:
+
+- It uses a [FSH](https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html)-inspired directory layout.
+
+- It is fully self-contained to its directories, allowing for co-existence of multiple installations in locations of your choosing.
+
+- It uses a pre-built [Python.framework](https://gitlab.com/dehesselle/python_macos) to run JHBuild on OS X El Capitan up to macOS Monterey without relying on the system's Python.
+
+## usage
+
+TBD
+
+## license
+
+[GPL-2.0-or-later](LICENSE)
diff --git a/packaging/macos/jhb/etc/jhb.conf.sh b/packaging/macos/jhb/etc/jhb.conf.sh
new file mode 100644
index 0000000..398e9d3
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf.sh
@@ -0,0 +1,53 @@
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This is a convenience wrapper to source all individual configuration files.
+# It also takes care of placing a custom configuration file in the appropriate
+# location.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1; pwd)
+
+CUSTOM_CONFIG=$SELF_DIR/jhb-custom.conf.sh
+# copy a custom configuration file to the appropriate place
+if [[ $1 == *.conf.sh ]] && [ -f "$1" ]; then
+ cp "$1" "$CUSTOM_CONFIG"
+fi
+
+# source a custom configuration file if present
+if [ -f "$CUSTOM_CONFIG" ]; then
+ # shellcheck disable=SC1090 # file is optional
+ source "$CUSTOM_CONFIG"
+fi
+unset CUSTOM_CONFIG
+
+# source items from jhb.conf directory
+for CONFIG_ITEM in $(\
+ "$SELF_DIR"/../usr/bin/run-parts list "$SELF_DIR"/jhb.conf/'*.sh' \
+ ); do
+ # shellcheck disable=SC1090 # can't point to a single source here
+ source "$CONFIG_ITEM"
+done
+unset CONFIG_ITEM
+
+unset SELF_DIR
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/10.sh b/packaging/macos/jhb/etc/jhb.conf/10.sh
new file mode 120000
index 0000000..b7ae2b7
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/10.sh
@@ -0,0 +1 @@
+version.sh \ No newline at end of file
diff --git a/packaging/macos/jhb/etc/jhb.conf/20.sh b/packaging/macos/jhb/etc/jhb.conf/20.sh
new file mode 120000
index 0000000..96f9d20
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/20.sh
@@ -0,0 +1 @@
+ci.sh \ No newline at end of file
diff --git a/packaging/macos/jhb/etc/jhb.conf/30.sh b/packaging/macos/jhb/etc/jhb.conf/30.sh
new file mode 120000
index 0000000..c1d5631
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/30.sh
@@ -0,0 +1 @@
+directories.sh \ No newline at end of file
diff --git a/packaging/macos/jhb/etc/jhb.conf/README.md b/packaging/macos/jhb/etc/jhb.conf/README.md
new file mode 100644
index 0000000..c79b3ad
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/README.md
@@ -0,0 +1,12 @@
+# JHB configuration
+
+Files in here are being sourced by `../../usr/bin/run-parts`
+
+- in their lexical order _and_
+- only once in case a symlink exists.
+
+This way we don't have to prefix the filenames themselves to influnce the order of inclusion (a "poor man's dependency management").
+
+The filename is also the prefix for any variable or function name within.
+
+A file is not allowed to depend on any function or variable outside this directory, with the exception of functions included from `bash_d.sh`.
diff --git a/packaging/macos/jhb/etc/jhb.conf/bash_d.sh b/packaging/macos/jhb/etc/jhb.conf/bash_d.sh
new file mode 100644
index 0000000..5ab11b2
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/bash_d.sh
@@ -0,0 +1,30 @@
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Enable bash_d usage by providing bash_d_include function.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+# shellcheck source=../../usr/src/bash_d/bash_d.sh
+source "$(dirname "${BASH_SOURCE[0]}")"/../../usr/src/bash_d/bash_d.sh
+
+bash_d_include echo
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/ccache.sh b/packaging/macos/jhb/etc/jhb.conf/ccache.sh
new file mode 100644
index 0000000..82a2208
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/ccache.sh
@@ -0,0 +1,49 @@
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Settings and functions to setup ccache.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### variables ##################################################################
+
+export CCACHE_DIR=${CCACHE_DIR:-$WRK_DIR/ccache}
+
+# https://ccache.dev
+# https://github.com/ccache/ccache
+# https://gitlab.com/dehesselle/ccache_macos
+CCACHE_VER=4.6.3r1
+CCACHE_URL=https://gitlab.com/api/v4/projects/29039216/packages/generic/\
+ccache_macos/$CCACHE_VER/ccache_$(uname -m).tar.xz
+
+### functions ##################################################################
+
+function ccache_configure
+{
+ mkdir -p "$CCACHE_DIR"
+
+ cat <<EOF > "$CCACHE_DIR/ccache.conf"
+base_dir = $WRK_DIR
+hash_dir = false
+max_size = 3.0G
+temporary_dir = $CCACHE_DIR/tmp
+EOF
+}
+
+function ccache_install
+{
+ curl -L "$CCACHE_URL" | tar -C "$USR_DIR"/bin --exclude="ccache.sha256" -xJ
+
+ for compiler in clang clang++ gcc g++; do
+ ln -sf ccache "$USR_DIR"/bin/$compiler
+ done
+}
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/ci.sh b/packaging/macos/jhb/etc/jhb.conf/ci.sh
new file mode 100644
index 0000000..727cb2a
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/ci.sh
@@ -0,0 +1,42 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# check if running in CI (GitHub or GitLab)
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+if [ -z "$CI" ]; then # both GitHub and GitLab set this
+ CI=false
+ CI_GITHUB=false
+ CI_GITLAB=false
+else
+ CI=true
+
+ if [ -z "$CI_PROJECT_NAME" ]; then # this is a GitLab-only variable
+ CI_GITHUB=true
+ CI_GITLAB=false
+ else
+ CI_GITHUB=false
+ CI_GITLAB=true
+
+ # Since GitLab uses colors in their CI there's no need to disable ours.
+ # shellcheck disable=SC2034 # this is a bash_d setting
+ ANSI_TERM_ONLY=false # use ANSI control characters even if not in terminal
+ fi
+fi
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/jhb/etc/jhb.conf/directories.sh b/packaging/macos/jhb/etc/jhb.conf/directories.sh
new file mode 100644
index 0000000..4119456
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/directories.sh
@@ -0,0 +1,83 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# FSH-inspired directory layout
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+#--------------------------------------------------------- main directory layout
+
+# WRK_DIR (/Users/Shared/work)
+# ┃
+# ┣━━ REP_DIR (repo)
+# ┃
+# ┗━━ VER_DIR (jhb-$VERSION)
+# ┃
+# ┣━━ BIN_DIR (bin)
+# ┣━━ ETC_DIR (etc)
+# ┣━━ INC_DIR (include)
+# ┣━━ LIB_DIR (lib)
+# ┣━━ OPT_DIR (opt)
+# ┃
+# ┣━━ TMP_DIR (tmp)
+# ┃
+# ┣━━ USR_DIR (usr)
+# ┃ ┗━━ SRC_DIR (src)
+# ┃
+# ┗━━ VAR_DIR (var)
+# ┣━━ BLD_DIR (build)
+# ┗━━ PKG_DIR (cache/pkg)
+#
+# You can either override a variable directly or use a corresponding
+# "*_TEMPLATE" variable if you want to reference other variables, e.g.
+#
+# VER_DIR_TEMPLATE="\$WRK_DIR/myFoo-\$VERSION"
+
+WRK_DIR=$(eval echo "${WRK_DIR:-${WRK_DIR_TEMPLATE:-/Users/Shared/work}}")
+
+REP_DIR=$(eval echo "${REP_DIR:-${REP_DIR_TEMPLATE:-$WRK_DIR/repo}}")
+
+VER_DIR=$(eval echo "${VER_DIR:-${VER_DIR_TEMPLATE:-$WRK_DIR/jhb-$VERSION}}")
+
+BIN_DIR=$(eval echo "${BIN_DIR:-${BIN_DIR_TEMPLATE:-$VER_DIR/bin}}")
+ETC_DIR=$(eval echo "${ETC_DIR:-${ETC_DIR_TEMPLATE:-$VER_DIR/etc}}")
+INC_DIR=$(eval echo "${INC_DIR:-${INC_DIR_TEMPLATE:-$VER_DIR/include}}")
+LIB_DIR=$(eval echo "${LIB_DIR:-${LIB_DIR_TEMPLATE:-$VER_DIR/lib}}")
+OPT_DIR=$(eval echo "${OPT_DIR:-${OPT_DIR_TEMPLATE:-$VER_DIR/opt}}")
+
+USR_DIR=$(eval echo "${USR_DIR:-${USR_DIR_TEMPLATE:-$VER_DIR/usr}}")
+SRC_DIR=$(eval echo "${SRC_DIR:-${SRC_DIR_TEMPLATE:-$USR_DIR/src}}")
+
+TMP_DIR=$(eval echo "${TMP_DIR:-${TMP_DIR_TEMPLATE:-$VER_DIR/tmp}}")
+
+VAR_DIR=$(eval echo "${VAR_DIR:-${VAR_DIR_TEMPLATE:-$VER_DIR/var}}")
+BLD_DIR=$(eval echo "${BLD_DIR:-${BLD_DIR_TEMPLATE:-$VAR_DIR/build}}")
+PKG_DIR=$(eval echo "${PKG_DIR:-${PKG_DIR_TEMPLATE:-$VAR_DIR/cache/pkg}}")
+
+#------------------------------------------------------------ artifact directory
+
+if [ -z "$ARTIFACT_DIR" ]; then
+ if $CI_GITHUB; then
+ ARTIFACT_DIR=$GITHUB_WORKSPACE
+ elif $CI_GITLAB; then
+ ARTIFACT_DIR=$CI_PROJECT_DIR
+ else
+ ARTIFACT_DIR=$VER_DIR
+ fi
+fi
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/jhb/etc/jhb.conf/dmgbuild.sh b/packaging/macos/jhb/etc/jhb.conf/dmgbuild.sh
new file mode 100644
index 0000000..d957703
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/dmgbuild.sh
@@ -0,0 +1,96 @@
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# dmgbuild is a Python package that simplifies the process of creating a
+# disk image (dmg) for distribution.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+# https://dmgbuild.readthedocs.io/en/latest/
+# https://github.com/al45tair/dmgbuild
+# including optional dependencies:
+# - biplist: binary plist parser/generator
+# - pyobjc-*: framework wrappers
+DMGBUILD_PIP="\
+ biplist==1.0.3\
+ dmgbuild==1.5.2\
+ ds-store==1.3.0\
+ mac-alias==2.2.0\
+ pyobjc-core==8.5.1\
+ pyobjc-framework-Cocoa==8.5.1\
+ pyobjc-framework-Quartz==8.5.1\
+"
+
+### functions ##################################################################
+
+function dmgbuild_install
+{
+ # shellcheck disable=SC2086 # we need word splitting here
+ jhb run $JHBUILD_PYTHON_PIP install --prefix=$USR_DIR wheel $DMGBUILD_PIP
+
+ # dmgbuild has issues with detaching, workaround is to increase max retries
+ gsed -i '$ s/HiDPI)/HiDPI, detach_retries=15)/g' "$USR_DIR"/bin/dmgbuild
+}
+
+function dmgbuild_run
+{
+ local config=$1
+ local plist=$2
+ local dmg=$3 # optional; default is <name>_<version>_<build>_<arch>.dmg
+
+ local app_dir
+ app_dir=$(echo "$ARTIFACT_DIR"/*.app)
+
+ if [ -z "$dmg" ]; then
+ local version
+ version=$(/usr/libexec/PlistBuddy \
+ -c "Print :CFBundleShortVersionString" "$plist")
+ local build
+ build=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$plist")
+
+ dmg=$(basename -s .app "$app_dir")_${version}+${build}_$(uname -m).dmg
+ fi
+
+ # Copy templated version of the file (it contains placeholders) to source
+ # directory. They copy will be modified to contain the actual values.
+ cp "$config" "$SRC_DIR"
+ config=$SRC_DIR/$(basename "$config")
+
+ # set application
+ gsed -i "s|PLACEHOLDERAPPLICATION|$app_dir|" "$config"
+
+ # set disk image icon (if it exists)
+ local icon
+ icon=$SRC_DIR/$(basename -s .py "$config").icns
+ if [ -f "$icon" ]; then
+ gsed -i "s|PLACEHOLDERICON|$icon|" "$config"
+ fi
+
+ # set background image (if it exists)
+ local background
+ background=$SRC_DIR/$(basename -s .py "$config").png
+ if [ -f "$background" ]; then
+ gsed -i "s|PLACEHOLDERBACKGROUND|$background|" "$config"
+ fi
+
+ # Create disk image in temporary location and move to target location
+ # afterwards. This way we can run multiple times without requiring cleanup.
+ dmgbuild -s "$config" "$(basename -s .app "$app_dir")" \
+ "$TMP_DIR"/"$(basename "$dmg")"
+ mv "$TMP_DIR"/"$(basename "$dmg")" "$dmg"
+}
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/home.sh b/packaging/macos/jhb/etc/jhb.conf/home.sh
new file mode 100644
index 0000000..31bf892
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/home.sh
@@ -0,0 +1,24 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Redirect user's home directory.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+export HOME=$VER_DIR/home
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/jhbuild.sh b/packaging/macos/jhb/etc/jhb.conf/jhbuild.sh
new file mode 100644
index 0000000..31df78c
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/jhbuild.sh
@@ -0,0 +1,229 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This file contains functions to download, install and configure JHBuild.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+export JHBUILDRC=$ETC_DIR/jhbuildrc
+export JHBUILDRC_CUSTOM=$JHBUILDRC-custom
+
+JHBUILD_REQUIREMENTS="\
+ certifi==2022.9.24\
+ meson==0.59.2\
+ ninja==1.10.2.3\
+"
+
+# JHBuild build system >3.38.0 (current master as of 08.03.2022)
+# The last stable release (3.38.0) is missing a critical fix (commit
+# a896cbf404461cab979fa3cd1c83ddf158efe83b) so we have to stay on master branch
+# for the time being.
+# https://gitlab.gnome.org/GNOME/jhbuild
+# https://wiki.gnome.org/Projects/Jhbuild/Introduction
+JHBUILD_VER=d1c5316
+JHBUILD_URL=https://gitlab.gnome.org/GNOME/jhbuild/-/archive/$JHBUILD_VER/\
+jhbuild-$JHBUILD_VER.tar.bz2
+
+# A dedicated Python runtime (only) for JHBuild. It is installed and kept
+# separately from the rest of the system. It won't interfere with a Python
+# that might get installed as part of building modules with JHBuild.
+JHBUILD_PYTHON_VER_MAJOR=3
+JHBUILD_PYTHON_VER_MINOR=8
+JHBUILD_PYTHON_VER=$JHBUILD_PYTHON_VER_MAJOR.$JHBUILD_PYTHON_VER_MINOR
+JHBUILD_PYTHON_URL="https://gitlab.com/api/v4/projects/26780227/packages/\
+generic/python_macos/15/python_${JHBUILD_PYTHON_VER/./}_$(uname -m).tar.xz"
+JHBUILD_PYTHON_DIR=$OPT_DIR/Python.framework/Versions/$JHBUILD_PYTHON_VER
+JHBUILD_PYTHON_BIN_DIR=$JHBUILD_PYTHON_DIR/bin
+
+export JHBUILD_PYTHON_BIN=$JHBUILD_PYTHON_BIN_DIR/python$JHBUILD_PYTHON_VER
+export JHBUILD_PYTHON_PIP=$JHBUILD_PYTHON_BIN_DIR/pip$JHBUILD_PYTHON_VER
+
+### functions ##################################################################
+
+function jhbuild_install_python
+{
+ # Download and extract Python.framework to OPT_DIR.
+ curl -L "$JHBUILD_PYTHON_URL" | tar -C "$OPT_DIR" -x
+
+ # Create a pkg-config configuration to match our installation location.
+ # Note: sed changes the prefix and exec_prefix lines!
+ find "$JHBUILD_PYTHON_DIR"/lib/pkgconfig/*.pc \
+ -type f \
+ -exec sed -i "" "s|prefix=.*|prefix=$JHBUILD_PYTHON_DIR|" {} \;
+
+ jhbuild_set_python_interpreter
+
+ # add to PYTHONPATH
+ echo "../../../../../../../usr/lib/python$JHBUILD_PYTHON_VER/site-packages"\
+ > "$OPT_DIR"/Python.framework/Versions/$JHBUILD_PYTHON_VER/lib/\
+python$JHBUILD_PYTHON_VER/site-packages/jhb.pth
+}
+
+function jhbuild_set_python_interpreter
+{
+ # Symlink binaries to USR_DIR/bin.
+ if command -v gln 1>/dev/null; then
+ local gnu=g # necessary for union mount
+ fi
+ ${gnu}ln -sf "$JHBUILD_PYTHON_BIN" "$USR_DIR"/bin
+ ${gnu}ln -sf "$JHBUILD_PYTHON_PIP" "$USR_DIR"/bin
+
+ # Set interpreter to the one in USR_DIR/bin.
+ while IFS= read -r -d '' file; do
+ local file_type
+ file_type=$(file "$file")
+ if [[ $file_type = *"Python script"* ]]; then
+ sed -i "" "1 s|.*|#!$USR_DIR/bin/python$JHBUILD_PYTHON_VER|" "$file"
+ fi
+ done < <(find "$USR_DIR"/bin/ -maxdepth 1 -type f -print0)
+}
+
+function jhbuild_install
+{
+ # We use our own custom Python.
+ jhbuild_install_python
+
+ # Install dependencies.
+ # shellcheck disable=SC2086 # we need word splitting for requirements
+ $JHBUILD_PYTHON_PIP install --prefix=$USR_DIR $JHBUILD_REQUIREMENTS
+
+ function pem_remove_expired
+ {
+ local pem_bundle=$1
+
+ # BSD's csplit does not support '{*}' (it's a GNU extension)
+ csplit -n 3 -k -f "$TMP_DIR"/pem- "$pem_bundle" \
+ '/END CERTIFICATE/+1' '{999}' >/dev/null 2>&1 || true
+
+ for pem in "$TMP_DIR"/pem-*; do
+ if [ "$(stat -f%z "$pem")" -eq 0 ]; then
+ rm "$pem" # the csplit command above created one superfluous empty file
+ elif ! openssl x509 -checkend 0 -noout -in "$pem"; then
+ echo_d "removing $pem: $(openssl x509 -enddate -noout -in "$pem")"
+ rm "$pem"
+ fi
+ done
+
+ cat "$TMP_DIR"/pem-??? > "$pem_bundle"
+ }
+
+ local cacert="$USR_DIR"/lib/python$JHBUILD_PYTHON_VER/site-packages/certifi/\
+cacert.pem
+
+ pem_remove_expired "$cacert"
+
+ # Download JHBuild. Setting CURL_CA_BUNDLE is required on older macOS, e.g.
+ # High Sierra.
+ local archive
+ archive=$PKG_DIR/$(basename $JHBUILD_URL)
+ CURL_CA_BUNDLE=$cacert curl -o "$archive" -L "$JHBUILD_URL"
+ tar -C "$SRC_DIR" -xf "$archive"
+
+ ( # Install JHBuild.
+ cd "$SRC_DIR"/jhbuild-$JHBUILD_VER || exit 1
+ ./autogen.sh \
+ --prefix="$USR_DIR" \
+ --with-python="$JHBUILD_PYTHON_BIN"
+ make
+ make install
+ )
+}
+
+function jhbuild_configure
+{
+ local moduleset=$1
+
+ moduleset=${moduleset:-jhb.modules}
+ local suffix
+ suffix=$(basename -s .modules "$moduleset")
+
+ # install custom moduleset
+ if [ "$suffix" != "jhb" ]; then
+ local moduleset_dir
+ moduleset_dir=$(dirname "$(greadlink -f "$moduleset")")
+ rsync -a --delete "$moduleset_dir"/ "$ETC_DIR/modulesets/$suffix/"
+ fi
+
+ local target
+ target=$(/usr/libexec/PlistBuddy -c "Print \
+ :DefaultProperties:MACOSX_DEPLOYMENT_TARGET" "$SDKROOT"/SDKSettings.plist)
+
+ # create custom jhbuildrc configuration
+ {
+ echo "# -*- mode: python -*-"
+
+ # moduleset
+ echo "modulesets_dir = '$ETC_DIR/modulesets/$suffix'"
+ echo "moduleset = '$(basename "$moduleset")'"
+ echo "use_local_modulesets = True"
+
+ # basic directory layout
+ echo "buildroot = '$BLD_DIR'"
+ echo "checkoutroot = '$SRC_DIR'"
+ echo "prefix = '$VER_DIR'"
+ echo "tarballdir = '$PKG_DIR'"
+ echo "top_builddir = '$VAR_DIR/jhbuild'"
+
+ # setup macOS SDK
+ echo "setup_sdk(target=\"$target\")"
+
+ # set release build
+ echo "setup_release()"
+
+ # Use compiler binaries from our own USR_DIR/bin if present, the intention
+ # being that these are symlinks pointing to ccache if that has been
+ # installed (see ccache.sh for details).
+ if [ -x "$USR_DIR/bin/gcc" ]; then
+ echo "os.environ[\"CC\"] = \"$USR_DIR/bin/gcc\""
+ echo "os.environ[\"OBJC\"] = \"$USR_DIR/bin/gcc\""
+ fi
+ if [ -x "$USR_DIR/bin/g++" ]; then
+ echo "os.environ[\"CXX\"] = \"$USR_DIR/bin/g++\""
+ fi
+
+ # certificates for https
+ echo "os.environ[\"SSL_CERT_FILE\"] = \
+ \"$USR_DIR/lib/python$JHBUILD_PYTHON_VER/site-packages/certifi/cacert.pem\""
+ echo "os.environ[\"REQUESTS_CA_BUNDLE\"] = \
+ \"$USR_DIR/lib/python$JHBUILD_PYTHON_VER/site-packages/certifi/cacert.pem\""
+
+ # user home directory
+ echo "os.environ[\"HOME\"] = \"$HOME\""
+
+ # less noise on the terminal if not CI
+ if ! $CI; then
+ echo "quiet_mode = True"
+ echo "progress_bar = True"
+ fi
+
+ # add moduleset-specific settings if exist
+ local moduleset_rc=$ETC_DIR/modulesets/$suffix/jhbuildrc
+ if [ -f "$moduleset_rc" ]; then
+ cat "$moduleset_rc"
+ fi
+
+ } > "$JHBUILDRC-$suffix"
+
+ if command -v gln 1>/dev/null; then
+ local gnu=g # necessary for union mount
+ fi
+ ${gnu}ln -sf "$(basename "$JHBUILDRC-$suffix")" "$JHBUILDRC_CUSTOM"
+
+ # Update the paths to Python.
+ jhbuild_set_python_interpreter
+}
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/jhb/etc/jhb.conf/path.sh b/packaging/macos/jhb/etc/jhb.conf/path.sh
new file mode 100644
index 0000000..07e7adc
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/path.sh
@@ -0,0 +1,23 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Set PATH.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### variables ##################################################################
+
+export PATH=$BIN_DIR:$USR_DIR/bin:/usr/bin:/bin:/usr/sbin:/sbin
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/pip.sh b/packaging/macos/jhb/etc/jhb.conf/pip.sh
new file mode 100644
index 0000000..5804468
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/pip.sh
@@ -0,0 +1,26 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Redirect pip cache directories.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+export PIP_CACHE_DIR=$VAR_DIR/cache/pip # instead ~/Library/Caches/pip
+export PIPENV_CACHE_DIR=$VAR_DIR/cache/pipenv # instead ~/Library/Caches/pipenv
+export PYTHONPYCACHEPREFIX=$VAR_DIR/cache/pycache
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/release.sh b/packaging/macos/jhb/etc/jhb.conf/release.sh
new file mode 100644
index 0000000..6fe8708
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/release.sh
@@ -0,0 +1,35 @@
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Release artifact.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+RELEASE_ARCHIVE=${RELEASE_ARCHIVE:-$(basename "$VER_DIR")_$(uname -m).tar.xz}
+
+# GitHub and GitLab
+# shellcheck disable=2206 # we need expansion for the array to work
+RELEASE_URLS=(${RELEASE_URLS[@]:-
+ "https://github.com/dehesselle/jhb/releases/download/\
+v$VERSION/$RELEASE_ARCHIVE"
+ "https://gitlab.com/api/v4/projects/35965804/packages/generic/jhb/\
+$VERSION/$RELEASE_ARCHIVE"
+})
+
+RELEASE_OVERLAY=overlay
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/sdkroot.sh b/packaging/macos/jhb/etc/jhb.conf/sdkroot.sh
new file mode 100644
index 0000000..deda692
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/sdkroot.sh
@@ -0,0 +1,41 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# If SDKROOT is set, use that. If it is not set, use whatever SDK is available.
+# This might still end up being invalid if neither Xcode nor CLT have been
+# installed, and that's what sdkroot_exists is for.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+if [ -z "$SDKROOT" ]; then
+ if xcodebuild --help 2>/dev/null; then
+ SDKROOT=$(xcodebuild -version -sdk macosx Path)
+ else
+ SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
+ fi
+fi
+export SDKROOT
+
+### functions ##################################################################
+
+function sdkroot_exists
+{
+ if [ -d "$SDKROOT" ]; then
+ return 0 # SDK found
+ else
+ echo_e "SDK not found: $SDKROOT"
+ return 1
+ fi
+}
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/sys.sh b/packaging/macos/jhb/etc/jhb.conf/sys.sh
new file mode 100644
index 0000000..1871b21
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/sys.sh
@@ -0,0 +1,121 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# System and version checks.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+SYS_ARCH=$(uname -m | tr '[:lower:]' '[:upper:]')
+
+if [ "$SYS_USRLOCAL_IGNORE" != "true" ]; then
+ SYS_USRLOCAL_IGNORE=false
+fi
+
+SYS_MACOS_VER=$(sw_vers -productVersion)
+
+# descending order on purpose: most recent platform first
+# shellcheck disable=2206 # we need expansion for the array to work
+SYS_MACOS_VER_RECOMMENDED=(${SYS_MACOS_VER_RECOMMENDED:-
+ 12.6.1
+ 12.6
+ 11.7
+})
+
+SYS_SDK_VER="$(/usr/libexec/PlistBuddy -c \
+ "Print :DefaultProperties:MACOSX_DEPLOYMENT_TARGET" \
+ "$SDKROOT"/SDKSettings.plist)"
+
+SYS_SDK_VER_RECOMMENDED_X86_64=${SYS_SDK_VER_RECOMMENDED_X86_64:-10.13}
+SYS_SDK_VER_RECOMMENDED_ARM64=${SYS_SDK_VER_RECOMMENDED_ARM64:-11.3}
+SYS_SDK_VER_RECOMMENDED=$(eval echo \$SYS_SDK_VER_RECOMMENDED_"$SYS_ARCH")
+
+### functions ##################################################################
+
+function sys_create_log
+{
+ # Create jhb.log file.
+
+ mkdir -p "$VAR_DIR"/log
+
+ for var in SYS_MACOS_VER SYS_SDK_VER VERSION VER_DIR WRK_DIR; do
+ echo "$var = $(eval echo \$$var)" >> "$VAR_DIR"/log/jhb.log
+ done
+}
+
+function sys_macos_is_recommended
+{
+ for version in "${SYS_MACOS_VER_RECOMMENDED[@]}"; do
+ if [ "$version" = "$SYS_MACOS_VER" ]; then
+ return 0
+ fi
+ done
+
+ echo_w "using macOS $SYS_MACOS_VER (recommended: \
+${SYS_MACOS_VER_RECOMMENDED[0]})"
+ return 1
+}
+
+function sys_sdk_is_recommended
+{
+ if [ "$SYS_SDK_VER_RECOMMENDED" = "$SYS_SDK_VER" ]; then
+ return 0
+ fi
+
+ echo_w "using SDK $SYS_SDK_VER (recommended: $SYS_SDK_VER_RECOMMENDED)"
+ return 1
+}
+
+function sys_usrlocal_is_clean
+{
+ local count=0
+
+ # Based on GitHub CI experience, it appears to be enough to make sure
+ # the following folders do not contain files.
+ for dir in include lib share; do
+ count=$(( count + \
+ $(find /usr/local/$dir -type f 2>/dev/null | wc -l | awk '{ print $1 }')\
+ ))
+ done
+
+ if [ "$count" -ne 0 ]; then
+ if $SYS_USRLOCAL_IGNORE; then
+ echo_w "Found files in '/usr/local/[include|lib|share]'."
+ else
+ echo_e "Found files in '/usr/local/[include|lib|share]'!"
+ echo_e "This is known to cause trouble, but you can downgrade this error"
+ echo_e "to a warning at your own risk:"
+ echo_e " "
+ echo_e " export SYS_USRLOCAL_IGNORE=true"
+ return 1
+ fi
+ fi
+
+ return 0
+}
+
+function sys_wrkdir_is_usable
+{
+ if mkdir -p "$WRK_DIR" 2>/dev/null &&
+ [ -w "$WRK_DIR" ] ; then
+ return 0 # WRK_DIR has been created or was already there and is writable
+ else
+ echo_e "WRK_DIR not usable: $WRK_DIR"
+ return 1
+ fi
+}
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/temp.sh b/packaging/macos/jhb/etc/jhb.conf/temp.sh
new file mode 100644
index 0000000..5de20a7
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/temp.sh
@@ -0,0 +1,27 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Redirect temporary locations.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+# shellcheck disable=SC2153 # this is no misspelling
+export TMP=$TMP_DIR
+export TEMP=$TMP_DIR
+export TMPDIR=$TMP_DIR # TMPDIR is the common macOS default
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/version.sh b/packaging/macos/jhb/etc/jhb.conf/version.sh
new file mode 100644
index 0000000..edd851b
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/version.sh
@@ -0,0 +1,24 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# The main version number.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+VERSION=${VERSION:-0.22}
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhb.conf/xdg.sh b/packaging/macos/jhb/etc/jhb.conf/xdg.sh
new file mode 100644
index 0000000..28a786e
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhb.conf/xdg.sh
@@ -0,0 +1,25 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Redirect some XDG directories.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # we only use exports if we really need them
+
+### variables ##################################################################
+
+export XDG_CACHE_HOME=$VAR_DIR/cache # instead ~/.cache
+export XDG_CONFIG_HOME=$ETC_DIR # instead ~/.config
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/etc/jhbuildrc b/packaging/macos/jhb/etc/jhbuildrc
new file mode 100644
index 0000000..2e3fb6f
--- /dev/null
+++ b/packaging/macos/jhb/etc/jhbuildrc
@@ -0,0 +1,613 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2006, 2007, 2008 Imendio AB
+# Copyright 2009, 2010, 2011 John Ralls, Fremont, CA
+#
+# Default setup for building GTK+ on Mac OS X. Note that you should
+# normally never need to edit this file. Any custom settings should be
+# done in ~/.jhbuildrc-custom.
+#
+# Specific builds can be set up by creating files named
+# ~/.jhbuildrc-<build>. When setting the environment variable JHB to
+# such a name, the corresponding rc file will be read (e.g.:
+# JHB=mybuild jhbuild shell).
+#
+# Use .jhbuildrc-custom to override the moduleset, modules to build,
+# the source checkout location, installation prefix, or svn usernames
+# etc.
+#
+# Please email richard@imendio.com if you have suggestions for
+# improving this setup, or have any patches that you would like to get
+# included.
+
+import sys
+import errno
+import re
+
+#some variables we'll need defined later
+_default_arch = ""
+_osx_version = 0.0
+_target = '10.11'
+
+def _popen(cmd_arg):
+ from subprocess import Popen, PIPE
+ devnull = open('/dev/null')
+ cmd = Popen(cmd_arg, stdout=PIPE, stderr=devnull, shell=True)
+ retval = cmd.stdout.read().strip()
+ err = cmd.wait()
+ cmd.stdout.close()
+ devnull.close()
+ if err:
+ raise RuntimeError("Failed to close %s stream" % cmd_arg)
+ return retval.decode('utf-8')
+
+# Register an extra command to get the checkout dir for a module.
+#
+import jhbuild
+class _cmd_get_srcdir(jhbuild.commands.Command):
+ doc = 'Display information about one or more modules'
+
+ from jhbuild.errors import FatalError
+
+ name = 'gtk-osx-get-srcdir'
+ usage_args = 'module'
+
+ def run(self, config, options, args, help=None):
+ module_set = jhbuild.moduleset.load(config)
+
+ if args:
+ modname = args[0]
+ try:
+ module = module_set.get_module(modname, ignore_case = True)
+ except KeyError:
+ raise RuntimeError(_('unknown module %s') % modname)
+ print(module.get_srcdir(None))
+ else:
+ raise FatalError('no module specified')
+
+jhbuild.commands.register_command(_cmd_get_srcdir)
+
+class _cmd_bootstrap_gtk_osx(jhbuild.commands.base.cmd_build):
+ doc = 'Build buildsystem tools not provided by MacOS.'
+
+ name = 'bootstrap-gtk-osx'
+
+ def run(self, config, options, args, help=None):
+ global use_local_modulesets
+ moduleset="bootstrap"
+ modulesets_dir = os.path.dirname(config.moduleset)
+ if (use_local_modulesets and
+ os.path.exists(os.path.join(modulesets_dir,
+ moduleset + '.modules'))):
+ config.modulesets_dir = modulesets_dir
+ config.moduleset = moduleset
+ elif (use_local_modulesets and config.modulesets_dir and
+ os.path.exists(os.path.join(config.modulesets_dir,
+ moduleset + '.modules'))):
+ config.moduleset = moduleset
+ else:
+ config.moduleset = 'https://raw.githubusercontent.com/dehesselle/jhb/master/etc/modulesets/jhb/bootstrap.modules'
+
+ args = ['meta-bootstrap']
+
+ for item in options.skip:
+ config.skip += item.split(',')
+ options.skip = []
+
+ rc = jhbuild.commands.base.cmd_build.run(self, config, options, args)
+ return rc
+
+jhbuild.commands.register_command(_cmd_bootstrap_gtk_osx)
+
+class _getenv(jhbuild.commands.Command):
+ doc = "Retrieve an environment variable set within jhbuild"
+
+ name = "gtk-osx-getenv"
+ usage_args = 'envvar'
+
+ def run(self, config, options, args):
+ # module_set = jhbuild.moduleset.load(config)
+
+ if not args:
+ raise FatalError("No environment variable")
+
+ var = args[0]
+ if var not in os.environ:
+ raise FatalError("variable " + var + " not defined in jhbuild environment")
+ print(os.environ[var])
+
+jhbuild.commands.register_command(_getenv)
+
+# Determine the native system:
+def osx_ver():
+ global _default_arch, _osx_version, _target
+ vstring = _popen("uname -r")
+ mstring = _popen("machine")
+ exp = re.compile(r'(\d+\.\d+)\.\d+')
+ vernum = exp.match(vstring)
+ _osx_version = float(vernum.group(1)) - 4.0
+ if _osx_version < 16:
+ _target = '10.%d' % int(_osx_version)
+ else:
+ _target = '%d' % (_osx_version - 5)
+
+ _default_arch = _popen("uname -m")
+
+# Determine the XCode Version:
+def xcode_ver():
+ global conditions
+ devdir = _popen("xcode-select -p")
+ if devdir != "/Library/Developer/CommandLineTools":
+ ver = _popen("xcodebuild -version")
+ exp = re.compile(r'Xcode (\d+\.\d+)')
+ vernum = exp.match(ver)
+ if vernum:
+ _xcode_ver = float(vernum.group(1))
+ if _xcode_ver < 5.0:
+ raise EnvironmentError("Xcode Version %f is not supported; if you want to build with Xcode versions earlier than 5.0 checkout tag Last-Lion." % _xcode_ver)
+ if _xcode_ver < 10.0:
+ conditions.add('pre-Mavericks')
+ return _xcode_ver
+ else:
+ raise EnvironmentError("No suitable Xcode found. Xcode 5.0 or later is required.")
+ else: #Command-Line Tools instead of Xcode
+ ver_str = _popen("pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version*")
+ print("Found Command Line Tools '%s'" % ver_str)
+ exp = re.compile(r'version: (\d+\.\d+)')
+ vernum = exp.match(ver_str)
+ if vernum:
+ print("Command Line Tools version %f" % float(vernum.group(1)))
+ return float(vernum.group(1))
+ else:
+ return 8.0
+
+# Some utitily functions used here and in custom files:
+#
+def environ_append(key, value, separator=' '):
+ old_value = os.environ.get(key)
+ if old_value is not None:
+ value = old_value + separator + value
+ os.environ[key] = value
+
+def environ_prepend(key, value, separator=' '):
+ old_value = os.environ.get(key)
+ if old_value is not None:
+ value = value + separator + old_value
+ os.environ[key] = value
+
+def environ_remove(key, value, separator=':'):
+ old_value = os.environ.get(key)
+ if old_value is not None:
+ old_value_split = old_value.split(separator)
+ value_split = [x for x in old_value_split if x != value]
+ value = separator.join(value_split)
+ os.environ[key] = value
+
+def parse_custom_argument(key):
+ for i, arg in enumerate(sys.argv[:-1]):
+ if arg == key:
+ return sys.argv[i+1]
+ return None
+
+def append_autogenargs(module, args):
+ old_value = module_autogenargs.get(module, autogenargs)
+ module_autogenargs[module] = old_value + " " + args
+
+def remove_autogenargs(module, args):
+ arg_string = module_autogenargs.get(module, autogenargs)
+ module_autogenargs[module] = arg_string.replace(args, "")
+
+# Call either setup_debug or setup_release in your .jhbuildrc-custom
+# or other customization file to get the compilation flags.
+def setup_debug():
+ global autogenargs
+# The enable-debug option generally turns on ASSERTS, which can slow
+# down code and in the case of WebKit, breaks it on OSX because of
+# threading problems. It's better to set it for individual packages
+# with append_autogenargs().
+
+# autogenargs = autogenargs + " --enable-debug=yes"
+
+# Gtk+ crashes in gdk_window_quartz_raise() -- in a call to [NSWindow
+# orderFront:] if gcc is passed -O0 for 64-bit compilation. The old
+# stabs+ debug format also doesn't work. See Snow Leopard in the Wiki
+# for more information about debugging.
+ environ_prepend('CFLAGS', "-O0 -g")
+ environ_prepend('CXXFLAGS', "-O0 -g")
+ environ_prepend('OBJCFLAGS', "-O0 -g")
+
+def setup_release():
+ environ_prepend('CFLAGS', "-O2")
+ environ_prepend('CXXFLAGS', "-O2")
+ environ_prepend('OBJCFLAGS', "-O2")
+
+# Set up the environment for building against particular SDK.
+#
+
+#We call osx_ver() here so that we can set up _default_arch for setup_sdk
+osx_ver()
+
+#
+# This is the workhorse of the setup. Call this function from
+# .jhbuildrc-custom to configure compile and link flags. Optionally
+# specify a minimum MacOS version (10.11, 10.12, 10.13, etc.) and a list
+# of architectures.
+#
+# The sdk_version does nothing, as since Xcode 5 it is preferred to
+# build with the SDK that goes with the selected Xcode or command-line
+# tools, which we retrieve via xcrun. sdk_version remains in the
+# setup_sdk signature to prevent breaking existing jhbuildrc-customs.
+#
+# For most users accepting the defaults is the right course.
+
+def setup_sdk(target=_target, sdk_version=None, architectures=[_default_arch]):
+
+ global use_local_modulesets, conditions
+ os.environ["MACOSX_DEPLOYMENT_TARGET"] = target
+ sdkdir = None
+ xcodepath = None
+ xcodeversion = xcode_ver()
+
+ sdkdir = _popen("xcrun --show-sdk-path")
+
+ if sdkdir:
+ environ_prepend("LDFLAGS", "-L" + sdkdir + "/usr/lib")
+ environ_prepend("CFLAGS", "-I" + sdkdir + "/usr/include")
+ environ_prepend("CXXFLAGS", "-I" + sdkdir + "/usr/include")
+ environ_prepend("OBJCFLAGS", "-I" + sdkdir + "/usr/include")
+ environ_prepend("CPPFLAGS", "-I" + sdkdir + "/usr/include")
+ environ_prepend("CMAKE_PREFIX_PATH", os.path.join(sdkdir, 'usr'), ':')
+ environ_prepend("LIBRARY_PATH", sdkdir + "/usr/lib", ':')
+
+ # It's often necessary to look for things in the SDK when
+ # developing, and it takes a lot of typing, so define a
+ # convenience environment variable:
+ environ_append('SDKDIR', sdkdir)
+ os.environ["SDKROOT"] = sdkdir
+
+ # Apple Documentation says that "-syslibroot" is the arg to pass to the
+ # linker, but we are using the compiler to control the linker, and
+ # everything seems to be working correctly.
+ environ_append("CFLAGS", "-isysroot " + sdkdir)
+ environ_append("CPPFLAGS", "-isysroot " + sdkdir)
+ environ_append("CXXFLAGS", "-isysroot " + sdkdir)
+ environ_append("OBJCFLAGS", "-isysroot " + sdkdir)
+ environ_append("LDFLAGS", "-isysroot " + sdkdir)
+
+ # To pick up cups-config from the right place.
+ os.environ["CUPS_CONFIG"] = os.path.join(sdkdir, "usr/bin/cups-config")
+
+ if architectures == ["i386"]:
+ # The '#' on openssl is to stop jhbuild from appending any more autogen
+ # arguments such as --disable-Werror; they cause openssl to error out
+ append_autogenargs("openssl", "darwin-i386-cc #")
+ elif architectures == ["x86_64"]:
+ conditions.add('64-bit')
+ append_autogenargs("glib", "ac_cv_c_bigendian=no")
+ append_autogenargs("openssl", "darwin64-x86_64-cc #")
+ elif architectures == ["arm64"]:
+ conditions.add('64-bit')
+ conditions.add('arm64')
+ append_autogenargs("glib", "ac_cv_c_bigendian=no")
+ append_autogenargs("openssl", "darwin64-arm64-cc #") # Not a legal value
+ elif len(set(architectures) - {"i386", "x86_64", 'arm64'}) > 0:
+ raise EnvironmentError("Only architectures i386, x86_64, and arm64 are supported.")
+ if len(set(architectures)) > 1:
+ print("WARNING: Universal builds are neither prohibited nor supported. It might work, but if it doesn't you're on your own.")
+ # For unknown reasons, iconv is not picked up correctly without this
+ #
+ gcc = _popen("xcrun -f gcc")
+ gpp = _popen("xcrun -f g++")
+ ld = _popen("xcrun -f ld")
+ os.environ["CC"] = gcc
+ os.environ["OBJC"] = gcc
+ os.environ["CXX"] = gpp
+ os.environ['LD'] = ld
+
+ # Set the -arch flags for everything we're building.
+ #
+ for arch in architectures:
+ environ_prepend("CFLAGS", "-arch " + arch)
+ environ_prepend("CXXFLAGS", "-arch " + arch)
+ environ_prepend("CPPFLAGS", "-arch " + arch)
+ environ_prepend("OBJCFLAGS", "-arch " + arch)
+ environ_prepend("LDFLAGS", "-arch " + arch)
+ # For intel, set glib's build parameter so that it builds the
+ # correct atomic asm functions
+ #
+ if architectures == ["i386"]:
+ append_autogenargs("glib", "--build=i486-apple-darwin")
+ append_autogenargs("gmp", "ABI=32")
+ append_autogenargs("liboil", "--host=i486-apple-darwin")
+ append_autogenargs("gnutls", "--host=i486-apple-darwin")
+ elif architectures == ["x86_64"]:
+ append_autogenargs("glib", "--build=x86_64-apple-darwin")
+ append_autogenargs("gmp", "--host=x86_64-apple-darwin ABI=64")
+ append_autogenargs("liboil", "--host=x86_64-apple-darwin")
+ append_autogenargs("gnutls", "--host=x86_64-apple-darwin")
+ elif architectures == ["arm64"]:
+ append_autogenargs("glib", "--build=aarch64-apple-darwin")
+ append_autogenargs("gmp", "--host=aarch64-apple-darwin ABI=64")
+ append_autogenargs("liboil", "--host=aarch64-apple-darwin")
+ append_autogenargs("libffi", "--host=aarch64-apple-darwin")
+
+ # El Capitan needs bash to work around SIP. If you're using a
+ # common bootstrap directory (e.g. $HOME/.local) then override
+ # CONFIG_SHELL in .jhbuildrc-custom after calling setup_sdk().
+ config_shell = os.path.join(prefix, 'bin', 'bash')
+ if _osx_version < 11.0:
+ skip.append('bash')
+ elif os.path.exists(config_shell):
+ os.environ['CONFIG_SHELL'] = config_shell
+
+ if not sdkdir:
+ sdkdir = '/'
+ if os.path.exists(os.path.join(sdkdir, "usr", "include", "openssl")):
+ skip.append('openssl') # openssl removed in El Capitan
+
+ # gettext-fw rebuilds gettext with an in-tree libiconv to get
+ # around the Apple-provided one not defining _libiconv_init for
+ # x86_64
+ append_autogenargs("gettext-fw", "--with-libiconv-prefix=" + prefix)
+
+ environ_append("CFLAGS", "-mmacosx-version-min=" + target)
+ environ_append("CXXFLAGS", "-mmacosx-version-min=" + target)
+ environ_append("OBJCFLAGS", "-mmacosx-version-min=" + target)
+ environ_append("LDFLAGS", "-mmacosx-version-min=" + target)
+
+ #Overcome Python's obnoxious misconfiguration of portable builds
+ if len(architectures) == 1:
+ os.environ["BUILDCFLAGS"] = os.environ["CFLAGS"]
+ append_autogenargs("gnutls", "--disable-guile")
+ append_autogenargs("guile", 'CFLAGS="$CFLAGS -O1"')
+ #Some packages require special arguments or flags to compile with Clang:
+ module_extra_env["pkg-config"] = {'CFLAGS': os.environ['CFLAGS'] + ' -std=gnu89'}
+ append_autogenargs('libgcrypt', 'CFLAGS="$CFLAGS -fheinous-gnu-extensions"')
+ module_makeargs['liboil'] = 'CFLAGS="$CFLAGS -DHAVE_SYMBOL_UNDERSCORE -fheinous-gnu-extensions"'
+
+ # openssl doesn't understand DESTDIR, but luckily it has its own mechanism.
+ module_extra_env['openssl'] = {'INSTALL_PREFIX': os.path.join(prefix, '_jhbuild', 'root-openssl')}
+ # GMP deliberately attempts to use CC_FOR_BUILD with no separate
+ # cflags so we need to force it:
+ module_extra_env['gmp'] = {'CC_FOR_BUILD':os.environ['CC'] + ' ' + os.environ['CFLAGS']}
+ # Kill a couple of noisy warnings for webkit1:
+ module_extra_env["webkit"] = {'CPPFLAGS':os.environ['CPPFLAGS'] + " -Wno-unused-local-typedef -Wno-missing-field-initializsers"}
+ module_extra_env["webkit1gtk3"] = {'CPPFLAGS':os.environ['CPPFLAGS'] + " -Wno-unused-local-typedef -Wno-missing-field-initializsers -Wno-undefined-bool-conversion"}
+ module_extra_env["webkit"] = {'CXXFLAGS':os.environ['CXXFLAGS'] + ' -Wno-inconsistent-missing-override'}
+ module_extra_env["webkit1gtk3"] = {'CXXFLAGS':os.environ['CXXFLAGS'] + ' -Wno-inconsistent-missing-override'}
+
+ # Finally when building normally we need to force CFLAGS_FOR_BUILD
+ # to our current CFLAGS so that everything will link with other
+ # build products. Note that this will generally break
+ # cross-compilation, not that it works anyway.
+ os.environ['CFLAGS_FOR_BUILD'] = os.environ['CFLAGS']
+
+ # Make sure we don't link against XQuartz whose freetype-config is on PATH
+ # when XQuartz is installed by removing it from PATH
+ environ_remove('PATH', '/opt/X11/bin')
+ return sdkdir
+
+
+###### End Function Definitions #######
+
+
+##### The following configuration can be overridden in custom files ######
+
+# Moduleset to use. You can override this in .jhbuildrc-custom or on
+# the command line.
+#
+moduleset = ""
+use_local_modulesets = False
+modulesets_dir = ""
+
+# A list of the modules to build. You can override this in
+# .jhbuildrc-custom or on the command line.
+#
+modules = [ 'meta-gtk-osx-bootstrap', 'meta-gtk-osx-gtk3' ]
+
+# A list of modules to skip.
+#
+# Source and installation locations.
+#
+_root = os.path.expanduser("~/gtk")
+checkoutroot = os.path.join(_root, "source")
+prefix = os.path.join(_root, "inst")
+_exec_prefix = None
+tarballdir = None
+# Extra arguments to pass to all autogen.sh scripts.
+#
+autogenargs=''
+
+# Extra meson args. --wrapmode=nofallback prevents meson projects from
+# building dependencies on their own. We generally want failed
+# dependencies to error out so that we know to add them to the
+# appropriate modules.
+
+mesonargs='--wrap-mode=nofallback'
+
+# Use the included install-check program if available. It won't update
+# timestamps if the header hasn't changed, which speeds up builds.
+#
+_path = os.path.expanduser('~/.local/bin/install-check')
+if os.path.exists(_path):
+ os.environ['INSTALL'] = _path
+
+_gtk_osx_prompt_prefix = "JH"
+
+_gtk_osx_default_build = ""
+
+#print "Default Architecture %s\n" % _default_arch
+
+if _osx_version < 11.0:
+ print("Error: Mac OS X 10.11 or newer is required, exiting.")
+ raise SystemExit
+
+###### Import Customizations ######
+
+# Import optional user RC for further customization. You can override
+# the prefix or default build setup for example, or CFLAGS or
+# module_autogenargs, etc.
+#
+_this_dir = os.path.dirname(__file__);
+_home = os.path.expanduser('~')
+_user_config_dir = os.environ.get('XDG_CONFIG_HOME',
+ os.path.join(_home, '.config'))
+
+_user_rc = ''
+if ('JHBUILDRC_CUSTOM' in os.environ and
+ os.environ['JHBUILDRC_CUSTOM']):
+ _user_rc = os.environ['JHBUILDRC_CUSTOM']
+if not os.path.exists(_user_rc):
+ _user_rc = os.path.join(_this_dir, 'jhbuildrc-custom');
+if not os.path.exists(_user_rc):
+ _user_rc = os.path.join(_this_dir, '.jhbuildrc-custom')
+if not os.path.exists(_user_rc):
+ _user_rc = os.path.join(_user_config_dir, 'jhbuildrc-custom')
+if not os.path.exists(_user_rc):
+ _user_rc = os.path.join(_user_config_dir, '.jhbuildrc-custom')
+if not os.path.exists(_user_rc):
+ _user_rc = os.path.join(_home, 'jhbuildrc-custom')
+if not os.path.exists(_user_rc):
+ _user_rc = os.path.join(_home, '.jhbuildrc-custom')
+
+if os.path.exists(_user_rc):
+ exec(compile(open(_user_rc, "rb").read(), _user_rc, 'exec'))
+
+# Allow including different variants depending on the environment
+# variable JHB. This can be used to have different setups for SDK
+# builds, for example.
+#
+_build = os.environ.get('JHB', _gtk_osx_default_build)
+disable_Werror = False
+
+###### Everything Below Uses (and Overrides) customizations! #######
+# jhbuild turns on 'nice' by default ut that messes up some of the
+# custom autogen-templates Gtk-OSX needs to use:"
+nice_build = False
+
+# Harfbuzz needs to be built twice, once before cairo and again after
+# gobject-introspection because cairo needs harfbuzz and
+# gobject-introspection needs cairo. The only way to get jhbuild to
+# run the configuration for harfbuzz the second time is to set
+# alwaysautogen to true.
+
+alwaysautogen = True
+
+# Freetype2 if left to itself will create an install name without the
+# path so none of the libraries that depend on it can link. Require
+# the install name to be an absolute path.
+
+module_cmakeargs["freetype"] = '-DCMAKE_INSTALL_NAME_DIR="' + os.path.join(prefix, 'lib') + '"'
+module_cmakeargs["freetype-no-harfbuzz"] = '-DCMAKE_INSTALL_NAME_DIR="' + os.path.join(prefix, 'lib') + '"'
+module_cmakeargs["webkit2gtk3"] = '-DCMAKE_INSTALL_NAME_DIR="' + os.path.join(prefix, 'lib') + '"'
+module_cmakeargs["zlib"] = '-DCMAKE_INSTALL_NAME_DIR="' + os.path.join(prefix, 'lib') + '"'
+
+# Check and warn if jhbuild is started from within jhbuild, since that
+# will mess up environment variables, especially if different build
+# setups are used.
+#
+_old_prefix = os.environ.get('JHBUILD_PREFIX', "")
+_old_build = os.environ.get('JHBUILD_CONFIG', "")
+_ran_recursively = _old_prefix != ""
+if _ran_recursively:
+ if _old_build != _build:
+ print("Error: jhbuild is already running with a different build setup, exiting.")
+ raise SystemExit
+
+ print("Warning: jhbuild is started from within a jhbuild session.")
+
+if _build != "":
+ try:
+ exec(compile(open(os.path.join(os.environ['HOME'], '.jhbuildrc-' + _build), "rb").read(), os.path.join(os.environ['HOME'], '.jhbuildrc-' + _build), 'exec'))
+ except EnvironmentError as e:
+ print("Couldn't find the file '.jhbuildrc-" + _build + "', exiting.")
+ raise SystemExit
+
+# The following parameters were set to None at the top of the file;
+# they're set here to their default values after processing the
+# customizations, but tested to make sure that if they've been
+# customized, it will stick.
+
+# Default location for tarball download is into checkoutroot/pkgs. If
+# you do multiple builds with different checkoutroots, you'll want to
+# override this to somewhere common (~/.local/pkgs is one alternative)
+if tarballdir == None:
+ tarballdir = os.path.join(checkoutroot, 'pkgs')
+# _exec_prefix is used to set $M4 and $LIBTOOLIZE. We set it here to
+# prefix if it wasn't over-ridden in .jhbuildrc-custom
+if _exec_prefix == None:
+ _exec_prefix = prefix
+
+
+os.environ['PREFIX'] = prefix # Deprecated, please move to JHBUILD_PREFIX.
+os.environ['JHBUILD_PREFIX'] = prefix
+os.environ['JHBUILD_SOURCE'] = checkoutroot
+
+# Some packages go off and find /usr/lib/gm4, which is broken Note the
+# use of _exec_prefix here. By default it's prefix, but you can
+# override it to somewhere else in jhbuildrc-custom if you like.
+#os.environ["M4"] = _exec_prefix + "/bin/m4"
+#os.environ['LIBTOOLIZE'] = _exec_prefix + '/bin/libtoolize'
+#Some autogens detect that it's a Mac and use glibtoolize if it's
+#available. Override this behavior.
+if not ("LIBTOOLIZE" in os.environ and os.environ["LIBTOOLIZE"]):
+ environ_append('LIBTOOLIZE', os.path.join(prefix, "bin", "libtoolize"))
+
+
+# The option "headerpad_max_install_names" is there to leave some room for
+# changing the library locations with install_name_tool. Note that GNU
+# libtool seems to drop the option if we don't use -W here.
+#
+environ_append('LDFLAGS', '-Wl,-headerpad_max_install_names')
+#environ_append('LDFLAGS', '-Wl,-no_weak_imports')
+
+# Make sure we find our installed modules, and before other versions.
+environ_prepend('LDFLAGS', '-L' + prefix + '/lib')
+environ_prepend('CPPFLAGS', '-I' + prefix + '/include')
+
+# Make sure that ltdl can find our libraries
+addpath("LTDL_LIBRARY_PATH", prefix + "/lib")
+
+# Add additional Perl paths so that our modules can be found.
+
+prependpath('PERL5LIB', prefix + '/lib/perl5/vendor_perl')
+prependpath('PERL5LIB', prefix + '/lib/perl5/site_perl')
+
+# Point gtk-doc and other xsltproc users to our XML catalog.
+#
+_pfx_cat_file = os.path.join(prefix, 'share', 'xml', 'catalog')
+if not os.path.exists(_pfx_cat_file):
+ os.makedirs(os.path.dirname(_pfx_cat_file))
+ open(_pfx_cat_file, "w").close()
+if 'XML_CATALOG_FILES' in os.environ:
+# os.environ['XML_CATALOG_FILES'] += ':' + _pfx_cat_file
+ pass
+else:
+ os.environ['XML_CATALOG_FILES'] = _pfx_cat_file
+
+#GConf needs to be built static, overriding the generic autogenargs,
+#but including it in the module puts it in front of where autogenargs
+#puts --disable-static, so we need the override here.
+#
+append_autogenargs("gconf", "--enable-static")
+
+if _build:
+ if "shell" in sys.argv:
+ print("Build setup: %s, prefix: %s" % (_build, prefix))
+ os.environ["JHBUILD_CONFIG"] = _build
+else:
+ if "shell" in sys.argv:
+ print("Prefix: %s" % (prefix))
+
+if not _ran_recursively and _gtk_osx_prompt_prefix:
+ os.environ["JHBUILD_PROMPT"] = "[" + _gtk_osx_prompt_prefix + "] "
+
+os.environ["PYTHON"] = os.path.join(prefix, 'bin', 'python3')
+module_extra_env['pkg-config'] = {'PYTHON':sys.executable}
+module_extra_env["spidermonkey"] = {'AUTOCONF':'autoconf'}
+# Unset this so we don't mess with the check for not starting
+# recursively.
+os.unsetenv("JHB")
+
+if "shell" in sys.argv:
+ print("Entered jhbuild shell, type 'exit' to return.")
diff --git a/packaging/macos/jhb/etc/modulesets/jhb/bootstrap.modules b/packaging/macos/jhb/etc/modulesets/jhb/bootstrap.modules
new file mode 100644
index 0000000..6cc2ed6
--- /dev/null
+++ b/packaging/macos/jhb/etc/modulesets/jhb/bootstrap.modules
@@ -0,0 +1,158 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: nxml -*-->
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+ <repository type="tarball" name="ftp.gnu.org"
+ href="https://ftp.gnu.org/gnu/"/>
+ <repository type="tarball" name="pkgconfig"
+ href="http://pkgconfig.freedesktop.org/releases/"/>
+ <repository type="tarball" name="sourceforge"
+ href="http://downloads.sourceforge.net/sourceforge/"/>
+ <repository type="tarball" name="tukaani.org"
+ href="http://tukaani.org/"/>
+ <repository type="tarball" name="cmake"
+ href="https://cmake.org/files/"/>
+ <repository type="tarball" name="cpan" href="http://search.cpan.org/CPAN/" />
+ <repository type="tarball" name="intltool"
+ href="http://launchpad.net/intltool/trunk/"/>
+ <repository type="tarball" name="github" href="https://github.com"/>
+
+ <autotools id="xz" autogen-sh="configure" bootstrap="true">
+ <branch repo="tukaani.org" module="xz/xz-5.2.5.tar.bz2" version="5.2.5"
+ hash="sha256:5117f930900b341493827d63aa910ff5e011e0b994197c3b71c08a20228a42df"/>
+ </autotools>
+
+ <!-- gnu make 4.xx, needed to unbreak parallel builds for the webkit -->
+ <autotools id="gnumake" autogen-sh="configure" bootstrap="true"
+ autogenargs="--disable-dependency-tracking">
+ <branch repo="ftp.gnu.org"
+ module="make/make-4.3.tar.gz" version="4.3"
+ hash="sha256:e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19">
+ </branch>
+ </autotools>
+
+ <autotools id="gettext" autogen-sh="configure"
+ autogenargs="--without-emacs --disable-java --disable-native-java --disable-libasprintf --disable-csharp --with-included-glib --with-included-libcroco"
+ hash="sha256:d20fcbb537e02dcf1383197ba05bd0734ef7bf5db06bdb241eb69b7d16b73192">
+ <branch repo="ftp.gnu.org"
+ module="gettext/gettext-0.21.tar.xz" version="0.21">
+ </branch>
+ </autotools>
+
+ <!-- cmakes ./configure is picky about invalid flags so we manually set it -->
+ <autotools id="cmake" autogen-sh="bootstrap" bootstrap="true"
+ autogen-template="%(srcdir)s/%(autogen-sh)s --prefix=%(prefix)s --docdir=share/doc/cmake-3.20">
+ <branch repo="cmake" module="v3.20/cmake-3.20.0.tar.gz" version="3.20.0">
+ </branch>
+ </autotools>
+ <!-- The version of m4 provided with Xcode is now too old, see
+ https://savannah.gnu.org/support/index.php?110397 -->
+ <autotools id="m4" autogen-sh="configure" bootstrap="true">
+ <branch repo="ftp.gnu.org"
+ module="m4/m4-1.4.18.tar.xz" version="1.4.18"
+ hash="sha256:f2c1e86ca0a404ff281631bdc8377638992744b175afb806e25871a24a934e07">
+ <patch file="vasnprintf.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="autoconf" autogen-sh="configure" bootstrap="true">
+ <branch repo="ftp.gnu.org"
+ module="autoconf/autoconf-2.71.tar.xz" version="2.71"
+ hash="shas56:f14c83cfebcc9427f2c3cea7258bd90df972d92eb26752da4ddad81c87a0faa4"/>
+ <dependencies>
+ <dep package="m4"/>
+ <dep package="xz"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="autoconf-archive" autogen-sh="configure" bootstrap="true">
+ <branch repo="ftp.gnu.org"
+ module="autoconf-archive/autoconf-archive-2021.02.19.tar.xz"
+ version="2021-02-19"
+ hash="sha256:e8a6eb9d28ddcba8ffef3fa211653239e9bf239aba6a01a6b7cfc7ceaec69cbd"/>
+ </autotools>
+
+ <autotools id="libtool" autogen-sh="configure" bootstrap="true">
+ <branch repo="ftp.gnu.org"
+ module="libtool/libtool-2.4.6.tar.gz" version="2.4.6"
+ hash="sha256:e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3">
+ <patch file="libtool-apple-sort.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+
+ <autotools id="automake" autogen-sh="configure" bootstrap="true">
+ <branch repo="ftp.gnu.org" version="1.16.3"
+ module="automake/automake-1.16.3.tar.xz"
+ hash="sha256:ff2bf7656c4d1c6fdda3b8bebb21f09153a736bcba169aaf65eab25fa113bf3a"/>
+ <dependencies>
+ <dep package="autoconf"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="pkg-config" autogen-sh="configure" bootstrap="true"
+ autogenargs="--with-internal-glib">
+ <branch repo="pkgconfig"
+ module="pkg-config-0.29.2.tar.gz" version="0.29.2"
+ hash="sha256:6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591"/>
+ </autotools>
+
+ <!-- MacOS provides 2.3 (presumably the last GPL2 version, gstreamer
+ requires 2.4. -->
+ <autotools id="bison" autogen-sh="configure">
+ <branch repo="ftp.gnu.org" module="bison/bison-3.7.6.tar.xz"
+ version="3.7.6"
+ hash="sha256:67d68ce1e22192050525643fc0a7a22297576682bef6a5c51446903f5aeef3cf">
+ </branch>
+ <dependencies>
+ <dep package='flex'/>
+ </dependencies>
+ </autotools>
+
+ <!-- As of 29 March 2021 Flex hasn't had an update since May 2017. -->
+ <autotools id="flex" autogen-sh="configure" autogenargs="--disable-libfl">
+ <branch module="westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz"
+ repo="github" version="2.6.4"
+ hash="sha256:e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995"/>
+ </autotools>
+
+ <!-- This is generated by tarring up the needed docbook stylesheets
+ for gtk-doc to work. If someone wants to work on a setup that
+ uses the real docbook source from upstream, feel free to do so,
+ it used to be a huge amount of work, but might be easier these
+ days.
+
+ -->
+ <autotools id="gtk-osx-docbook" autogen-sh="configure"
+ supports-non-srcdir-builds="no" >
+ <branch repo="github" module="jralls/gtk-osx-docbook/releases/download/gtk-osx-docbook-1.3/gtk-osx-docbook-1.3.tar.xz"
+ version="1.3"
+ hash="sha256:fcf497688a1d531b192301bd09c55adefda5a662729a58eb8a895166e38ef219"/>
+ </autotools>
+
+ <autotools id="intltool" autogen-sh="configure">
+ <branch repo="intltool" module="0.51.0/+download/intltool-0.51.0.tar.gz"
+ version="0.51.0"
+ hash="sha256:67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"/>
+ <!--dependencies>
+ <dep package="perl-xml-parser"/>
+ </dependencies-->
+ </autotools>
+
+ <metamodule id="meta-bootstrap">
+ <dependencies>
+ <dep package="xz"/>
+ <dep package="gettext" /> <!-- Needed for 64-bit -->
+ <dep package="cmake"/>
+ <dep package="autoconf-archive" />
+ <dep package="libtool" />
+ <dep package="automake"/>
+ <dep package="pkg-config" />
+ <dep package="bison"/>
+ <dep package="flex"/>
+ <dep package="gtk-osx-docbook"/>
+ <dep package="intltool"/>
+ <dep package="gnumake"/>
+ </dependencies>
+ </metamodule>
+
+</moduleset>
diff --git a/packaging/macos/jhb/etc/modulesets/jhb/jhb.modules b/packaging/macos/jhb/etc/modulesets/jhb/jhb.modules
new file mode 100644
index 0000000..f2fc9e3
--- /dev/null
+++ b/packaging/macos/jhb/etc/modulesets/jhb/jhb.modules
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+
+ <repository name="gnu" type="tarball" href="http://ftp.halifax.rwth-aachen.de/gnu/"/>
+
+ <!-- GNU core utilities https://www.gnu.org/software/coreutils/ -->
+ <autotools
+ id="coreutils"
+ autogen-sh="configure"
+ autogenargs="--prefix=$JHBUILD_PREFIX/usr --program-prefix=g">
+ <branch
+ module="coreutils/coreutils-9.1.tar.xz"
+ version="9.1"
+ hash="sha256:61a1f410d78ba7e7f37a5a4f50e6d1320aca33375484a3255eddf17a38580423"
+ repo="gnu">
+ </branch>
+ </autotools>
+
+ <!-- GNU Find Utilities https://www.gnu.org/software/findutils/ -->
+ <autotools
+ id="findutils"
+ autogen-sh="configure"
+ autogenargs="--prefix=$JHBUILD_PREFIX/usr --program-prefix=g">
+ <branch
+ module="findutils/findutils-4.9.0.tar.xz"
+ version="4.9.0"
+ hash="sha256:a2bfb8c09d436770edc59f50fa483e785b161a3b7b9d547573cb08065fd462fe"
+ repo="gnu">
+ </branch>
+ </autotools>
+
+ <!-- GNU sed https://www.gnu.org/software/sed/ -->
+ <autotools
+ id="sed"
+ autogen-sh="configure"
+ autogenargs="--prefix=$JHBUILD_PREFIX/usr --program-prefix=g">
+ <branch
+ module="sed/sed-4.8.tar.xz"
+ version="4.8"
+ hash="sha256:f79b0cfea71b37a8eeec8490db6c5f7ae7719c35587f21edb0617f370eeff633"
+ repo="gnu">
+ </branch>
+ </autotools>
+
+ <!-- GNU Tar https://www.gnu.org/software/tar/ -->
+ <autotools
+ id="tar"
+ autogen-sh="configure"
+ autogenargs="--prefix=$JHBUILD_PREFIX/usr --program-prefix=g">
+ <branch
+ module="tar/tar-1.34.tar.xz"
+ version="1.34"
+ hash="sha256:63bebd26879c5e1eea4352f0d03c991f966aeb3ddeb3c7445c902568d5411d28"
+ repo="gnu">
+ </branch>
+ </autotools>
+
+</moduleset>
diff --git a/packaging/macos/jhb/etc/modulesets/jhb/moduleset.dtd b/packaging/macos/jhb/etc/modulesets/jhb/moduleset.dtd
new file mode 100644
index 0000000..d9c392a
--- /dev/null
+++ b/packaging/macos/jhb/etc/modulesets/jhb/moduleset.dtd
@@ -0,0 +1,240 @@
+<!ELEMENT moduleset (if|redirect|repository|include|autotools|metamodule|tarball|distutils|perl|linux|testmodule|cvsroot|cvsmodule|waf|cmake|meson|systemmodule)+>
+<!ATTLIST moduleset
+ name CDATA #IMPLIED>
+
+<!-- DTD is incapable of allowing different children of an element
+ of a given name depending on the context in which it appears so
+ this is more permissive than it ought to be. The RNG version
+ of the schema gets this correct.
+
+ DTD also appears to be incapable of describing the fact that
+ exactly one of condition-set='' and condition-unset='' is required.
+-->
+<!ELEMENT if (if|autotools|dep|autogenargs|cmakeargs|mesonargs|makeargs|ninjaargs|makeinstallargs)+>
+<!ATTLIST if
+ condition-set CDATA #IMPLIED
+ condition-unset CDATA #IMPLIED>
+
+<!ELEMENT repository (mirror*)>
+<!ATTLIST repository
+ name CDATA #REQUIRED
+ type (arch|bzr|cvs|darcs|fossil|git|hg|mtn|svn|system|tarball) #REQUIRED
+ default (yes|no) "no"
+ password CDATA #IMPLIED
+ cvsroot CDATA #IMPLIED
+ archive CDATA #IMPLIED
+ href CDATA #IMPLIED
+ server CDATA #IMPLIED
+ database CDATA #IMPLIED
+ defbranch CDATA #IMPLIED
+ developer-href-example CDATA #IMPLIED
+ trunk-template CDATA #IMPLIED
+ branches-template CDATA #IMPLIED
+ tags-template CDATA #IMPLIED>
+<!-- note the following attributes are specific to some repository types:
+ - CVS: password & cvsroot
+ - Arch: archive & href
+ - Monotone: server, database, defbranch
+ - Subversion: *-template -->
+
+<!ELEMENT mirror EMPTY>
+<!ATTLIST mirror
+ type (arch|bzr|cvs|darcs|fossil|git|hg|svn|tarball) #REQUIRED
+ trunk-template CDATA #IMPLIED
+ branches-template CDATA #IMPLIED
+ href CDATA #IMPLIED>
+
+<!ELEMENT include EMPTY>
+<!ATTLIST include href CDATA #REQUIRED>
+
+<!ELEMENT redirect EMPTY>
+<!ATTLIST redirect href CDATA #REQUIRED>
+
+<!ELEMENT autotools (if*,autogenargs*,makeargs*,makeinstallargs*,pkg-config?,branch,dependencies?,suggests?,after?)>
+<!-- Note: Here the ID type is not used as some existing IDs in modsets are not
+ valid XML ID types - instead CDATA is used -->
+<!ATTLIST autotools
+ id CDATA #REQUIRED
+ autogenargs CDATA #IMPLIED
+ makeargs CDATA #IMPLIED
+ makeinstallargs CDATA #IMPLIED
+ autogen-sh CDATA #IMPLIED
+ makefile CDATA #IMPLIED
+ bootstrap (true|false) "false"
+ skip-autogen (true|false|never) "false"
+ skip-install (yes|no) "no"
+ uninstall-before-install (true|false) "false"
+ supports-non-srcdir-builds (yes|no) "yes"
+ force-non-srcdir-builds (yes|no) "no"
+ supports-parallel-builds (yes|no) "yes"
+ supports-unknown-configure-options (yes|no) "yes"
+ autogen-template CDATA #IMPLIED
+ check-target (true|false) "true">
+
+<!ELEMENT autogenargs EMPTY>
+<!ATTLIST autogenargs value CDATA #REQUIRED>
+<!ELEMENT makeargs EMPTY>
+<!ATTLIST makeargs value CDATA #REQUIRED>
+<!ELEMENT makeinstallargs EMPTY>
+<!ATTLIST makeinstallargs value CDATA #REQUIRED>
+
+<!ELEMENT waf (pkg-config?,branch,dependencies?,suggests?,after?)>
+<!-- Note: Here the ID type is not used as some existing IDs in modsets are not
+ valid XML ID types - instead CDATA is used -->
+<!ATTLIST waf
+ id CDATA #REQUIRED
+ waf-command CDATA #IMPLIED>
+
+<!ELEMENT metamodule (dependencies,suggests?,after?)>
+<!ATTLIST metamodule
+ id CDATA #REQUIRED>
+
+<!-- tarball module type is deprecated, a tarball repository inside the
+ appropriate modtype should be used instead -->
+<!ELEMENT tarball (pkg-config?,source,branch?,dependencies?,suggests?,after?,patches?)>
+<!ATTLIST tarball
+ id CDATA #REQUIRED
+ version CDATA #REQUIRED
+ checkoutdir CDATA #IMPLIED
+ autogenargs CDATA #IMPLIED
+ makeargs CDATA #IMPLIED
+ autogen-sh CDATA #IMPLIED
+ supports-non-srcdir-builds (yes|no) "yes">
+
+<!ELEMENT distutils (pkg-config?,branch?,dependencies?,after?)>
+<!ATTLIST distutils
+ id ID #REQUIRED
+ python3 CDATA #FIXED "1"
+ supports-non-srcdir-builds (yes|no) "yes">
+
+<!ELEMENT ninjaargs EMPTY>
+<!ATTLIST ninjaargs value CDATA #REQUIRED>
+
+<!ELEMENT cmake (if*,cmakeargs*,makeargs*,ninjaargs*,pkg-config?,branch?,dependencies?,suggests?,after?)>
+<!ATTLIST cmake
+ id CDATA #REQUIRED
+ cmakeargs CDATA #IMPLIED
+ makeargs CDATA #IMPLIED
+ ninjaargs CDATA #IMPLIED
+ use-ninja (yes|no) "yes"
+ supports-non-srcdir-builds (yes|no) "yes"
+ force-non-srcdir-builds (yes|no) "no">
+
+<!ELEMENT cmakeargs EMPTY>
+<!ATTLIST cmakeargs value CDATA #REQUIRED>
+
+<!ELEMENT meson (if*,mesonargs*,ninjaargs*,pkg-config?,branch?,dependencies?,suggests?,after?)>
+<!ATTLIST meson
+ id CDATA #REQUIRED
+ mesonargs CDATA #IMPLIED
+ ninjaargs CDATA #IMPLIED>
+
+<!ELEMENT mesonargs EMPTY>
+<!ATTLIST mesonargs value CDATA #REQUIRED>
+
+<!ELEMENT perl (pkg-config?,branch?,dependencies?,after?)>
+<!ATTLIST perl
+ id CDATA #REQUIRED
+ makeargs CDATA #IMPLIED>
+
+<!ELEMENT linux (pkg-config?,branch?,dependencies?,after?,kconfig+)>
+<!ATTLIST linux
+ id CDATA #REQUIRED>
+
+<!ELEMENT systemmodule (pkg-config?,branch,dependencies?,suggests?,after?,systemdependencies?)>
+<!ATTLIST systemmodule
+ id CDATA #REQUIRED
+ supports-parallel-builds (yes|no) "yes">
+
+<!ELEMENT testmodule (pkg-config?,branch?,dependencies?,after?,testedmodules?)>
+<!ATTLIST testmodule
+ id CDATA #REQUIRED
+ type CDATA #REQUIRED>
+
+<!ELEMENT cvsroot EMPTY>
+<!ATTLIST cvsroot
+ name CDATA #REQUIRED
+ root CDATA #REQUIRED
+ password CDATA "">
+
+
+<!ELEMENT cvsmodule (suggests?,dependencies?,after?)>
+<!ATTLIST cvsmodule
+ id CDATA #REQUIRED
+ cvsroot CDATA #REQUIRED
+ supports-non-srcdir-builds (yes|no) "yes">
+
+<!-- Tarball's children -->
+<!ELEMENT source EMPTY>
+<!ATTLIST source
+ href CDATA #REQUIRED
+ size CDATA #IMPLIED
+ md5sum CDATA #IMPLIED
+ hash CDATA #IMPLIED>
+
+<!ELEMENT patches (patch*)>
+<!ELEMENT patch EMPTY>
+<!ATTLIST patch
+ file CDATA #REQUIRED
+ strip CDATA "0">
+
+
+<!-- Linux's children -->
+<!ELEMENT kconfig EMPTY>
+<!ATTLIST kconfig
+ repo CDATA #IMPLIED
+ version CDATA #REQUIRED
+ module CDATA #IMPLIED
+ config CDATA #IMPLIED>
+
+
+<!-- Testmodule's children -->
+<!ELEMENT testedmodules (tested)>
+<!ELEMENT tested EMPTY>
+<!ATTLIST tested
+ package CDATA #REQUIRED>
+
+<!-- Other children -->
+<!ELEMENT pkg-config (#PCDATA)>
+<!ELEMENT dependencies (dep|if)*>
+<!ELEMENT suggests (dep|if)*>
+<!ELEMENT after (dep|if)*>
+<!ELEMENT systemdependencies (dep*)>
+<!ELEMENT dep (altdep*)>
+<!-- This is actually 2 different types of element: <dep package=""/> as used in <dependencies>
+ and <dep type="" name=""/> as used in <systemdependencies>. The DTD can't specify both
+ separately since they have the same element name. -->
+<!ATTLIST dep
+ package CDATA #IMPLIED
+ type CDATA #IMPLIED
+ name CDATA #IMPLIED>
+<!-- <altdep> is only used in <systemdependencies> to specify alternative dependencies. -->
+<!ELEMENT altdep EMPTY>
+<!ATTLIST altdep
+ type CDATA #IMPLIED
+ name CDATA #IMPLIED>
+
+<!ELEMENT branch (patch*,quilt*)>
+<!ATTLIST branch
+ repo CDATA #IMPLIED
+ module CDATA #IMPLIED
+ checkoutdir CDATA #IMPLIED
+ override-checkoutdir (yes|no) "yes"
+ update-new-dirs (yes|no) "yes"
+ source-subdir CDATA #IMPLIED
+ revision CDATA #IMPLIED
+ tag CDATA #IMPLIED
+ user CDATA #IMPLIED
+ revspec CDATA #IMPLIED
+ branch CDATA #IMPLIED
+ version CDATA #IMPLIED
+ size CDATA #IMPLIED
+ md5sum CDATA #IMPLIED
+ hash CDATA #IMPLIED
+ rename-tarball CDATA #IMPLIED>
+ <!-- override-checkoutdir and update-new-dirs are CVS only
+ source-subdir is tarballs only -->
+
+<!ELEMENT quilt (branch)>
+<!ATTLIST quilt
+ id CDATA #REQUIRED>
diff --git a/packaging/macos/jhb/etc/modulesets/jhb/moduleset.xsl b/packaging/macos/jhb/etc/modulesets/jhb/moduleset.xsl
new file mode 100644
index 0000000..c2e7f7a
--- /dev/null
+++ b/packaging/macos/jhb/etc/modulesets/jhb/moduleset.xsl
@@ -0,0 +1,196 @@
+<?xml version='1.0'?> <!--*- mode: nxml -*-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:output method="html" encoding="ISO-8859-1" indent="yes" />
+ <xsl:key name="module-id" match="moduleset/*" use="@id" />
+
+ <xsl:template match="/">
+ <html>
+ <head>
+ <title>Module Set</title>
+ <style type="text/css">
+ <xsl:text>
+ dl {
+ -moz-column-width: 40em;
+ -moz-column-gap: 2em;
+ }
+ dt {
+ font-weight: bold;
+ background: #8f8;
+ display: inline;
+ padding: 0 1ex;
+ }
+ dt.metamodule {
+ background: #F08080;
+ }
+ dt.tarball {
+ background: #EEDD82;
+ }
+ dd {
+ font-size: smaller;
+ }
+ dd {
+ margin-bottom: 0.5em;
+ }
+ th {
+ text-align: left;
+ vertical-align: top;
+ }
+ ul.patches {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ }
+ </xsl:text>
+ </style>
+ </head>
+ <body>
+ <xsl:apply-templates />
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="moduleset">
+ <h1>JHBuild Module Set</h1>
+ <dl>
+ <xsl:apply-templates />
+ </dl>
+ </xsl:template>
+
+ <xsl:template match="dependencies|suggests|after">
+ <xsl:variable name="deps" select="dep/@package" />
+ <xsl:for-each select="$deps">
+ <a href="#{generate-id(key('module-id', .))}">
+ <xsl:value-of select="." />
+ </a>
+ <xsl:if test="not($deps[last()] = .)">
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="moduleset/*">
+ <xsl:param name="reponame">
+ <xsl:choose>
+ <xsl:when test="branch/@repo"><xsl:value-of select="branch/@repo"/></xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="//repository[@default = 'yes']/@name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+
+ <dt id="{generate-id(.)}">
+ <xsl:attribute name="class">module
+ <xsl:if test="name(.) = 'tarball' or
+ //repository[@name = $reponame]/@type = 'tarball'">tarball</xsl:if>
+ </xsl:attribute>
+ <xsl:value-of select="@id" />
+ </dt>
+
+ <dd>
+ <table>
+ <tr>
+ <th>Module:</th>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@module">
+ <xsl:value-of select="@module" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@id" />
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="branch/@revision">
+ <xsl:text> revision: </xsl:text>
+ <xsl:value-of select="branch/@revision" />
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:if test="name(.) = 'tarball' or //repository[@name = $reponame]/@type = 'tarball'">
+ <tr>
+ <th>URL:</th>
+ <td>
+ <xsl:variable name="url">
+ <xsl:choose>
+ <xsl:when test="name(.) = 'tarball'">
+ <xsl:value-of select="source/@href"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="//repository[@name=$reponame]/@href"
+ /><xsl:value-of select="branch/@module"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <a href="{$url}"><xsl:value-of select="$url"/></a>
+ <xsl:if test="branch/@size"> (<xsl:value-of select="branch/@size"/> bytes)</xsl:if>
+ <xsl:if test="source/@size"> (<xsl:value-of select="source/@size"/> bytes)</xsl:if>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="branch/patch">
+ <tr>
+ <th>Patches:</th>
+ <td>
+ <ul class="patches">
+ <xsl:apply-templates select="branch/patch"/>
+ </ul>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="@checkoutdir">
+ <tr>
+ <th>Checkout directory:</th>
+ <td><xsl:value-of select="@checkoutdir" /></td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="@autogenargs">
+ <tr>
+ <th>Autogen args:</th>
+ <td><xsl:value-of select="@autogenargs" /></td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="dependencies/dep">
+ <tr>
+ <th>Dependencies:</th>
+ <td><xsl:apply-templates select="dependencies" /></td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="suggests">
+ <tr>
+ <th>Suggests:</th>
+ <td><xsl:apply-templates select="suggests" /></td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="after">
+ <tr>
+ <th>After:</th>
+ <td><xsl:apply-templates select="after" /></td>
+ </tr>
+ </xsl:if>
+ </table>
+ </dd>
+ </xsl:template>
+
+ <xsl:template match="moduleset/repository|moduleset/include">
+ </xsl:template>
+
+ <xsl:template match="moduleset/metamodule">
+ <dt id="{generate-id(.)}" class="metamodule"><xsl:value-of select="@id" /></dt>
+ <dd>
+ <table>
+ <xsl:if test="dependencies/dep">
+ <tr>
+ <th>Dependencies:</th>
+ <td><xsl:apply-templates select="dependencies" /></td>
+ </tr>
+ </xsl:if>
+ </table>
+ </dd>
+ </xsl:template>
+
+ <xsl:template match="patch">
+ <li><xsl:value-of select="@file" /></li>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/packaging/macos/jhb/etc/modulesets/jhb/patches/libtool-apple-sort.patch b/packaging/macos/jhb/etc/modulesets/jhb/patches/libtool-apple-sort.patch
new file mode 100644
index 0000000..8c880ef
--- /dev/null
+++ b/packaging/macos/jhb/etc/modulesets/jhb/patches/libtool-apple-sort.patch
@@ -0,0 +1,38 @@
+--- a/Makefile.am 2015-01-20 07:34:33.000000000 -0800
++++ b/Makefile.am 2021-11-12 10:18:23.000000000 -0800
+@@ -416,8 +416,8 @@
+ # files created in the build tree, so instead we regenerate the
+ # manual pages if the sources for the build-tree files we want to
+ # run have changed.
+-$(libtool_1): $(ltmain_sh)
+- $(AM_V_GEN)$(update_mans) --help-option=--help-all libtool
++#$(libtool_1): $(ltmain_sh)
++# $(AM_V_GEN)$(update_mans) --help-option=--help-all libtool
+ $(libtoolize_1): $(libtoolize_in)
+ $(AM_V_GEN)$(update_mans) libtoolize
+
+--- s/Makefile.in 2015-02-15 08:14:14.000000000 -0800
++++ b/Makefile.in 2021-11-12 10:26:26.000000000 -0800
+@@ -2324,8 +2324,8 @@
+ # files created in the build tree, so instead we regenerate the
+ # manual pages if the sources for the build-tree files we want to
+ # run have changed.
+-$(libtool_1): $(ltmain_sh)
+- $(AM_V_GEN)$(update_mans) --help-option=--help-all libtool
++#$(libtool_1): $(ltmain_sh)
++# $(AM_V_GEN)$(update_mans) --help-option=--help-all libtool
+ $(libtoolize_1): $(libtoolize_in)
+ $(AM_V_GEN)$(update_mans) libtoolize
+
+--- a/build-aux/ltmain.in 2015-02-06 04:57:56.000000000 -0800
++++ b/build-aux/ltmain.in 2021-11-08 14:58:33.000000000 -0800
+@@ -3188,7 +3188,7 @@
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+- if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
++ if ($AR t "$f_ex_an_ar_oldlib" | sort -u | sort -c >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+
diff --git a/packaging/macos/jhb/etc/modulesets/jhb/patches/vasnprintf.patch b/packaging/macos/jhb/etc/modulesets/jhb/patches/vasnprintf.patch
new file mode 100644
index 0000000..995e1e3
--- /dev/null
+++ b/packaging/macos/jhb/etc/modulesets/jhb/patches/vasnprintf.patch
@@ -0,0 +1,11 @@
+--- a/lib/vasnprintf.c 2017-09-29 11:10:29.000000000 +0200
++++ b/lib/vasnprintf.c 2017-09-29 11:15:06.000000000 +0200
+@@ -4858,7 +4858,7 @@
+ #endif
+ *fbp = dp->conversion;
+ #if USE_SNPRINTF
+-# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
++# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) || defined __APPLE__)
+ fbp[1] = '%';
+ fbp[2] = 'n';
+ fbp[3] = '\0';
diff --git a/packaging/macos/jhb/usr/bin/archive b/packaging/macos/jhb/usr/bin/archive
new file mode 100755
index 0000000..f84f0c8
--- /dev/null
+++ b/packaging/macos/jhb/usr/bin/archive
@@ -0,0 +1,205 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This is a helper to create release archives and mount them.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+#------------------------------------------------------ source jhb configuration
+
+source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh
+
+#------------------------------------------- source common functions from bash_d
+
+# bash_d is already available (it's part of jhb configuration)
+
+bash_d_include error
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+function create_tar
+{
+ local file=$ARTIFACT_DIR/$RELEASE_ARCHIVE
+
+ echo_i "creating $file"
+
+ tar -C "$WRK_DIR" -cp "$(basename "$VER_DIR")" |
+ XZ_OPT=-T0 "$BIN_DIR"/xz > "$file"
+
+ shasum -a 256 "$file" > "$file".sha256
+ cat "$file".sha256
+}
+
+function create_dmg
+{
+ local file=$ARTIFACT_DIR/$RELEASE_ARCHIVE
+
+ ( # create dmg
+ local vol_name
+ vol_name=$(basename "$VER_DIR")
+
+ cd "$WRK_DIR" || exit 1
+ hdiutil create -fs HFS+ -ov -format UDBZ \
+ -srcfolder "$vol_name" \
+ -volname "$vol_name" \
+ "$file"
+ )
+
+ ( # create and print checksum
+ cd "$(dirname "$file")" || exit 1
+ shasum -a 256 "$(basename "$file")" > "$file".sha256
+ cat "$file".sha256
+ )
+}
+
+function mount_dmg
+{
+ local file=$REP_DIR/$RELEASE_ARCHIVE
+ local mountpoint=$VER_DIR
+
+ if [ ! -d "$mountpoint" ]; then
+ mkdir -p "$mountpoint"
+ fi
+
+ echo_i "mounting $(basename "$file") may take some time"
+ local device
+ device=$(hdiutil attach -nomount "$file" | grep "^/dev/disk" |
+ grep "Apple_HFS" | awk '{ print $1 }')
+ echo_i "$file attached to $device"
+ mount -o nobrowse,noowners,noquarantine,ro -t hfs "$device" "$mountpoint"
+ echo_i "$device mounted to $mountpoint"
+}
+
+function unmount_dmg
+{
+ local mountpoint=$VER_DIR
+
+ while : ; do # unmount everything (in reverse order)
+ local disk
+ disk=$(mount | grep "$mountpoint" | tail -n1 | awk '{ print $1 }')
+ disk=${disk%s[0-9]} # cut off slice specification
+
+ if [ ${#disk} -eq 0 ]; then
+ break # nothing to do here
+ else
+ # We loop over the 'eject' since it occasionally timeouts.
+ while ! diskutil eject "$disk" > /dev/null; do
+ echo_w "retrying to eject $disk in 5 seconds"
+ sleep 5
+ done
+
+ echo_i "ejected $disk"
+ fi
+ done
+}
+
+function download_dmg
+{
+ if [ ! -d "$REP_DIR" ]; then
+ mkdir -p "$REP_DIR"
+ fi
+
+ for url in "${RELEASE_URLS[@]}"; do
+ local partial_download=$REP_DIR/${FUNCNAME[0]} # TMP_DIR not available yet
+ # download (at least) 100 kb of data
+ curl -L "$url" 2>/dev/null | head -c 100000 > "$partial_download"
+ # if we got 100 kb, it's not a "404 file not found"
+ if [ "$(stat -f%z "$partial_download")" -eq 100000 ]; then
+ echo_i "downloading $url"
+ curl -o "$REP_DIR/$RELEASE_ARCHIVE" -L -C - "$url"
+ break
+ fi
+ done
+
+ rm "$partial_download"
+}
+
+function install_dmg
+{
+ local overlay_size=${1:-1} # unit GiB, default 1
+
+ local file=$REP_DIR/$RELEASE_ARCHIVE
+
+ # download and mount read-only disk image
+ if [ -f "$file" ]; then
+ echo_i "using $file"
+ else
+ download_dmg
+ fi
+ mount_dmg
+
+ # create writable overlay
+ local device
+ device=$(hdiutil attach -nomount ram://$((overlay_size * 1024 * 2048)) | xargs)
+ newfs_hfs -v "$RELEASE_OVERLAY" "$device" >/dev/null
+ echo_i "$overlay_size GiB ram attached to $device"
+ mount -o nobrowse,rw,union -t hfs "$device" "$VER_DIR"
+ echo_i "$device union-mounted at $VER_DIR"
+
+ # Sadly, there are some limitations involved with union-mounting:
+ # - Files are not visible to macOS' versions of 'ls' or 'find'.
+ # (The GNU versions do work though.)
+ # - You cannot write in a location without having written to its
+ # parent location first. That's why we need to pre-create all directories
+ # below.
+ #
+ # (Shadow-mounting a dmg is not a feasible alternative due to its
+ # bad write-performance.)
+
+ # Create and run a script for mass-creating directories.
+ echo_i "setting up directories in overlay"
+ gfind "$VER_DIR" -mindepth 1 -type d \
+ ! -path "$BLD_DIR/*" ! -path "$SRC_DIR/*" \
+ -exec echo "mkdir {}" \; > "$VER_DIR"/create_dirs.sh
+ chmod 755 "$VER_DIR"/create_dirs.sh
+ "$VER_DIR"/create_dirs.sh
+ rm "$VER_DIR"/create_dirs.sh
+}
+
+function uninstall_dmg
+{
+ unmount_dmg
+}
+
+function main
+{
+ local command=$1
+ local option=$2
+
+ case "$command" in
+ create_dmg)
+ create_dmg
+ ;;
+ create_tar)
+ create_tar
+ ;;
+ install_dmg)
+ install_dmg "$option" # option: overlay size in GiB, defaul is 1
+ ;;
+ uninstall_dmg)
+ uninstall_dmg
+ ;;
+ *)
+ echo_e "usage: $0 {create_dmg|create_tar|install_dmg|uninstall_dmg}"
+ ;;
+ esac
+}
+
+### main #######################################################################
+
+error_trace_enable
+
+main "$@"
diff --git a/packaging/macos/jhb/usr/bin/bootstrap b/packaging/macos/jhb/usr/bin/bootstrap
new file mode 100755
index 0000000..3d46dbb
--- /dev/null
+++ b/packaging/macos/jhb/usr/bin/bootstrap
@@ -0,0 +1,135 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This script bootstraps JHBuild so it's ready to build any module.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+#------------------------------------------------------ source jhb configuration
+
+# You can install a custom configuration file by passing it as first
+# argument. It has to be named '*.conf.sh'.
+
+source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh "$1"
+
+#------------------------------------------- source common functions from bash_d
+
+# bash_d is already available (it's part of jhb configuration)
+
+bash_d_include error
+
+### variables ##################################################################
+
+SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1; pwd)
+
+FORCE_BUILD_FROM_SOURCE=${FORCE_BUILD_FROM_SOURCE:-false}
+
+### functions ##################################################################
+
+function is_release_usable
+{
+ local url=$1
+
+ local partial_download="$TMP_DIR/${FUNCNAME[0]}".tar.xz
+ local rc=1
+
+ # download at least 100 kb of data
+ curl -L "$url" 2>/dev/null | head -c 100000 > "$partial_download"
+ # if we got 100 kb, it's not a "404 file not found"
+ if [ "$(stat -f%z "$partial_download")" -eq 100000 ]; then
+ # look inside: dir needs to match our VER_DIR to be usable
+ local dir
+ dir=$(basename "$(tar -tvJf "$partial_download" 2>/dev/null |
+ head -n 1 | awk '{ print $NF }')")
+ if [ "$dir" = "$(basename "$VER_DIR")" ]; then
+ rc=0
+ fi
+ fi
+
+ rm "$partial_download"
+
+ return $rc
+}
+
+### main #######################################################################
+
+error_trace_enable
+
+#-------------------------------------------------------- print main directories
+
+echo_i "WRK_DIR = $WRK_DIR"
+echo_i "VER_DIR = $VER_DIR"
+
+#--------------------------------------------------------- perform system checks
+
+if sys_wrkdir_is_usable &&
+ sdkroot_exists &&
+ sys_usrlocal_is_clean; then
+
+ # these checks may issue warnings but have have no consequences otherwise
+ sys_macos_is_recommended || true
+ sys_sdk_is_recommended || true
+else
+ exit 1 # cannot continue
+fi
+
+#--------------------------------------------------- initialize directory layout
+
+if [ "$SELF_DIR" = "$USR_DIR"/bin ]; then
+ : # we are already running inside target directory layout
+else
+ # sync repository into target structure, remove everything git-related
+ rsync -a "$SELF_DIR"/../../../jhb/ "$VER_DIR"/
+ find "$VER_DIR" -type f -name ".gitignore" -delete
+ rm -rf "$VER_DIR"/.git
+ rm "$VER_DIR"/.gitmodules
+fi
+
+#------------------------------------------- check if binary release can be used
+
+for URL in "${RELEASE_URLS[@]}"; do
+ if is_release_usable "$URL" && ! $FORCE_BUILD_FROM_SOURCE; then
+ echo_i "using $URL"
+ curl -L "$URL" | tar -C "$WRK_DIR" -xJ
+ exit $? # we can quit here and now, nothing further to do
+ fi
+done
+
+echo_i "building everything from scratch"
+
+#---------------------------------------------------------------- install ccache
+
+ccache_install
+ccache_configure
+
+#------------------------------------------ log relevant versions to release.log
+
+sys_create_log
+
+#------------------------------------------------- install and configure JHBuild
+
+jhbuild_install
+jhbuild_configure
+
+#------------------------------------------------------- run bootstrap procedure
+
+jhbuild bootstrap-gtk-osx
+
+#--------------------------------------------------------- install GNU utilities
+
+# GNU versions of various utilites make life significantly easier on macOS.
+
+jhbuild build coreutils findutils sed tar
+
+#-------------------------------------------------------------- install dmgbuild
+
+dmgbuild_install
diff --git a/packaging/macos/jhb/usr/bin/jhb b/packaging/macos/jhb/usr/bin/jhb
new file mode 100755
index 0000000..b268339
--- /dev/null
+++ b/packaging/macos/jhb/usr/bin/jhb
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This script is a wrapper around the jhbuild binary to run it in our
+# configured environment (etc/jhb.conf).
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+#---------------------------------------------------------- source configuration
+
+source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh
+
+#------------------------------------------- source common functions from bash_d
+
+# bash_d is already available (it's part of etc/jhb.conf)
+
+bash_d_include error
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+if $CI; then # break in CI, otherwise we get interactive prompt by JHBuild
+ error_trace_enable
+fi
+
+case "$1" in
+ debug)
+ echo_d "doing nothing"
+ ;;
+ configure)
+ jhbuild_configure "$2" # e.g. 'jhbuild/myapp.modules'
+ ccache_configure
+ ;;
+ *)
+ if sys_wrkdir_is_usable &&
+ sdkroot_exists &&
+ sys_usrlocal_is_clean; then
+
+ # these checks may issue warnings but have have no consequences otherwise
+ sys_macos_is_recommended || true
+ sys_sdk_is_recommended || true
+ else
+ exit 1 # cannot continue
+ fi
+ "$USR_DIR"/bin/jhbuild "$@"
+ ;;
+esac \ No newline at end of file
diff --git a/packaging/macos/jhb/usr/bin/run-parts b/packaging/macos/jhb/usr/bin/run-parts
new file mode 100755
index 0000000..ff0470c
--- /dev/null
+++ b/packaging/macos/jhb/usr/bin/run-parts
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+
+### description ################################################################
+
+# A partial replacement for Debian's "run-parts" tool. Execute files in a
+# directory in their lexical order with the specialty of being able to
+# use symlinks to create an order without executing the files twice.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+function main
+{
+ local mode=$1
+ local dir=$2
+
+ local file_pattern
+
+ if [ -d "$dir" ]; then
+ # reconstruct to make it proper (e.g. remove superfluous slashes)
+ dir=$(dirname "$dir")/$(basename "$dir")
+ else
+ # split into directory and file
+ file_pattern=$(basename "$dir")
+ dir=$(dirname "$dir")
+ fi
+
+ file_pattern=${file_pattern:-*} # default pattern is "*"
+
+ local linked_files
+ linked_files=$(find "$dir" -type l -exec readlink {} +)
+
+ for file in "$dir"/$file_pattern; do # requires 'shopt -s nullglob'
+ # Only process files that have no symlinks (in that same directory) pointing
+ # at them.
+ if [[ "$linked_files" != *$(basename "$file")* ]]; then
+ case "$mode" in
+ list)
+ echo "$file"
+ ;;
+ run)
+ $file
+ ;;
+ esac
+ fi
+ done
+}
+
+### main #######################################################################
+
+set -e
+
+shopt -s nullglob # in case no files are found
+
+case "$1" in
+ list)
+ main "list" "$2"
+ ;;
+ *)
+ main "run" "$1"
+ ;;
+esac
diff --git a/packaging/macos/jhb/usr/src/bash_d/README.md b/packaging/macos/jhb/usr/src/bash_d/README.md
new file mode 100644
index 0000000..fc97cc4
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/README.md
@@ -0,0 +1,9 @@
+# `bash_d`
+
+Conceived as part of my (unpublished) dotfiles on macOS, this collection of functions outgrew its originally limited scope and I began developing this into the spiritual successor of [bashlib](https://github.com/dehesselle/bashlib).
+
+This is far from finished and comes with no support and without documentation at this point, but I need to put this online now so I can start using this in other projects.
+
+## License
+
+[GPL](LICENSE) \ No newline at end of file
diff --git a/packaging/macos/jhb/usr/src/bash_d/ansi.sh b/packaging/macos/jhb/usr/src/bash_d/ansi.sh
new file mode 100644
index 0000000..5ecc5ff
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/ansi.sh
@@ -0,0 +1,76 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This file contains ANSI control codes to control terminal output.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # there are a lot of unexported vars here
+
+### includes ###################################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+ANSI_ENABLED=${ANSI_ENABLED:-true} # allow ANSI escape sequences...
+ANSI_TERM_ONLY=${ANSI_TERM_ONLY:-true} # ...but only when running in a terminal
+
+ANSI_CURSOR_LEFT="\033[1D"
+
+# 0: normal
+# 1: bold
+# 2: faint
+# |
+# \033[1;32m
+# |
+# color
+ANSI_FG_BLACK="\033[0;30m"
+ANSI_FG_BLACK_BOLD="\033[1;30m"
+ANSI_FG_BLACK_BRIGHT="\033[0;90m"
+ANSI_FG_BLUE="\033[0;34m"
+ANSI_FG_BLUE_BOLD="\033[1;34m"
+ANSI_FG_BLUE_BRIGHT="\033[0;94m"
+ANSI_FG_CYAN="\033[0;36m"
+ANSI_FG_CYAN_BOLD="\033[1;36m"
+ANSI_FG_CYAN_BRIGHT="\033[0;96m"
+ANSI_FG_GREEN="\033[0;32m"
+ANSI_FG_GREEN_BOLD="\033[1;32m"
+ANSI_FG_GREEN_BRIGHT="\033[0;92m"
+ANSI_FG_MAGENTA="\033[0;35m"
+ANSI_FG_MAGENTA_BOLD="\033[1;35m"
+ANSI_FG_MAGENTA_BRIGHT="\033[0;95m"
+ANSI_FG_RED="\033[0;31m"
+ANSI_FG_RED_BOLD="\033[1;31m"
+ANSI_FG_RED_BRIGHT="\033[0;91m"
+ANSI_FG_RESET="\033[0;0m"
+ANSI_FG_WHITE="\033[0;37m"
+ANSI_FG_WHITE_BOLD="\033[1;37m"
+ANSI_FG_WHITE_BRIGHT="\033[0;97m"
+ANSI_FG_YELLOW="\033[0;33m"
+ANSI_FG_YELLOW_BOLD="\033[1;33m"
+ANSI_FG_YELLOW_BRIGHT="\033[0;93m"
+
+### functions ##################################################################
+
+function ansi_test_colors
+{
+ for color in ${!ANSI_FG_*}; do
+ echo -e "${!color}This is $color"
+ done
+}
+
+### aliases ####################################################################
+
+# This performs the following check:
+# - usage of ANSI is generally enabled AND
+# - we are either running in a terminal OR we don't care at all
+alias ansi_is_usable='$ANSI_ENABLED && ([ -t 1 ] || ! $ANSI_TERM_ONLY)'
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/usr/src/bash_d/assert.sh b/packaging/macos/jhb/usr/src/bash_d/assert.sh
new file mode 100644
index 0000000..6b65138
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/assert.sh
@@ -0,0 +1,42 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This file provides a mechanism to restrict sourcing a script to specific
+# platforms.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+bash_d_include echo
+
+### variables ##################################################################
+
+ASSERT_RC=0
+
+### functions ##################################################################
+
+# Nothing here.
+
+### aliases ####################################################################
+
+# Bash version
+alias assert_bash4_or_above='[ ${BASH_VERSINFO[0]} -lt 4 ] && echo_e "$(basename ${BASH_SOURCE[0]}) will be unavailable (depends on bash >= 4)" && return $LINENO || true'
+
+# Git
+alias assert_git='[ ! -x "$(command -v git)" ] && echo_e "$(basename ${BASH_SOURCE[0]}) will be unavailable (depends on git)" && return $LINENO || true'
+
+# Unix platforms
+alias assert_darwin='[ "$(uname)" != "Darwin" ] && echo_e "Darwin required" && return $LINENO || true'
+alias assert_linux='[ "$(uname)" != "Linux" ] && echo_e "Linux required" && return $LINENO || true'
+
+alias assert_ok='ASSERT_RC=$?; [ $ASSERT_RC -ne 0 ] && echo_e "assert_ok rc=$ASSERT_RC" && return $LINENO'
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/usr/src/bash_d/bash_d.sh b/packaging/macos/jhb/usr/src/bash_d/bash_d.sh
new file mode 100644
index 0000000..e0715b4
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/bash_d.sh
@@ -0,0 +1,98 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Provide an include guard to be used in every script to protect them from
+# being sourced multiple times.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+# All of these need to be "or true" because they fail on the first run.
+
+bash_d_include echo 2>/dev/null || true
+bash_d_include assert 2>/dev/null || true
+
+### variables ##################################################################
+
+BASH_D_DIR=${BASH_D_DIR:-$(dirname "${BASH_SOURCE[0]}")}
+
+if [ "$BASH_D_FAIL_ON_INCLUDE_ERROR" != "false" ]; then
+ BASH_D_FAIL_ON_INCLUDE_ERROR=true
+fi
+
+### functions ##################################################################
+
+function bash_d_include_all
+{
+ local includes
+ includes=$(mktemp "$TMP/${FUNCNAME[0]}".XXXXXX)
+
+ echo "BASH_D_FAIL_ON_INCLUDE_ERROR=false" >> "$includes"
+ for file in "$BASH_D_DIR"/*.sh; do
+ echo "bash_d_include $(basename "$file")" >> "$includes"
+ done
+ echo "BASH_D_FAIL_ON_INCLUDE_ERROR=true" >> "$includes"
+
+ # shellcheck disable=SC1090 # dynamic sourcing on purpose
+ source "$includes"
+ rm "$includes"
+}
+
+function bash_d_is_included
+{
+ local file=$1
+
+ #shellcheck disable=SC2076 # we want literal match, not regex
+ if [[ " ${BASH_D_INCLUDE_FILES[*]} " =~ \
+ " $BASH_D_DIR/$(basename -s .sh "$file").sh " ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+### aliases ####################################################################
+
+# shellcheck disable=SC2142 # too much trickery for shellcheck to digest
+alias bash_d_include=\
+'declare -a BASH_D_INCLUDE_FILES; '\
+'BASH_D_INCLUDE_FILE=$(sed -n ${LINENO}p ${BASH_SOURCE[0]} | awk '"'"'{ print $2 }'"'"'); '\
+'BASH_D_INCLUDE_FILE=$BASH_D_DIR/$(basename -s .sh $BASH_D_INCLUDE_FILE).sh; '\
+'if [[ " ${BASH_D_INCLUDE_FILES[@]} " =~ " ${BASH_D_INCLUDE_FILE} " ]]; then '\
+' : ; '\
+'else '\
+' if [ "$BASH_D_INCLUDE_FILE" = "$BASH_D_DIR/bash_d.sh" ] && '\
+' [ ${#BASH_D_INCLUDE_FILES[@]} -gt 0 ] || '\
+' source $BASH_D_INCLUDE_FILE; then '\
+' BASH_D_INCLUDE_FILE=$(sed -n ${LINENO}p ${BASH_SOURCE[0]} | awk '"'"'{ print $2 }'"'"'); '\
+' BASH_D_INCLUDE_FILE=$BASH_D_DIR/$(basename -s .sh $BASH_D_INCLUDE_FILE).sh; '\
+' BASH_D_INCLUDE_FILES+=("$BASH_D_INCLUDE_FILE"); '\
+' else '\
+' if alias | grep "echo_e" >/dev/null; then '\
+' echo_e "$BASH_D_INCLUDE_FILE will be unavailable"; '\
+' else '\
+' >&2 echo "error: $BASH_D_INCLUDE_FILE will be unavailable"; '\
+' fi; '\
+' if [ "$BASH_D_INCLUDE_FILE" != "$BASH_D_DIR/bash_d.sh" ] && $BASH_D_FAIL_ON_INCLUDE_ERROR; then '\
+' exit 1; '\
+' fi '\
+' fi '\
+'fi '\
+'# '
+
+### main #######################################################################
+
+if [ ! -d "$BASH_D_DIR" ]; then
+ echo "error: BASH_D_DIR=$BASH_D_DIR is invalid [${BASH_SOURCE[0]}]"
+ exit 1
+fi
+
+shopt -s expand_aliases
+
+bash_d_include bash_d # Need to rerun so complete setting us up.
diff --git a/packaging/macos/jhb/usr/src/bash_d/echo.sh b/packaging/macos/jhb/usr/src/bash_d/echo.sh
new file mode 100644
index 0000000..d160db0
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/echo.sh
@@ -0,0 +1,52 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Provide colorful convenience functions for echo.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### includes ###################################################################
+
+bash_d_include ansi
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+function echo_message__
+{
+ local funcname=$1 # empty if outside function
+ local filename=$2
+ local type=$3
+ local color=$4
+ local args=${*:5}
+
+ if [ -z "$funcname" ] || [ "$funcname" = "source" ]; then
+ funcname=$(basename "$filename")
+ fi
+
+ if ansi_is_usable; then
+ echo -e "${color}$type:$ANSI_FG_RESET $args ${ANSI_FG_BLACK_BRIGHT}[$funcname]$ANSI_FG_RESET"
+ else
+ echo "$type: $args [$funcname]"
+ fi
+}
+
+### aliases ####################################################################
+
+alias echo_d='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "debug" "$ANSI_FG_BLUE_BOLD"'
+alias echo_e='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "error" "$ANSI_FG_RED_BRIGHT"'
+alias echo_i='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "info" "$ANSI_FG_BLUE_BRIGHT"'
+alias echo_o='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "ok" "$ANSI_FG_GREEN_BRIGHT"'
+alias echo_w='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "warning" "$ANSI_FG_YELLOW_BRIGHT"'
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/usr/src/bash_d/error.sh b/packaging/macos/jhb/usr/src/bash_d/error.sh
new file mode 100644
index 0000000..69ec0be
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/error.sh
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# https://github.com/dehesselle/bash_d
+
+### includes ###################################################################
+
+bash_d_include ansi.sh
+bash_d_include echo.sh
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+function error_catch
+{
+ local rc=$1
+
+ local index=0
+ local output
+
+ while output=$(caller $index); do
+ if [ $index -eq 0 ]; then
+ if ansi_is_usable; then
+ echo_e "rc=$rc $ANSI_FG_YELLOW_BRIGHT$BASH_COMMAND$ANSI_FG_RESET"
+ else
+ echo "rc=$rc $BASH_COMMAND"
+ fi
+ fi
+
+ echo_e $output
+ ((index+=1))
+ done
+
+ exit $rc
+}
+
+### aliases ####################################################################
+
+alias error_trace_enable='set -o errtrace; trap '\''error_catch ${?}'\'' ERR'
+alias error_trace_disable='trap - ERR'
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/jhb/usr/src/bash_d/lib.sh b/packaging/macos/jhb/usr/src/bash_d/lib.sh
new file mode 100644
index 0000000..c1f385e
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/lib.sh
@@ -0,0 +1,174 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Provide convenience wrappers for install_name_tool.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+assert_darwin
+bash_d_include echo
+bash_d_include readlinkf
+
+### variables ##################################################################
+
+LIB_RESET_ID=keep # options: basename, canonical, keep
+
+### functions ##################################################################
+
+function lib_change_path
+{
+ # Compared to install_name_tool, this function
+ # - requires less arguments as 'source' can be deducted from 'target'
+ # - can apply the requested changes to multiple binaries at once
+
+ local target=$1 # new path to dynamically linked library
+ local binaries=${*:2} # binaries to modify
+
+ local source_lib=${target##*/} # get library filename from target location
+
+ for binary in $binaries; do # won't work if spaces in paths
+ if [[ $binary == *.so ]] ||
+ [[ $binary == *.dylib ]] ||
+ [ $(file $binary | grep "shared library" | wc -l) -eq 1 ]; then
+ lib_reset_id $binary
+ fi
+
+ local source=$(otool -L $binary | grep "$source_lib " | awk '{ print $1 }')
+ if [ -z $source ]; then
+ echo_w "no $source_lib in $binary"
+ else
+ # Reconstructing 'target' as it might have been specified as regex.
+ target=$(dirname $target)/$(basename $source)
+
+ install_name_tool -change $source $target $binary
+ fi
+ done
+}
+
+function lib_change_paths
+{
+ # This is a wrapper ontop lib_change_path: given a directory 'lib_dir' that
+ # contains the libraries, all (matching) libraries linked in 'binary' can be
+ # changed at once to a specified 'target' path.
+
+ local target=$1 # new path to dynamically linked library
+ local lib_dir=$2
+ local binaries=${*:3}
+
+ for binary in $binaries; do
+ for linked_lib in $(otool -L $binary | tail -n +2 | awk '{ print $1 }'); do
+ if [ "$(basename $binary)" != "$(basename $linked_lib)" ] &&
+ [ -f $lib_dir/$(basename $linked_lib) ]; then
+ lib_change_path $target/$(basename $linked_lib) $binary
+ fi
+ done
+ done
+}
+
+function lib_change_siblings
+{
+ # This is a wrapper ontop lib_change_path: all libraries inside a given
+ # 'lib_dir' that are linked to libraries located in that same 'lib_dir' can
+ # be automatically adjusted.
+
+ local lib_dir=$1
+
+ for lib in $lib_dir/*.dylib; do
+ lib_reset_id $lib
+ for linked_lib in $(otool -L $lib | tail -n +2 | awk '{ print $1 }'); do
+ if [ "$(basename $lib)" != "$(basename $linked_lib)" ] &&
+ [ -f $lib_dir/$(basename $linked_lib) ]; then
+ lib_change_path @loader_path/$(basename $linked_lib) $lib
+ fi
+ done
+ done
+}
+
+function lib_reset_id
+{
+ local lib=$1
+
+ case "$LIB_RESET_ID" in
+ basename)
+ install_name_tool -id $(basename $lib) $lib
+ ;;
+ canonical)
+ install_name_tool -id $(readlinkf $lib) $lib
+ ;;
+ keep)
+ : # don't do anything
+ ;;
+ *)
+ echo_e "invalid value for LIB_RESET_ID: $LIB_RESET_ID"
+ ;;
+ esac
+}
+
+function lib_add_rpath
+{
+ local rpath=$1
+ local binary=$2
+
+ install_name_tool -add_rpath "$rpath" "$binary"
+}
+
+function lib_clear_rpath
+{
+ local binary=$1
+
+ for rpath in $(otool -l $binary | grep -A2 LC_RPATH | grep -E "^[ ]+path" | awk '{ print $2 }'); do
+ install_name_tool -delete_rpath $rpath $binary
+ done
+}
+
+function lib_replace_path
+{
+ local source=$1
+ local target=$2
+ local binary=$3
+
+ for lib in $(lib_get_linked $binary); do
+ if [[ $lib =~ $source ]]; then
+ lib_change_path @rpath/$(basename $lib) $binary
+ fi
+ done
+}
+
+function lib_get_linked
+{
+ local binary=$1 # can be executable or library
+
+ #echo_d "binary: $binary"
+
+ local filter # we need to distinguish between executable and library
+
+ local file_type
+ file_type=$(file "$binary")
+ if [[ $file_type = *"shared library"* ]]; then
+ filter="-v $(otool -D "$binary" | tail -n 1)" # exclude library id
+ elif [[ $file_type = *"executable"* ]]; then
+ filter="-E [.]+" # include everything
+ else
+ echo_w "neither shared library nor executable: $binary"
+ return 1
+ fi
+
+ # since we're not echoing this, output will be newline-separated
+ # shellcheck disable=SC2086 # need word splitting for arguments
+ otool -L "$binary" | grep " " | grep $filter | awk '{ print $1 }'
+}
+
+### aliases ####################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/jhb/usr/src/bash_d/readlinkf.sh b/packaging/macos/jhb/usr/src/bash_d/readlinkf.sh
new file mode 100644
index 0000000..135a886
--- /dev/null
+++ b/packaging/macos/jhb/usr/src/bash_d/readlinkf.sh
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# https://github.com/dehesselle/bash_d
+
+### description ################################################################
+
+# This is a replacement for GNU's '-f' extension to 'readlink' which is not
+# part of the BSD version.
+
+### includes ###################################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+# Nothing here.
+
+### aliases ####################################################################
+
+alias readlinkf='perl -e '"'"'use Cwd "abs_path"; print abs_path(@ARGV[0])'"'"' --'
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/modulesets/README.md b/packaging/macos/modulesets/README.md
new file mode 100644
index 0000000..7f1031f
--- /dev/null
+++ b/packaging/macos/modulesets/README.md
@@ -0,0 +1,8 @@
+# JHBuild module set
+
+The module sets prefixed with `gtk-osx` are customized copies from [gtk-osx](https://gitlab.gnome.org/GNOME/gtk-osx). They differ from their upstream versions as follows:
+
+- Remove any module that we don't need to simplify maintainability.
+- Update a few select modules to other/newer versions, but don't needlessly divert from upstream. This way we can still benefit from using a largely identical base configuration in terms of stability, required patches etc.
+
+The module set `inkscape.modules` has been created from scratch to manage Inkscape's dependencies that are not part of [gtk-osx](https://gitlab.gnome.org/GNOME/gtk-osx).
diff --git a/packaging/macos/modulesets/gtk-osx-bootstrap.modules b/packaging/macos/modulesets/gtk-osx-bootstrap.modules
new file mode 100644
index 0000000..6127d99
--- /dev/null
+++ b/packaging/macos/modulesets/gtk-osx-bootstrap.modules
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+
+ <repository type="tarball" name="ftp.gnome.org" default="yes"
+ href="http://download.gnome.org/sources/"/>
+ <repository type="tarball" name="ftp.gnu.org" href="https://ftp.gnu.org/gnu/"/>
+ <repository type="tarball" name="sourceforge"
+ href="http://downloads.sourceforge.net/sourceforge/"/>
+ <repository type="tarball" name="jpeg"
+ href="https://www.fossies.org/"/>
+ <repository type="tarball" name="libtiff"
+ href="http://download.osgeo.org/"/>
+ <repository type="tarball" name="icon-theme"
+ href="http://icon-theme.freedesktop.org/releases/"/>
+ <repository type="tarball" name="xmlsoft.org"
+ href="ftp://xmlsoft.org/libxml2/"/>
+ <repository type="git" name="git.gnome.org"
+ href="https://gitlab.gnome.org/GNOME"/>
+ <repository type="tarball" name="itstool" href="http://files.itstool.org/"/>
+ <repository type="tarball" name="github-tarball" href="https://github.com/"/>
+
+ <autotools id="libpng" autogenargs="--enable-shared" autogen-sh="configure">
+ <branch version="1.6.37" module="libpng/libpng-1.6.37.tar.xz"
+ hash="sha256:505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca"
+ repo="sourceforge"/>
+ <dependencies>
+ <dep package="zlib"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="libjpeg" autogen-sh="configure">
+ <branch module="linux/misc/jpegsrc.v9e.tar.gz" version="9e"
+ repo="jpeg" checkoutdir="jpeg-9e"
+ hash="sha256:4077d6a6a75aeb01884f708919d25934c93305e49f7e3f36db9129320e6f4f3d">
+ </branch>
+ </autotools>
+
+ <autotools id="libtiff" autogen-sh="configure" autogenargs="--without-x">
+ <branch version="4.2.0" module="libtiff/tiff-4.2.0.tar.gz"
+ repo="libtiff"
+ hash="sha256:eb0484e568ead8fa23b513e9b0041df7e327f4ee2d22db5a533929dfc19633cb">
+ <patch file="tiff-nohtml.patch" strip="1" />
+ </branch>
+ <dependencies>
+ <dep package="libjpeg"/>
+ </dependencies>
+ </autotools>
+
+ <!-- The python package is in gtk-osx-python.modules. If you're
+ building "native" you can safely add python to the skip list, but
+ otherwise the links in the SDKs are messed up and libxml's python
+ module won't link. In case you're wondering, itstool
+ needs libxml2's python module. -->
+
+ <autotools id="libxml2" autogen-sh="autoreconf"
+ autogenargs='--libdir="$JHBUILD_LIBDIR" --with-python'>
+ <branch version="2.9.12" module="libxml2-2.9.12.tar.gz"
+ repo="xmlsoft.org"
+ hash="sha256:c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92">
+ <patch file="libxml2-python-config.patch" strip="1"/>
+ </branch>
+ <after>
+ <dep package="python3"/>
+ </after>
+ </autotools>
+
+ <autotools id="libxslt" autogen-sh="configure">
+ <branch version="1.1.34" module="libxslt-1.1.34.tar.gz"
+ hash="sha256:98b1bd46d6792925ad2dfe9a87452ea2adebf69dcb9919ffd55bf926a7f93f7f"
+ repo="xmlsoft.org"/>
+ <dependencies>
+ <dep package="libxml2"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="itstool" autogen-sh="configure">
+ <branch module="itstool/itstool-2.0.6.tar.bz2" version="2.0.6n"
+ repo="itstool"
+ hash="sha256:6233cc22726a9a5a83664bf67d1af79549a298c23185d926c3677afa917b92a9">
+ <patch file="itstool-config-python.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="libxml2"/>
+ </dependencies>
+ </autotools>
+
+ <meson id="gtk-doc" mesonargs="-Dyelp_manual=false -Dtests=false">
+ <branch version="1.33.2" module="gtk-doc/1.33/gtk-doc-1.33.2.tar.xz"
+ hash="sha256:cc1b709a20eb030a278a1f9842a362e00402b7f834ae1df4c1998a723152bf43"/>
+ <dependencies>
+ <dep package="libxml2"/>
+ <dep package="libxslt"/>
+ <dep package="itstool"/>
+ </dependencies>
+ <after>
+ <dep package="python3"/>
+ <dep package="pygments"/>
+ </after>
+ </meson>
+
+ <autotools id="icu" autogen-sh="source/configure" autogenargs="--enable-rpath"
+ makeargs='CFLAGS="$CFLAGS -DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=0"'>
+ <branch repo="github-tarball" version="68.2" checkoutdir="icu"
+ module="unicode-org/icu/releases/download/release-68-2/icu4c-68_2-src.tgz"
+ hash="sha256:c79193dee3907a2199b8296a93b52c5cb74332c26f3d167269487680d479d625"/>
+ </autotools>
+
+ <metamodule id="meta-gtk-osx-bootstrap">
+ <dependencies>
+ <dep package="libpng"/>
+ <dep package="libjpeg"/>
+ <dep package="libtiff"/>
+ <dep package="gtk-doc"/>
+ </dependencies>
+ </metamodule>
+
+</moduleset>
diff --git a/packaging/macos/modulesets/gtk-osx-gtkmm.modules b/packaging/macos/modulesets/gtk-osx-gtkmm.modules
new file mode 100644
index 0000000..c220242
--- /dev/null
+++ b/packaging/macos/modulesets/gtk-osx-gtkmm.modules
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+ <repository type="tarball" name="ftp.gnome.org" default="yes"
+ href="http://ftp.gnome.org/pub/GNOME/sources/"/>
+ <repository type="tarball" name="doxygen"
+ href="http://ftp.stack.nl/pub/users/dimitri/"/>
+ <repository type="tarball" name="cairographics"
+ href="http://cairographics.org/releases/"/>
+
+
+ <meson id="mm-common">
+ <branch module="mm-common/1.0/mm-common-1.0.2.tar.xz" version="1.0.2"
+ hash="sha256:a2a99f3fa943cf662f189163ed39a2cfc19a428d906dd4f92b387d3659d1641d"/>
+ </meson>
+
+ <!-- Libsigc++ was rewritten to use C++17 variadic templates for version 3, and adopting that has created substantial API breaks for the whole "mm" stack. gtkmm2 and gtkmm3 use the older versions, gtkmm4 the new ones.
+ Note that C++17 is supported only on macOS-10.13 and later.
+ -->
+ <meson id="cairomm-1.14">
+ <branch module="cairomm-1.14.2.tar.xz" version="1.14.2"
+ repo="cairographics"
+ hash="sha256:0126b9cc295dc36bc9c0860d5b720cb5469fd78d5620c8f10cc5f0c07b928de3"/>
+ <dependencies>
+ <dep package="cairo"/>
+ </dependencies>
+ </meson>
+
+ <autotools id="glibmm-2.4" autogen-sh="autoreconf">
+ <branch module="glibmm/2.60/glibmm-2.60.0.tar.xz" version="2.60.0"
+ hash="sha256:a3a1b1c9805479a16c0018acd84b3bfff23a122aee9e3c5013bb81231aeef2bc"/>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="libsigc++2"/>
+ <dep package="mm-common"/>
+ </dependencies>
+ </autotools>
+
+ <meson id="pangomm-1.4">
+ <branch module="pangomm/2.46/pangomm-2.46.2.tar.xz" version="2.46.2"
+ hash="sha256:57442ab4dc043877bfe3839915731ab2d693fc6634a71614422fb530c9eaa6f4"/>
+ <dependencies>
+ <dep package="glibmm-2.4"/>
+ <dep package="cairomm-1.14"/>
+ <dep package="pango"/>
+ </dependencies>
+</meson>
+
+ <meson id="atkmm-1.6">
+ <branch module="atkmm/2.28/atkmm-2.28.1.tar.xz" version="2.28.1"
+ hash="sha256:116876604770641a450e39c1f50302884848ce9cc48d43c5dc8e8efc31f31bad"/>
+ <dependencies>
+ <dep package="glibmm-2.4"/>
+ <dep package="cairomm-1.14"/>
+ <dep package="pangomm-1.4"/>
+ <dep package="atk"/>
+ </dependencies>
+ </meson>
+
+ <meson id="libsigc++2" >
+ <branch module="libsigc++/2.10/libsigc++-2.10.6.tar.xz" version="2.10.6"
+ hash="sha256:dda176dc4681bda9d5a2ac1bc55273bdd381662b7a6d49e918267d13e8774e1b"/>
+ </meson>
+
+ <meson id="gtkmm3" >
+ <branch module="gtkmm/3.24/gtkmm-3.24.5.tar.xz" version="3.24.5"
+ hash="sha256:856333de86689f6a81c123f2db15d85db9addc438bc3574c36f15736aeae22e6">
+ <patch file="gtkmm-3-bad-const-property-background.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="glibmm-2.4"/>
+ <dep package="cairomm-1.14"/>
+ <dep package="pangomm-1.4"/>
+ <dep package="atkmm-1.6"/>
+ <dep package="gtk+-3.0"/>
+ </dependencies>
+ </meson>
+
+</moduleset>
diff --git a/packaging/macos/modulesets/gtk-osx-network.modules b/packaging/macos/modulesets/gtk-osx-network.modules
new file mode 100644
index 0000000..3e12ae5
--- /dev/null
+++ b/packaging/macos/modulesets/gtk-osx-network.modules
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+ <repository name="ftp.gnome.org" type="tarball" default="yes"
+ href="http://ftp.gnome.org/pub/GNOME/sources/"/>
+ <repository name="openssl" type="tarball"
+ href="https://www.openssl.org/source/"/>
+ <repository name="ftp.gnu.org" type="tarball"
+ href="https://ftp.gnu.org/gnu/"/>
+ <repository name="sourceforge" type="tarball"
+ href="http://downloads.sourceforge.net/sourceforge/"/>
+ <repository name='gnupg.org' type='tarball' href="https://gnupg.org/ftp/" />
+ <repository name="webm" type="tarball"
+ href="http://downloads.webmproject.org/releases/"/>
+ <repository type="tarball" name="github-tarball" href="https://github.com/"/>
+ <repository type="tarball" name="zlib" href="https://www.zlib.net/"/>
+
+ <!-- of the many arguments such as prefix and libdir that jhbuild might pass
+ to configure, openssl only understands prefix, and only with =. -->
+ <autotools id="openssl" autogen-sh="Configure" autogenargs="shared "
+ autogen-template="%(srcdir)s/%(autogen-sh)s --prefix=%(prefix)s --openssldir=%(prefix)s/etc/ssl %(autogenargs)s"
+ makeinstallargs="install_sw" supports-non-srcdir-builds="no">
+ <branch module="openssl-1.1.1s.tar.gz" version="1.1.1s" repo="openssl"
+ hash="sha256:c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa"/>
+ </autotools>
+
+ <!-- Rudely demands TeX to build documentation -->
+ <!-- libnettle 3.7 doesn't have arm64 assembler support and the support that's added in master is for arm-64-neutron that's incompatible with Apple Silicon. -->
+ <if condition-set="arm64">
+ <autotools id="libnettle" autogen-sh="configure"
+ autogenargs="--disable-documentation --disable-assembler">
+ <branch repo="ftp.gnu.org" version="3.7.2"
+ module="nettle/nettle-3.7.2.tar.gz"
+ hash="sha256:8d2a604ef1cde4cd5fb77e422531ea25ad064679ff0adf956e78b3352e0ef162">
+ </branch>
+ <dependencies>
+ <dep package="gmp"/>
+ <dep package="openssl"/>
+ </dependencies>
+ </autotools>
+ </if>
+ <if condition-unset="arm64">
+ <autotools id="libnettle" autogen-sh="configure"
+ autogenargs="--disable-documentation">
+ <branch repo="ftp.gnu.org" version="3.7.2"
+ module="nettle/nettle-3.7.2.tar.gz"
+ hash="sha256:8d2a604ef1cde4cd5fb77e422531ea25ad064679ff0adf956e78b3352e0ef162">
+ </branch>
+ <dependencies>
+ <dep package="gmp"/>
+ <dep package="openssl"/>
+ </dependencies>
+ </autotools>
+ </if>
+
+ <autotools id="libtasn1" autogen-sh="configure">
+ <branch repo="ftp.gnu.org" version="4.17.0"
+ module="libtasn1/libtasn1-4.17.0.tar.gz"
+ hash="sha256:ece7551cea7922b8e10d7ebc70bc2248d1fdd73351646a2d6a8d68a9421c45a5">
+ <patch file="libtasn1-inline-fix.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <cmake id="zlib">
+ <branch repo="zlib" version="1.2.13"
+ module="zlib-1.2.13.tar.xz"
+ hash="sha256:d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98"/>
+ </cmake>
+
+ <autotools id="p11-kit" autogen-sh="configure"
+ autogenargs="--without-trust-paths">
+ <branch repo="github-tarball" version="0.23.22"
+ module="p11-glue/p11-kit/releases/download/0.23.22/p11-kit-0.23.22.tar.xz"
+ hash="sha256:8a8f40153dd5a3f8e7c03e641f8db400133fb2a6a9ab2aee1b6d0cb0495ec6b6">
+ </branch>
+ <dependencies>
+ <dep package="libffi"/>
+ <dep package="libtasn1"/>
+ </dependencies>
+ </autotools>
+
+ <if condition-unset="pre-Mavericks">
+ <autotools id="gnutls" autogen-sh="autoreconf"
+ autogenargs="--disable-gtk-doc-html --with-included-unistring">
+ <branch repo="gnupg.org" version="3.7.7"
+ module="gcrypt/gnutls/v3.7/gnutls-3.7.7.tar.xz">
+ </branch>
+ <dependencies>
+ <dep package="libnettle"/>
+ <dep package="libtasn1"/>
+ <dep package="zlib"/>
+ <dep package="p11-kit"/>
+ <dep package="libgcrypt"/>
+ </dependencies>
+ </autotools>
+ </if>
+
+ <autotools id="libgpg-error" autogen-sh="autoreconf"
+ autogenargs="--disable-doc">
+ <branch repo="gnupg.org" version="1.42"
+ module="gcrypt/libgpg-error/libgpg-error-1.42.tar.bz2"
+ hash="sha256:fc07e70f6c615f8c4f590a8e37a9b8dd2e2ca1e9408f8e60459c67452b925e23">
+ </branch>
+ </autotools>
+
+ <autotools id="libgcrypt" autogen-sh="configure">
+ <branch repo="gnupg.org" version="1.9.2"
+ module="gcrypt/libgcrypt/libgcrypt-1.9.2.tar.bz2"
+ hash="sha256:b2c10d091513b271e47177274607b1ffba3d95b188bbfa8797f948aec9053c5a"/>
+ <dependencies>
+ <dep package="libgpg-error"/>
+ </dependencies>
+ </autotools>
+
+
+ <meson id="glib-networking" mesonargs="-Dopenssl=enabled">
+ <branch module="glib-networking/2.68/glib-networking-2.68.0.tar.xz"
+ version="2.68.0"
+ hash="sha256:0b235e85ad26b3c0d12255d0963c460e5a639c4722f78e2a03e969e224b29f6e"/>
+ <dependencies>
+ <if condition-unset="pre-Mavericks">
+ <dep package="gnutls"/>
+ </if>
+ <dep package="glib"/>
+ </dependencies>
+ </meson>
+
+ <autotools id="libpsl" autogen-sh='configure'>
+ <branch repo="github-tarball" version="0.21.0"
+ module="rockdaboot/libpsl/releases/download/0.21.1/libpsl-0.21.1.tar.gz"
+ hash="sha256:ac6ce1e1fbd4d0254c4ddb9d37f1fa99dec83619c1253328155206b896210d4c"/>
+ </autotools>
+
+ <meson id="libsoup" mesonargs="-Dvapi=disabled">
+ <branch module="libsoup/2.72/libsoup-2.72.0.tar.xz" version="2.72.0"
+ hash="sha256:170c3f8446b0f65f8e4b93603349172b1085fb8917c181d10962f02bb85f5387">
+ </branch>
+ <dependencies>
+ <dep package="libpsl"/>
+ <dep package="python3"/>
+ <dep package="glib"/>
+ <dep package="glib-networking"/>
+ <dep package="sqlite"/>
+ <dep package="vala"/>
+ </dependencies>
+ </meson>
+
+ <autotools id="libwebp" autogen-sh="configure" autogenargs="--enable-libwebpmux --enable-libwebpdecoder">
+ <branch repo="webm" module="webp/libwebp-1.2.0.tar.gz" version="1.2.0"
+ hash="sha256:2fc8bbde9f97f2ab403c0224fb9ca62b2e6852cbc519e91ceaa7c153ffd88a0c"/>
+ </autotools>
+</moduleset>
diff --git a/packaging/macos/modulesets/gtk-osx-python.modules b/packaging/macos/modulesets/gtk-osx-python.modules
new file mode 100644
index 0000000..2d5ff96
--- /dev/null
+++ b/packaging/macos/modulesets/gtk-osx-python.modules
@@ -0,0 +1,150 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+
+ <repository type="tarball" name="ftp.gnome.org" default="yes"
+ href="http://ftp.gnome.org/pub/GNOME/sources/"/>
+ <repository type="tarball" name="cairographics.org"
+ href="http://cairographics.org/releases/"/>
+ <repository type="tarball" name="python"
+ href="https://www.python.org/ftp/python/"/>
+ <repository type="tarball" name="oracle"
+ href="http://download.oracle.com/"/>
+ <repository type="tarball" name="pymodules"
+ href="https://pypi.python.org/packages/"/>
+ <repository type="tarball" name="github-tarball"
+ href="https://github.com"/>
+
+ <metamodule id="meta-gtk-osx-python3-gtk3">
+ <dependencies>
+ <dep package="pycairo"/>
+ <dep package="pygobject3"/>
+ </dependencies>
+ <after>
+ <dep package="meta-gtk-osx-gtk3"/>
+ </after>
+ </metamodule>
+
+ <autotools id="python3" autogenargs="--enable-shared" autogen-sh="configure">
+ <branch repo="python" module="3.10.2/Python-3.10.2.tar.xz" version="3.10.2"
+ hash="sha256:17de3ac7da9f2519aa9d64378c603a73a0e9ad58dffa8812e45160c086de64c7"/>
+
+ <dependencies>
+ <dep package='readline'/>
+ <dep package="openssl"/> <!-- For hashlib -->
+ </dependencies>
+ </autotools>
+
+ <meson id="pycairo">
+ <branch module="/pygobject/pycairo/releases/download/v1.20.0/pycairo-1.20.0.tar.gz" repo="github-tarball"
+ version="1.20.0"
+ hash="sha256:5695a10cb7f9ae0d01f665b56602a845b0a8cb17e2123bfece10c2e58552468c"/>
+ <dependencies>
+ <dep package="cairo"/>
+ <dep package="python3"/>
+ <dep package="meta-gtk-osx-gtk3"/>
+ </dependencies>
+ </meson>
+
+ <meson id="pygobject3" >
+ <branch version="3.40.1" module="pygobject/3.40/pygobject-3.40.1.tar.xz"
+ hash="sha256:00c6d591f4cb40c335ab1fd3e8c17869ba15cfda54416fe363290af766790035"/>
+ <dependencies>
+ <dep package="pycairo"/>
+ </dependencies>
+ <after>
+ <dep package="python3"/>
+ </after>
+ </meson>
+
+ <distutils id="pygments">
+ <branch repo="pymodules" version="2.9.0"
+ module="ba/6e/7a7c13c21d8a4a7f82ccbfe257a045890d4dbf18c023f985f565f97393e3/Pygments-2.9.0.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="docutils">
+ <branch repo="pymodules" version="0.18.1"
+ module="57/b1/b880503681ea1b64df05106fc7e3c4e3801736cf63deffc6fa7fc5404cf5/docutils-0.18.1.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="gidocgen">
+ <branch repo="pymodules" version="2022.1"
+ module="25/11/64ea759ba610d7442e8827306d1adba233ca69547d2a0e974f5ea74fa320/gi-docgen-2022.1.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ <dep package="markdown"/>
+ <dep package="markupsafe"/>
+ <dep package="typogrify"/>
+ <dep package="jinja2"/>
+ <dep package="toml"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="markdown">
+ <branch repo="pymodules" version="3.3.6"
+ module="15/06/d60f21eda994b044cbd496892d4d4c5c708aa597fcaded7d421513cb219b/Markdown-3.3.6.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="markupsafe">
+ <branch repo="pymodules" version="2.1.1"
+ module="1d/97/2288fe498044284f39ab8950703e88abbac2abbdf65524d576157af70556/MarkupSafe-2.1.1.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="typogrify">
+ <branch repo="pymodules" version="2.0.7"
+ module="8a/bf/64959d6187d42472acb846bcf462347c9124952c05bd57e5769d5f28f9a6/typogrify-2.0.7.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ <dep package="smartypants"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="jinja2">
+ <branch repo="pymodules" version="3.1.1"
+ module="89/e3/b36266381ae7a1310a653bb85f4f3658c462a69634fa9b2fef76252a50ed/Jinja2-3.1.1.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="toml">
+ <branch repo="pymodules" version="0.10.2"
+ module="be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+ <distutils id="smartypants">
+ <branch repo="github-tarball" version="2.0.1"
+ module="leohemsted/smartypants.py/archive/refs/tags/v2.0.1.tar.gz"
+ rename-tarball="smartypants-2.0.1.tar.gz"
+ checkoutdir="smartypants-2.0.1">
+ </branch>
+ <dependencies>
+ <dep package="python3"/>
+ </dependencies>
+ </distutils>
+
+</moduleset>
diff --git a/packaging/macos/modulesets/gtk-osx-random.modules b/packaging/macos/modulesets/gtk-osx-random.modules
new file mode 100644
index 0000000..4811a0d
--- /dev/null
+++ b/packaging/macos/modulesets/gtk-osx-random.modules
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+ <repository type="tarball" name="ftp.gnome.org" default="yes"
+ href="http://download.gnome.org/sources/"/>
+ <repository type="tarball" name="github-tarball" href="https://github.com/"/>
+ <repository type="tarball" name="ftp.gnu.org" href="https://ftp.gnu.org/gnu/"/>
+
+ <repository type="tarball" name="shared-mime-info"
+ href="https://gitlab.freedesktop.org/xdg/shared-mime-info/uploads/"/>
+ <repository type="tarball" name="iso-codes"
+ href="https://salsa.debian.org/iso-codes-team/iso-codes/uploads/"/>
+ <repository type="tarball" name="sourceforge"
+ href="http://downloads.sourceforge.net/sourceforge/"/>
+ <repository type="tarball" name="graphviz"
+ href="https://gitlab.com/graphviz/graphviz/-/archive/"/>
+ <repository type="tarball" name="sqlite" href="http://www.sqlite.org/"/>
+ <repository type="tarball" name="frodo"
+ href="http://frodo.looijaard.name/system/files/software/"/>
+ <repository type="tarball" name="paguire" href="https://releases.pagure.org/"/>
+ <repository type="tarball" name="pcre" href="https://ftp.pcre.org/pub/"/>
+
+ <cmake id="graphviz">
+ <branch module="2.47.0/graphviz-2.47.0.tar.bz2" version="2.47.0"
+ repo="graphviz"
+ hash="sha256:dade5b374ce483bf28f2e535baef02280ba8ab86fbe6e93252ab0de48396b714">
+ <patch file="graphviz-remove-rpath.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="pango"/>
+ <dep package="librsvg"/>
+ </dependencies>
+ </cmake>
+
+ <autotools id="vala" autogen-sh="configure">
+ <branch repo="ftp.gnome.org" version="0.52.0"
+ module="vala/0.52/vala-0.52.0.tar.xz"
+ hash="sha256:1de26310db465aca525679d3b5a3c1d8db2e067c4cbc0e5ddd015cd938bac68b"/>
+ <dependencies>
+ <dep package="graphviz"/>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ <dep package="meta-gtk-osx-gtk3"/>
+ </dependencies>
+ </autotools>
+
+ <meson id="glade" mesonargs="-Dmac_bundle=true -Dman=false" >
+ <branch module="glade/3.38/glade-3.38.2.tar.xz" version="3.38.2"
+ hash="sha256:98fc87647d88505c97dd2f30f2db2d3e9527515b3af11694787d62a8d28fbab7">
+ </branch>
+ <dependencies>
+ <dep package="itstool"/>
+ <dep package="meta-gtk-osx-gtk3"/>
+ </dependencies>
+ </meson>
+
+ <!-- gtksourceview got a major version ahead: 4.x.x supports recent versions of gtk+-3 and 5.x.x is for gtk4.
+ -->
+ <meson id="gtksourceview3" mesonargs="-Dvapi=false">
+ <branch module="gtksourceview/4.8/gtksourceview-4.8.1.tar.xz"
+ version="4.8.1"
+ hash="sha256:d163d71b5fcafbc5b1eec6dd841edbdbcddd3a7511cd5fdcffd86b8bbfe69ac1">
+ </branch>
+ <dependencies>
+ <dep package="gtk+-3.0"/>
+ </dependencies>
+ </meson>
+
+ <autotools id="frodo-getopt" autogen-sh="configure"
+ supports-non-srcdir-builds="no">
+ <branch repo="frodo" version="1.1.6" module="getopt/getopt-1.1.6.tar.gz"
+ hash="sha256:d0bf1dc642a993e7388a1cddfb9409bed375c21d5278056ccca3a0acd09dc5fe">
+ <patch file="frodo-getopt-autotools.patch" strip="1"/>
+ </branch>
+ </autotools>
+ <autotools id="xmlto" autogen-sh="autoreconf">
+ <branch module="xmlto/xmlto-0.0.28.tar.bz2"
+ version="0.0.28" repo="paguire"
+ hash="sha256:1130df3a7957eb9f6f0d29e4aa1c75732a7dfb6d639be013859b5c7ec5421276">
+ <patch file="xmlto-allow-net-access.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="frodo-getopt"/>
+ </dependencies>
+ </autotools>
+
+ <meson id="shared-mime-info" supports-non-srcdir-builds="no" >
+ <branch module="0ee50652091363ab0d17e335e5e74fbe/shared-mime-info-2.1.tar.xz"
+ repo="shared-mime-info" version="2.1"
+ hash="sha256:b2d40cfcdd84e835d0f2c9107b3f3e77e9cf912f858171fe779946da634e8563">
+ <patch file="shared-mime-info-2.1-freedesktop-generate.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="xmlto"/>
+ </dependencies>
+ </meson>
+
+ <meson id="gsettings-desktop-schemas">
+ <branch module="gsettings-desktop-schemas/40/gsettings-desktop-schemas-40.0.tar.xz"
+ version="40.0"
+ hash="sha256:f1b83bf023c0261eacd0ed36066b76f4a520bbcb14bb69c402b7959257125685"/>
+ <dependencies>
+ <dep package="gobject-introspection"/>
+ </dependencies>
+ </meson>
+
+<!-- SQLite3 is also available from the macOS SDK -->
+ <autotools id="sqlite" autogenargs="--disable-tcl --enable-threadsafe"
+ autogen-sh="configure">
+ <branch module="2021/sqlite-autoconf-3350400.tar.gz" version='3.35.4'
+ repo="sqlite"
+ hash="sha256:7771525dff0185bfe9638ccce23faa0e1451757ddbda5a6c853bb80b923a512d"/>
+ </autotools>
+
+<!-- Goocanvas2 is for gtk+-3. -->
+
+ <autotools id="goocanvas2" supports-non-srcdir-builds="no">
+ <branch module="goocanvas/2.0/goocanvas-2.0.4.tar.xz" version="2.0.4"
+ hash="sha256:c728e2b7d4425ae81b54e1e07a3d3c8a4bd6377a63cffa43006045bceaa92e90"/>
+ <after>
+ <dep package="gtk+-3.0"/>
+ </after>
+ </autotools>
+
+ <autotools id="hunspell" autogen-sh="autoreconf">
+ <branch module="hunspell/hunspell/archive/v1.7.0.tar.gz" version="1.7.0"
+ repo="github-tarball" checkoutdir="hunspell-1.7.0"
+ rename-tarball="hunspell-1.7.0.tar.gz"
+ hash="sha256:bb27b86eb910a8285407cf3ca33b62643a02798cf2eef468c0a74f6c3ee6bc8a"/>
+ </autotools>
+
+ <autotools id="enchant" autogen-sh="configure"
+ autogenargs="--enable-relocatable" >
+ <branch module="AbiWord/enchant/releases/download/v2.3.3/enchant-2.3.3.tar.gz"
+ repo="github-tarball" version="2.3.3"
+ hash="sha256:3da12103f11cf49c3cf2fd2ce3017575c5321a489e5b9bfa81dd91ec413f3891">
+ <patch file="enchant-relocatable.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <after>
+ <dep package="hunspell"/>
+ </after>
+ </autotools>
+
+
+ <autotools id="gmp">
+ <branch repo="ftp.gnu.org" module="gmp/gmp-6.2.1.tar.bz2" version="6.2.1"
+ hash="sha256:eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c">
+ </branch>
+ </autotools>
+
+ <autotools id='readline' autogen-sh="configure">
+ <branch repo="ftp.gnu.org" module="readline/readline-8.1.tar.gz"
+ version="8.1"
+ hash="sha256:f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02">
+ </branch>
+ </autotools>
+
+ <autotools id="iso-codes" autogen-sh="configure">
+ <branch module="049ce6aac94d842be809f4063950646c/iso-codes-4.1.tar.xz"
+ version="4.1" repo="iso-codes"
+ hash="sha256:67117fb76f32c8fb5e37d2d60bce238f1f8e865cc7b569a57cbc3017ca15488a"/>
+ </autotools>
+
+</moduleset>
diff --git a/packaging/macos/modulesets/gtk-osx.modules b/packaging/macos/modulesets/gtk-osx.modules
new file mode 100644
index 0000000..f1f6b5f
--- /dev/null
+++ b/packaging/macos/modulesets/gtk-osx.modules
@@ -0,0 +1,336 @@
+<?xml version="1.0"?><!--*- mode: nxml; indent-tabs-mode: nil -*-->
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+ <repository type="tarball" name="ftp.gnome.org" default="yes"
+ href="http://ftp.gnome.org/pub/GNOME/sources/"/>
+ <repository type="tarball" name="cairographics"
+ href="https://www.cairographics.org/"/>
+ <repository type="tarball" name="cairographics-temp"
+ href="https://gitlab.freedesktop.org/cairo/cairo/-/archive/"/>
+ <repository type="tarball" name="ftp.gnu.org"
+ href="https://ftp.gnu.org/gnu/"/>
+ <repository type="tarball" name="xorg"
+ href="https://www.x.org/releases/"/>
+ <repository type="tarball" name="fontconfig"
+ href="http://www.freedesktop.org/software/fontconfig/release/"/>
+ <repository type="tarball" name="hicolor"
+ href="https://icon-theme.freedesktop.org/releases/"/>
+ <repository type="git" name="github" href="https://github.com/"/>
+ <repository type="tarball" name="github-tarball" href="https://github.com/"/>
+ <repository type="tarball" name="sourceforge"
+ href="http://downloads.sourceforge.net/sourceforge/"/>
+ <repository type="system" name="system"/>
+
+ <!-- This module set works a bit differently than for example the
+ GNOME ones do. It's split up in seperate pieces:
+
+ - gtk-osx-bootstrap: contains bootstrap-like modules that you
+ don't want to rebuild all the time.
+
+ - gtk-osx.modules: contains the core GTK+ stack. This does not
+ have a hard dependency on the bootstrap modules, in order to
+ make it easy to rebuild the whole core stack without redoing
+ the bootstrap parts. They have a soft, "after", depencency.
+
+ - gtk-osx-python.modules: Python bindings for Gtk.
+ - gtk-osx-gtkmm.modules: C++ wrappers for Gtk.
+ - gtk-osx-network.modules: The network/crypto stack and WebKit.
+ - gtk-osx-random.modules: "random stuff", has apps for testing GTK+.
+ -->
+
+ <include href="gtk-osx-bootstrap.modules"/>
+ <include href="gtk-osx-gtkmm.modules"/>
+ <include href="gtk-osx-network.modules"/>
+ <include href="gtk-osx-python.modules"/>
+ <include href="gtk-osx-random.modules"/>
+
+ <!-- Dummy meson module to shut up a jhbuild warning. -->
+ <systemmodule id="meson">
+ <branch repo="system"/>
+ </systemmodule>
+
+ <metamodule id="meta-gtk-osx-gtk3">
+ <dependencies>
+ <dep package="gtk+-3.0"/>
+ <dep package="adwaita-icon-theme"/>
+ </dependencies>
+ <after>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ </after>
+ </metamodule>
+
+ <autotools id="libffi" autogenargs="--disable-builddir"
+ autogen-sh="configure">
+ <branch module="libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz"
+ repo="github-tarball" version="3.3"
+ hash="sha256:72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056"/>
+ </autotools>
+
+ <autotools id="libpcre" autogen-sh="configure"
+ autogenargs="--enable-unicode-properties --enable-newline-is-any --enable-jit">
+ <branch repo="sourceforge" version="8.45"
+ module="pcre/pcre-8.45.tar.bz2"
+ hash="sha256:4dae6fdcd2bb0bb6c37b5f97c33c2be954da743985369cddac3546e3218bffb8"/>
+ </autotools>
+
+ <meson id="glib" mesonargs="-Dlibmount=disabled">
+ <branch module="glib/2.72/glib-2.72.1.tar.xz" version="2.72.1"
+ hash="sha256:c07e57147b254cef92ce80a0378dc0c02a4358e7de4702e9f403069781095fe2">
+ </branch>
+ <dependencies>
+ <dep package="libffi"/>
+ <dep package="libpcre"/>
+ </dependencies>
+ </meson>
+
+ <!-- To build Freetype *with* harfbuzz requires harfbuzz to be built
+ with freetype so we first have to build it *without* harfbuzz,
+ then build harfbuzz without cairo because cairo requires
+ harfbuzz. -->
+ <cmake id="freetype-no-harfbuzz" cmakeargs="-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE -DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE -D BUILD_SHARED_LIBS=true -D CMAKE_BUILD_TYPE=Release">
+ <branch module="freetype/freetype-2.11.1.tar.gz" version="2.11.1"
+ repo="sourceforge"
+ hash="sha256:f8db94d307e9c54961b39a1cc799a67d46681480696ed72ecf78d4473770f09b"/>
+ <dependencies>
+ <dep package="zlib"/>
+ </dependencies>
+ </cmake>
+
+ <meson id="harfbuzz-no-cairo" mesonargs="-Dcoretext=enabled -Ddocs=disabled -Dbenchmark=disabled -Dintrospection=disabled">
+ <branch repo="github-tarball" version="2.9.1"
+ module="harfbuzz/harfbuzz/releases/download/2.9.1/harfbuzz-2.9.1.tar.xz"
+ hash="sha256:0edcc980f526a338452180e701d6aba6323aef457b6686976a7d17ccbddc51cf">
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="freetype-no-harfbuzz"/>
+ <dep package="icu"/>
+ </dependencies>
+ </meson>
+
+ <cmake id="freetype" cmakeargs="-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE -D BUILD_SHARED_LIBS=true -D CMAKE_BUILD_TYPE=Release">
+ <branch module="freetype/freetype-2.11.1.tar.gz" version="2.11.1"
+ repo="sourceforge"/>
+ <dependencies>
+ <dep package="harfbuzz-no-cairo"/>
+ <dep package="zlib"/>
+ </dependencies>
+ </cmake>
+
+ <autotools id="fontconfig" autogen-sh="configure"
+ autogenargs="--disable-docs --with-default-fonts=/System/Library/Fonts --with-add-fonts=/Library/Fonts">
+ <branch repo="fontconfig" version="2.14.0"
+ module="fontconfig-2.14.0.tar.xz"
+ hash="sha256:dcbeb84c9c74bbfdb133d535fe1c7bedc9f2221a8daf3914b984c44c520e9bac"/>
+ <dependencies>
+ <dep package="freetype"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="pixman" autogenargs="--disable-gtk --disable-mmx"
+ autogen-sh="configure">
+ <branch version="0.40.0" module="releases/pixman-0.40.0.tar.gz"
+ repo="cairographics"
+ hash="sha512:063776e132f5d59a6d3f94497da41d6fc1c7dca0d269149c78247f0e0d7f520a25208d908cf5e421d1564889a91da44267b12d61c0bd7934cd54261729a7de5f">
+ </branch>
+ <after>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ </after>
+ </autotools>
+
+ <!-- cairo doesn't really need fontconfig, but if Pango finds
+ freetype it insists that it has to have fontconfig too and that
+ they are both built into cairo. -->
+ <meson id="cairo">
+ <branch module="1.17.6/cairo-1.17.6.tar.bz2" version="1.17.6"
+ repo="cairographics-temp"
+ hash="sha256:90496d135c9ef7612c98f8ee358390cdec0825534573778a896ea021155599d2">
+ <patch file="cairo-pixman_dithering.patch" strip="1"/> <!-- Inkscape: packaging/cario.patch -->
+ <patch file="cairo-color_mgmt_perf.patch" strip="1"/> <!-- https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/290 -->
+ <patch file="cairo-snapshot_leak.patch" strip="1"/> <!-- https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/316 -->
+ </branch>
+ <dependencies>
+ <dep package="pixman"/>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ <dep package="harfbuzz-no-cairo"/>
+ <dep package="fontconfig"/>
+ </dependencies>
+ </meson>
+
+ <meson id="gobject-introspection">
+ <branch module="gobject-introspection/1.72/gobject-introspection-1.72.0.tar.xz"
+ version="1.72.0"
+ hash="sha256:02fe8e590861d88f83060dd39cda5ccaa60b2da1d21d0f95499301b186beaabc">
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="cairo"/>
+ </dependencies>
+ <after>
+ <dep package='python3'/>
+ </after>
+ </meson>
+
+ <!--
+ harfbuzz 4.1.0 breaks the following tests for Inkscape:
+ 351 - render_test-glyph-y-pos (Failed)
+ 352 - render_text-glyphs-combining (Failed)
+ 353 - render_text-glyphs-vertical (Failed)
+ 356 - render_test-rtl-vertical (Failed)
+
+ harfbuzz 3.4.0 breaks the following tests for Inkscape:
+ 351 - render_test-glyph-y-pos (Failed)
+ 353 - render_text-glyphs-vertical (Failed)
+ 356 - render_test-rtl-vertical (Failed)
+ -->
+ <meson id="harfbuzz" mesonargs="-Dcoretext=enabled -Ddocs=disabled -Dbenchmark=disabled">
+ <branch repo="github-tarball" version="2.9.1"
+ module="harfbuzz/harfbuzz/releases/download/2.9.1/harfbuzz-2.9.1.tar.xz"
+ hash="sha256:0edcc980f526a338452180e701d6aba6323aef457b6686976a7d17ccbddc51cf"
+>
+ </branch>
+ <dependencies>
+ <dep package="gobject-introspection"/>
+ <dep package="cairo"/>
+ <!-- no longer required as of https://github.com/harfbuzz/harfbuzz/releases/tag/2.8.1
+ <dep package="fontconfig"/>
+ -->
+ </dependencies>
+ </meson>
+
+ <meson id="fribidi" mesonargs="-Ddocs=false">
+ <branch module="fribidi/fribidi/releases/download/v1.0.11/fribidi-1.0.11.tar.xz"
+ repo="github-tarball" version="1.0.11"
+ hash="sha256:30f93e9c63ee627d1a2cedcf59ac34d45bf30240982f99e44c6e015466b4e73d"/>
+ <dependencies>
+ <!--dep package="c2man"/ -->
+ </dependencies>
+ </meson>
+
+ <meson id="pango" mesonargs="-Dfontconfig=enabled">
+ <branch version="1.50.6" module="pango/1.50/pango-1.50.6.tar.xz"
+ hash="sha256:a998bcf36881c3ac20495d40bceb304f4eaa9175bd2967c85656434cbdafe86a">
+ <patch file="pango-coretext-fix-clang-build-failure.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="cairo"/>
+ <dep package="harfbuzz"/>
+ <dep package="fribidi"/>
+ </dependencies>
+ <after>
+ <dep package="gobject-introspection"/>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ </after>
+ </meson>
+
+ <meson id="atk">
+ <branch module="atk/2.36/atk-2.36.0.tar.xz" version="2.36.0"
+ hash="sha256:fb76247e369402be23f1f5c65d38a9639c1164d934e40f6a9cf3c9e96b652788"/>
+ <dependencies>
+ </dependencies>
+ <after>
+ <dep package="glib"/>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ <dep package="gobject-introspection"/>
+ </after>
+ </meson>
+
+ <!--
+ relocatability breaks two tests in Inkscape
+ - <symbol> geometric properties (SVG 2.0 feature)
+ - .otf font with compressed SVG glyphs
+ <meson id="gdk-pixbuf" mesonargs="-Drelocatable=true -Dman=false">
+ -->
+ <meson id="gdk-pixbuf" mesonargs="-Dman=false">
+
+ <branch module="gdk-pixbuf/2.42/gdk-pixbuf-2.42.8.tar.xz" version="2.42.8"
+ hash="sha256:84acea3acb2411b29134b32015a5b1aaa62844b19c4b1ef8b8971c6b0759f4c6">
+ <patch file="gdk-pixbuf-loader-name.patch" strip="1"/>
+ </branch>
+ <after>
+ <dep package="pango"/>
+ <dep package="gobject-introspection"/>
+ </after>
+ </meson>
+
+ <autotools id="hicolor-icon-theme">
+ <branch module="hicolor-icon-theme-0.17.tar.xz" version="0.17"
+ repo="hicolor"/>
+ </autotools>
+
+ <autotools id="xorg-util-macros">
+ <branch repo="xorg" version="1.19.3"
+ module="individual/util/util-macros-1.19.3.tar.bz2"
+ hash="sha256:0f812e6e9d2786ba8f54b960ee563c0663ddbe2434bf24ff193f5feab1f31971"/>
+ </autotools>
+
+ <meson id="libepoxy">
+ <branch repo="github-tarball" version="1.5.4"
+ hash="sha256:0bd2cc681dfeffdef739cb29913f8c3caa47a88a451fd2bc6e606c02997289d2"
+ module="anholt/libepoxy/releases/download/1.5.4/libepoxy-1.5.4.tar.xz"/>
+ <dependencies>
+ <dep package="xorg-util-macros"/>
+ </dependencies>
+ </meson>
+
+ <!-- gtk3 is in maintenance mode with 3.24 the final release series. -->
+ <meson id="gtk+-3.0" mesonargs="-Dx11_backend=false">
+ <branch module="gtk+/3.24/gtk+-3.24.34.tar.xz" version="3.24.34"
+ hash="sha256:dbc69f90ddc821b8d1441f00374dc1da4323a2eafa9078e61edbe5eeefa852ec">
+ <patch file="gtk-3.24.33-remove-gtk4-update-icon-cache-dependency.patch" strip="1"/>
+ <patch file="gtk-3.24.33-quartz-window-transient-for.patch" strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="pango"/>
+ <dep package="atk"/>
+ <dep package="gdk-pixbuf"/>
+ <dep package="gobject-introspection"/>
+ <dep package="libepoxy"/>
+ <dep package="hicolor-icon-theme"/>
+ </dependencies>
+ <after>
+ <dep package="meta-gtk-osx-bootstrap"/>
+ </after>
+ </meson>
+
+ <autotools id="libcroco" autogenargs="--disable-Bsymbolic"
+ autogen-sh="configure">
+ <branch module="libcroco/0.6/libcroco-0.6.13.tar.xz" version="0.6.13"
+ hash="sha256:767ec234ae7aa684695b3a735548224888132e063f92db585759b422570621d4"/>
+ </autotools>
+
+ <autotools id="librsvg" autogen-sh="autoreconf"
+ autogenargs="--disable-Bsymbolic">
+ <branch module="librsvg/2.54/librsvg-2.54.0.tar.xz" version="2.54.0"
+ hash="sha256:baf8ebc147f146b4261bb3d0cd0fac944bf8dbb4b1f2347d23341f974dcc3085"/>
+ <dependencies>
+ <dep package="cairo"/>
+ <dep package="pango"/>
+ <dep package="harfbuzz"/>
+ <dep package="freetype"/>
+ <dep package="rust"/>
+ <dep package="docutils"/>
+ <dep package="gidocgen"/>
+ </dependencies>
+ <after>
+ <!-- Circular dependency if we depend on meta-gtk-osx or meta-gtk-osx-gtk3 -->
+ <dep package="gtk+-3.0"/>
+ </after>
+ </autotools>
+
+ <autotools id="adwaita-icon-theme" autogen-sh="configure">
+ <branch module="adwaita-icon-theme/42/adwaita-icon-theme-42.0.tar.xz"
+ version="42.0"
+ hash="sha256:5e85b5adc8dee666900fcaf271ba717f7dcb9d0a03d96dae08f9cbd27e18b1e0"/>
+ <dependencies>
+ <dep package="librsvg"/>
+ </dependencies>
+ </autotools>
+
+ <!-- Null metamodule, provided so as not to break modules that use it. -->
+ <metamodule id="meta-gtk-osx-freetype" />
+
+</moduleset>
diff --git a/packaging/macos/modulesets/inkscape.modules b/packaging/macos/modulesets/inkscape.modules
new file mode 100644
index 0000000..04763f4
--- /dev/null
+++ b/packaging/macos/modulesets/inkscape.modules
@@ -0,0 +1,371 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+
+ <repository name="boost" type="tarball" href="https://boostorg.jfrog.io/artifactory/main/release/"/>
+ <repository name="freedesktop" type="tarball" href="https://gitlab.freedesktop.org/"/>
+ <repository name="github" type="tarball" href="https://github.com/"/>
+ <repository name="gnome_web" type="tarball" href="https://download.gnome.org/sources/"/>
+ <repository name="gnome_gitlab" type="tarball" href="https://gitlab.gnome.org/GNOME/"/>
+ <repository name="gnu" type="tarball" href="http://ftp.halifax.rwth-aachen.de/gnu/"/>
+ <repository name="libreoffice" type="tarball" href="https://dev-www.libreoffice.org/src/"/>
+ <repository name="poppler" type="tarball" href="https://poppler.freedesktop.org/"/>
+ <repository name="sourceforge" type="tarball" href="https://netcologne.dl.sourceforge.net/project/"/>
+
+ <include href="gtk-osx.modules"/>
+
+ <!-- Boehm-Demers-Weiser Garbage Collector https://github.com/ivmai/bdwgc -->
+ <autotools
+ id="bdwgc"
+ autogen-sh="configure">
+ <branch
+ module="ivmai/bdwgc/releases/download/v8.0.4/gc-8.0.4.tar.gz"
+ version="8.0.4"
+ hash="sha256:436a0ddc67b1ac0b0405b61a9675bca9e075c8156f4debd1d06f3a56c7cd289d"
+ repo="github">
+ </branch>
+ </autotools>
+
+ <!-- boost C++ libraries https://www.boost.org
+
+ This is a hackish way of installing boost with JHBuild. Skipping
+ installation means that JHBuild will (re-)install this everytime
+ it gets pulled in.
+ -->
+ <autotools
+ id="boost"
+ autogen-sh="bootstrap.sh"
+ autogenargs="--without-libraries=python"
+ autogen-template="%(srcdir)s/%(autogen-sh)s --prefix=%(prefix)s %(autogenargs)s"
+ makeargs="|| ./b2 -d0 install"
+ skip-install="yes"
+ supports-non-srcdir-builds="no">
+ <branch
+ module="1.76.0/source/boost_1_76_0.tar.bz2"
+ version="1.76.0"
+ hash="sha256:f0397ba6e982c4450f27bf32a2a83292aba035b827a5623a14636ea583318c41"
+ repo="boost">
+ </branch>
+ </autotools>
+
+ <!-- binary<->decimal routines for IEEE doubles https://github.com/google/double-conversion -->
+ <cmake
+ id="doubleconversion">
+ <branch
+ module="google/double-conversion/archive/v3.1.5.tar.gz"
+ version="3.1.5"
+ hash="sha256:a63ecb93182134ba4293fd5f22d6e08ca417caafa244afaa751cbfddf6415b13"
+ repo="github"
+ checkoutdir="doubleconversion-3.1.5"
+ rename-tarball="doubleconversion-3.1.5.tar.gz">
+ </branch>
+ </cmake>
+
+ <!-- cppunit test framework https://www.freedesktop.org/wiki/Software/cppunit/ -->
+ <autotools
+ id="cppunit"
+ autogen-sh="configure">
+ <branch
+ module="cppunit-1.15.1.tar.gz"
+ version="1.15.1"
+ hash="sha256:89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7"
+ repo="libreoffice">
+ </branch>
+ </autotools>
+
+ <!-- Ghostscript https://www.ghostscript.com
+
+ This has to be removed entirely for GPLv2+ compatibility.
+ -->
+ <autotools
+ id="ghostscript"
+ autogen-sh="configure"
+ autogenargs="--without-tesseract --without-x">
+ <branch
+ module="ArtifexSoftware/ghostpdl-downloads/releases/download/gs9561/ghostscript-9.56.1.tar.xz"
+ version="9.56.1"
+ hash="sha256:d43406805650009b42c3d5f6dc535233454533c1e27c13a77dd1d462a056b8e4"
+ repo="github">
+ <patch
+ file="ghostscript_configure_libtiff.patch"
+ strip="1"/>
+ <patch
+ file="ghostscript_link_cupsimage.patch"
+ strip="1"/>
+ </branch>
+ </autotools>
+
+ <!-- Google Testing and Mocking Framework https://github.com/google/googletest -->
+ <cmake
+ id="googletest">
+ <branch
+ module="google/googletest/archive/release-1.12.1.tar.gz"
+ version="1.12.1"
+ hash="sha256:81964fe578e9bd7c94dfdb09c8e4d6e6759e19967e397dbea48d1c10e45d0df2"
+ repo="github"
+ checkoutdir="googletest-1.12.1"
+ rename-tarball="googletest-1.12.1.tar.gz">
+ </branch>
+ </cmake>
+
+ <!-- GNU Scientific Library https://www.gnu.org/software/gsl
+
+ We stick to version 1.9 as this is the last one licensed under GPLv2.
+ -->
+ <autotools
+ id="gsl"
+ autogen-sh='configure CFLAGS="$CFLAGS -Wno-error=implicit-function-declaration"'
+ autogen-template="%(srcdir)s/%(autogen-sh)s --prefix=%(prefix)s --infodir=%(prefix)s/share/info %(autogenargs)s">
+ <branch
+ module="gsl/gsl-1.9.tar.gz"
+ version="1.9"
+ hash="sha256:fcd1c6784997c2312d922d107fcb30462f5be4335ebdfa8e1e0e07568c962250"
+ repo="gnu">
+ </branch>
+ </autotools>
+
+ <!-- Spell checking for GTK https://wiki.gnome.org/Projects/gspell -->
+ <autotools
+ id="gspell">
+ <branch
+ module="gspell/1.11/gspell-1.11.1.tar.xz"
+ version="1.11.1"
+ hash="sha256:ef6aa4e3f711775158a7e241a5f809cf2426bc0e02c23a7d2b5c71fc3de00292"
+ repo="gnome_web">
+ <patch
+ file="gspell-makefile_objc.patch"
+ strip="1"/>
+ <patch
+ file="gspell-remove_gtkmacintegration.patch"
+ strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="enchant"/>
+ <dep package="glib"/>
+ <dep package="gtk+-3.0"/>
+ <dep package="iso-codes"/>
+ <dep package="vala"/>
+ </dependencies>
+ </autotools>
+
+ <!-- GTK Mac Bundler https://gitlab.gnome.org/GNOME/gtk-mac-bundler
+
+ This is a hackish way of installing GTK Mac Bundler with JHBuild.
+ The patch supplies a mocked configure script that's only interested in
+ taking the prefix and patching the Makefile accordingly. Skipping
+ installation means that JHBuild will (re-)install this everytime
+ it gets pulled in.
+ -->
+ <autotools
+ id="gtkmacbundler"
+ autogen-sh="configure"
+ supports-non-srcdir-builds="no"
+ makeargs="&amp;&amp; make install"
+ skip-install="yes">
+ <branch
+ module="gtk-mac-bundler/-/archive/58d951c8/gtk-mac-bundler-58d951c8.tar.bz2"
+ version="58d951c8"
+ hash="sha256:4617a36dadb7fe9ad242bdd826819e78098a089ccb3c4a002eb7b105ea0ca97c"
+ repo="gnome_gitlab"
+ checkoutdir="gtk-mac-bundler_58d951c8"
+ rename-tarball="gtk-mac-bundler_58d951c8.tar.bz2">
+ <patch
+ file="gtk-mac-bundler_configure.patch"
+ strip="1"/>
+ </branch>
+ </autotools>
+
+ <!-- ImageMagick 6 https://legacy.imagemagick.org -->
+ <autotools
+ id="imagemagick"
+ autogen-sh="configure">
+ <branch
+ module="ImageMagick/ImageMagick6/archive/6.9.12-7.tar.gz"
+ version="6.9.12-7"
+ hash="sha256:6abbd6afe7130edba7652a49c03a699657d6a71cf631a3c82014a31c8f93996d"
+ repo="github"
+ checkoutdir="imagemagick-6.9.12-7"
+ rename-tarball="imagemagick-6.9.12-7.tar.gz">
+ <patch
+ file="imagemagick_configure_pango.patch"
+ strip="1"/>
+ </branch>
+ <dependencies>
+ <dep package="pango"/>
+ </dependencies>
+ </autotools>
+
+ <!-- Little cms color engine https://sourceforge.net/projects/lcms/ -->
+ <autotools
+ id="lcms"
+ autogen-sh="configure">
+ <branch
+ module="lcms/lcms/2.12/lcms2-2.12.tar.gz"
+ version="2.12"
+ hash="sha256:18663985e864100455ac3e507625c438c3710354d85e5cbb7cd4043e11fe10f5"
+ repo="sourceforge"/>
+ </autotools>
+
+ <!-- Reading/Writing CorelDRAW files https://github.com/LibreOffice/libcdr -->
+ <autotools
+ id="libcdr"
+ autogen-sh="autoreconf">
+ <branch
+ module="LibreOffice/libcdr/archive/libcdr-0.1.7.tar.gz"
+ version="0.1.7"
+ hash="sha256:0cfd3304b6ecaaa37fc2fb7213f5e69ab05153152f49e8e91776cd4fc7c09e23"
+ repo="github"
+ checkoutdir="libcdr-0.1.7">
+ </branch>
+ <dependencies>
+ <dep package="boost"/>
+ <dep package="icu"/>
+ <dep package="lcms"/>
+ <dep package="librevenge"/>
+ <dep package="zlib"/>
+ </dependencies>
+ </autotools>
+
+ <!-- base library for document import filters https://sourceforge.net/p/libwpd/wiki/librevenge/ -->
+ <autotools
+ id="librevenge"
+ autogen-sh="configure">
+ <branch
+ module="libwpd/librevenge/librevenge-0.0.4/librevenge-0.0.4.tar.gz"
+ version="0.0.4"
+ hash="sha256:a2718efd86000fe769cb6178478af0fd424a9128807361241facd2491bcb772f"
+ repo="sourceforge">
+ </branch>
+ <dependencies>
+ <dep package="cppunit"/>
+ </dependencies>
+ </autotools>
+
+ <!-- Reading/Converting Visio files https://github.com/LibreOffice/libvisio -->
+ <autotools
+ id="libvisio"
+ autogen-sh="autoreconf">
+ <branch
+ module="LibreOffice/libvisio/archive/libvisio-0.1.7.tar.gz"
+ version="0.1.7"
+ hash="sha256:68b8a0b45e39b6ba154fe79169f2887cc19f6ee2b82f287b4b625c70294aff27"
+ repo="github"
+ checkoutdir="libvisio-0.1.7">
+ </branch>
+ <dependencies>
+ <dep package="boost"/>
+ <dep package="icu"/>
+ <dep package="librevenge"/>
+ <dep package="libxml2"/>
+ <dep package="zlib"/>
+ </dependencies>
+ </autotools>
+
+ <metamodule
+ id="meta-inkscape-dependencies">
+ <dependencies>
+ <dep package="bdwgc"/>
+ <dep package="doubleconversion"/>
+ <dep package="ghostscript"/>
+ <dep package="googletest"/>
+ <dep package="gspell"/>
+ <dep package="gsl"/>
+ <dep package="gspell"/>
+ <dep package="imagemagick"/>
+ <dep package="libcdr"/>
+ <dep package="libsoup"/>
+ <dep package="libvisio"/>
+ <dep package="libwebp"/>
+ <dep package="openjpeg"/>
+ <dep package="openmp"/>
+ <dep package="poppler"/>
+ <dep package="potrace"/>
+ </dependencies>
+ </metamodule>
+
+ <!-- OpenJPEG https://github.com/uclouvain/openjpeg -->
+ <cmake
+ id="openjpeg">
+ <branch
+ module="uclouvain/openjpeg/archive/v2.4.0.tar.gz"
+ version="2.4.0"
+ hash="sha256:8702ba68b442657f11aaeb2b338443ca8d5fb95b0d845757968a7be31ef7f16d"
+ repo="github"
+ checkoutdir="openjpeg-2.4.0"
+ rename-tarball="openjpeg-2.4.0.tar.gz">
+ </branch>
+ <dependencies>
+ <dep package="lcms"/>
+ <dep package="libpng"/>
+ <dep package="libtiff"/>
+ </dependencies>
+ </cmake>
+
+ <!-- OpenMP https://github.com/llvm/llvm-project -->
+ <cmake
+ id="openmp">
+ <branch
+ module="llvm/llvm-project/releases/download/llvmorg-12.0.1/openmp-12.0.1.src.tar.xz"
+ version="12.0.1"
+ hash="sha256:60fe79440eaa9ebf583a6ea7f81501310388c02754dbe7dc210776014d06b091"
+ repo="github"
+ checkoutdir="openmp-12.0.1">
+ </branch>
+ </cmake>
+
+ <!-- Poppler https://poppler.freedesktop.org -->
+ <cmake
+ id="poppler"
+ cmakeargs="-DENABLE_UNSTABLE_API_ABI_HEADERS=ON -DENABLE_GOBJECT_INTROSPECTION=OFF">
+ <branch
+ module="poppler-21.06.1.tar.xz"
+ version="21.06.1"
+ hash="sha256:86b09e5a02de40081a3916ef8711c5128eaf4b1fc59d5f87d0ec66f04f595db4"
+ repo="poppler">
+ </branch>
+ <dependencies>
+ <dep package="cmake"/>
+ <dep package="glib"/>
+ <dep package="gtk+-3.0"/>
+ <dep package="gdk-pixbuf"/>
+ </dependencies>
+ </cmake>
+
+ <!-- Potrace http://potrace.sourceforge.net -->
+ <autotools
+ id="potrace"
+ autogen-sh="configure"
+ autogenargs="--with-libpotrace">
+ <branch
+ module="potrace/1.16/potrace-1.16.tar.gz"
+ version="1.16"
+ hash="sha256:be8248a17dedd6ccbaab2fcc45835bb0502d062e40fbded3bc56028ce5eb7acc"
+ repo="sourceforge">
+ </branch>
+ </autotools>
+
+ <!-- Rust https://www.rust-lang.org
+
+ Rust has a custom setup routine (rustup) which is wrapped into
+ a cmake file introduced by that patch below.
+ -->
+ <cmake
+ id="rust"
+ cmakeargs="-DVERSION=1.59.0"
+ supports-non-srcdir-builds="no"
+ use-ninja="no">
+ <branch
+ module="rust-lang/rustup/archive/1.24.3.tar.gz"
+ version="1.24.3"
+ hash="sha256:24a8cede4ccbbf45ab7b8de141d92f47d1881bb546b3b9180d5a51dc0622d0f6"
+ repo="github"
+ checkoutdir="rustup-1.24.3"
+ rename-tarball="rustup-1.24.3.tar.gz">
+ <patch
+ file="rust_cmake_install.patch"
+ strip="1"/>
+ </branch>
+ </cmake>
+
+</moduleset>
diff --git a/packaging/macos/modulesets/jhbuildrc b/packaging/macos/modulesets/jhbuildrc
new file mode 100644
index 0000000..1953c49
--- /dev/null
+++ b/packaging/macos/modulesets/jhbuildrc
@@ -0,0 +1,4 @@
+# The following code will be appended to jhbuildrc-custom.
+
+if _default_arch == "arm64":
+ module_extra_env["gsl"] = { "MACOSX_DEPLOYMENT_TARGET": "" }
diff --git a/packaging/macos/modulesets/moduleset.dtd b/packaging/macos/modulesets/moduleset.dtd
new file mode 120000
index 0000000..8620b76
--- /dev/null
+++ b/packaging/macos/modulesets/moduleset.dtd
@@ -0,0 +1 @@
+../jhb/etc/modulesets/jhb/moduleset.dtd \ No newline at end of file
diff --git a/packaging/macos/modulesets/moduleset.xsl b/packaging/macos/modulesets/moduleset.xsl
new file mode 120000
index 0000000..018df53
--- /dev/null
+++ b/packaging/macos/modulesets/moduleset.xsl
@@ -0,0 +1 @@
+../jhb/etc/modulesets/jhb/moduleset.xsl \ No newline at end of file
diff --git a/packaging/macos/modulesets/patches/Quartz-version-detection-for-macOS-12.patch b/packaging/macos/modulesets/patches/Quartz-version-detection-for-macOS-12.patch
new file mode 100644
index 0000000..69c7586
--- /dev/null
+++ b/packaging/macos/modulesets/patches/Quartz-version-detection-for-macOS-12.patch
@@ -0,0 +1,67 @@
+From a752e338381bc37dbe8d4c04ec23e4f6fd911b30 Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Wed, 8 Sep 2021 18:01:50 -0700
+Subject: [PATCH] Update Quartz version detection for macOS 12.
+
+---
+ gdk/quartz/gdkglobals-quartz.c | 16 +++++++---------
+ gdk/quartz/gdkquartz.h | 3 ++-
+ 2 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/gdk/quartz/gdkglobals-quartz.c b/gdk/quartz/gdkglobals-quartz.c
+index 72aed1c92d..30649efe8a 100644
+--- a/gdk/quartz/gdkglobals-quartz.c
++++ b/gdk/quartz/gdkglobals-quartz.c
+@@ -29,28 +29,26 @@ GdkWindow *_gdk_root = NULL;
+ GdkOSXVersion
+ gdk_quartz_osx_version (void)
+ {
+- static gint32 minor = GDK_OSX_UNSUPPORTED;
++ static gint32 vkey = GDK_OSX_UNSUPPORTED;
+
+- if (minor == GDK_OSX_UNSUPPORTED)
++ if (vkey == GDK_OSX_UNSUPPORTED)
+ {
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+- OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&minor);
++ OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&vkey);
+
+ g_return_val_if_fail (err == noErr, GDK_OSX_UNSUPPORTED);
+ #else
+ NSOperatingSystemVersion version;
+
+ version = [[NSProcessInfo processInfo] operatingSystemVersion];
+- minor = version.minorVersion;
+- if (version.majorVersion == 11)
+- minor += 16;
++ vkey = version.majorVersion == 10 ? version.minorVersion : version.majorVersion + 5;
+ #endif
+ }
+
+- if (minor < GDK_OSX_MIN)
++ if (vkey < GDK_OSX_MIN)
+ return GDK_OSX_UNSUPPORTED;
+- else if (minor > GDK_OSX_CURRENT)
++ else if (vkey > GDK_OSX_CURRENT)
+ return GDK_OSX_NEW;
+ else
+- return minor;
++ return vkey;
+ }
+diff --git a/gdk/quartz/gdkquartz.h b/gdk/quartz/gdkquartz.h
+index dd1b4f41af..2d53dcbce6 100644
+--- a/gdk/quartz/gdkquartz.h
++++ b/gdk/quartz/gdkquartz.h
+@@ -42,7 +42,8 @@ typedef enum
+ GDK_OSX_MOJAVE = 14,
+ GDK_OSX_CATALINA = 15,
+ GDK_OSX_BIGSUR = 16,
+- GDK_OSX_CURRENT = 15,
++ GDK_OSX_MONTEREY = 17,
++ GDK_OSX_CURRENT = 17,
+ GDK_OSX_NEW = 99
+ } GdkOSXVersion;
+
+--
+2.30.1 (Apple Git-130)
+
diff --git a/packaging/macos/modulesets/patches/README.md b/packaging/macos/modulesets/patches/README.md
new file mode 100644
index 0000000..c0671a1
--- /dev/null
+++ b/packaging/macos/modulesets/patches/README.md
@@ -0,0 +1,3 @@
+# patches
+
+This is an offspring of [gtk-osx](https://gitlab.gnome.org/GNOME/gtk-osx)'s `patches` folder.
diff --git a/packaging/macos/modulesets/patches/cairo-color_mgmt_perf.patch b/packaging/macos/modulesets/patches/cairo-color_mgmt_perf.patch
new file mode 100644
index 0000000..a97dc64
--- /dev/null
+++ b/packaging/macos/modulesets/patches/cairo-color_mgmt_perf.patch
@@ -0,0 +1,472 @@
+https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/290
+From dbaab35b42c559ef3eb8ef0df6277246fd02a03f Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Sat, 26 Feb 2022 16:47:22 -0800
+Subject: [PATCH 1/3] Conditionally Use Main Display ColorSpace instead of
+ kCGColorSpaceDefaultRGB.
+
+The default RGB colorspace must be converted to the GPU's colorspace
+using CGColorTransformConvertUsingCMSConverter. Profiling has shown this
+function to consume as much as 48% of a redraw cycle in gdk-quartz.
+
+There seems to be no named colorspace that matches the one stored on the
+display, so we use the one associated with the main display. This has
+some risks for users with multiple monitors but in testing with my own
+two-monitor setup, one of which is HDR and the other not, the colorspace
+was the same for both.
+
+There's another issue: The monitor's color space is wrong for generating
+PNGs, producing somewhat faded colors and causing many tests to fail, so
+I've resorted to a bit of a hack: If
+cairo_quartz_surface_create_for_cg_context has been called then we're
+drawing for a screen and need to use its colorspace, otherwise we use
+kCGColorSpaceDefaultRGB as usual.
+
+Fixes https://gitlab.freedesktop.org/cairo/cairo/-/issues/330
+---
+ src/cairo-mutex-list-private.h | 4 ++++
+ src/cairo-quartz-surface.c | 42 ++++++++++++++++++++++++++++++----
+ 2 files changed, 41 insertions(+), 5 deletions(-)
+
+diff --git a/src/cairo-mutex-list-private.h b/src/cairo-mutex-list-private.h
+index 70d566ebb..eef6a10a1 100644
+--- a/src/cairo-mutex-list-private.h
++++ b/src/cairo-mutex-list-private.h
+@@ -68,6 +68,10 @@ CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
+ CAIRO_MUTEX_DECLARE (_cairo_gl_context_mutex)
+ #endif
+
++#if CAIRO_HAS_QUARTZ_SURFACE
++CAIRO_MUTEX_DECLARE (_cairo_quartz_surface_draw_to_screen_mutex)
++#endif
++
+ #if !defined (HAS_ATOMIC_OPS) || defined (ATOMIC_OP_NEEDS_MEMORY_BARRIER)
+ CAIRO_MUTEX_DECLARE (_cairo_atomic_mutex)
+ #endif
+diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
+index 5681918c4..d32ada32a 100644
+--- a/src/cairo-quartz-surface.c
++++ b/src/cairo-quartz-surface.c
+@@ -64,6 +64,10 @@
+ #define ND(_x) do {} while(0)
+ #endif
+
++#if ! CAIRO_NO_MUTEX
++static bool _draw_to_screen = FALSE;
++#endif
++
+ #define IS_EMPTY(s) ((s)->extents.width == 0 || (s)->extents.height == 0)
+
+ /**
+@@ -166,6 +170,28 @@ static void quartz_ensure_symbols (void)
+ _cairo_quartz_symbol_lookup_done = TRUE;
+ }
+
++static CGColorSpaceRef
++_cairo_quartz_create_color_space (CGContextRef context)
++{
++ CGColorSpaceRef color_space = NULL;
++
++ if (context)
++ {
++ color_space = CGBitmapContextGetColorSpace (context);
++ return CGColorSpaceRetain (color_space);
++ }
++#if !CAIRO_NO_MUTEX
++ CAIRO_MUTEX_LOCK (_cairo_quartz_surface_draw_to_screen_mutex);
++ if (_draw_to_screen)
++ color_space = CGDisplayCopyColorSpace (CGMainDisplayID ());
++ CAIRO_MUTEX_UNLOCK (_cairo_quartz_surface_draw_to_screen_mutex);
++#endif
++ if (!color_space)
++ color_space = CGColorSpaceCreateDeviceRGB ();
++
++ return color_space;
++}
++
+ CGImageRef
+ CairoQuartzCreateCGImage (cairo_format_t format,
+ unsigned int width,
+@@ -186,7 +212,7 @@ CairoQuartzCreateCGImage (cairo_format_t format,
+ switch (format) {
+ case CAIRO_FORMAT_ARGB32:
+ if (colorSpace == NULL)
+- colorSpace = CGColorSpaceCreateDeviceRGB ();
++ colorSpace = _cairo_quartz_create_color_space (NULL);
+ bitinfo |= kCGImageAlphaPremultipliedFirst;
+ bitsPerComponent = 8;
+ bitsPerPixel = 32;
+@@ -194,7 +220,7 @@ CairoQuartzCreateCGImage (cairo_format_t format,
+
+ case CAIRO_FORMAT_RGB24:
+ if (colorSpace == NULL)
+- colorSpace = CGColorSpaceCreateDeviceRGB ();
++ colorSpace = _cairo_quartz_create_color_space (NULL);
+ bitinfo |= kCGImageAlphaNoneSkipFirst;
+ bitsPerComponent = 8;
+ bitsPerPixel = 32;
+@@ -788,6 +814,7 @@ CairoQuartzCreateGradientFunction (const cairo_gradient_pattern_t *gradient,
+ input_value_range,
+ 4,
+ gradient_output_value_ranges,
++
+ &gradient_callbacks);
+ }
+
+@@ -1234,7 +1261,7 @@ _cairo_quartz_setup_gradient_source (cairo_quartz_drawing_state_t *state,
+ if (unlikely (gradFunc == NULL))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+- rgb = CGColorSpaceCreateDeviceRGB ();
++ rgb = _cairo_quartz_create_color_space (NULL);
+
+ if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
+ state->shading = CGShadingCreateAxial (rgb,
+@@ -1485,7 +1512,7 @@ _cairo_quartz_surface_map_to_image (void *abstract_surface,
+ bpp = CGBitmapContextGetBitsPerPixel (surface->cgContext);
+
+ // let's hope they don't add YUV under us
+- colorspace = CGBitmapContextGetColorSpace (surface->cgContext);
++ colorspace = _cairo_quartz_create_color_space (surface->cgContext);
+ color_comps = CGColorSpaceGetNumberOfComponents (colorspace);
+
+ /* XXX TODO: We can handle many more data formats by
+@@ -2398,6 +2425,11 @@ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
+ {
+ cairo_quartz_surface_t *surf;
+
++#if !CAIRO_NO_MUTEX
++ CAIRO_MUTEX_LOCK (_cairo_quartz_surface_draw_to_screen_mutex);
++ _draw_to_screen = TRUE;
++ CAIRO_MUTEX_UNLOCK (_cairo_quartz_surface_draw_to_screen_mutex);
++#endif
+ surf = _cairo_quartz_surface_create_internal (cgContext, CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+ if (likely (!surf->base.status))
+@@ -2445,7 +2477,7 @@ cairo_quartz_surface_create (cairo_format_t format,
+ if (format == CAIRO_FORMAT_ARGB32 ||
+ format == CAIRO_FORMAT_RGB24)
+ {
+- cgColorspace = CGColorSpaceCreateDeviceRGB ();
++ cgColorspace = _cairo_quartz_create_color_space (NULL);
+ bitinfo = kCGBitmapByteOrder32Host;
+ if (format == CAIRO_FORMAT_ARGB32)
+ bitinfo |= kCGImageAlphaPremultipliedFirst;
+--
+GitLab
+
+
+From 94a3792078de492920af2944b25a5e1b6722a8ac Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Sat, 26 Feb 2022 17:53:50 -0800
+Subject: [PATCH 2/3] [quartz] Use CGContextSetFooColorWithColor
+
+Replacing CGContextSetFooRGBColor because that re-sets the CGContext's
+color space to kCGColorSpaceDefaultRGB and we don't want that.
+---
+ src/cairo-quartz-surface.c | 53 ++++++++++++++++++++++++++++----------
+ 1 file changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
+index d32ada32a..ec8cd9b75 100644
+--- a/src/cairo-quartz-surface.c
++++ b/src/cairo-quartz-surface.c
+@@ -192,6 +192,25 @@ _cairo_quartz_create_color_space (CGContextRef context)
+ return color_space;
+ }
+
++static CGColorRef
++_cairo_quartz_create_cgcolor (CGColorSpaceRef cs, CGFloat red, CGFloat green,
++ CGFloat blue, CGFloat alpha)
++{
++ CGFloat colors[4] = { red, green, blue, alpha };
++ CGColorRef cgc;
++ if (!cs)
++ cs = _cairo_quartz_create_color_space (NULL);
++ cgc = CGColorCreate (cs, colors);
++ CGColorSpaceRelease (cs);
++ return cgc;
++}
++
++static CGColorRef
++_cairo_quartz_black (CGColorSpaceRef cs)
++{
++ return _cairo_quartz_create_cgcolor (cs, 0.0, 0.0, 0.0, 1.0);
++}
++
+ CGImageRef
+ CairoQuartzCreateCGImage (cairo_format_t format,
+ unsigned int width,
+@@ -1128,6 +1147,7 @@ _cairo_quartz_setup_pattern_source (cairo_quartz_drawing_state_t *state,
+ CGColorSpaceRef patternSpace;
+ CGPatternRef cgpat = NULL;
+ cairo_int_status_t status;
++ CGColorRef black = _cairo_quartz_black (_cairo_quartz_create_color_space (state->cgDrawContext));
+
+ _cairo_surface_get_extents (&surface->base, &extents);
+
+@@ -1183,7 +1203,7 @@ _cairo_quartz_setup_pattern_source (cairo_quartz_drawing_state_t *state,
+ -state->clipRect.origin.y);
+ }
+
+- CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 1);
++ CGContextSetFillColorWithColor (state->cgDrawContext, black);
+
+ state->rect = CGRectMake (0, 0, pattern_extents.width, pattern_extents.height);
+ state->action = DO_IMAGE;
+@@ -1222,6 +1242,7 @@ _cairo_quartz_setup_pattern_source (cairo_quartz_drawing_state_t *state,
+ CGContextSetPatternPhase (state->cgDrawContext, CGSizeMake (0, 0));
+
+ CGPatternRelease (cgpat);
++ CGColorRelease (black);
+
+ state->action = DO_DIRECT;
+ return CAIRO_STATUS_SUCCESS;
+@@ -1300,6 +1321,7 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
+ const cairo_clip_t *clip = composite->clip;
+ cairo_bool_t needs_temp;
+ cairo_status_t status;
++ CGColorRef black;
+
+ state->layer = NULL;
+ state->image = NULL;
+@@ -1332,9 +1354,11 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
+ state->filter = _cairo_quartz_filter_to_quartz (source->filter);
+
+ if (op == CAIRO_OPERATOR_CLEAR) {
+- CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 1);
++ CGColorRef black = _cairo_quartz_black (_cairo_quartz_create_color_space (surface->cgContext));
++ CGContextSetFillColorWithColor (state->cgDrawContext, black);
+
+ state->action = DO_DIRECT;
++ CGColorRelease (black);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+@@ -1371,18 +1395,17 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
+
+ if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+ cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
++ CGColorRef color = _cairo_quartz_create_cgcolor (_cairo_quartz_create_color_space (state->cgDrawContext),
++ solid->color.red,
++ solid->color.green,
++ solid->color.blue,
++ solid->color.alpha);
+
+- CGContextSetRGBStrokeColor (state->cgDrawContext,
+- solid->color.red,
+- solid->color.green,
+- solid->color.blue,
+- solid->color.alpha);
+- CGContextSetRGBFillColor (state->cgDrawContext,
+- solid->color.red,
+- solid->color.green,
+- solid->color.blue,
+- solid->color.alpha);
+
++ CGContextSetStrokeColorWithColor (state->cgDrawContext, color);
++ CGContextSetFillColorWithColor (state->cgDrawContext, color);
++
++ CGColorRelease (color);
+ state->action = DO_DIRECT;
+ return CAIRO_STATUS_SUCCESS;
+ }
+@@ -1436,6 +1459,9 @@ static inline void
+ _cairo_quartz_draw_cgcontext (cairo_quartz_drawing_state_t *state,
+ cairo_operator_t op)
+ {
++ CGColorSpaceRef cs = _cairo_quartz_create_color_space (state->cgDrawContext);
++ CGColorRef transparent = _cairo_quartz_create_cgcolor (cs, 0.0, 0.0, 0.0, 0.0);
++
+ if (! (op == CAIRO_OPERATOR_SOURCE &&
+ state->cgDrawContext == state->cgMaskContext))
+ return;
+@@ -1450,8 +1476,9 @@ _cairo_quartz_draw_cgcontext (cairo_quartz_drawing_state_t *state,
+
+ CGContextAddRect (state->cgDrawContext, state->clipRect);
+
+- CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 0);
++ CGContextSetFillColorWithColor (state->cgDrawContext, transparent);
+ CGContextEOFillPath (state->cgDrawContext);
++ CGColorRelease (transparent);
+ }
+
+
+--
+GitLab
+
+
+From 79624a15d3c3bfcd089d2d833bd986a1177301f3 Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Thu, 7 Apr 2022 10:58:02 -0700
+Subject: [PATCH 3/3] Use macOS png creation facilities for creating test PNGs
+
+---
+ boilerplate/cairo-boilerplate-quartz.c | 6 +--
+ src/cairo-quartz-private.h | 3 ++
+ src/cairo-quartz-surface.c | 52 ++++++--------------------
+ 3 files changed, 18 insertions(+), 43 deletions(-)
+
+diff --git a/boilerplate/cairo-boilerplate-quartz.c b/boilerplate/cairo-boilerplate-quartz.c
+index d4ca35383..1a1417c75 100644
+--- a/boilerplate/cairo-boilerplate-quartz.c
++++ b/boilerplate/cairo-boilerplate-quartz.c
+@@ -26,7 +26,7 @@
+
+ #include "cairo-boilerplate-private.h"
+
+-#include <cairo-quartz.h>
++#include <cairo-quartz-private.h>
+
+ static cairo_surface_t *
+ _cairo_boilerplate_quartz_create_surface (const char *name,
+@@ -56,7 +56,7 @@ static const cairo_boilerplate_target_t targets[] = {
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+- cairo_surface_write_to_png,
++ _cairo_quartz_surface_to_png,
+ NULL, NULL, NULL,
+ TRUE, FALSE, FALSE
+ },
+@@ -68,7 +68,7 @@ static const cairo_boilerplate_target_t targets[] = {
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+- cairo_surface_write_to_png,
++ _cairo_quartz_surface_to_png,
+ NULL, NULL, NULL,
+ FALSE, FALSE, FALSE
+ },
+diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
+index 609a9052c..08d9a33c1 100644
+--- a/src/cairo-quartz-private.h
++++ b/src/cairo-quartz-private.h
+@@ -106,6 +106,9 @@ CairoQuartzCreateCGImage (cairo_format_t format,
+ cairo_private CGFontRef
+ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
+
++cairo_status_t _cairo_quartz_surface_to_png (cairo_quartz_surface_t *nq, const char *dest);
++cairo_private void _cairo_quartz_image_to_png (CGImageRef, const char *dest);
++
+ #else
+
+ # error Cairo was not compiled with support for the quartz backend
+diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
+index ec8cd9b75..13f409339 100644
+--- a/src/cairo-quartz-surface.c
++++ b/src/cairo-quartz-surface.c
+@@ -64,10 +64,6 @@
+ #define ND(_x) do {} while(0)
+ #endif
+
+-#if ! CAIRO_NO_MUTEX
+-static bool _draw_to_screen = FALSE;
+-#endif
+-
+ #define IS_EMPTY(s) ((s)->extents.width == 0 || (s)->extents.height == 0)
+
+ /**
+@@ -126,15 +122,6 @@ static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
+
+ static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
+
+-/*
+- * Utility functions
+- */
+-
+-#ifdef QUARTZ_DEBUG
+-static void quartz_surface_to_png (cairo_quartz_surface_t *nq, const char *dest);
+-static void quartz_image_to_png (CGImageRef, const char *dest);
+-#endif
+-
+ typedef struct
+ {
+ cairo_surface_t base;
+@@ -180,12 +167,8 @@ _cairo_quartz_create_color_space (CGContextRef context)
+ color_space = CGBitmapContextGetColorSpace (context);
+ return CGColorSpaceRetain (color_space);
+ }
+-#if !CAIRO_NO_MUTEX
+- CAIRO_MUTEX_LOCK (_cairo_quartz_surface_draw_to_screen_mutex);
+- if (_draw_to_screen)
+- color_space = CGDisplayCopyColorSpace (CGMainDisplayID ());
+- CAIRO_MUTEX_UNLOCK (_cairo_quartz_surface_draw_to_screen_mutex);
+-#endif
++ color_space = CGDisplayCopyColorSpace (CGMainDisplayID ());
++
+ if (!color_space)
+ color_space = CGColorSpaceCreateDeviceRGB ();
+
+@@ -2450,15 +2433,9 @@ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
+ unsigned int width,
+ unsigned int height)
+ {
+- cairo_quartz_surface_t *surf;
+-
+-#if !CAIRO_NO_MUTEX
+- CAIRO_MUTEX_LOCK (_cairo_quartz_surface_draw_to_screen_mutex);
+- _draw_to_screen = TRUE;
+- CAIRO_MUTEX_UNLOCK (_cairo_quartz_surface_draw_to_screen_mutex);
+-#endif
+- surf = _cairo_quartz_surface_create_internal (cgContext, CAIRO_CONTENT_COLOR_ALPHA,
+- width, height);
++ cairo_quartz_surface_t *surf =
++ _cairo_quartz_surface_create_internal (cgContext, CAIRO_CONTENT_COLOR_ALPHA,
++ width, height);
+ if (likely (!surf->base.status))
+ CGContextRetain (cgContext);
+
+@@ -2673,12 +2650,8 @@ _cairo_quartz_surface_snapshot_get_image (cairo_quartz_surface_t *surface)
+ return CGImageRetain (((cairo_quartz_snapshot_t*)snapshot)->image);
+ }
+
+-/* Debug stuff */
+-
+-#ifdef QUARTZ_DEBUG
+-
+ void
+-quartz_image_to_png (CGImageRef image, const char *dest)
++_cairo_quartz_image_to_png (CGImageRef image, const char *dest)
+ {
+ static int sctr = 0;
+ const char* image_name = "quartz-image";
+@@ -2691,7 +2664,7 @@ quartz_image_to_png (CGImageRef image, const char *dest)
+
+ memset (pathbuf, 0, sizeof (pathbuf));
+ dest = dest ? dest : image_name;
+- snprintf (pathbuf, sizeof (pathbuf), "%s/Desktop/%s%d.png",getenv ("HOME"), dest, sctr++, ext);
++ snprintf (pathbuf, sizeof (pathbuf), "%s/Desktop/%s%d.png",getenv ("HOME"), dest, sctr++);
+ path = CFStringCreateWithCString (NULL, pathbuf, kCFStringEncodingUTF8);
+ url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, FALSE);
+ image_dest = CGImageDestinationCreateWithURL (url, png_utti, 1, NULL);
+@@ -2703,21 +2676,20 @@ quartz_image_to_png (CGImageRef image, const char *dest)
+ CFRelease (path);
+ }
+
+-void
+-quartz_surface_to_png (cairo_quartz_surface_t *nq, const char *dest)
++cairo_status_t
++_cairo_quartz_surface_to_png (cairo_quartz_surface_t *nq, const char *dest)
+ {
+ static int sctr = 0;
+ CGImageRef image;
+
+ if (nq->base.type != CAIRO_SURFACE_TYPE_QUARTZ) {
+ fprintf (stderr, "** quartz_surface_to_png: surface %p isn't quartz!\n", nq);
+- return;
++ return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+ }
+
+ image = CGBitmapContextCreateImage (nq->cgContext);
+- quartz_image_to_png (image, dest);
++ _cairo_quartz_image_to_png (image, dest);
+
+ CGImageRelease (image);
++ return CAIRO_STATUS_SUCCESS;
+ }
+-
+-#endif /* QUARTZ_DEBUG */
+--
+GitLab
+
diff --git a/packaging/macos/modulesets/patches/cairo-pixman_dithering.patch b/packaging/macos/modulesets/patches/cairo-pixman_dithering.patch
new file mode 100644
index 0000000..dc92e26
--- /dev/null
+++ b/packaging/macos/modulesets/patches/cairo-pixman_dithering.patch
@@ -0,0 +1,659 @@
+From e0d713b9bbd6d4a1e27e18c15141fa7f568001c7 Mon Sep 17 00:00:00 2001
+From: Marc Jeanmougin <marc@jeanmougin.fr>
+Date: Wed, 29 May 2019 09:44:09 +0200
+Subject: [PATCH 1/3] Enable access to the pixman dithering path Code to choose
+ between dithering quality is modeled on the filter rendering choice
+
+---
+ src/cairo-gl-gradient.c | 4 +++-
+ src/cairo-image-source.c | 48 +++++++++++++++++++++++++++++++++++++
+ src/cairo-pattern-private.h | 1 +
+ src/cairo-pattern.c | 45 ++++++++++++++++++++++++++++++++++
+ src/cairo.h | 14 +++++++++++
+ 5 files changed, 111 insertions(+), 1 deletion(-)
+
+diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
+index 293d4e30e..a22cca729 100644
+--- a/src/cairo-gl-gradient.c
++++ b/src/cairo-gl-gradient.c
+@@ -160,7 +160,9 @@ _cairo_gl_gradient_render (const cairo_gl_context_t *ctx,
+
+ pixman_image_set_filter (gradient, PIXMAN_FILTER_BILINEAR, NULL, 0);
+ pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD);
+-
++#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
++ pixman_image_set_dither (gradient, PIXMAN_DITHER_BEST);
++#endif
+ image = pixman_image_create_bits (gradient_pixman_format, width, 1,
+ bytes, sizeof(uint32_t)*width);
+ if (unlikely (image == NULL)) {
+diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
+index c56845ab2..274f43df7 100644
+--- a/src/cairo-image-source.c
++++ b/src/cairo-image-source.c
+@@ -383,6 +383,30 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
+
+ pixman_image_set_repeat (pixman_image, pixman_repeat);
+ }
++#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
++ {
++ pixman_dither_t pixman_dither;
++
++ switch (pattern->base.dither) {
++ default:
++ case CAIRO_DITHER_NONE:
++ case CAIRO_DITHER_DEFAULT:
++ pixman_dither = PIXMAN_DITHER_NONE;
++ break;
++ case CAIRO_DITHER_FAST:
++ pixman_dither = PIXMAN_DITHER_FAST;
++ break;
++ case CAIRO_DITHER_GOOD:
++ pixman_dither = PIXMAN_DITHER_GOOD;
++ break;
++ case CAIRO_DITHER_BEST:
++ pixman_dither = PIXMAN_DITHER_BEST;
++ break;
++ }
++
++ pixman_image_set_dither (pixman_image, pixman_dither);
++ }
++#endif
+
+ return pixman_image;
+ }
+@@ -1047,6 +1071,30 @@ _pixman_image_set_properties (pixman_image_t *pixman_image,
+
+ pixman_image_set_repeat (pixman_image, pixman_repeat);
+ }
++#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
++ {
++ pixman_dither_t pixman_dither;
++
++ switch (pattern->dither) {
++ default:
++ case CAIRO_DITHER_NONE:
++ case CAIRO_DITHER_DEFAULT:
++ pixman_dither = PIXMAN_DITHER_NONE;
++ break;
++ case CAIRO_DITHER_FAST:
++ pixman_dither = PIXMAN_DITHER_FAST;
++ break;
++ case CAIRO_DITHER_GOOD:
++ pixman_dither = PIXMAN_DITHER_GOOD;
++ break;
++ case CAIRO_DITHER_BEST:
++ pixman_dither = PIXMAN_DITHER_BEST;
++ break;
++ }
++
++ pixman_image_set_dither (pixman_image, pixman_dither);
++ }
++#endif
+
+ if (pattern->has_component_alpha)
+ pixman_image_set_component_alpha (pixman_image, TRUE);
+diff --git a/src/cairo-pattern-private.h b/src/cairo-pattern-private.h
+index f6138fb70..96ae4f615 100644
+--- a/src/cairo-pattern-private.h
++++ b/src/cairo-pattern-private.h
+@@ -70,6 +70,7 @@ struct _cairo_pattern {
+ cairo_pattern_type_t type;
+
+ cairo_filter_t filter;
++ cairo_dither_t dither;
+ cairo_extend_t extend;
+ cairo_bool_t has_component_alpha;
+ cairo_bool_t is_userfont_foreground;
+diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
+index 6bd3edfd8..6cf907f36 100644
+--- a/src/cairo-pattern.c
++++ b/src/cairo-pattern.c
+@@ -74,6 +74,7 @@ static const cairo_solid_pattern_t _cairo_pattern_nil = {
+
+ CAIRO_PATTERN_TYPE_SOLID, /* type */
+ CAIRO_FILTER_DEFAULT, /* filter */
++ CAIRO_DITHER_DEFAULT, /* dither */
+ CAIRO_EXTEND_GRADIENT_DEFAULT, /* extend */
+ FALSE, /* has component alpha */
+ FALSE, /* is_userfont_foreground */
+@@ -91,6 +92,7 @@ static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
+
+ CAIRO_PATTERN_TYPE_SOLID, /* type */
+ CAIRO_FILTER_DEFAULT, /* filter */
++ CAIRO_DITHER_DEFAULT, /* dither */
+ CAIRO_EXTEND_GRADIENT_DEFAULT, /* extend */
+ FALSE, /* has component alpha */
+ FALSE, /* is_userfont_foreground */
+@@ -108,6 +110,7 @@ const cairo_solid_pattern_t _cairo_pattern_black = {
+
+ CAIRO_PATTERN_TYPE_SOLID, /* type */
+ CAIRO_FILTER_NEAREST, /* filter */
++ CAIRO_DITHER_DEFAULT, /* dither */
+ CAIRO_EXTEND_REPEAT, /* extend */
+ FALSE, /* has component alpha */
+ FALSE, /* is_userfont_foreground */
+@@ -126,6 +129,7 @@ const cairo_solid_pattern_t _cairo_pattern_clear = {
+
+ CAIRO_PATTERN_TYPE_SOLID, /* type */
+ CAIRO_FILTER_NEAREST, /* filter */
++ CAIRO_DITHER_DEFAULT, /* dither */
+ CAIRO_EXTEND_REPEAT, /* extend */
+ FALSE, /* has component alpha */
+ FALSE, /* is_userfont_foreground */
+@@ -144,6 +148,7 @@ const cairo_solid_pattern_t _cairo_pattern_white = {
+
+ CAIRO_PATTERN_TYPE_SOLID, /* type */
+ CAIRO_FILTER_NEAREST, /* filter */
++ CAIRO_DITHER_DEFAULT, /* dither */
+ CAIRO_EXTEND_REPEAT, /* extend */
+ FALSE, /* has component alpha */
+ FALSE, /* is_userfont_foreground */
+@@ -235,6 +240,7 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
+ pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;
+
+ pattern->filter = CAIRO_FILTER_DEFAULT;
++ pattern->dither = CAIRO_DITHER_DEFAULT;
+ pattern->opacity = 1.0;
+
+ pattern->has_component_alpha = FALSE;
+@@ -2074,6 +2080,28 @@ cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
+ _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_FILTER);
+ }
+
++/**
++ * cairo_pattern_set_dither:
++ * @pattern: a #cairo_pattern_t
++ * @filter: a #cairo_dither_t describing the dithering to use
++ *
++ * See #cairo_dither_t for details on each algorithm.
++ *
++ * Since: TODO
++ **/
++void
++cairo_pattern_set_dither (cairo_pattern_t *pattern, cairo_dither_t dither)
++{
++ if (pattern->status)
++ return;
++
++ pattern->dither = dither;
++ _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_FILTER);
++ /* We probably can notify the same observers as when we notify filter
++ * changes (?) TODO CHECK THAT */
++}
++
++
+ /**
+ * cairo_pattern_get_filter:
+ * @pattern: a #cairo_pattern_t
+@@ -2091,6 +2119,23 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
+ return pattern->filter;
+ }
+
++/**
++ * cairo_pattern_get_dither:
++ * @pattern: a #cairo_pattern_t
++ *
++ * Gets the current dithering for a pattern. See #cairo_dither_t
++ * for details.
++ *
++ * Return value: the current dithering algorithm of the pattern
++ *
++ * Since: TODO
++ **/
++cairo_dither_t
++cairo_pattern_get_dither (cairo_pattern_t *pattern)
++{
++ return pattern->dither;
++}
++
+ /**
+ * cairo_pattern_set_extend:
+ * @pattern: a #cairo_pattern_t
+diff --git a/src/cairo.h b/src/cairo.h
+index fb1da4146..1c911d09d 100644
+--- a/src/cairo.h
++++ b/src/cairo.h
+@@ -3003,12 +3003,26 @@ typedef enum _cairo_filter {
+ CAIRO_FILTER_GAUSSIAN
+ } cairo_filter_t;
+
++typedef enum _cairo_dither {
++ CAIRO_DITHER_NONE,
++ CAIRO_DITHER_DEFAULT,
++ CAIRO_DITHER_FAST,
++ CAIRO_DITHER_GOOD,
++ CAIRO_DITHER_BEST
++} cairo_dither_t;
++
+ cairo_public void
+ cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter);
+
+ cairo_public cairo_filter_t
+ cairo_pattern_get_filter (cairo_pattern_t *pattern);
+
++cairo_public void
++cairo_pattern_set_dither (cairo_pattern_t *pattern, cairo_dither_t dither);
++
++cairo_public cairo_dither_t
++cairo_pattern_get_dither (cairo_pattern_t *pattern);
++
+ cairo_public cairo_status_t
+ cairo_pattern_get_rgba (cairo_pattern_t *pattern,
+ double *red, double *green,
+--
+2.25.1
+
+
+From 659173b4bb01e2de438d894dca9ed01838eaf028 Mon Sep 17 00:00:00 2001
+From: Marc Jeanmougin <marc@jeanmougin.fr>
+Date: Sat, 27 Mar 2021 23:53:28 +0100
+Subject: [PATCH 2/3] Expose dithering property at the image surface level.
+
+Copies the property on push_group
+---
+ src/cairo-default-context.c | 6 ++-
+ src/cairo-image-source.c | 40 ++----------------
+ src/cairo-image-surface-private.h | 1 +
+ src/cairo-image-surface.c | 67 +++++++++++++++++++++++++++++++
+ src/cairo.h | 22 ++++++----
+ src/cairoint.h | 5 +++
+ 6 files changed, 96 insertions(+), 45 deletions(-)
+
+diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c
+index 567c5d4d5..24af125da 100644
+--- a/src/cairo-default-context.c
++++ b/src/cairo-default-context.c
+@@ -180,7 +180,11 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
+ if (unlikely (status))
+ goto bail;
+
+- /* Set device offsets on the new surface so that logically it appears at
++ /* copies over the dither property */
++ cairo_image_surface_set_dither(group_surface,
++ cairo_image_surface_get_dither(parent_surface));
++
++ /* Set device offsets on the new surface so that logically it appears at
+ * the same location on the parent surface -- when we pop_group this,
+ * the source pattern will get fixed up for the appropriate target surface
+ * device offsets, so we want to set our own surface offsets from /that/,
+diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
+index 274f43df7..93daff3c0 100644
+--- a/src/cairo-image-source.c
++++ b/src/cairo-image-source.c
+@@ -385,24 +385,8 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
+ }
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
+ {
+- pixman_dither_t pixman_dither;
+-
+- switch (pattern->base.dither) {
+- default:
+- case CAIRO_DITHER_NONE:
+- case CAIRO_DITHER_DEFAULT:
+- pixman_dither = PIXMAN_DITHER_NONE;
+- break;
+- case CAIRO_DITHER_FAST:
+- pixman_dither = PIXMAN_DITHER_FAST;
+- break;
+- case CAIRO_DITHER_GOOD:
+- pixman_dither = PIXMAN_DITHER_GOOD;
+- break;
+- case CAIRO_DITHER_BEST:
+- pixman_dither = PIXMAN_DITHER_BEST;
+- break;
+- }
++ pixman_dither_t pixman_dither =
++ _pixman_dither_from_cairo_dither(pattern->base.dither);
+
+ pixman_image_set_dither (pixman_image, pixman_dither);
+ }
+@@ -1073,24 +1057,8 @@ _pixman_image_set_properties (pixman_image_t *pixman_image,
+ }
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
+ {
+- pixman_dither_t pixman_dither;
+-
+- switch (pattern->dither) {
+- default:
+- case CAIRO_DITHER_NONE:
+- case CAIRO_DITHER_DEFAULT:
+- pixman_dither = PIXMAN_DITHER_NONE;
+- break;
+- case CAIRO_DITHER_FAST:
+- pixman_dither = PIXMAN_DITHER_FAST;
+- break;
+- case CAIRO_DITHER_GOOD:
+- pixman_dither = PIXMAN_DITHER_GOOD;
+- break;
+- case CAIRO_DITHER_BEST:
+- pixman_dither = PIXMAN_DITHER_BEST;
+- break;
+- }
++ pixman_dither_t pixman_dither =
++ _pixman_dither_from_cairo_dither (pattern->dither);
+
+ pixman_image_set_dither (pixman_image, pixman_dither);
+ }
+diff --git a/src/cairo-image-surface-private.h b/src/cairo-image-surface-private.h
+index 2b7921133..c06b9737b 100644
+--- a/src/cairo-image-surface-private.h
++++ b/src/cairo-image-surface-private.h
+@@ -78,6 +78,7 @@ struct _cairo_image_surface {
+ unsigned owns_data : 1;
+ unsigned transparency : 2;
+ unsigned color : 2;
++ cairo_dither_t dither : 3;
+ };
+ #define to_image_surface(S) ((cairo_image_surface_t *)(S))
+
+diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
+index 3b11eb981..977bb48e6 100644
+--- a/src/cairo-image-surface.c
++++ b/src/cairo-image-surface.c
+@@ -169,6 +169,7 @@ _cairo_image_surface_init (cairo_image_surface_t *surface,
+ surface->owns_data = FALSE;
+ surface->transparency = CAIRO_IMAGE_UNKNOWN;
+ surface->color = CAIRO_IMAGE_UNKNOWN_COLOR;
++ surface->dither = CAIRO_DITHER_DEFAULT;
+
+ surface->width = pixman_image_get_width (pixman_image);
+ surface->height = pixman_image_get_height (pixman_image);
+@@ -248,6 +249,25 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
+ return TRUE;
+ }
+
++#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
++/* Convenience function to convert cairo_dither_t into pixman_dither_t */
++pixman_dither_t _pixman_dither_from_cairo_dither(cairo_dither_t dither)
++{
++ switch(dither) {
++ default:
++ case CAIRO_DITHER_NONE:
++ case CAIRO_DITHER_DEFAULT:
++ return PIXMAN_DITHER_NONE;
++ case CAIRO_DITHER_FAST:
++ return PIXMAN_DITHER_FAST;
++ case CAIRO_DITHER_GOOD:
++ return PIXMAN_DITHER_GOOD;
++ case CAIRO_DITHER_BEST:
++ return PIXMAN_DITHER_BEST;
++ }
++}
++#endif
++
+ /* A mask consisting of N bits set to 1. */
+ #define MASK(N) ((1UL << (N))-1)
+
+@@ -631,6 +651,30 @@ cairo_image_surface_get_width (cairo_surface_t *surface)
+ }
+ slim_hidden_def (cairo_image_surface_get_width);
+
++/**
++ * cairo_image_surface_get_dither:
++ * @surface: a #cairo_image_surface_t
++ *
++ * Get the current dithering method
++ *
++ * Return value: the current dithering method.
++ *
++ * Since: TODO
++ **/
++cairo_dither_t
++cairo_image_surface_get_dither (cairo_surface_t *surface)
++{
++ cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
++
++ if (! _cairo_surface_is_image (surface)) {
++ _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
++ return CAIRO_DITHER_DEFAULT;
++ }
++
++ return image_surface->dither;
++}
++//slim_hidden_def (cairo_image_surface_get_dither);
++
+ /**
+ * cairo_image_surface_get_height:
+ * @surface: a #cairo_image_surface_t
+@@ -792,6 +836,7 @@ _cairo_image_surface_snapshot (void *abstract_surface)
+
+ clone->transparency = image->transparency;
+ clone->color = image->color;
++ clone->dither = image->dither;
+
+ clone->owns_data = TRUE;
+ return &clone->base;
+@@ -1361,3 +1406,25 @@ error:
+ cairo_surface_destroy (image);
+ return to_image_surface (_cairo_surface_create_in_error (status));
+ }
++
++cairo_public int
++cairo_image_surface_set_dither (cairo_surface_t *surface, cairo_dither_t dither)
++{
++ cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
++
++ if (! _cairo_surface_is_image (surface)) {
++ _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
++ return 0;
++ }
++
++ image_surface->dither = dither;
++ if (image_surface->pixman_image) {
++#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
++ pixman_image_set_dither(image_surface->pixman_image,
++ _pixman_dither_from_cairo_dither(dither));
++#endif
++ }
++
++}
++//slim_hidden_def (cairo_image_surface_set_dither);
++
+diff --git a/src/cairo.h b/src/cairo.h
+index 1c911d09d..76db87d2e 100644
+--- a/src/cairo.h
++++ b/src/cairo.h
+@@ -427,6 +427,14 @@ typedef enum _cairo_format {
+ CAIRO_FORMAT_RGBA128F = 7
+ } cairo_format_t;
+
++typedef enum _cairo_dither {
++ CAIRO_DITHER_NONE,
++ CAIRO_DITHER_DEFAULT,
++ CAIRO_DITHER_FAST,
++ CAIRO_DITHER_GOOD,
++ CAIRO_DITHER_BEST
++} cairo_dither_t;
++
+
+ /**
+ * cairo_write_func_t:
+@@ -2607,6 +2615,12 @@ cairo_image_surface_create_for_data (unsigned char *data,
+ cairo_public unsigned char *
+ cairo_image_surface_get_data (cairo_surface_t *surface);
+
++cairo_public cairo_dither_t
++cairo_image_surface_get_dither (cairo_surface_t *surface);
++
++cairo_public int
++cairo_image_surface_set_dither (cairo_surface_t *surface, cairo_dither_t dither);
++
+ cairo_public cairo_format_t
+ cairo_image_surface_get_format (cairo_surface_t *surface);
+
+@@ -3003,14 +3017,6 @@ typedef enum _cairo_filter {
+ CAIRO_FILTER_GAUSSIAN
+ } cairo_filter_t;
+
+-typedef enum _cairo_dither {
+- CAIRO_DITHER_NONE,
+- CAIRO_DITHER_DEFAULT,
+- CAIRO_DITHER_FAST,
+- CAIRO_DITHER_GOOD,
+- CAIRO_DITHER_BEST
+-} cairo_dither_t;
+-
+ cairo_public void
+ cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter);
+
+diff --git a/src/cairoint.h b/src/cairoint.h
+index 80b695feb..a8442b5fe 100644
+--- a/src/cairoint.h
++++ b/src/cairoint.h
+@@ -1592,6 +1592,11 @@ cairo_private cairo_bool_t
+ _pixman_format_to_masks (pixman_format_code_t pixman_format,
+ cairo_format_masks_t *masks);
+
++#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
++cairo_private pixman_dither_t
++_pixman_dither_from_cairo_dither(cairo_dither_t dither);
++#endif
++
+ cairo_private void
+ _cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
+ cairo_scaled_glyph_t *scaled_glyph);
+--
+2.25.1
+
+
+From edf60824e871d2393136303761135bb49986fa33 Mon Sep 17 00:00:00 2001
+From: Marc Jeanmougin <marc@jeanmougin.fr>
+Date: Mon, 29 Mar 2021 12:18:56 +0200
+Subject: [PATCH 3/3] make lint tests pass
+
+---
+ src/cairo-image-surface.c | 20 +++++++++++++++-----
+ src/cairo-pattern.c | 4 ++--
+ src/cairoint.h | 4 +++-
+ 3 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
+index 977bb48e6..d2f544a68 100644
+--- a/src/cairo-image-surface.c
++++ b/src/cairo-image-surface.c
+@@ -250,8 +250,9 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
+ }
+
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
+-/* Convenience function to convert cairo_dither_t into pixman_dither_t */
+-pixman_dither_t _pixman_dither_from_cairo_dither(cairo_dither_t dither)
++/* Convenience function to convert #cairo_dither_t into #pixman_dither_t */
++pixman_dither_t
++_pixman_dither_from_cairo_dither (cairo_dither_t dither)
+ {
+ switch(dither) {
+ default:
+@@ -659,7 +660,7 @@ slim_hidden_def (cairo_image_surface_get_width);
+ *
+ * Return value: the current dithering method.
+ *
+- * Since: TODO
++ * Since: 1.18
+ **/
+ cairo_dither_t
+ cairo_image_surface_get_dither (cairo_surface_t *surface)
+@@ -673,7 +674,7 @@ cairo_image_surface_get_dither (cairo_surface_t *surface)
+
+ return image_surface->dither;
+ }
+-//slim_hidden_def (cairo_image_surface_get_dither);
++slim_hidden_def (cairo_image_surface_get_dither);
+
+ /**
+ * cairo_image_surface_get_height:
+@@ -1407,6 +1408,15 @@ error:
+ return to_image_surface (_cairo_surface_create_in_error (status));
+ }
+
++/**
++ * cairo_image_surface_set_dither:
++ * @surface: a #cairo_image_surface_t
++ * @dither: a #cairo_dither_t
++ *
++ * Sets the current dithering method
++ *
++ * Since: 1.18
++ **/
+ cairo_public int
+ cairo_image_surface_set_dither (cairo_surface_t *surface, cairo_dither_t dither)
+ {
+@@ -1426,5 +1436,5 @@ cairo_image_surface_set_dither (cairo_surface_t *surface, cairo_dither_t dither)
+ }
+
+ }
+-//slim_hidden_def (cairo_image_surface_set_dither);
++slim_hidden_def (cairo_image_surface_set_dither);
+
+diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
+index 6cf907f36..7d05b06a1 100644
+--- a/src/cairo-pattern.c
++++ b/src/cairo-pattern.c
+@@ -2087,7 +2087,7 @@ cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
+ *
+ * See #cairo_dither_t for details on each algorithm.
+ *
+- * Since: TODO
++ * Since: 1.18
+ **/
+ void
+ cairo_pattern_set_dither (cairo_pattern_t *pattern, cairo_dither_t dither)
+@@ -2128,7 +2128,7 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
+ *
+ * Return value: the current dithering algorithm of the pattern
+ *
+- * Since: TODO
++ * Since: 1.18
+ **/
+ cairo_dither_t
+ cairo_pattern_get_dither (cairo_pattern_t *pattern)
+diff --git a/src/cairoint.h b/src/cairoint.h
+index a8442b5fe..274d43556 100644
+--- a/src/cairoint.h
++++ b/src/cairoint.h
+@@ -1594,7 +1594,7 @@ _pixman_format_to_masks (pixman_format_code_t pixman_format,
+
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,39,0)
+ cairo_private pixman_dither_t
+-_pixman_dither_from_cairo_dither(cairo_dither_t dither);
++_pixman_dither_from_cairo_dither (cairo_dither_t dither);
+ #endif
+
+ cairo_private void
+@@ -1982,6 +1982,8 @@ slim_hidden_proto (cairo_image_surface_get_format);
+ slim_hidden_proto (cairo_image_surface_get_height);
+ slim_hidden_proto (cairo_image_surface_get_stride);
+ slim_hidden_proto (cairo_image_surface_get_width);
++slim_hidden_proto (cairo_image_surface_get_dither);
++slim_hidden_proto (cairo_image_surface_set_dither);
+ slim_hidden_proto (cairo_line_to);
+ slim_hidden_proto (cairo_mask);
+ slim_hidden_proto (cairo_matrix_init);
+--
+2.25.1
+
+
+From b2e0f1d6f69ad3013dfb8d677f7b3ee9fac0fceb Mon Sep 17 00:00:00 2001
+From: Marc Jeanmougin <marc@jeanmougin.fr>
+Date: Mon, 24 Jan 2022 21:28:44 +0100
+Subject: [PATCH] add define to detect patched cairo
+
+---
+ src/cairo.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/cairo.h b/src/cairo.h
+index 76db87d2e..934bf65d0 100644
+--- a/src/cairo.h
++++ b/src/cairo.h
+@@ -2615,6 +2615,7 @@ cairo_image_surface_create_for_data (unsigned char *data,
+ cairo_public unsigned char *
+ cairo_image_surface_get_data (cairo_surface_t *surface);
+
++#define CAIRO_HAS_DITHER
+ cairo_public cairo_dither_t
+ cairo_image_surface_get_dither (cairo_surface_t *surface);
+
+--
+2.25.1
+
diff --git a/packaging/macos/modulesets/patches/cairo-snapshot_leak.patch b/packaging/macos/modulesets/patches/cairo-snapshot_leak.patch
new file mode 100644
index 0000000..5780735
--- /dev/null
+++ b/packaging/macos/modulesets/patches/cairo-snapshot_leak.patch
@@ -0,0 +1,27 @@
+https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/316
+From 243938c61a08dac8911153352e55933e0618581e Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Sat, 23 Apr 2022 16:38:01 -0700
+Subject: [PATCH] [quartz] Destroy local copy of snapshot after attaching it.
+
+Because cairo_surface_snapshot_attach refs the snapshot.
+
+Fixes https://gitlab.freedesktop.org/cairo/cairo/-/issues/562
+---
+ src/cairo-quartz-surface.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
+index 5681918c4..fa6d9b1c9 100644
+--- a/src/cairo-quartz-surface.c
++++ b/src/cairo-quartz-surface.c
+@@ -2609,6 +2609,7 @@ _cairo_quartz_surface_snapshot_get_image (cairo_quartz_surface_t *surface)
+ if (unlikely (!snapshot || cairo_surface_status (snapshot)))
+ return NULL;
+ _cairo_surface_attach_snapshot (&surface->base, snapshot, NULL);
++ cairo_surface_destroy (snapshot);
+ }
+
+ return CGImageRetain (((cairo_quartz_snapshot_t*)snapshot)->image);
+--
+GitLab
diff --git a/packaging/macos/modulesets/patches/enchant-relocatable.patch b/packaging/macos/modulesets/patches/enchant-relocatable.patch
new file mode 100644
index 0000000..602b5c1
--- /dev/null
+++ b/packaging/macos/modulesets/patches/enchant-relocatable.patch
@@ -0,0 +1,38 @@
+diff --git a/src/lib.c b/src/lib.c
+index d9d3c54..ae3642f 100644
+--- a/src/lib.c
++++ b/src/lib.c
+@@ -130,6 +130,10 @@ enchant_get_conf_dirs (void)
+ char *pkgconfdir = NULL;
+ char *user_config_dir = NULL;
+
++ const char *prefix = g_getenv("ENCHANT_PREFIX");
++ if (prefix)
++ conf_dirs = g_slist_append(conf_dirs, g_build_filename(prefix, "/share/enchant", NULL));
++
+ if ((pkgdatadir = enchant_relocate (PKGDATADIR)) == NULL)
+ goto error_exit;
+ conf_dirs = g_slist_append (conf_dirs, pkgdatadir);
+@@ -148,6 +152,7 @@ enchant_get_conf_dirs (void)
+ return conf_dirs;
+
+ error_exit:
++ g_warning("error_exit in enchant_get_conf_dirs");
+ free (pkgdatadir);
+ free (sysconfdir);
+ g_free (pkgconfdir);
+@@ -878,7 +883,13 @@ enchant_load_providers_in_dir (EnchantBroker * broker, const char *dir_name)
+ static void
+ enchant_load_providers (EnchantBroker * broker)
+ {
+- char *module_dir = enchant_relocate (PKGLIBDIR "-" ENCHANT_MAJOR_VERSION);
++ const char *prefix = g_getenv("ENCHANT_PREFIX");
++ char *module_dir = NULL;
++ if (prefix)
++ module_dir = g_build_filename(prefix, "/lib/enchant-2", NULL);
++ else
++ module_dir = enchant_relocate (PKGLIBDIR "-" ENCHANT_MAJOR_VERSION);
++
+ if (module_dir)
+ enchant_load_providers_in_dir (broker, module_dir);
+ free (module_dir);
diff --git a/packaging/macos/modulesets/patches/frodo-getopt-autotools.patch b/packaging/macos/modulesets/patches/frodo-getopt-autotools.patch
new file mode 100644
index 0000000..dd374a2
--- /dev/null
+++ b/packaging/macos/modulesets/patches/frodo-getopt-autotools.patch
@@ -0,0 +1,28 @@
+--- a/Makefile 2014-11-24 04:33:39.000000000 -0800
++++ b/Makefile 2021-04-09 15:26:46.000000000 -0700
+@@ -1,7 +1,7 @@
+ .SUFFIXES:
+
+ DESTDIR=
+-prefix=/usr/local
++prefix=${PREFIX}
+ bindir=$(prefix)/bin
+ mandir=$(prefix)/man
+ man1dir=$(mandir)/man1
+@@ -43,7 +43,7 @@
+ -Wnested-externs -Winline
+ OPTIMIZE=-O3 -fno-strength-reduce
+ CFLAGS=$(WARNINGS) $(OPTIMIZE)
+-LDFLAGS=
++LDFLAGS=-L ${PREFIX}/lib -lintl
+
+ sources=getopt.c
+ ifeq ($(LIBCGETOPT),0)
+
+Diff finished. Fri Apr 9 15:28:12 2021
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index e69de29..b53cf7a 100644
+--- a/configure
++++ b/configure
+@@ -0,0 +1,1 @@
++ #Do Nothing
diff --git a/packaging/macos/modulesets/patches/gdk-pixbuf-loader-name.patch b/packaging/macos/modulesets/patches/gdk-pixbuf-loader-name.patch
new file mode 100644
index 0000000..db499ba
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gdk-pixbuf-loader-name.patch
@@ -0,0 +1,25 @@
+diff -c /Users/john/Development/gtk-build/gtk-stable-10.9-x86_64/src/gdk-pixbuf-2.38.0/gdk-pixbuf/meson.build\~ /Users/john/Development/gtk-build/gtk-stable-10.9-x86_64/src/gdk-pixbuf-2.38.0/gdk-pixbuf/meson.build
+--- a/gdk-pixbuf/meson.build Mon Sep 3 07:41:50 2018
++++ b/gdk-pixbuf/meson.build Wed Jul 31 16:04:12 2019
+@@ -246,7 +246,8 @@
+ include_directories: [ root_inc, gdk_pixbuf_inc ],
+ c_args: common_cflags + gdk_pixbuf_cflags + cflags,
+ install: true,
+- install_dir: gdk_pixbuf_loaderdir)
++ install_dir: gdk_pixbuf_loaderdir,
++ name_suffix: 'so')
+
+ # We need the path to build loaders.cache for tests
+ dynamic_loaders += mod.full_path()
+@@ -265,7 +266,8 @@
+ include_directories: [ root_inc, gdk_pixbuf_inc ],
+ c_args: common_cflags + gdk_pixbuf_cflags + cflags,
+ install: true,
+- install_dir: gdk_pixbuf_loaderdir)
++ install_dir: gdk_pixbuf_loaderdir,
++ name_suffix: 'so')
+ dynamic_loaders += mod.full_path()
+ endforeach
+ endif
+
+Diff finished. Wed Jul 31 16:09:09 2019
diff --git a/packaging/macos/modulesets/patches/ghostscript_configure_libtiff.patch b/packaging/macos/modulesets/patches/ghostscript_configure_libtiff.patch
new file mode 100644
index 0000000..e53115e
--- /dev/null
+++ b/packaging/macos/modulesets/patches/ghostscript_configure_libtiff.patch
@@ -0,0 +1,11 @@
+--- a/configure 2022-04-04 15:48:49.000000000 +0200
++++ b/configure 2022-07-06 01:03:53.000000000 +0200
+@@ -8796,7 +8796,7 @@
+ if ! test -d "$LIBTIFFCONFDIR" ; then
+ mkdir "$LIBTIFFCONFDIR"
+ fi
+- cd "$LIBTIFFCONFDIR" && "$absolute_source_path/$LIBTIFFDIR/configure" $GS_TIFF_CONFIGURE_OPTS --disable-jbig --disable-lzma --disable-zstd --disable-webp --disable-libdeflate $SUBCONFIG_OPTS
++ cd "$LIBTIFFCONFDIR" && "$LIBTIFFDIR/configure" $GS_TIFF_CONFIGURE_OPTS --disable-jbig --disable-lzma --disable-zstd --disable-webp --disable-libdeflate $SUBCONFIG_OPTS
+ status=$?
+ if test $status -ne 0 ; then
+ as_fn_error $status "libtiff configure script failed" "$LINENO" 5
diff --git a/packaging/macos/modulesets/patches/ghostscript_link_cupsimage.patch b/packaging/macos/modulesets/patches/ghostscript_link_cupsimage.patch
new file mode 100644
index 0000000..81bc20a
--- /dev/null
+++ b/packaging/macos/modulesets/patches/ghostscript_link_cupsimage.patch
@@ -0,0 +1,11 @@
+--- a/base/unixlink.mak 2020-03-19 09:21:42.000000000 +0100
++++ b/base/unixlink.mak 2020-05-02 01:11:38.000000000 +0200
+@@ -168,7 +168,7 @@
+ $(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(GS_LDFLAGS) -o $(GS_XE)
+ $(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) $(GS_DOT_O) -s
+ cat $(gsld_tr) >> $(ldt_tr)
+- $(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) $(STDLIBS)
++ $(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) $(STDLIBS) -lcupsimage
+ if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \
+ XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \
+ PSI_FEATURE_DEVS= FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \
diff --git a/packaging/macos/modulesets/patches/graphviz-remove-rpath.patch b/packaging/macos/modulesets/patches/graphviz-remove-rpath.patch
new file mode 100644
index 0000000..857165b
--- /dev/null
+++ b/packaging/macos/modulesets/patches/graphviz-remove-rpath.patch
@@ -0,0 +1,55 @@
+--- a/CMakeLists.txt 2021-03-15 17:04:01.000000000 -0700
++++ b/CMakeLists.txt 2021-07-29 13:42:38.000000000 -0700
+@@ -72,6 +72,8 @@
+ # Name of the config file used by Graphviz
+ set(GVPLUGIN_CONFIG_FILE config${GRAPHVIZ_PLUGIN_VERSION})
+
++set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIBRARY_INSTALL_DIR}")
++
+ # ============================ Library dependencies ============================
+ if (WIN32)
+ list(APPEND CMAKE_PREFIX_PATH ${WINDOWS_DEPENDENCY_DIR})
+--- a/plugin/core/CMakeLists.txt 2021-03-15 17:04:01.000000000 -0700
++++ b/plugin/core/CMakeLists.txt 2021-07-29 13:42:09.000000000 -0700
+@@ -53,6 +53,8 @@
+ ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
+ )
+
++set_target_properties(gvplugin_core PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_INSTALL_DIR}")
++
+ # Specify library version and soversion
+ set_target_properties(gvplugin_core PROPERTIES
+ VERSION ${GRAPHVIZ_PLUGIN_VERSION}.0.0
+--- a/plugin/pango/CMakeLists.txt 2021-03-15 17:04:01.000000000 -0700
++++ b/plugin/pango/CMakeLists.txt 2021-07-29 13:43:13.000000000 -0700
+@@ -40,6 +40,8 @@
+ ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
+ )
+
++set_target_properties(gvplugin_pango PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_INSTALL_DIR}")
++
+ # Include DLLs with this library on Windows
+ if (WIN32)
+ install(
+--- a/plugin/neato_layout/CMakeLists.txt 2021-03-15 17:04:01.000000000 -0700
++++ b/plugin/neato_layout/CMakeLists.txt 2021-07-29 13:42:57.000000000 -0700
+@@ -45,6 +45,8 @@
+ ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
+ )
+
++set_target_properties(gvplugin_neato_layout PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_INSTALL_DIR}")
++
+ # Specify library version and soversion
+ set_target_properties(gvplugin_neato_layout PROPERTIES
+ VERSION ${GRAPHVIZ_PLUGIN_VERSION}.0.0
+--- a/plugin/dot_layout/CMakeLists.txt 2021-03-15 17:04:01.000000000 -0700
++++ b/plugin/dot_layout/CMakeLists.txt 2021-07-29 13:42:28.000000000 -0700
+@@ -30,6 +30,8 @@
+ ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
+ )
+
++set_target_properties(gvplugin_dot_layout PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_INSTALL_DIR}")
++
+ # Specify library version and soversion
+ set_target_properties(gvplugin_dot_layout PROPERTIES
+ VERSION ${GRAPHVIZ_PLUGIN_VERSION}.0.0
diff --git a/packaging/macos/modulesets/patches/gspell-makefile_objc.patch b/packaging/macos/modulesets/patches/gspell-makefile_objc.patch
new file mode 100644
index 0000000..e9a7e65
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gspell-makefile_objc.patch
@@ -0,0 +1,20 @@
+Patch taken from homebrew formula.
+Removed gtk-mac-integration dependency.
+https://github.com/Homebrew/homebrew-core/blob/cd1e31a/Formula/gspell.rb
+diff --git a/gspell/Makefile.am b/gspell/Makefile.am
+index 076a9fd..6c67184 100644
+--- a/gspell/Makefile.am
++++ b/gspell/Makefile.am
+@@ -155,6 +156,12 @@ gspell_private_headers += \
+ gspell_private_c_files += \
+ gspell-osx.c
+
++libgspell_core_la_CFLAGS += \
++ -xobjective-c
++
++libgspell_core_la_LDFLAGS += \
++ -framework Cocoa
++
+ endif # OS_OSX
+
+ if HAVE_INTROSPECTION
diff --git a/packaging/macos/modulesets/patches/gspell-remove_gtkmacintegration.patch b/packaging/macos/modulesets/patches/gspell-remove_gtkmacintegration.patch
new file mode 100644
index 0000000..6d05bc4
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gspell-remove_gtkmacintegration.patch
@@ -0,0 +1,59 @@
+# Remove the dependency on gtk-mac-integration and replace it with a
+# simpler solution.
+diff --git a/configure.ac b/configure.ac
+index 15da2b1..8f3d70c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -204,13 +204,6 @@ AM_CONDITIONAL(OS_OSX, test "$os_osx" = "yes")
+
+ if test "$os_osx" = "yes"; then
+ AC_DEFINE([OS_OSX], [1], [Defined if OS is Mac OSX])
+-
+- AX_PKG_CHECK_MODULES([GTK_MAC],
+- [],
+- [gtk-mac-integration-gtk3 >= 2.0.8])
+-
+- AC_SUBST(GTK_MAC_CFLAGS)
+- AC_SUBST(GTK_MAC_LIBS)
+ fi
+
+ # Output files
+diff --git a/gspell/gspell-osx.c b/gspell/gspell-osx.c
+index e3b9615..9d71cbb 100644
+--- a/gspell/gspell-osx.c
++++ b/gspell/gspell-osx.c
+@@ -22,24 +22,24 @@
+ #endif
+
+ #include "gspell-osx.h"
+-#include <gtkosxapplication.h>
++#include <mach-o/dyld.h>
++#include <limits.h>
+ #import <Cocoa/Cocoa.h>
+
+ gchar *
+ _gspell_osx_get_resource_path (void)
+ {
+- gchar *id;
+- gchar *ret = NULL;
+-
+- id = gtkosx_application_get_bundle_id ();
++ uint32_t size = PATH_MAX + 1;
+
+- if (id != NULL)
+- {
+- ret = gtkosx_application_get_resource_path ();
++ gchar* path = (gchar*)g_malloc(size);
++ if (_NSGetExecutablePath(path, &size) == 0) {
++ gchar* contents_dir = g_strstr_len(path, -1, "Contents");
++ g_snprintf(contents_dir, 19, "Contents/Resources");
++ return path;
+ }
+
+- g_free (id);
+- return ret;
++ g_free(path);
++ return NULL;
+ }
+
+ gchar *
diff --git a/packaging/macos/modulesets/patches/gtk+-scale-absolute-value.patch b/packaging/macos/modulesets/patches/gtk+-scale-absolute-value.patch
new file mode 100644
index 0000000..d0a49a1
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gtk+-scale-absolute-value.patch
@@ -0,0 +1,32 @@
+From 36315cbe2b3c9d1c1b7508d9494a251eddbc4452 Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Thu, 14 Oct 2021 12:41:05 -0700
+Subject: [PATCH] [quartz]Use the absolute value of Scale values for
+ CGContextScaleSCM
+
+In macOS-12.sdk CGContextConverSizeToDeviceSpace returns a negative
+height and passing that to CGContextScaleCTM in turn causes the cairo
+surface to draw outside the window where it can't be seen. Passing the
+absolute values of the scale factors fixes the display on macOS 12 without
+affecting earlier macOS versions.
+---
+ gdk/quartz/gdkwindow-quartz.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
+index 1a3389bb32..a5c5c31945 100644
+--- a/gdk/quartz/gdkwindow-quartz.c
++++ b/gdk/quartz/gdkwindow-quartz.c
+@@ -183,8 +183,7 @@ gdk_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
+ * in gdk_quartz_ref_cairo_surface () */
+ scale = CGContextConvertSizeToDeviceSpace (cg_context,
+ CGSizeMake (1.0, 1.0));
+- CGContextScaleCTM (cg_context, 1.0 / scale.width, 1.0 / scale.height);
+-
++ CGContextScaleCTM (cg_context, 1.0 / fabs(scale.width), 1.0 / fabs(scale.height));
+ return cg_context;
+ }
+
+--
+2.30.1 (Apple Git-130)
+
diff --git a/packaging/macos/modulesets/patches/gtk-3.24.33-quartz-window-transient-for.patch b/packaging/macos/modulesets/patches/gtk-3.24.33-quartz-window-transient-for.patch
new file mode 100644
index 0000000..39435df
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gtk-3.24.33-quartz-window-transient-for.patch
@@ -0,0 +1,46 @@
+From f42f7adc531da47b5c34a05da84ac873618f55ed Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Mon, 28 Mar 2022 11:26:41 -0700
+Subject: [PATCH] [quartz-window]Always ensure that transient_for isn't
+ destroyed before using it.
+
+Fixes crash when destroying a dialog whose transient_for parent is
+already destroyed.
+---
+ gdk/quartz/gdkwindow-quartz.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
+index aa85318e0b..15cde981a0 100644
+--- a/gdk/quartz/gdkwindow-quartz.c
++++ b/gdk/quartz/gdkwindow-quartz.c
+@@ -788,7 +788,7 @@ _gdk_quartz_window_did_become_main (GdkWindow *window)
+ if (window->window_type != GDK_WINDOW_TEMP)
+ main_window_stack = g_slist_prepend (main_window_stack, window);
+
+- if (impl->transient_for)
++ if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
+ raise_transient (impl);
+
+ clear_toplevel_order ();
+@@ -1176,6 +1176,8 @@ _gdk_quartz_window_detach_from_parent (GdkWindow *window)
+ parent_impl = GDK_WINDOW_IMPL_QUARTZ (impl->transient_for->impl);
+ [parent_impl->toplevel removeChildWindow:impl->toplevel];
+ clear_toplevel_order ();
++ g_object_unref (impl->transient_for);
++ impl->transient_for = NULL;
+ }
+ }
+
+@@ -1557,7 +1559,7 @@ gdk_window_quartz_raise (GdkWindow *window)
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+- if (impl->transient_for)
++ if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
+ raise_transient (impl);
+ else
+ [impl->toplevel orderFront:impl->toplevel];
+--
+2.32.0 (Apple Git-132)
+
diff --git a/packaging/macos/modulesets/patches/gtk-3.24.33-remove-gtk4-update-icon-cache-dependency.patch b/packaging/macos/modulesets/patches/gtk-3.24.33-remove-gtk4-update-icon-cache-dependency.patch
new file mode 100644
index 0000000..2850343
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gtk-3.24.33-remove-gtk4-update-icon-cache-dependency.patch
@@ -0,0 +1,10 @@
+--- a/meson.build~ 2022-03-04 20:53:25.000000000 -0800
++++ b/meson.build 2022-03-22 15:44:32.000000000 -0700
+@@ -1013,7 +1013,6 @@
+ gnome.post_install(
+ glib_compile_schemas: true,
+ gio_querymodules: gio_module_dirs,
+- gtk_update_icon_cache: get_option('demos'),
+ )
+ else
+ # Keep this in sync with post-install.py expected arguments
diff --git a/packaging/macos/modulesets/patches/gtk-mac-bundler_configure.patch b/packaging/macos/modulesets/patches/gtk-mac-bundler_configure.patch
new file mode 100644
index 0000000..10365cd
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gtk-mac-bundler_configure.patch
@@ -0,0 +1,24 @@
+--- a/configure 2020-11-29 14:24:17.000000000 +0100
++++ b/configure 2020-11-29 14:21:40.000000000 +0100
+@@ -0,0 +1,21 @@
++#!/usr/bin/env bash
++
++# This mocks a configure script to provide an interface for JHBuild.
++# We're only interested in the prefix so we can patch the Makefile.
++
++while [ "$#" -gt 0 ]; do
++ case $1 in
++ --prefix=*) PREFIX=${1:9}; break ;;
++ *) echo "ignoring parameter: $1" ;;
++ esac
++ shift
++done
++
++if [ -z $PREFIX ]; then
++ echo "--prefix=* argument not found"
++ exit 1
++else
++ sed -i "" "/bindir=/a\\
++ bindir=$PREFIX\/bin\\
++ " Makefile
++fi
diff --git a/packaging/macos/modulesets/patches/gtkmm-3-bad-const-property-background.patch b/packaging/macos/modulesets/patches/gtkmm-3-bad-const-property-background.patch
new file mode 100644
index 0000000..4768b2f
--- /dev/null
+++ b/packaging/macos/modulesets/patches/gtkmm-3-bad-const-property-background.patch
@@ -0,0 +1,13 @@
+--- a/tests/builder/main.cc 2021-02-23 01:07:04.000000000 -0800
++++ b/tests/builder/main.cc 2021-04-03 10:28:40.000000000 -0700
+@@ -120,7 +120,7 @@
+ }
+ }
+
+- Glib::PropertyProxy_ReadOnly<Glib::ustring> property_background() const { return m_property_background.get_proxy(); }
++ //Glib::PropertyProxy_ReadOnly<Glib::ustring> property_background() const { return m_property_background.get_proxy(); }
+ Glib::PropertyProxy <Glib::ustring> property_background() { return m_property_background.get_proxy(); }
+ Glib::ustring get_background() const { return m_property_background.get_value(); }
+ void set_background(const Glib::ustring& background){ m_property_background.set_value(background); }
+
+Diff finished. Sat Apr 3 10:38:41 2021
diff --git a/packaging/macos/modulesets/patches/imagemagick_configure_pango.patch b/packaging/macos/modulesets/patches/imagemagick_configure_pango.patch
new file mode 100644
index 0000000..8ce359b
--- /dev/null
+++ b/packaging/macos/modulesets/patches/imagemagick_configure_pango.patch
@@ -0,0 +1,18 @@
+Recently a new issue manifested out of thin air: linking to pango fails with
+missing symbols like '_g_object_unref'. Pango requires '-lgobject-2.0',
+but this does not appear in the linker flags (check invocation with
+'make V=1'). Easiest way for a quick & dirty fix is to configure with
+PANGO_LIBS set accordingly, but the configure scripts deletes the setting
+although claiming to respect it. Therefore we patch the configure
+script first.
+--- a/configure
++++ b/configure
+@@ -31889,7 +31889,7 @@
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+- pkg_cv_PANGO_LIBS=`$PKG_CONFIG --libs "pangocairo >= 1.28.1" 2>/dev/null`
++ pkg_cv_PANGO_LIBS="$($PKG_CONFIG --libs pangocairo) -lgobject-2.0"
+ test "x$?" != "x0" && pkg_failed=yes
+ else
+ pkg_failed=yes
diff --git a/packaging/macos/modulesets/patches/itstool-config-python.patch b/packaging/macos/modulesets/patches/itstool-config-python.patch
new file mode 100644
index 0000000..592c37a
--- /dev/null
+++ b/packaging/macos/modulesets/patches/itstool-config-python.patch
@@ -0,0 +1,14 @@
+diff -c /Users/john/configure\~ /Users/john/configure
+--- a/configure Wed Jul 31 13:57:01 2019
++++ b/configure Wed Jul 31 13:57:39 2019
+@@ -2377,7 +2377,7 @@
+ $as_echo_n "(cached) " >&6
+ else
+
+- for am_cv_pathless_PYTHON in python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
++ for am_cv_pathless_PYTHON in python3 python2 python python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
+ test "$am_cv_pathless_PYTHON" = none && break
+ prog="import sys
+ # split strings by '.' and convert to numeric. Append some zeros
+
+Diff finished. Wed Jul 31 13:57:51 2019
diff --git a/packaging/macos/modulesets/patches/libtasn1-inline-fix.patch b/packaging/macos/modulesets/patches/libtasn1-inline-fix.patch
new file mode 100644
index 0000000..10160ab
--- /dev/null
+++ b/packaging/macos/modulesets/patches/libtasn1-inline-fix.patch
@@ -0,0 +1,10 @@
+--- a/lib/parser_aux.c 2021-05-13 08:59:58.000000000 -0700
++++ b/lib/parser_aux.c 2021-08-03 10:25:36.000000000 -0700
+@@ -20,8 +20,9 @@
+ */
+
+ #include <limits.h> // WORD_BIT
++#define _GL_EXTERN_INLINE_STDHEADER_BUG
+
+ #include "int.h"
+ #include "parser_aux.h"
diff --git a/packaging/macos/modulesets/patches/libxml2-python-config.patch b/packaging/macos/modulesets/patches/libxml2-python-config.patch
new file mode 100644
index 0000000..6844fec
--- /dev/null
+++ b/packaging/macos/modulesets/patches/libxml2-python-config.patch
@@ -0,0 +1,23 @@
+--- a/configure.ac 2021-05-13 11:44:23.000000000 -0700
++++ b/configure.ac 2021-11-08 11:13:54.000000000 -0800
+@@ -905,7 +905,17 @@
+ fi
+ fi
+ pythondir='$(PYTHON_SITE_PACKAGES)'
+- PYTHON_LIBS=`python$PYTHON_VERSION-config --ldflags`
++ py_ver_major=$(echo $PYTHON_VERSION | cut -d . -f 1)
++ py_ver_minor=$(echo $PYTHON_VERSION | cut -d . -f 2)
++ if test $py_ver_major -eq 3 -a $py_ver_minor -ge 8
++ then
++ PYTHON_LIBS=`python$PYTHON_VERSION-config --ldflags --embed`
++ elif test $py_ver_major -gt 3
++ then
++ PYTHON_LIBS=`python$PYTHON_VERSION-config --ldflags --embed`
++ else
++ PYTHON_LIBS=`python$PYTHON_VERSION-config --ldflags`
++ fi
+ else
+ PYTHON=
+ fi
+
+Diff finished. Mon Nov 8 11:28:35 2021
diff --git a/packaging/macos/modulesets/patches/pango-coretext-fix-clang-build-failure.patch b/packaging/macos/modulesets/patches/pango-coretext-fix-clang-build-failure.patch
new file mode 100644
index 0000000..8476d50
--- /dev/null
+++ b/packaging/macos/modulesets/patches/pango-coretext-fix-clang-build-failure.patch
@@ -0,0 +1,30 @@
+From 9093ffd69850b630622a3fc8dcf09c45c51ae2f9 Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls@ceridwen.us>
+Date: Tue, 22 Mar 2022 12:09:09 -0700
+Subject: [PATCH] Coretext: fix clang build failure.
+
+Recent versions of clang notice that pango_core_text_fontset_load_font's
+`key` local variable isn't used and errors out. Remove it.
+---
+ pango/pangocoretext-fontmap.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/pango/pangocoretext-fontmap.c b/pango/pangocoretext-fontmap.c
+index 40e62eed..e090bfc4 100644
+--- a/pango/pangocoretext-fontmap.c
++++ b/pango/pangocoretext-fontmap.c
+@@ -1696,11 +1696,8 @@ static PangoFont *
+ pango_core_text_fontset_load_font (PangoCoreTextFontset *ctfontset,
+ CTFontDescriptorRef ctdescriptor)
+ {
+- PangoCoreTextFontsetKey *key;
+ PangoCoreTextFont *font;
+
+- key = pango_core_text_fontset_get_key (ctfontset);
+-
+ /* For now, we will default the fallbacks to not have synthetic italic,
+ * in the future this may be improved.
+ */
+--
+2.32.0 (Apple Git-132)
+
diff --git a/packaging/macos/modulesets/patches/rust_cmake_install.patch b/packaging/macos/modulesets/patches/rust_cmake_install.patch
new file mode 100644
index 0000000..b1025cd
--- /dev/null
+++ b/packaging/macos/modulesets/patches/rust_cmake_install.patch
@@ -0,0 +1,27 @@
+--- a/CMakeLists.txt 2020-11-29 02:35:19.000000000 +0100
++++ b/CMakeLists.txt 2020-11-29 02:35:44.000000000 +0100
+@@ -0,0 +1,24 @@
++# This is a wrapper to install Rust via cmake. Its only purpose is to supply an
++# interface that can be used from JHBuild.
++#
++# usage:
++# cmake -DVERSION=<Rust version>
++# make install
++
++cmake_minimum_required(VERSION 3.1)
++project(rust)
++
++add_custom_command(OUTPUT rust
++ # use bash so we can supply environment variables to rustup-init.sh
++ COMMAND bash "-c" "RUSTUP_HOME=${CMAKE_INSTALL_PREFIX}/home/.rustup CARGO_HOME=${CMAKE_INSTALL_PREFIX}/home/.cargo ${CMAKE_CURRENT_SOURCE_DIR}/rustup-init.sh -y --no-modify-path --profile minimal"
++ COMMAND bash "-c" "${CMAKE_INSTALL_PREFIX}/home/.cargo/bin/rustup toolchain install ${VERSION}"
++ COMMAND bash "-c" "${CMAKE_INSTALL_PREFIX}/home/.cargo/bin/rustup default ${VERSION}"
++ COMMAND bash "-c" "${CMAKE_INSTALL_PREFIX}/home/.cargo/bin/rustup toolchain remove stable"
++)
++
++add_custom_target(
++ install_rust ALL
++ DEPENDS rust
++)
++
++install(DIRECTORY ${CMAKE_INSTALL_PREFIX}/home/.cargo/bin/ DESTINATION bin USE_SOURCE_PERMISSIONS)
diff --git a/packaging/macos/modulesets/patches/shared-mime-info-2.1-freedesktop-generate.patch b/packaging/macos/modulesets/patches/shared-mime-info-2.1-freedesktop-generate.patch
new file mode 100644
index 0000000..d058eda
--- /dev/null
+++ b/packaging/macos/modulesets/patches/shared-mime-info-2.1-freedesktop-generate.patch
@@ -0,0 +1,27 @@
+--- a/data/freedesktop_generate.sh 2020-12-31 11:12:16.000000000 -0800
++++ b/data/freedesktop_generate.sh 2021-11-07 13:50:19.000000000 -0800
+@@ -3,10 +3,17 @@
+ src_root="$1"
+ build_root="$2"
+
+-ninja -C "${build_root}" shared-mime-info-gmo
+-
+-itstool \
+- --its "${src_root}/data/its/shared-mime-info.its" \
+- --join "${src_root}/data/freedesktop.org.xml.in" \
+- -o "${build_root}/data/freedesktop.org.xml" \
+- "${build_root}/po/"*".gmo"
++if test ! -d "${build_root}/po/de"; then
++ ninja -C "${build_root}" shared-mime-info-gmo
++ itstool \
++ --its "${src_root}/data/its/shared-mime-info.its" \
++ --join "${src_root}/data/freedesktop.org.xml.in" \
++ -o "${build_root}/data/freedesktop.org.xml" \
++ "${build_root}/po/"*".gmo"
++else
++ itstool \
++ --its "${src_root}/data/its/shared-mime-info.its" \
++ --join "${src_root}/data/freedesktop.org.xml.in" \
++ -o "${build_root}/data/freedesktop.org.xml" \
++ "${build_root}/po/"*"/LC_MESSAGES/shared-mime-info.mo"
++fi
diff --git a/packaging/macos/modulesets/patches/tiff-nohtml.patch b/packaging/macos/modulesets/patches/tiff-nohtml.patch
new file mode 100644
index 0000000..0368fb0
--- /dev/null
+++ b/packaging/macos/modulesets/patches/tiff-nohtml.patch
@@ -0,0 +1,44 @@
+--- a/configure 2017-05-22 01:49:37.000000000 +0700
++++ b/configure 2017-06-12 02:37:01.000000000 +0700
+@@ -20927,7 +20927,7 @@
+ ac_config_headers="$ac_config_headers libtiff/tif_config.h libtiff/tiffconf.h"
+
+
+-ac_config_files="$ac_config_files Makefile build/Makefile contrib/Makefile contrib/addtiffo/Makefile contrib/dbs/Makefile contrib/dbs/xtiff/Makefile contrib/iptcutil/Makefile contrib/mfs/Makefile contrib/pds/Makefile contrib/ras/Makefile contrib/stream/Makefile contrib/tags/Makefile contrib/win_dib/Makefile html/Makefile html/images/Makefile html/man/Makefile libtiff-4.pc libtiff/Makefile man/Makefile port/Makefile test/Makefile tools/Makefile"
++ac_config_files="$ac_config_files Makefile build/Makefile contrib/Makefile contrib/addtiffo/Makefile contrib/dbs/Makefile contrib/dbs/xtiff/Makefile contrib/iptcutil/Makefile contrib/mfs/Makefile contrib/pds/Makefile contrib/ras/Makefile contrib/stream/Makefile contrib/tags/Makefile contrib/win_dib/Makefile libtiff-4.pc libtiff/Makefile man/Makefile port/Makefile test/Makefile tools/Makefile"
+
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+@@ -22095,9 +22095,6 @@
+ "contrib/stream/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/stream/Makefile" ;;
+ "contrib/tags/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/tags/Makefile" ;;
+ "contrib/win_dib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/win_dib/Makefile" ;;
+- "html/Makefile") CONFIG_FILES="$CONFIG_FILES html/Makefile" ;;
+- "html/images/Makefile") CONFIG_FILES="$CONFIG_FILES html/images/Makefile" ;;
+- "html/man/Makefile") CONFIG_FILES="$CONFIG_FILES html/man/Makefile" ;;
+ "libtiff-4.pc") CONFIG_FILES="$CONFIG_FILES libtiff-4.pc" ;;
+ "libtiff/Makefile") CONFIG_FILES="$CONFIG_FILES libtiff/Makefile" ;;
+ "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+--- a/Makefile.in 2017-05-22 01:49:35.000000000 +0700
++++ b/Makefile.in 2017-06-12 02:47:22.000000000 +0700
+@@ -436,7 +436,7 @@
+ nmake.opt
+
+ dist_doc_DATA = $(docfiles)
+-SUBDIRS = port libtiff tools build contrib test man html
++SUBDIRS = port libtiff tools build contrib test man
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = libtiff-4.pc
+
+--- a/Makefile.am 2015-09-07 02:30:46.000000000 +0700
++++ b/Makefile.am 2017-06-12 02:46:47.000000000 +0700
+@@ -61,7 +61,7 @@
+ rm -rf $(distdir)/_build/cmake
+ rm -rf $(distdir)/_inst/cmake
+
+-SUBDIRS = port libtiff tools build contrib test man html
++SUBDIRS = port libtiff tools build contrib test man
+
+ release:
+ (rm -f $(top_srcdir)/RELEASE-DATE && echo $(LIBTIFF_RELEASE_DATE) > $(top_srcdir)/RELEASE-DATE)
+
diff --git a/packaging/macos/modulesets/patches/xmlto-allow-net-access.patch b/packaging/macos/modulesets/patches/xmlto-allow-net-access.patch
new file mode 100644
index 0000000..a4f1280
--- /dev/null
+++ b/packaging/macos/modulesets/patches/xmlto-allow-net-access.patch
@@ -0,0 +1,27 @@
+diff -u /Users/john/Development/gtk-build/gtk-stable-10.13-x86_64/src/xmlto-0.0.28/xmlto.in\~ /Users/john/Development/gtk-build/gtk-stable-10.13-x86_64/src/xmlto-0.0.28/xmlto.in
+--- a/xmlto.in 2015-11-16 06:07:10.000000000 -0800
++++ b/xmlto.in 2021-04-10 13:33:24.000000000 -0700
+@@ -225,7 +225,7 @@
+ export VERBOSE
+
+ # Disable network entities
+-XSLTOPTS="$XSLTOPTS --nonet"
++XSLTOPTS="$XSLTOPTS"
+
+ # The names parameter for the XSLT stylesheet
+ XSLTPARAMS=""
+@@ -542,10 +542,10 @@
+
+ [ "$VERBOSE" -ge 1 ] && \
+ echo >&2 \
+- "\"${XMLLINT_PATH}\" --noout --nonet --xinclude --postvalid --noent ${SEARCHPATH_FORMATTED} \"${INPUT_FILE}\""
++ "\"${XMLLINT_PATH}\" --noout --xinclude --postvalid --noent ${SEARCHPATH_FORMATTED} \"${INPUT_FILE}\""
+ # eval is for SEARCHPATH_FORMATTED's proper expansion
+ # make sure expansions are protected from eval
+- eval "\"${XMLLINT_PATH}\" --noout --nonet --xinclude --postvalid --noent ${SEARCHPATH_FORMATTED} \"${INPUT_FILE}\"" 2>"${VALIDATION}"
++ eval "\"${XMLLINT_PATH}\" --noout --xinclude --postvalid --noent ${SEARCHPATH_FORMATTED} \"${INPUT_FILE}\"" 2>"${VALIDATION}"
+ xmllint_status=$?
+
+ if [ $xmllint_status -ne 0 ]
+
+Diff finished. Sat Apr 10 13:33:31 2021
diff --git a/packaging/macos/res/Inkscape-Generic.icns b/packaging/macos/res/Inkscape-Generic.icns
new file mode 100644
index 0000000..9843be9
--- /dev/null
+++ b/packaging/macos/res/Inkscape-Generic.icns
Binary files differ
diff --git a/packaging/macos/res/application-gimp-gradient.icns b/packaging/macos/res/application-gimp-gradient.icns
new file mode 100644
index 0000000..ebd4b2a
--- /dev/null
+++ b/packaging/macos/res/application-gimp-gradient.icns
Binary files differ
diff --git a/packaging/macos/res/application-illustrator-svg.icns b/packaging/macos/res/application-illustrator-svg.icns
new file mode 100644
index 0000000..b666dcc
--- /dev/null
+++ b/packaging/macos/res/application-illustrator-svg.icns
Binary files differ
diff --git a/packaging/macos/res/application-illustrator.icns b/packaging/macos/res/application-illustrator.icns
new file mode 100644
index 0000000..c44d465
--- /dev/null
+++ b/packaging/macos/res/application-illustrator.icns
Binary files differ
diff --git a/packaging/macos/res/application-pdf.icns b/packaging/macos/res/application-pdf.icns
new file mode 100644
index 0000000..1eb670f
--- /dev/null
+++ b/packaging/macos/res/application-pdf.icns
Binary files differ
diff --git a/packaging/macos/res/application-vnd.corel-draw-compressed.icns b/packaging/macos/res/application-vnd.corel-draw-compressed.icns
new file mode 100644
index 0000000..ad5dad9
--- /dev/null
+++ b/packaging/macos/res/application-vnd.corel-draw-compressed.icns
Binary files differ
diff --git a/packaging/macos/res/application-vnd.corel-draw-template.icns b/packaging/macos/res/application-vnd.corel-draw-template.icns
new file mode 100644
index 0000000..475c3fc
--- /dev/null
+++ b/packaging/macos/res/application-vnd.corel-draw-template.icns
Binary files differ
diff --git a/packaging/macos/res/application-vnd.corel-draw.icns b/packaging/macos/res/application-vnd.corel-draw.icns
new file mode 100644
index 0000000..5907b7e
--- /dev/null
+++ b/packaging/macos/res/application-vnd.corel-draw.icns
Binary files differ
diff --git a/packaging/macos/res/application-vnd.ms.xaml.icns b/packaging/macos/res/application-vnd.ms.xaml.icns
new file mode 100644
index 0000000..6a44b4a
--- /dev/null
+++ b/packaging/macos/res/application-vnd.ms.xaml.icns
Binary files differ
diff --git a/packaging/macos/res/application-vnd.wordperfect-graphic.icns b/packaging/macos/res/application-vnd.wordperfect-graphic.icns
new file mode 100644
index 0000000..9ee4993
--- /dev/null
+++ b/packaging/macos/res/application-vnd.wordperfect-graphic.icns
Binary files differ
diff --git a/packaging/macos/res/fonts.conf b/packaging/macos/res/fonts.conf
new file mode 100644
index 0000000..f6f6583
--- /dev/null
+++ b/packaging/macos/res/fonts.conf
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- Inkscape.app/Contents/Resources/etc/fonts/fonts.conf file to configure system font access -->
+<fontconfig>
+ <its:rules xmlns:its="http://www.w3.org/2005/11/its" version="1.0">
+ <its:translateRule translate="no" selector="/fontconfig/*[not(self::description)]"/>
+ </its:rules>
+
+ <description>Default configuration file</description>
+
+ <!--
+ Usually you'll find the "DO NOT EDIT THIS FILE" warning here.
+ I removed it since I clearly edited this file. I removed the
+ non-macOS paths and configured the cachedir.
+ -->
+
+ <!-- Font directory list -->
+ <dir>/System/Library/Fonts</dir>
+ <dir>/Library/Fonts</dir>
+ <dir>~/Library/Fonts</dir>
+
+ <!-- Accept deprecated 'mono' alias, replacing it with 'monospace' -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>monospace</string>
+ </edit>
+ </match>
+
+ <!-- Accept alternate 'sans serif' spelling, replacing it with 'sans-serif' -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+ <!-- Accept deprecated 'sans' alias, replacing it with 'sans-serif' -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+ <!-- Load local system customization file -->
+ <include ignore_missing="yes">conf.d</include>
+
+ <!-- Font cache directory list
+ TODO: this should probably go below ~/Library/Caches
+ -->
+ <cachedir>~/Library/Application Support/org.inkscape.Inkscape/cache/fontconfig</cachedir>
+
+ <config>
+ <rescan>
+ <!-- Rescan configuration every 30 seconds when FcFontSetList is called -->
+ <int>30</int>
+ </rescan>
+ </config>
+
+</fontconfig>
diff --git a/packaging/macos/res/image-svg+xml-compressed.icns b/packaging/macos/res/image-svg+xml-compressed.icns
new file mode 100644
index 0000000..7d24206
--- /dev/null
+++ b/packaging/macos/res/image-svg+xml-compressed.icns
Binary files differ
diff --git a/packaging/macos/res/image-svg+xml.icns b/packaging/macos/res/image-svg+xml.icns
new file mode 100644
index 0000000..6341984
--- /dev/null
+++ b/packaging/macos/res/image-svg+xml.icns
Binary files differ
diff --git a/packaging/macos/res/image-vnd.dxf.icns b/packaging/macos/res/image-vnd.dxf.icns
new file mode 100644
index 0000000..3b18609
--- /dev/null
+++ b/packaging/macos/res/image-vnd.dxf.icns
Binary files differ
diff --git a/packaging/macos/res/image-vnd.windows-metafile.icns b/packaging/macos/res/image-vnd.windows-metafile.icns
new file mode 100644
index 0000000..fb0bfa9
--- /dev/null
+++ b/packaging/macos/res/image-vnd.windows-metafile.icns
Binary files differ
diff --git a/packaging/macos/res/inkscape.plist b/packaging/macos/res/inkscape.plist
new file mode 100644
index 0000000..9667c23
--- /dev/null
+++ b/packaging/macos/res/inkscape.plist
@@ -0,0 +1,485 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>ATSApplicationFontsPath</key>
+ <string>share/inkscape/fonts</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>svg</string>
+ <string>SVG</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>image-svg+xml.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/svg+xml</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Scalable Vector Graphics Image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>SVG </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Owner</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>svgz</string>
+ <string>SVGZ</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>image-svg+xml-compressed.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/svg+xml-compressed</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Compressed Scalable Vector Graphics Image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>SVGZ</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Owner</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>ai</string>
+ <string>AI</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-illustrator.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/illustrator</string>
+ <string>application/pdf</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Adobe Illustrator Document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>AI </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>com.adobe.illustrator.ai-image</string>
+ </array>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>aisvg</string>
+ <string>AISVG</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-illustrator-svg.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/illustrator-svg</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Adobe Illustrator SVG Document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>AISVG</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>wmf</string>
+ <string>WMF</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>image-vnd.windows-metafile.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/vnd.windows-metafile</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Windows MetaFile</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>WMF </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>pdf</string>
+ <string>PDF</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-pdf.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/pdf</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>NSPDFPboardType</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>PDF </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>com.adobe.pdf</string>
+ </array>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>ggr</string>
+ <string>GGR</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-gimp-gradient.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/x-gimp-gradient</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Gimp Gradient</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>org.gimp.ggr</string>
+ </array>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>ccx</string>
+ <string>CCX</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-vnd.corel-draw-compressed.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.corel-draw-compressed</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Corel Draw Compressed Document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>CCX </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>cdt</string>
+ <string>CDT</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-vnd.corel-draw-template.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.corel-draw-template</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Corel Draw Template</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>CDT </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>cdr</string>
+ <string>CDR</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-vnd.corel-draw.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.corel-draw</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Corel Draw Compressed Document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>CDR </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>xaml</string>
+ <string>XAML</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-vnd.ms.xaml.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.ms.xaml</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Extensible Application Markup Language (XAML)</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>XAML</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>dxf</string>
+ <string>DXF</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>image-vnd.dxf.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/vnd.dxf</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>AutoCAD Document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>DXF </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>wpg</string>
+ <string>WPG</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>application-vnd.wordperfect-graphic.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.wordperfect-graphic</string>
+ <string>image/x-wpg</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>WordPerfect Graphics</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>WPG </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>emf</string>
+ <string>EMF</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>Inkscape-Generic.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/emf</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Windows Enhanced Metafile document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>EMF </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>vsd</string>
+ <string>VSD</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>Inkscape-Generic.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.visio</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Microsoft Visio Diagram</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>vdx</string>
+ <string>VDX</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>Inkscape-Generic.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.visio</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Microsoft Visio XML Diagram</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>vsdm</string>
+ <string>VSDM</string>
+ <string>vsdx</string>
+ <string>VSDX</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>Inkscape-Generic.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.visio</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Microsoft Visio 2013 drawing</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>plt</string>
+ <string>PLT</string>
+ <string>hpgl</string>
+ <string>hpgl</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>Inkscape-Generic.icons</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/vnd.hp-HPGL</string>
+ <string>image/hpgl</string>
+ <string>image/plt</string>
+ <string>image/x-plt</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>HP Graphics Language file</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>png</string>
+ <string>PNG</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>Inkscape-Generic.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/png</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Portable Network Graphics Image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>PNGf</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSHandlerRank</key>
+ <string>None</string>
+ </dict>
+ </array>
+ <key>CFBundleExecutable</key>
+ <string>inkscape</string>
+ <key>CFBundleName</key>
+ <string>Inkscape</string>
+ <key>CFBundleIconFile</key>
+ <string>inkscape.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.inkscape.Inkscape</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>CFBundleShortVersionString</string>
+ <key>CFBundleSignature</key>
+ <string>Inks</string>
+ <key>CFBundleVersion</key>
+ <string>CFBundleVersion</string>
+ <key>LSApplicationCategoryType</key>
+ <string>public.app-category.graphics-design</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>LSMinimumSystemVersion</string>
+ <key>NSDesktopFolderUsageDescription</key>
+ <string>Inkscape needs your permission to access the Desktop folder.</string>
+ <key>NSDocumentsFolderUsageDescription</key>
+ <string>Inkscape needs your permission to access the Documents folder.</string>
+ <key>NSDownloadsFolderUsageDescription</key>
+ <string>Inkscape needs your permission to access the Downloads folder.</string>
+ <key>NSRemoveableVolumesUsageDescription</key>
+ <string>Inkscape needs your permission to access removable volumes.</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2022 Inkscape Developers, GNU General Public License.</string>
+ <key>NSRequiresAquaSystemAppearance</key>
+ <false/>
+ </dict>
+</plist>
diff --git a/packaging/macos/res/mibap_icon.png b/packaging/macos/res/mibap_icon.png
new file mode 100644
index 0000000..2ea6521
--- /dev/null
+++ b/packaging/macos/res/mibap_icon.png
Binary files differ
diff --git a/packaging/macos/src/cairosvg.sh b/packaging/macos/src/cairosvg.sh
new file mode 100644
index 0000000..bcd2aa6
--- /dev/null
+++ b/packaging/macos/src/cairosvg.sh
@@ -0,0 +1,38 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# cairosvg is a Python package so we can convert svg to png.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+# https://cairocffi.readthedocs.io/en/stable/
+# https://github.com/Kozea/cairocffi
+# https://cairosvg.org
+# https://github.com/Kozea/CairoSVG
+CAIROSVG_PIP="\
+ cairocffi==1.2.0\
+ cairosvg==2.5.2\
+"
+
+### functions ##################################################################
+
+function cairosvg_install
+{
+ # shellcheck disable=SC2086 # we need word splitting here
+ jhb run pip3 install $CAIROSVG_PIP
+}
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/src/ink.sh b/packaging/macos/src/ink.sh
new file mode 100644
index 0000000..fe4d19c
--- /dev/null
+++ b/packaging/macos/src/ink.sh
@@ -0,0 +1,329 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# This file contains everything related to Inkscape.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+# shellcheck disable=SC2034 # multipe vars only used outside this script
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+#----------------------------------------------- source directory and git branch
+
+# There are 3 possible scenarios:
+#
+# 1. We're running inside Inkscape's CI:
+# The repository has already been cloned, set INK_DIR accordingly.
+#
+# 2. We're not running inside Inkscape's CI and INK_DIR has been set:
+# Use INK_DIR provided as-is, we expect the source to be there.
+#
+# 3. We're not running inside Inkscape's CI CI and INK_DIR has not been set:
+# Set INK_DIR to our default location, we'll clone the repo there.
+
+if [ "$CI_PROJECT_NAME" = "inkscape" ]; then # running in Inkscape's CI
+ INK_DIR=$CI_PROJECT_DIR
+else # not running in Inkscape's CI
+ # Use default directory if not provided.
+ if [ -z "$INK_DIR" ]; then
+ INK_DIR=$SRC_DIR/inkscape
+ fi
+
+ # Allow using a custom Inkscape repository and branch.
+ if [ -z "$INK_URL" ]; then
+ INK_URL=https://gitlab.com/inkscape/inkscape
+ fi
+
+ # Allow using a custom branch.
+ if [ -z "$INK_BRANCH" ]; then
+ INK_BRANCH=1.2.x
+ fi
+fi
+
+INK_BLD_DIR=$BLD_DIR/$(basename "$INK_DIR") # we build out-of-tree
+
+#------------------------------------------------------------------ build number
+
+INK_BUILD=${INK_BUILD:-0}
+
+#------------------------------------ Python runtime to be bundled with Inkscape
+
+# Inkscape will be bundled with its own (customized) Python 3 runtime to make
+# the core extensions work out-of-the-box.
+
+INK_PYTHON_VER_MAJOR=3
+INK_PYTHON_VER_MINOR=10
+INK_PYTHON_VER=$INK_PYTHON_VER_MAJOR.$INK_PYTHON_VER_MINOR
+INK_PYTHON_URL="https://gitlab.com/api/v4/projects/26780227/packages/generic/\
+python_macos/15/python_${INK_PYTHON_VER/./}_$(uname -m)_inkscape.tar.xz"
+INK_PYTHON_ICON_URL="https://gitlab.com/inkscape/vectors/content/-/raw/\
+5f4f4cdf/branding/projects/extensions_c1.svg"
+
+#----------------------------------- Python packages to be bundled with Inkscape
+
+# https://pypi.org/project/appdirs/
+INK_PYTHON_PKG_APPDIRS=appdirs==1.4.4
+
+# https://pypi.org/project/beautifulsoup4/
+# https://pypi.org/project/soupsieve/
+INK_PYTHON_PKG_BEAUTIFULSOUP4="\
+ beautifulsoup4==4.10.0\
+ soupsieve==2.3.1\
+"
+
+# https://pypi.org/project/CacheControl/
+# https://pypi.org/project/certifi/
+# https://pypi.org/project/charset-normalizer/
+# https://pypi.org/project/idna/
+# https://pypi.org/project/lockfile/
+# https://pypi.org/project/msgpack/
+# https://pypi.org/project/requests/
+# https://pypi.org/project/urllib3/
+INK_PYTHON_PKG_CACHECONTROL="\
+ CacheControl==0.12.10\
+ certifi==2021.10.8\
+ charset_normalizer==2.0.11\
+ idna==3.3\
+ lockfile==0.12.2\
+ msgpack==1.0.3\
+ requests==2.27.1\
+ urllib3==1.26.8\
+"
+
+# https://pypi.org/project/cssselect/
+INK_PYTHON_PKG_CSSSELECT=cssselect==1.1.0
+
+# https://pypi.org/project/lxml/
+INK_PYTHON_PKG_LXML=lxml==4.7.1
+
+# https://pypi.org/project/numpy/
+INK_PYTHON_PKG_NUMPY=https://files.pythonhosted.org/packages/\
+b4/85/8097082c4794d854e40f84639c83e33e516431faaeb9cecba39eba6921d5/\
+numpy-1.22.1-cp310-cp310-macosx_10_9_universal2.whl
+
+# https://pypi.org/project/Pillow/
+INK_PYTHON_PKG_PILLOW=Pillow==9.0.0
+
+# https://pypi.org/project/pycairo/
+# https://pypi.org/project/PyGObject/
+INK_PYTHON_PKG_PYGOBJECT="\
+ PyGObject==3.42.1\
+ pycairo==1.21.0\
+"
+
+# https://pypi.org/project/pyserial/
+INK_PYTHON_PKG_PYSERIAL=pyserial==3.5
+
+# https://pypi.org/project/scour/
+# https://pypi.org/project/six/
+INK_PYTHON_PKG_SCOUR="\
+ scour==0.38.2\
+ six==1.16.0\
+ packaging==21.3 \
+ pyparsing==3.0.7 \
+"
+
+#------------------------------------------- application bundle directory layout
+
+INK_APP_DIR=$ARTIFACT_DIR/Inkscape.app
+
+INK_APP_CON_DIR=$INK_APP_DIR/Contents
+INK_APP_RES_DIR=$INK_APP_CON_DIR/Resources
+INK_APP_FRA_DIR=$INK_APP_CON_DIR/Frameworks
+INK_APP_BIN_DIR=$INK_APP_RES_DIR/bin
+INK_APP_ETC_DIR=$INK_APP_RES_DIR/etc
+INK_APP_EXE_DIR=$INK_APP_CON_DIR/MacOS
+INK_APP_LIB_DIR=$INK_APP_RES_DIR/lib
+INK_APP_SPK_DIR=$INK_APP_LIB_DIR/python$INK_PYTHON_VER/site-packages
+
+INK_APP_PLIST=$INK_APP_CON_DIR/Info.plist
+
+### functions ##################################################################
+
+function ink_get_version
+{
+ local file=$INK_DIR/CMakeLists.txt
+ local ver_major
+ ver_major=$(grep INKSCAPE_VERSION_MAJOR "$file" | head -n 1 |
+ awk '{ print $2+0 }')
+ local ver_minor
+ ver_minor=$(grep INKSCAPE_VERSION_MINOR "$file" | head -n 1 |
+ awk '{ print $2+0 }')
+ local ver_patch
+ ver_patch=$(grep INKSCAPE_VERSION_PATCH "$file" | head -n 1 |
+ awk '{ print $2+0 }')
+ local ver_suffix
+ ver_suffix=$(grep INKSCAPE_VERSION_SUFFIX "$file" | head -n 1 |
+ awk '{ print $2 }')
+
+ ver_suffix=${ver_suffix%\"*} # remove "double quotes and all" from end
+ ver_suffix=${ver_suffix#\"} # remove "double quote" from beginning
+
+ echo "$ver_major.$ver_minor.$ver_patch$ver_suffix"
+}
+
+function ink_get_repo_shorthash
+{
+ # do it the same way as in CMakeScripts/inkscape-version.cmake
+ git -C "$INK_DIR" rev-parse --short HEAD
+}
+
+function ink_pipinstall
+{
+ local packages=$1 # name of variable that resolves to list of packages
+ local options=$2 # optional
+
+ # turn package names into filenames of our wheels
+ local wheels
+ for package in $(eval echo \$"$packages"); do
+ if [ "${package::8}" = "https://" ]; then
+ package=$(basename "$package")
+ else
+ package=$(eval echo "${package/==/-}"*.whl)
+ fi
+
+ # If present in TMP_DIR, use that. This is how the externally built
+ # packages can be fed into this.
+ if [ -f "$TMP_DIR/$package" ]; then
+ wheels="$wheels $TMP_DIR/$package"
+ else
+ wheels="$wheels $PKG_DIR/$package"
+ fi
+ done
+
+ local path_original=$PATH
+ export PATH=$INK_APP_FRA_DIR/Python.framework/Versions/Current/bin:$PATH
+
+ # shellcheck disable=SC2086 # we need word splitting here
+ pip$INK_PYTHON_VER_MAJOR install \
+ --prefix "$INK_APP_RES_DIR" \
+ --ignore-installed \
+ $options \
+ $wheels
+
+ export PATH=$path_original
+
+ local ink_pipinstall_func
+ ink_pipinstall_func=ink_pipinstall_$(echo "${packages##*_}" |
+ tr "[:upper:]" "[:lower:]")
+
+ if declare -F "$ink_pipinstall_func" > /dev/null; then
+ $ink_pipinstall_func
+ fi
+}
+
+function ink_pipinstall_lxml
+{
+ lib_change_paths \
+ @loader_path/../../.. \
+ "$INK_APP_LIB_DIR" \
+ "$INK_APP_SPK_DIR"/lxml/etree.cpython-"${INK_PYTHON_VER/./}"-darwin.so \
+ "$INK_APP_SPK_DIR"/lxml/objectify.cpython-"${INK_PYTHON_VER/./}"-darwin.so
+}
+
+function ink_pipinstall_numpy
+{
+ sed -i '' '1s|.*|#!/usr/bin/env python'"$INK_PYTHON_VER_MAJOR"'|' \
+ "$INK_APP_BIN_DIR"/f2py
+ sed -i '' '1s|.*|#!/usr/bin/env python'"$INK_PYTHON_VER_MAJOR"'|' \
+ "$INK_APP_BIN_DIR"/f2py$INK_PYTHON_VER_MAJOR
+ sed -i '' '1s|.*|#!/usr/bin/env python'"$INK_PYTHON_VER_MAJOR"'|' \
+ "$INK_APP_BIN_DIR"/f2py$INK_PYTHON_VER
+
+ find "$INK_APP_LIB_DIR/python$INK_PYTHON_VER/site-packages/numpy" \
+ '(' -name "*.so" -o -name "*.dylib" ')' \
+ -exec codesign --remove-signature {} \;
+
+ find "$INK_APP_LIB_DIR/python$INK_PYTHON_VER/site-packages/numpy" \
+ -name "*.a" -delete
+}
+
+function ink_pipinstall_pygobject
+{
+ lib_change_paths \
+ @loader_path/../../.. \
+ "$INK_APP_LIB_DIR" \
+ "$INK_APP_SPK_DIR"/gi/_gi.cpython-"${INK_PYTHON_VER/./}"-darwin.so \
+ "$INK_APP_SPK_DIR"/gi/_gi_cairo.cpython-"${INK_PYTHON_VER/./}"-darwin.so \
+ "$INK_APP_SPK_DIR"/cairo/_cairo.cpython-"${INK_PYTHON_VER/./}"-darwin.so
+}
+
+function ink_pipinstall_pyserial
+{
+ find "$INK_APP_SPK_DIR"/serial -type f -name "*.pyc" -exec rm {} \;
+ sed -i '' '1s|.*|#!/usr/bin/env python3|' \
+ "$INK_APP_BIN_DIR"/pyserial-miniterm
+ sed -i '' '1s|.*|#!/usr/bin/env python3|' "$INK_APP_BIN_DIR"/pyserial-ports
+}
+
+function ink_pipinstall_scour
+{
+ sed -i '' '1s|.*|#!/usr/bin/env python3|' "$INK_APP_BIN_DIR"/scour
+}
+
+function ink_download_python
+{
+ curl -o "$PKG_DIR"/"$(basename "${INK_PYTHON_URL%\?*}")" -L "$INK_PYTHON_URL"
+ curl -o "$PKG_DIR"/"$(basename "$INK_PYTHON_ICON_URL")" \
+ -L "$INK_PYTHON_ICON_URL"
+}
+
+function ink_install_python
+{
+ mkdir "$INK_APP_FRA_DIR"
+ tar -C "$INK_APP_FRA_DIR" -xf "$PKG_DIR"/"$(basename "${INK_PYTHON_URL%\?*}")"
+
+ # link it to INK_APP_BIN_DIR so it'll be in PATH for the app
+ mkdir -p "$INK_APP_BIN_DIR"
+ # shellcheck disable=SC2086 # it's an integer
+ ln -sf ../../Frameworks/Python.framework/Versions/Current/bin/\
+python$INK_PYTHON_VER_MAJOR "$INK_APP_BIN_DIR"
+
+ # create '.pth' file inside Framework to include our site-packages directory
+ # shellcheck disable=SC2086 # it's an integer
+ echo "../../../../../../../Resources/lib/python$INK_PYTHON_VER/site-packages"\
+ > "$INK_APP_FRA_DIR"/Python.framework/Versions/Current/lib/\
+python$INK_PYTHON_VER/site-packages/inkscape.pth
+
+ # use custom icon for Python.app
+ svg2icns \
+ "$PKG_DIR/$(basename "$INK_PYTHON_ICON_URL")" \
+ "$INK_APP_FRA_DIR/Python.framework/Resources/Python.app/Contents/\
+Resources/PythonInterpreter.icns" \
+ 8
+}
+
+function ink_build_wheels
+{
+ jhb run pip3 install wheel
+
+ for package_set in ${!INK_PYTHON_PKG_*}; do
+ local packages
+ for package in $(eval echo \$"$package_set"); do
+ if [ "${package::8}" = "https://" ]; then
+ curl -L -o "$PKG_DIR/$(basename "$package")" "$package"
+ else
+ packages="$packages $package"
+ fi
+ done
+
+ if [ -n "$packages" ]; then
+ # shellcheck disable=SC2086 # we need word splitting here
+ jhb run pip3 wheel --no-binary :all: $packages -w "$PKG_DIR"
+ packages=""
+ fi
+ done
+}
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/src/inkscape.bundle b/packaging/macos/src/inkscape.bundle
new file mode 100644
index 0000000..892963b
--- /dev/null
+++ b/packaging/macos/src/inkscape.bundle
@@ -0,0 +1,181 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<app-bundle>
+
+ <meta>
+ <!-- Where to pick up the GTK+ installation, icon themes,
+ etc. Note that "${env:JHBUILD_PREFIX}" is evaluated to the
+ value of the environment variable JHBUILD_PREFIX. You can
+ define additional prefixes and refer to them in paths
+ throughout this file on the form "${prefix:name}". This is
+ useful for installing certain libraries or even the
+ application itself separately. Note that JHBUILD_PREFIX is
+ defined by jhbuild, so it you are not using jhbuild you can
+ either define your own or just hardcode the path here.
+ -->
+ <prefix name="default">${env:JHBUILD_PREFIX}</prefix>
+
+ <!-- The project directory is the default location of the created
+ app. If you leave out the path, the current directory is
+ used. Note the usage of an environment variable here again.
+ -->
+ <destination overwrite="yes">${env:ARTIFACT_DIR}</destination>
+
+ <image>
+ <!-- Not implemented yet (DMG image). -->
+ </image>
+
+ <!-- Comment this out to keep the install names in binaries -->
+ <run-install-name-tool/>
+
+ <!-- Optionally specify a launcher script to use. If the
+ application sets up everything needed itself, like
+ environment variable, linker paths, etc, a launcher script is
+ not needed. If the source path is left out, the default
+ script will be used.
+ <launcher-script>${project}/gtk3-launcher.sh</launcher-script >
+ -->
+
+ <!-- Not implemented: Optional runtime, could be python or mono
+ for example.
+ -->
+ <!-- runtime copy="yes">/usr/bin/python</runtime -->
+ <!-- Indicate the active gtk version to use. This is needed only
+ for gtk+-3.0 projects. -->
+ <gtk>gtk+-3.0</gtk>
+ </meta>
+
+ <!-- The special macro "${project}" refers to the directory where
+ this bundle file is located. The application name and bundle
+ identifier are taken from the plist file.
+ -->
+ <plist>${project}/inkscape.plist</plist>
+
+ <main-binary>${prefix}/bin/inkscape</main-binary>
+
+ <!-- Copy in the input methods. Dunno if they actually work with
+ OSX. Note the ${gtkdir} macro, which expands to the correct
+ library subdirectory for the specified gtk version. -->
+ <binary>
+ ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/*.so
+ </binary>
+
+<!-- And the print backends -->
+ <binary>
+ ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so
+ </binary>
+
+<!-- Starting with 2.24, gdk-pixbuf installs into its own directory. -->
+ <binary>
+ ${prefix}/lib/gdk-pixbuf-2.0/${pkg:gdk-pixbuf-2.0:gdk_pixbuf_binary_version}/loaders/*.so
+ </binary>
+
+<!-- No longer needed for pango >= 1.38
+ <binary>
+ ${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/
+ </binary>
+-->
+ <binary>
+ ${prefix}/lib/inkscape/libinkscape_base.dylib
+ </binary>
+ <binary>
+ ${prefix}/lib/libexslt.0.dylib
+ </binary>
+ <binary>
+ ${prefix}/lib/libssl.1.1.dylib
+ </binary>
+ <binary>
+ ${prefix}/lib/gio/modules/*.so
+ </binary>
+ <binary>
+ ${prefix}/lib/enchant-2/*.so
+ </binary>
+ <!-- Ghostscript (disable this for GPLv2+ compliance!) -->
+ <binary>
+ ${prefix}/bin/gs
+ </binary>
+ <data>
+ ${prefix}/share/ghostscript
+ </data>
+ <data>
+ ${prefix}/bin/ps2pdf*
+ </data>
+ <!-- GObject Introspection -->
+ <binary>
+ ${prefix}/lib/libgirepository-1.0.1.dylib
+ </binary>
+ <gir>
+ ${prefix}/share/gir-1.0/*.gir
+ </gir>
+ <!-- WebP Codec -->
+ <binary>
+ ${prefix}/lib/libwebp.7.dylib
+ </binary>
+ <binary>
+ ${prefix}/lib/libwebpmux.3.dylib
+ </binary>
+ <binary>
+ ${prefix}/lib/libwebpdemux.2.dylib
+ </binary>
+ <!-- Translation filenames, one for each program or library that you
+ want to copy in to the bundle. The "dest" attribute is
+ optional, as usual. Bundler will find all translations of that
+ library/program under the indicated directory and copy them.-->
+ <translations name="gdk-pixbuf">
+ ${prefix}/share/locale
+ </translations>
+ <translations name="gtk30">
+ ${prefix}/share/locale
+ </translations>
+ <translations name="gtk30-properties">
+ ${prefix}/share/locale
+ </translations>
+ <translations name="inkscape">
+ ${prefix}/share/locale
+ </translations>
+
+ <!-- Data to copy in, usually Glade/UI files, images, sounds files
+ etc. The destination inside the bundle can be specified if the
+ files should end up at a different location, by using the
+ "dest" property. The destination must then start with the macro
+ "${bundle}", which refers to the bundle root directory.
+ -->
+ <!-- data>
+ ${prefix}/share/gtk3-demo
+ </data -->
+
+ <data>
+ ${prefix}/etc/fonts
+ </data>
+ <data>
+ ${prefix}/share/enchant
+ </data>
+ <data>
+ ${prefix}/share/fontconfig
+ </data>
+ <data>
+ ${prefix}/share/glib-2.0
+ </data>
+ <data>
+ ${prefix}/share/icons
+ </data>
+ <data>
+ ${prefix}/share/ImageMagick-6
+ </data>
+ <data>
+ ${prefix}/share/inkscape
+ </data>
+ <!-- Copy in the themes data. You may want to trim this to save space
+ in your bundle. -->
+ <data>
+ ${prefix}/share/themes
+ </data>
+
+ <!-- Copy icons. Note that the .icns file is an Apple format which
+ contains up to 4 sizes of icon. You can use
+ /Developer/Applications/Utilities/Icon Composer.app to import
+ artwork and create the file. >
+ <data dest="${bundle}/Contents/Resources">
+ ${project}/Giggle.icns
+ </data -->
+
+ </app-bundle>
diff --git a/packaging/macos/src/inkscape_dmg.py b/packaging/macos/src/inkscape_dmg.py
new file mode 100644
index 0000000..8a51d8b
--- /dev/null
+++ b/packaging/macos/src/inkscape_dmg.py
@@ -0,0 +1,246 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+import biplist
+import os.path
+
+#
+# Example settings file for dmgbuild
+#
+
+# Use like this: dmgbuild -s settings.py "Test Volume" test.dmg
+
+# You can actually use this file for your own application (not just TextEdit)
+# by doing e.g.
+#
+# dmgbuild -s settings.py -D app=/path/to/My.app "My Application" MyApp.dmg
+
+# .. Useful stuff ..............................................................
+
+application = defines.get('app', 'PLACEHOLDERAPPLICATION')
+appname = os.path.basename(application)
+
+def icon_from_app(app_path):
+ plist_path = os.path.join(app_path, 'Contents', 'Info.plist')
+ plist = biplist.readPlist(plist_path)
+ icon_name = plist['CFBundleIconFile']
+ icon_root,icon_ext = os.path.splitext(icon_name)
+ if not icon_ext:
+ icon_ext = '.icns'
+ icon_name = icon_root + icon_ext
+ return os.path.join(app_path, 'Contents', 'Resources', icon_name)
+
+# .. Basics ....................................................................
+
+# Uncomment to override the output filename
+# filename = 'test.dmg'
+
+# Uncomment to override the output volume name
+# volume_name = 'Test'
+
+# Volume format (see hdiutil create -help)
+format = defines.get('format', 'UDBZ')
+
+# Volume size
+size = defines.get('size', None)
+
+# Files to include
+files = [ application ]
+
+# Symlinks to create
+#symlinks = { 'Applications': '/Applications' }
+
+# Volume icon
+#
+# You can either define icon, in which case that icon file will be copied to the
+# image, *or* you can define badge_icon, in which case the icon file you specify
+# will be used to badge the system's Removable Disk icon
+#
+#icon = 'PLACEHOLDERICON'
+badge_icon = icon_from_app(application)
+
+# Where to put the icons
+icon_locations = {
+ appname: (390, 240),
+# 'Applications': (500, 120)
+ }
+
+# .. Window configuration ......................................................
+
+# Background
+#
+# This is a STRING containing any of the following:
+#
+# #3344ff - web-style RGB color
+# #34f - web-style RGB color, short form (#34f == #3344ff)
+# rgb(1,0,0) - RGB color, each value is between 0 and 1
+# hsl(120,1,.5) - HSL (hue saturation lightness) color
+# hwb(300,0,0) - HWB (hue whiteness blackness) color
+# cmyk(0,1,0,0) - CMYK color
+# goldenrod - X11/SVG named color
+# builtin-arrow - A simple built-in background with a blue arrow
+# /foo/bar/baz.png - The path to an image file
+#
+# The hue component in hsl() and hwb() may include a unit; it defaults to
+# degrees ('deg'), but also supports radians ('rad') and gradians ('grad'
+# or 'gon').
+#
+# Other color components may be expressed either in the range 0 to 1, or
+# as percentages (e.g. 60% is equivalent to 0.6).
+background = 'PLACEHOLDERBACKGROUND'
+
+show_status_bar = False
+show_tab_view = False
+show_toolbar = False
+show_pathbar = False
+show_sidebar = False
+sidebar_width = 180
+
+# Window position in ((x, y), (w, h)) format
+window_rect = ((100, 100), (500, 380))
+
+# Select the default view; must be one of
+#
+# 'icon-view'
+# 'list-view'
+# 'column-view'
+# 'coverflow'
+#
+default_view = 'icon-view'
+
+# General view configuration
+show_icon_preview = False
+
+# Set these to True to force inclusion of icon/list view settings (otherwise
+# we only include settings for the default view)
+include_icon_view_settings = 'auto'
+include_list_view_settings = 'auto'
+
+# .. Icon view configuration ...................................................
+
+arrange_by = None
+grid_offset = (0, 0)
+grid_spacing = 100
+scroll_position = (0, 0)
+label_pos = 'bottom' # or 'right'
+text_size = 12
+icon_size = 64
+
+# .. List view configuration ...................................................
+
+# Column names are as follows:
+#
+# name
+# date-modified
+# date-created
+# date-added
+# date-last-opened
+# size
+# kind
+# label
+# version
+# comments
+#
+list_icon_size = 16
+list_text_size = 12
+list_scroll_position = (0, 0)
+list_sort_by = 'name'
+list_use_relative_dates = True
+list_calculate_all_sizes = False,
+list_columns = ('name', 'date-modified', 'size', 'kind', 'date-added')
+list_column_widths = {
+ 'name': 300,
+ 'date-modified': 181,
+ 'date-created': 181,
+ 'date-added': 181,
+ 'date-last-opened': 181,
+ 'size': 97,
+ 'kind': 115,
+ 'label': 100,
+ 'version': 75,
+ 'comments': 300,
+ }
+list_column_sort_directions = {
+ 'name': 'ascending',
+ 'date-modified': 'descending',
+ 'date-created': 'descending',
+ 'date-added': 'descending',
+ 'date-last-opened': 'descending',
+ 'size': 'descending',
+ 'kind': 'ascending',
+ 'label': 'ascending',
+ 'version': 'ascending',
+ 'comments': 'ascending',
+ }
+
+# .. License configuration .....................................................
+
+# Text in the license configuration is stored in the resources, which means
+# it gets stored in a legacy Mac encoding according to the language. dmgbuild
+# will *try* to convert Unicode strings to the appropriate encoding, *but*
+# you should be aware that Python doesn't support all of the necessary encodings;
+# in many cases you will need to encode the text yourself and use byte strings
+# instead here.
+
+# Recognized language names are:
+#
+# af_ZA, ar, be_BY, bg_BG, bn, bo, br, ca_ES, cs_CZ, cy, da_DK, de_AT, de_CH,
+# de_DE, dz_BT, el_CY, el_GR, en_AU, en_CA, en_GB, en_IE, en_SG, en_US, eo,
+# es_419, es_ES, et_EE, fa_IR, fi_FI, fo_FO, fr_001, fr_BE, fr_CA, fr_CH,
+# fr_FR, ga-Latg_IE, ga_IE, gd, grc, gu_IN, gv, he_IL, hi_IN, hr_HR, hu_HU,
+# hy_AM, is_IS, it_CH, it_IT, iu_CA, ja_JP, ka_GE, kl, ko_KR, lt_LT, lv_LV,
+# mk_MK, mr_IN, mt_MT, nb_NO, ne_NP, nl_BE, nl_NL, nn_NO, pa, pl_PL, pt_BR,
+# pt_PT, ro_RO, ru_RU, se, sk_SK, sl_SI, sr_RS, sv_SE, th_TH, to_TO, tr_TR,
+# uk_UA, ur_IN, ur_PK, uz_UZ, vi_VN, zh_CN, zh_TW
+
+# license = {
+# 'default-language': 'en_US',
+# 'licenses': {
+# # For each language, the text of the license. This can be plain text,
+# # RTF (in which case it must start "{\rtf1"), or a path to a file
+# # containing the license text. If you're using RTF,
+# # watch out for Python escaping (or read it from a file).
+# 'English': b'''{\\rtf1\\ansi\\ansicpg1252\\cocoartf1504\\cocoasubrtf820
+# {\\fonttbl\\f0\\fnil\\fcharset0 Helvetica-Bold;\\f1\\fnil\\fcharset0 Helvetica;}
+# {\\colortbl;\\red255\\green255\\blue255;\\red0\\green0\\blue0;}
+# {\\*\\expandedcolortbl;;\\cssrgb\\c0\\c0\\c0;}
+# \\paperw11905\\paperh16837\\margl1133\\margr1133\\margb1133\\margt1133
+# \\deftab720
+# \\pard\\pardeftab720\\sa160\\partightenfactor0
+
+# \\f0\\b\\fs60 \\cf2 \\expnd0\\expndtw0\\kerning0
+# \\up0 \\nosupersub \\ulnone \\outl0\\strokewidth0 \\strokec2 Test License\\
+# \\pard\\pardeftab720\\sa160\\partightenfactor0
+
+# \\fs36 \\cf2 \\strokec2 What is this?\\
+# \\pard\\pardeftab720\\sa160\\partightenfactor0
+
+# \\f1\\b0\\fs22 \\cf2 \\strokec2 This is the English license. It says what you are allowed to do with this software.\\
+# \\
+# }''',
+# },
+# 'buttons': {
+# # For each language, text for the buttons on the licensing window.
+# #
+# # Default buttons and text are built-in for the following languages:
+# #
+# # English (en_US), German (de_DE), Spanish (es_ES), French (fr_FR),
+# # Italian (it_IT), Japanese (ja_JP), Dutch (nl_NL), Swedish (sv_SE),
+# # Brazilian Portuguese (pt_BR), Simplified Chinese (zh_CN),
+# # Traditional Chinese (zh_TW), Danish (da_DK), Finnish (fi_FI),
+# # Korean (ko_KR), Norwegian (nb_NO)
+# #
+# # You don't need to specify them for those languages; if you fail to
+# # specify them for some other language, English will be used instead.
+
+# 'en_US': (
+# b'English',
+# b'Agree',
+# b'Disagree',
+# b'Print',
+# b'Save',
+# b'If you agree with the terms of this license, press "Agree" to '
+# b'install the software. If you do not agree, press "Disagree".'
+# ),
+# },
+# }
diff --git a/packaging/macos/src/jhb-custom.conf.sh b/packaging/macos/src/jhb-custom.conf.sh
new file mode 100644
index 0000000..d4d7b2b
--- /dev/null
+++ b/packaging/macos/src/jhb-custom.conf.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2022 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Custom configuration for jhb.
+
+### shellcheck #################################################################
+
+# shellcheck disable=SC2034 # no unused variables
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+VERSION=0.69
+VER_DIR_TEMPLATE="\$WRK_DIR/mibap-\$VERSION"
+
+RELEASE_ARCHIVE=mibap-"$VERSION"_$(uname -m).dmg
+
+# GitHub: https://github.com/dehesselle/mibap
+# GitLab: https://gitlab.com/inkscape/devel/mibap
+RELEASE_URLS=(
+ "https://github.com/dehesselle/mibap/releases/download/\
+v$VERSION/$RELEASE_ARCHIVE"
+ "https://gitlab.com/api/v4/projects/15865869/packages/generic/mibap/\
+$VERSION/$RELEASE_ARCHIVE"
+)
+
+### functions ##################################################################
+
+# Nothing here.
+
+### main #######################################################################
+
+# Nothing here.
diff --git a/packaging/macos/src/png2icns.sh b/packaging/macos/src/png2icns.sh
new file mode 100644
index 0000000..9781781
--- /dev/null
+++ b/packaging/macos/src/png2icns.sh
@@ -0,0 +1,37 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Convert png to icns.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+# Nothing here.
+
+### variables ##################################################################
+
+# https://github.com/bitboss-ca/png2icns
+PNG2ICNS_VER=0.1
+PNG2ICNS_URL=https://github.com/bitboss-ca/png2icns/archive/\
+v$PNG2ICNS_VER.tar.gz
+
+### functions ##################################################################
+
+function png2icns_install
+{
+ local archive
+ archive=$PKG_DIR/$(basename $PNG2ICNS_URL)
+ curl -o "$archive" -L "$PNG2ICNS_URL"
+ tar -C "$SRC_DIR" -xf "$archive"
+ ln -s "$SRC_DIR"/png2icns-$PNG2ICNS_VER/png2icns.sh "$BIN_DIR"
+}
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/src/svg2icns.sh b/packaging/macos/src/svg2icns.sh
new file mode 100644
index 0000000..c072646
--- /dev/null
+++ b/packaging/macos/src/svg2icns.sh
@@ -0,0 +1,56 @@
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Convert svg to icns. This is the "wrapper" that utilizes/requires caivrosvg
+# and png2icns packages.
+
+### shellcheck #################################################################
+
+# shellcheck shell=bash # no shebang as this file is intended to be sourced
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/cairosvg.sh
+source "$(dirname "${BASH_SOURCE[0]}")"/png2icns.sh
+
+### variables ##################################################################
+
+# Nothing here.
+
+### functions ##################################################################
+
+function svg2icns_install
+{
+ cairosvg_install
+ png2icns_install
+}
+
+function svg2icns
+{
+ local svg_file=$1
+ local icns_file=$2
+ local scale=$3 # optional
+
+ if [ -z "$scale" ]; then
+ scale=1
+ fi
+
+ local png_file
+ png_file=$TMP_DIR/$(basename -s .svg "$svg_file").png
+
+ # svg to png
+ jhb run cairosvg -f png -s $scale -o "$png_file" "$svg_file"
+
+ # png to icns
+ cd "$TMP_DIR" || exit 1 # png2icns.sh outputs to current directory
+ png2icns.sh "$png_file"
+
+ mv "$(basename -s .png "$png_file")".icns "$icns_file"
+}
+
+### main #######################################################################
+
+# Nothing here. \ No newline at end of file
diff --git a/packaging/macos/uninstall_toolset.sh b/packaging/macos/uninstall_toolset.sh
new file mode 100755
index 0000000..82b154f
--- /dev/null
+++ b/packaging/macos/uninstall_toolset.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+### description ################################################################
+
+# Uninstall a previously installed toolset: unmount the disk images.
+
+### shellcheck #################################################################
+
+# Nothing here.
+
+### dependencies ###############################################################
+
+source "$(dirname "${BASH_SOURCE[0]}")"/jhb/etc/jhb.conf.sh \
+ "$(dirname "${BASH_SOURCE[0]}")"/src/jhb-custom.conf.sh
+source "$(dirname "${BASH_SOURCE[0]}")"/src/ink.sh
+
+bash_d_include echo
+bash_d_include error
+
+### variables ##################################################################
+
+SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1; pwd)
+
+### functions ##################################################################
+
+function save_overlay
+{
+ local overlay
+ overlay=$(diskutil list | grep "$RELEASE_OVERLAY" | grep "0:" |
+ awk '{ print $5 }')
+ umount /dev/"$overlay"
+
+ mount -o nobrowse,ro -t hfs /dev/"$overlay" "$TMP_DIR"
+ tar -C "$TMP_DIR" --exclude "Inkscape.???" --exclude ".fseventsd" -cp . |
+ XZ_OPT=-T0 xz > "$ARTIFACT_DIR"/toolset_overlay.tar.xz
+
+ diskutil eject "$overlay"
+}
+
+### main #######################################################################
+
+error_trace_enable
+
+case "$1" in
+ save_overlay) # save files from build stage (to be used later in test stage)
+ save_overlay
+ ;;
+ save_testfiles) # save files from test stage (test evidence)
+ tar -C "$INK_BLD_DIR" -cp testfiles |
+ XZ_OPT=-T0 xz > "$ARTIFACT_DIR"/testfiles.tar.xz
+ ;;
+esac
+
+"$SELF_DIR"/jhb/usr/bin/archive uninstall_dmg \ No newline at end of file