Browse Source

first commit

Tom Kelsey 4 years ago
commit
2a3ae1366c

BIN
.DS_Store


+ 77 - 0
.github/workflows/build-release.yml

@@ -0,0 +1,77 @@
+name: Build Release
+on:
+  push:
+    tags:
+      - v*
+jobs:
+  create-release:
+    runs-on: 'ubuntu-latest'
+    outputs:
+      upload_url: ${{ steps.create-release.outputs.upload_url }}
+    steps:
+    - name: Create Release
+      id: create-release
+      uses: actions/create-release@v1
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      with:
+        tag_name: ${{ github.ref }}
+        release_name: Release ${{ github.ref }}
+        draft: false
+        prerelease: true
+  build:
+    runs-on: ${{ matrix.os }}
+    continue-on-error: ${{ matrix.experimental }}
+    needs: create-release
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest]
+        platform:
+          - 'linux-x64'
+          - 'linuxmusl-x64'
+          - 'linux-armv6'
+          - 'linux-armv7'
+          - 'linux-arm64v8'
+          - 'win32-ia32'
+          - 'win32-x64'
+          - 'win32-arm64v8'
+        experimental: [false]
+        include:
+          - os: macos-10.15
+            platform: 'darwin-x64'
+            experimental: true
+    steps:
+    - name: Checkout
+      uses: actions/checkout@v2
+    - name: Install dependencies (macOS)
+      run: |
+        pip3 install meson==0.55.3 ninja
+        brew install advancecomp automake brotli nasm pkg-config
+      if: matrix.platform == 'darwin-x64'
+    - name: Build ${{ matrix.platform }}
+      id: build-release
+      run: |
+        ./build.sh $(cat LIBVIPS_VERSION) ${{ matrix.platform }}
+        echo "::set-output name=asset_file_name_gz::libvips-$(cat LIBVIPS_VERSION)-${{ matrix.platform }}.tar.gz"
+        echo "::set-output name=asset_file_name_br::libvips-$(cat LIBVIPS_VERSION)-${{ matrix.platform }}.tar.br"
+    - name: Upload Release Asset (.tar.gz)
+      id: upload-release-asset-gz
+      uses: actions/upload-release-asset@v1
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      with:
+        upload_url: ${{ needs.create-release.outputs.upload_url }}
+        asset_path: ${{ steps.build-release.outputs.asset_file_name_gz }}
+        asset_name: ${{ steps.build-release.outputs.asset_file_name_gz }}
+        asset_content_type: application/gzip
+    - name: Upload Release Asset (.tar.br)
+      id: upload-release-asset-br
+      uses: actions/upload-release-asset@v1
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      with:
+        upload_url: ${{ needs.create-release.outputs.upload_url }}
+        asset_path: ${{ steps.build-release.outputs.asset_file_name_br }}
+        asset_name: ${{ steps.build-release.outputs.asset_file_name_br }}
+        asset_content_type: application/x-brotli

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+*.log
+deps/
+target/

+ 1 - 0
LIBVIPS_VERSION

@@ -0,0 +1 @@
+8.10.2

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 53 - 0
README.md

@@ -0,0 +1,53 @@
+# Packaging scripts
+
+libvips and its dependencies are provided as pre-compiled shared libraries
+for the most common operating systems and CPU architectures.
+
+During `npm install`, these binaries are fetched as tarballs from
+this repository via HTTPS and stored locally within `node_modules/sharp/vendor`.
+
+The base URL can be overridden using the
+`npm_config_sharp_libvips_binary_host` environment variable.
+
+https://sharp.pixelplumbing.com/install#custom-prebuilt-binaries
+
+## Creating a tarball
+
+Most people will not need to do this; proceed with caution.
+
+Run the top-level [build script](build.sh) without parameters for help.
+
+### Linux
+
+One [build script](build/lin.sh) is used to (cross-)compile
+the same shared libraries within multiple containers.
+
+* [x64 glibc](linux-x64/Dockerfile)
+* [x64 musl](linuxmusl-x64/Dockerfile)
+* [ARMv6](linux-armv6/Dockerfile)
+* [ARMv7-A](linux-armv7/Dockerfile)
+* [ARM64v8-A](linux-arm64v8/Dockerfile)
+
+### Windows
+
+The output of libvips' [build-win64-mxe](https://github.com/libvips/build-win64-mxe)
+"web" target is [post-processed](build/win.sh) within multiple containers.
+
+* [win32-ia32](win32-ia32/Dockerfile)
+* [win32-x64](win32-x64/Dockerfile)
+* [win32-arm64v8](win32-arm64v8/Dockerfile)
+
+### macOS
+
+Uses a macOS virtual machine hosted by GitHub to compile the shared libraries.
+The dylib files are compiled within the same build script as Linux.
+
+Depedency paths are modified to be the relative `@rpath` using `install_name_tool`.
+
+## Licences
+
+These scripts are licensed under the terms of the [Apache 2.0 Licence](LICENSE).
+
+The shared libraries contained in the tarballs are distributed under
+the terms of [various licences](THIRD-PARTY-NOTICES.md), all of which
+are compatible with the Apache 2.0 Licence.

+ 41 - 0
THIRD-PARTY-NOTICES.md

@@ -0,0 +1,41 @@
+# Third-party notices
+
+This software contains third-party libraries
+used under the terms of the following licences:
+
+| Library       | Used under the terms of                                                                                   |
+|---------------|-----------------------------------------------------------------------------------------------------------|
+| aom           | BSD 2-Clause + [Alliance for Open Media Patent License 1.0](https://aomedia.org/license/patent-license/)  |
+| cairo         | Mozilla Public License 2.0                                                                                |
+| expat         | MIT Licence                                                                                               |
+| fontconfig    | [fontconfig Licence](https://gitlab.freedesktop.org/fontconfig/fontconfig/blob/master/COPYING) (BSD-like) |
+| freetype      | [freetype Licence](https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT) (BSD-like) |
+| fribidi       | LGPLv3                                                                                                    |
+| gdk-pixbuf    | LGPLv3                                                                                                    |
+| gettext       | LGPLv3                                                                                                    |
+| giflib        | MIT Licence                                                                                               |
+| glib          | LGPLv3                                                                                                    |
+| harfbuzz      | MIT Licence                                                                                               |
+| lcms          | MIT Licence                                                                                               |
+| libexif       | LGPLv3                                                                                                    |
+| libffi        | MIT Licence                                                                                               |
+| libgsf        | LGPLv3                                                                                                    |
+| libheif       | LGPLv3                                                                                                    |
+| libjpeg-turbo | [zlib License, IJG License](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/master/LICENSE.md)        |
+| libpng        | [libpng License](https://github.com/glennrp/libpng/blob/master/LICENSE)                                   |
+| librsvg       | LGPLv3                                                                                                    |
+| libspng       | [BSD 2-Clause, libpng License](https://github.com/randy408/libspng/blob/master/LICENSE)                   |
+| libtiff       | [libtiff License](https://libtiff.gitlab.io/libtiff/misc.html) (BSD-like)                                 |
+| libvips       | LGPLv3                                                                                                    |
+| libwebp       | New BSD License                                                                                           |
+| libxml2       | MIT Licence                                                                                               |
+| orc           | [orc License](https://gitlab.freedesktop.org/gstreamer/orc/blob/master/COPYING) (BSD-like)                |
+| pango         | LGPLv3                                                                                                    |
+| pixman        | MIT Licence                                                                                               |
+| zlib          | [zlib Licence](https://github.com/madler/zlib/blob/master/zlib.h)                                         |
+
+Use of libraries under the terms of the LGPLv3 is via the
+"any later version" clause of the LGPLv2 or LGPLv2.1.
+
+Please report any errors or omissions via
+https://github.com/lovell/sharp-libvips/issues/new

+ 83 - 0
build.sh

@@ -0,0 +1,83 @@
+#!/usr/bin/env bash
+set -e
+
+if [ $# -lt 1 ]; then
+  echo
+  echo "Usage: $0 VERSION [PLATFORM]"
+  echo "Build shared libraries for libvips and its dependencies via containers"
+  echo
+  echo "Please specify the libvips VERSION, e.g. 8.9.2"
+  echo
+  echo "Optionally build for only one PLATFORM, defaults to building for all"
+  echo
+  echo "Possible values for PLATFORM are:"
+  echo "- win32-ia32"
+  echo "- win32-x64"
+  echo "- win32-arm64v8"
+  echo "- linux-x64"
+  echo "- linuxmusl-x64"
+  echo "- linux-armv6"
+  echo "- linux-armv7"
+  echo "- linux-arm64v8"
+  echo "- darwin-x64"
+  echo
+  exit 1
+fi
+VERSION_VIPS="$1"
+PLATFORM="${2:-all}"
+
+# macOS
+# Note: we intentionally don't build these binaries inside a Docker container
+if [ $PLATFORM = "darwin-x64" ] && [ "$(uname)" == "Darwin" ]; then
+  # Use Clang provided by XCode
+  export CC="clang"
+  export CXX="clang++"
+
+  export VERSION_VIPS
+  export PLATFORM
+
+  # 10.9 should be a good minimal release target
+  export MACOSX_DEPLOYMENT_TARGET="10.9"
+
+  # Added -fno-stack-check to workaround a stack misalignment bug on macOS 10.15
+  # See:
+  # https://forums.developer.apple.com/thread/121887
+  # https://trac.ffmpeg.org/ticket/8073#comment:12
+  export FLAGS="-O3 -fPIC -fno-stack-check"
+
+  . $PWD/build/mac.sh
+
+  exit 0
+fi
+
+# Is docker available?
+if ! [ -x "$(command -v docker)" ]; then
+  echo "Please install docker"
+  exit 1
+fi
+
+# Update base images
+for baseimage in centos:7 debian:buster debian:bullseye alpine:3.11; do
+  docker pull $baseimage
+done
+
+# Windows
+for flavour in win32-ia32 win32-x64 win32-arm64v8; do
+  if [ $PLATFORM = "all" ] || [ $PLATFORM = $flavour ]; then
+    echo "Building $flavour..."
+    docker build -t vips-dev-win32 win32
+    docker run --rm -e "VERSION_VIPS=${VERSION_VIPS}" -e "PLATFORM=${flavour}" -v $PWD:/packaging vips-dev-win32 sh -c "/packaging/build/win.sh"
+  fi
+done
+
+# Linux (x64, ARMv6, ARMv7, ARM64v8)
+for flavour in linux-x64 linuxmusl-x64 linux-armv6 linux-armv7 linux-arm64v8; do
+  if [ $PLATFORM = "all" ] || [ $PLATFORM = $flavour ]; then
+    echo "Building $flavour..."
+    docker build -t vips-dev-$flavour $flavour
+    docker run --rm -e "VERSION_VIPS=${VERSION_VIPS}" -v $PWD:/packaging vips-dev-$flavour sh -c "/packaging/build/lin.sh"
+  fi
+done
+
+# Display checksums
+sha256sum *.tar.{br,gz}

+ 499 - 0
build/lin.sh

@@ -0,0 +1,499 @@
+#!/usr/bin/env bash
+set -e
+
+# Environment / working directories
+case ${PLATFORM} in
+  linux*)
+    LINUX=true
+    DEPS=/deps
+    TARGET=/target
+    PACKAGE=/packaging
+    ROOT=/root
+    VIPS_CPP_DEP=libvips-cpp.so.42
+    ;;
+  darwin*)
+    DARWIN=true
+    DEPS=$PWD/deps
+    TARGET=$PWD/target
+    PACKAGE=$PWD
+    ROOT=$PWD/darwin-x64
+    VIPS_CPP_DEP=libvips-cpp.42.dylib
+    ;;
+esac
+
+mkdir ${DEPS}
+mkdir ${TARGET}
+
+# Common build paths and flags
+export PKG_CONFIG_LIBDIR="${TARGET}/lib/pkgconfig"
+export PATH="${PATH}:${TARGET}/bin"
+export CPATH="${TARGET}/include"
+export LIBRARY_PATH="${TARGET}/lib"
+export LD_LIBRARY_PATH="${TARGET}/lib"
+export CFLAGS="${FLAGS}"
+export CXXFLAGS="${FLAGS}"
+export LDFLAGS="-L${TARGET}/lib"
+
+# On Linux, we need to create a relocatable library
+# Note: this is handled for macOS using the `install_name_tool` (see below)
+if [ "$LINUX" = true ]; then
+  export LDFLAGS+=" -Wl,-rpath='\$\$ORIGIN/'"
+fi
+
+# On macOS, we need to explicitly link against the system libraries
+if [ "$DARWIN" = true ]; then
+  export LDFLAGS+=" -framework CoreServices -framework CoreFoundation -framework Foundation -framework AppKit"
+fi
+
+# Run as many parallel jobs as there are available CPU cores
+if [ "$LINUX" = true ]; then
+  export MAKEFLAGS="-j$(nproc)"
+elif [ "$DARWIN" = true ]; then
+  export MAKEFLAGS="-j$(sysctl -n hw.logicalcpu)"
+fi
+
+# Optimise Rust code for binary size
+export CARGO_PROFILE_RELEASE_DEBUG=false
+export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1
+export CARGO_PROFILE_RELEASE_INCREMENTAL=false
+export CARGO_PROFILE_RELEASE_LTO=true
+export CARGO_PROFILE_RELEASE_OPT_LEVEL=s
+export CARGO_PROFILE_RELEASE_PANIC=abort
+
+# We don't want to use any native libraries, so unset PKG_CONFIG_PATH
+unset PKG_CONFIG_PATH
+
+# Common options for curl
+CURL="curl --silent --location --retry 3 --retry-max-time 30"
+
+# Dependency version numbers
+VERSION_ZLIB=1.2.11
+VERSION_FFI=3.3
+VERSION_GLIB=2.67.0
+VERSION_XML2=2.9.10
+VERSION_GSF=1.14.47
+VERSION_EXIF=0.6.22
+VERSION_LCMS2=2.11
+VERSION_JPEG=2.0.6
+VERSION_PNG16=1.6.37
+VERSION_SPNG=0.6.1
+VERSION_WEBP=1.1.0
+VERSION_TIFF=4.1.0
+VERSION_ORC=0.4.32
+VERSION_GETTEXT=0.21
+VERSION_GDKPIXBUF=2.42.0
+VERSION_FREETYPE=2.10.4
+VERSION_EXPAT=2.2.10
+VERSION_FONTCONFIG=2.13.92
+VERSION_HARFBUZZ=2.7.2
+VERSION_PIXMAN=0.40.0
+VERSION_CAIRO=1.16.0
+VERSION_FRIBIDI=1.0.10
+VERSION_PANGO=1.48.0
+VERSION_SVG=2.50.1
+VERSION_GIF=5.1.4
+VERSION_AOM=2.0.0
+VERSION_HEIF=1.9.1
+VERSION_MOZJPEG=4.0.0
+
+# Remove patch version component
+without_patch() {
+  echo "${1%.[[:digit:]]*}"
+}
+
+# Check for newer versions
+ALL_AT_VERSION_LATEST=true
+version_latest() {
+  VERSION_LATEST=$($CURL https://release-monitoring.org/api/project/$3 | jq -r '.versions[]' | grep -E -m1 '^[0-9]+(.[0-9]+)*$')
+  if [ "$VERSION_LATEST" != "$2" ]; then
+    ALL_AT_VERSION_LATEST=false
+    echo "$1 version $2 has been superseded by $VERSION_LATEST"
+  fi
+}
+version_latest "zlib" "$VERSION_ZLIB" "5303"
+version_latest "ffi" "$VERSION_FFI" "1611"
+version_latest "glib" "$VERSION_GLIB" "10024"
+version_latest "xml2" "$VERSION_XML2" "1783"
+version_latest "gsf" "$VERSION_GSF" "1980"
+version_latest "exif" "$VERSION_EXIF" "1607"
+version_latest "lcms2" "$VERSION_LCMS2" "9815"
+version_latest "jpeg" "$VERSION_JPEG" "1648"
+version_latest "png" "$VERSION_PNG16" "1705"
+version_latest "spng" "$VERSION_SPNG" "24289"
+version_latest "webp" "$VERSION_WEBP" "1761"
+version_latest "tiff" "$VERSION_TIFF" "13521"
+version_latest "orc" "$VERSION_ORC" "2573"
+version_latest "gettext" "$VERSION_GETTEXT" "898"
+version_latest "gdkpixbuf" "$VERSION_GDKPIXBUF" "9533"
+version_latest "freetype" "$VERSION_FREETYPE" "854"
+version_latest "expat" "$VERSION_EXPAT" "770"
+version_latest "fontconfig" "$VERSION_FONTCONFIG" "827"
+version_latest "harfbuzz" "$VERSION_HARFBUZZ" "1299"
+version_latest "pixman" "$VERSION_PIXMAN" "3648"
+#version_latest "cairo" "$VERSION_CAIRO" "247" # latest version in release monitoring is unstable
+version_latest "fribidi" "$VERSION_FRIBIDI" "857"
+version_latest "pango" "$VERSION_PANGO" "11783"
+version_latest "svg" "$VERSION_SVG" "5420"
+#version_latest "gif" "$VERSION_GIF" "1158" # v5.1.5+ provides a Makefile only so will require custom cross-compilation setup
+#version_latest "aom" "$VERSION_AOM" "17628" # latest version in release monitoring does not exist
+version_latest "heif" "$VERSION_HEIF" "64439"
+if [ "$ALL_AT_VERSION_LATEST" = "false" ]; then exit 1; fi
+
+# Download and build dependencies from source
+
+if [ "${PLATFORM%-*}" == "linuxmusl" ] || [ "$DARWIN" = true ]; then
+  mkdir ${DEPS}/gettext
+  $CURL https://ftp.gnu.org/pub/gnu/gettext/gettext-${VERSION_GETTEXT}.tar.xz | tar xJC ${DEPS}/gettext --strip-components=1
+  cd ${DEPS}/gettext/gettext-runtime
+  ./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+    --disable-libasprintf --disable-java --disable-native-java --disable-csharp
+  make install-strip
+fi
+
+mkdir ${DEPS}/zlib
+$CURL https://zlib.net/zlib-${VERSION_ZLIB}.tar.xz | tar xJC ${DEPS}/zlib --strip-components=1
+cd ${DEPS}/zlib
+./configure --prefix=${TARGET} ${LINUX:+--uname=linux} ${DARWIN:+--uname=darwin} --static
+make install
+
+mkdir ${DEPS}/ffi
+$CURL https://github.com/libffi/libffi/releases/download/v${VERSION_FFI}/libffi-${VERSION_FFI}.tar.gz | tar xzC ${DEPS}/ffi --strip-components=1
+cd ${DEPS}/ffi
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-structs
+make install-strip
+
+mkdir ${DEPS}/glib
+$CURL https://download.gnome.org/sources/glib/$(without_patch $VERSION_GLIB)/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1
+cd ${DEPS}/glib
+# Disable tests
+sed -i'.bak' "/build_tests =/ s/= .*/= false/" meson.build
+if [ "${PLATFORM%-*}" == "linuxmusl" ]; then
+  #$CURL https://git.alpinelinux.org/aports/plain/main/glib/musl-libintl.patch | patch -p1 # not compatible with glib 2.65.0
+  $CURL https://gist.github.com/kleisauke/f4bda6fc3030cf7b8a4fdb88e2ce8e13/raw/246ac97dfba72ad7607c69eed1810b2354cd2e86/musl-libintl.patch | patch -p1
+fi
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dinternal_pcre=true -Dinstalled_tests=false -Dlibmount=disabled -Dlibelf=disabled ${DARWIN:+-Dbsymbolic_functions=false}
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/xml2
+$CURL http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1
+cd ${DEPS}/xml2
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --without-python --without-debug --without-docbook --without-ftp --without-html --without-legacy \
+  --without-push --without-schematron --without-lzma --with-zlib=${TARGET}
+make install-strip
+
+mkdir ${DEPS}/gsf
+$CURL https://download.gnome.org/sources/libgsf/$(without_patch $VERSION_GSF)/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1
+cd ${DEPS}/gsf
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --without-bz2 --without-gdk-pixbuf --with-zlib=${TARGET}
+make install-strip
+
+mkdir ${DEPS}/exif
+$CURL https://github.com/libexif/libexif/releases/download/libexif-${VERSION_EXIF//./_}-release/libexif-${VERSION_EXIF}.tar.xz | tar xJC ${DEPS}/exif --strip-components=1
+cd ${DEPS}/exif
+autoreconf -fiv
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking
+make install-strip
+
+mkdir ${DEPS}/lcms2
+$CURL https://downloads.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1
+cd ${DEPS}/lcms2
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking
+make install-strip
+
+mkdir ${DEPS}/aom
+$CURL https://aomedia.googlesource.com/aom/+archive/v${VERSION_AOM}.tar.gz | tar xzC ${DEPS}/aom
+cd ${DEPS}/aom
+mkdir aom_build
+cd aom_build
+AOM_AS_FLAGS="${FLAGS}" LDFLAGS=${LDFLAGS/\$/} cmake -G"Unix Makefiles" \
+  -DCMAKE_TOOLCHAIN_FILE=${ROOT}/Toolchain.cmake -DCMAKE_INSTALL_PREFIX=${TARGET} -DCMAKE_INSTALL_LIBDIR=lib \
+  -DENABLE_DOCS=0 -DENABLE_TESTS=0 -DENABLE_TESTDATA=0 -DENABLE_TOOLS=0 -DENABLE_EXAMPLES=0 \
+  -DCONFIG_PIC=1 -DENABLE_NASM=1 ${WITHOUT_NEON:+-DENABLE_NEON=0} \
+  ..
+make install/strip
+
+mkdir ${DEPS}/heif
+$CURL https://github.com/strukturag/libheif/releases/download/v${VERSION_HEIF}/libheif-${VERSION_HEIF}.tar.gz | tar xzC ${DEPS}/heif --strip-components=1
+cd ${DEPS}/heif
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --disable-gdk-pixbuf --disable-go --disable-examples --disable-libde265 --disable-x265
+sed -i'.bak' -e '/^Requires:/a\'$'\n''Requires.private: aom' libheif.pc # https://github.com/strukturag/libheif/pull/354
+make install-strip
+
+mkdir ${DEPS}/mozjpeg
+curl -Ls https://github.com/mozilla/mozjpeg/archive/v${VERSION_MOZJPEG}.tar.gz | tar xzC ${DEPS}/mozjpeg --strip-components=1
+cd ${DEPS}/mozjpeg
+autoreconf -fiv
+./configure --host=${CHOST} --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-jpeg8
+make install-strip
+
+mkdir ${DEPS}/jpeg
+$CURL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1
+cd ${DEPS}/jpeg
+LDFLAGS=${LDFLAGS/\$/} cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=${ROOT}/Toolchain.cmake -DCMAKE_INSTALL_PREFIX=${TARGET} -DCMAKE_INSTALL_LIBDIR=${TARGET}/lib \
+  -DENABLE_STATIC=TRUE -DENABLE_SHARED=FALSE -DWITH_JPEG8=1 -DWITH_TURBOJPEG=FALSE
+make install/strip
+
+mkdir ${DEPS}/png16
+$CURL https://downloads.sourceforge.net/project/libpng/libpng16/${VERSION_PNG16}/libpng-${VERSION_PNG16}.tar.xz | tar xJC ${DEPS}/png16 --strip-components=1
+cd ${DEPS}/png16
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking
+make install-strip
+
+mkdir ${DEPS}/spng
+$CURL https://github.com/randy408/libspng/archive/v${VERSION_SPNG}.tar.gz | tar xzC ${DEPS}/spng --strip-components=1
+cd ${DEPS}/spng
+meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dstatic_zlib=true
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/webp
+$CURL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${VERSION_WEBP}.tar.gz | tar xzC ${DEPS}/webp --strip-components=1
+cd ${DEPS}/webp
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --disable-neon --enable-libwebpmux --enable-libwebpdemux
+make install-strip
+
+mkdir ${DEPS}/tiff
+$CURL https://download.osgeo.org/libtiff/tiff-${VERSION_TIFF}.tar.gz | tar xzC ${DEPS}/tiff --strip-components=1
+cd ${DEPS}/tiff
+if [ -n "${CHOST}" ]; then autoreconf -fiv; fi
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --disable-mdi --disable-pixarlog --disable-old-jpeg --disable-cxx --disable-lzma --disable-zstd \
+  --with-jpeg-include-dir=${TARGET}/include --with-jpeg-lib-dir=${TARGET}/lib
+make install-strip
+
+mkdir ${DEPS}/orc
+$CURL https://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1
+cd ${DEPS}/orc
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dorc-test=disabled -Dbenchmarks=disabled -Dexamples=disabled -Dgtk_doc=disabled -Dtests=disabled -Dtools=disabled
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/gdkpixbuf
+$CURL https://download.gnome.org/sources/gdk-pixbuf/$(without_patch $VERSION_GDKPIXBUF)/gdk-pixbuf-${VERSION_GDKPIXBUF}.tar.xz | tar xJC ${DEPS}/gdkpixbuf --strip-components=1
+cd ${DEPS}/gdkpixbuf
+# Disable tests and thumbnailer
+sed -i'.bak' "/subdir('tests')/{N;d;}" meson.build
+# Disable the built-in loaders for BMP, GIF, ICO, PNM, XPM, XBM, TGA, ICNS and QTIF
+sed -i'.bak' "/\[ 'bmp'/{N;N;N;d;}" gdk-pixbuf/meson.build
+sed -i'.bak' "/\[ 'pnm'/d" gdk-pixbuf/meson.build
+sed -i'.bak' "/\[ 'xpm'/{N;N;N;N;d;}" gdk-pixbuf/meson.build
+# Ensure meson can find libjpeg when cross-compiling
+sed -i'.bak' "s/has_header('jpeglib.h')/has_header('jpeglib.h', args: '-I\/target\/include')/g" meson.build
+sed -i'.bak' "s/cc.find_library('jpeg'/dependency('libjpeg'/g" meson.build
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dtiff=false -Dintrospection=disabled -Dinstalled_tests=false -Dgio_sniffing=false -Dman=false -Dbuiltin_loaders=png,jpeg
+ninja -C _build
+ninja -C _build install
+# Include libjpeg and libpng as a dependency of gdk-pixbuf, see: https://gitlab.gnome.org/GNOME/gdk-pixbuf/merge_requests/50
+sed -i'.bak' "s/^\(Requires:.*\)/\1 libjpeg, libpng16/" ${TARGET}/lib/pkgconfig/gdk-pixbuf-2.0.pc
+
+mkdir ${DEPS}/freetype
+$CURL https://download.savannah.gnu.org/releases/freetype/freetype-${VERSION_FREETYPE}.tar.xz | tar xJC ${DEPS}/freetype --strip-components=1
+cd ${DEPS}/freetype
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --without-bzip2 --without-png
+make install
+
+mkdir ${DEPS}/expat
+$CURL https://github.com/libexpat/libexpat/releases/download/R_${VERSION_EXPAT//./_}/expat-${VERSION_EXPAT}.tar.xz | tar xJC ${DEPS}/expat --strip-components=1
+cd ${DEPS}/expat
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared \
+  --disable-dependency-tracking --without-xmlwf --without-docbook --without-getrandom --without-sys-getrandom
+make install
+
+mkdir ${DEPS}/fontconfig
+$CURL https://www.freedesktop.org/software/fontconfig/release/fontconfig-${VERSION_FONTCONFIG}.tar.xz | tar xJC ${DEPS}/fontconfig --strip-components=1
+cd ${DEPS}/fontconfig
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --with-expat-includes=${TARGET}/include --with-expat-lib=${TARGET}/lib ${LINUX:+--sysconfdir=/etc} \
+  ${DARWIN:+--sysconfdir=/usr/local/etc} --disable-docs
+make install-strip
+
+mkdir ${DEPS}/harfbuzz
+$CURL https://github.com/harfbuzz/harfbuzz/archive/${VERSION_HARFBUZZ}.tar.gz | tar xzC ${DEPS}/harfbuzz --strip-components=1
+cd ${DEPS}/harfbuzz
+# Disable utils
+sed -i'.bak' "/subdir('util')/d" meson.build
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dicu=disabled -Dtests=disabled -Dintrospection=disabled -Ddocs=disabled -Dbenchmark=disabled ${DARWIN:+-Dcoretext=enabled}
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/pixman
+$CURL https://cairographics.org/releases/pixman-${VERSION_PIXMAN}.tar.gz | tar xzC ${DEPS}/pixman --strip-components=1
+cd ${DEPS}/pixman
+# Disable tests and demos
+sed -i'.bak' "/subdir('test')/{N;d;}" meson.build
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dlibpng=disabled -Diwmmxt=disabled -Dgtk=disabled -Dopenmp=disabled
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/cairo
+$CURL https://cairographics.org/releases/cairo-${VERSION_CAIRO}.tar.xz | tar xJC ${DEPS}/cairo --strip-components=1
+cd ${DEPS}/cairo
+sed -i'.bak' "s/^\(Libs:.*\)/\1 @CAIRO_NONPKGCONFIG_LIBS@/" src/cairo.pc.in
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --disable-xlib --disable-xcb --disable-win32 --disable-egl --disable-glx --disable-wgl --disable-ps \
+  --disable-trace --disable-interpreter ${LINUX:+--disable-quartz} ${DARWIN:+--enable-quartz-image} \
+  LIBS="-lpixman-1 -lfreetype"
+make install-strip
+
+mkdir ${DEPS}/fribidi
+$CURL https://github.com/fribidi/fribidi/releases/download/v${VERSION_FRIBIDI}/fribidi-${VERSION_FRIBIDI}.tar.xz | tar xJC ${DEPS}/fribidi --strip-components=1
+cd ${DEPS}/fribidi
+# Disable tests
+sed -i'.bak' "/subdir('test')/d" meson.build
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Ddocs=false
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/pango
+$CURL https://download.gnome.org/sources/pango/$(without_patch $VERSION_PANGO)/pango-${VERSION_PANGO}.tar.xz | tar xJC ${DEPS}/pango --strip-components=1
+cd ${DEPS}/pango
+# Disable utils, examples, tests and tools
+sed -i'.bak' "/subdir('utils')/{N;N;N;d;}" meson.build
+LDFLAGS=${LDFLAGS/\$/} meson setup _build --default-library=static --buildtype=release --strip --prefix=${TARGET} ${MESON} \
+  -Dgtk_doc=false -Dintrospection=disabled -Dfontconfig=enabled
+ninja -C _build
+ninja -C _build install
+
+mkdir ${DEPS}/svg
+$CURL https://download.gnome.org/sources/librsvg/$(without_patch $VERSION_SVG)/librsvg-${VERSION_SVG}.tar.xz | tar xJC ${DEPS}/svg --strip-components=1
+cd ${DEPS}/svg
+sed -i'.bak' "s/^\(Requires:.*\)/\1 cairo-gobject pangocairo/" librsvg.pc.in
+# Do not include debugging symbols
+sed -i'.bak' "/debug =/ s/= .*/= false/" Cargo.toml
+# LTO optimization does not work for staticlib+rlib compilation
+sed -i'.bak' "s/, \"rlib\"//" librsvg/Cargo.toml
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking \
+  --disable-introspection --disable-tools --disable-pixbuf-loader ${DARWIN:+--disable-Bsymbolic}
+make install-strip
+
+mkdir ${DEPS}/gif
+$CURL https://downloads.sourceforge.net/project/giflib/giflib-${VERSION_GIF}.tar.gz | tar xzC ${DEPS}/gif --strip-components=1
+cd ${DEPS}/gif
+./configure --host=${CHOST} --prefix=${TARGET} --enable-static --disable-shared --disable-dependency-tracking
+make install-strip
+
+mkdir ${DEPS}/vips
+$CURL https://github.com/libvips/libvips/releases/download/v${VERSION_VIPS}/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1
+cd ${DEPS}/vips
+PKG_CONFIG="pkg-config --static" ./configure --host=${CHOST} --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \
+  --disable-debug --disable-deprecated --disable-introspection --without-analyze --without-cfitsio --without-fftw \
+  --without-imagequant --without-magick --without-matio --without-nifti --without-OpenEXR \
+  --without-openslide --without-pdfium --without-poppler --without-ppm --without-radiance \
+  ${LINUX:+LDFLAGS="$LDFLAGS -Wl,-Bsymbolic-functions"}
+# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_removing_rpath
+sed -i'.bak' 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
+make install-strip
+
+# Cleanup
+rm -rf ${TARGET}/lib/{pkgconfig,.libs,*.la,cmake}
+
+mkdir ${TARGET}/lib-filtered
+mv ${TARGET}/lib/glib-2.0 ${TARGET}/lib-filtered
+
+# Pack only the relevant libraries
+# Note: we can't use ldd on Linux, since that can only be executed on the target machine
+# Note 2: we modify all dylib dependencies to use relative paths on macOS
+function copydeps {
+  local base=$1
+  local dest_dir=$2
+
+  cp -L $base $dest_dir/$base
+  chmod 644 $dest_dir/$base
+
+  if [ "$LINUX" = true ]; then
+    local dependencies=$(readelf -d $base | grep NEEDED | awk '{ print $5 }' | tr -d '[]')
+  elif [ "$DARWIN" = true ]; then
+    local dependencies=$(otool -LX $base | awk '{print $1}' | grep $TARGET)
+
+    install_name_tool -id @rpath/$base $dest_dir/$base
+  fi
+
+  for dep in $dependencies; do
+    base_dep=$(basename $dep)
+
+    [ ! -f "$PWD/$base_dep" ] && echo "$base_dep does not exist in $PWD" && continue
+    echo "$base depends on $base_dep"
+
+    if [ ! -f "$dest_dir/$base_dep" ]; then
+      if [ "$DARWIN" = true ]; then
+        install_name_tool -change $dep @rpath/$base_dep $dest_dir/$base
+      fi
+
+      # Call this function (recursive) on each dependency of this library
+      copydeps $base_dep $dest_dir
+    fi
+  done;
+}
+
+cd ${TARGET}/lib
+copydeps ${VIPS_CPP_DEP} ${TARGET}/lib-filtered
+
+# Create JSON file of version numbers
+cd ${TARGET}
+printf "{\n\
+  \"aom\": \"${VERSION_AOM}\",\n\
+  \"cairo\": \"${VERSION_CAIRO}\",\n\
+  \"exif\": \"${VERSION_EXIF}\",\n\
+  \"expat\": \"${VERSION_EXPAT}\",\n\
+  \"ffi\": \"${VERSION_FFI}\",\n\
+  \"fontconfig\": \"${VERSION_FONTCONFIG}\",\n\
+  \"freetype\": \"${VERSION_FREETYPE}\",\n\
+  \"fribidi\": \"${VERSION_FRIBIDI}\",\n\
+  \"gdkpixbuf\": \"${VERSION_GDKPIXBUF}\",\n\
+  \"gettext\": \"${VERSION_GETTEXT}\",\n\
+  \"gif\": \"${VERSION_GIF}\",\n\
+  \"glib\": \"${VERSION_GLIB}\",\n\
+  \"gsf\": \"${VERSION_GSF}\",\n\
+  \"harfbuzz\": \"${VERSION_HARFBUZZ}\",\n\
+  \"heif\": \"${VERSION_HEIF}\",\n\
+  \"jpeg\": \"${VERSION_JPEG}\",\n\
+  \"lcms\": \"${VERSION_LCMS2}\",\n\
+  \"orc\": \"${VERSION_ORC}\",\n\
+  \"pango\": \"${VERSION_PANGO}\",\n\
+  \"pixman\": \"${VERSION_PIXMAN}\",\n\
+  \"png\": \"${VERSION_PNG16}\",\n\
+  \"svg\": \"${VERSION_SVG}\",\n\
+  \"spng\": \"${VERSION_SPNG}\",\n\
+  \"tiff\": \"${VERSION_TIFF}\",\n\
+  \"vips\": \"${VERSION_VIPS}\",\n\
+  \"webp\": \"${VERSION_WEBP}\",\n\
+  \"xml\": \"${VERSION_XML2}\",\n\
+  \"zlib\": \"${VERSION_ZLIB}\"\n\
+}" >versions.json
+
+printf "\"${PLATFORM}\"" >platform.json
+
+# Add third-party notices
+$CURL -O https://raw.githubusercontent.com/lovell/sharp-libvips/master/THIRD-PARTY-NOTICES.md
+
+# Create the tarball
+rm -rf lib
+mv lib-filtered lib
+tar chzf ${PACKAGE}/libvips-${VERSION_VIPS}-${PLATFORM}.tar.gz \
+  include \
+  lib \
+  *.json \
+  THIRD-PARTY-NOTICES.md
+
+# Recompress using AdvanceCOMP, ~5% smaller
+advdef --recompress --shrink-insane ${PACKAGE}/libvips-${VERSION_VIPS}-${PLATFORM}.tar.gz
+
+# Recompress using Brotli, ~15% smaller
+gunzip -c ${PACKAGE}/libvips-${VERSION_VIPS}-${PLATFORM}.tar.gz | brotli -o ${PACKAGE}/libvips-${VERSION_VIPS}-${PLATFORM}.tar.br
+
+# Allow tarballs to be read outside container
+chmod 644 ${PACKAGE}/libvips-${VERSION_VIPS}-${PLATFORM}.tar.*

+ 1 - 0
build/mac.sh

@@ -0,0 +1 @@
+lin.sh

+ 63 - 0
build/win.sh

@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+set -e
+
+VERSION_VIPS_SHORT=${VERSION_VIPS%.[[:digit:]]*}
+
+# Common options for curl
+CURL="curl --silent --location --retry 3 --retry-max-time 30"
+
+# Fetch and unzip
+mkdir /vips
+cd /vips
+
+case ${PLATFORM} in
+  *arm64v8)
+    ARCH=arm64
+    ;;
+  *x64)
+    ARCH=w64
+    ;;
+  *ia32)
+    ARCH=w32
+    ;;
+esac
+
+FILENAME="vips-dev-${ARCH}-web-${VERSION_VIPS}-static.zip"
+URL="https://github.com/libvips/build-win64-mxe/releases/download/v${VERSION_VIPS}-build2/${FILENAME}"
+echo "Downloading $URL"
+$CURL -O $URL
+unzip $FILENAME
+
+# Clean and zip
+cd /vips/vips-dev-${VERSION_VIPS_SHORT}
+rm bin/libvips-cpp-42.dll
+cp bin/*.dll lib/
+
+# Create platform.json
+printf "\"${PLATFORM}\"" >platform.json
+
+# Add third-party notices
+$CURL -O https://raw.githubusercontent.com/lovell/sharp-libvips/master/THIRD-PARTY-NOTICES.md
+
+echo "Creating tarball"
+tar czf /packaging/libvips-${VERSION_VIPS}-${PLATFORM}.tar.gz \
+  include \
+  lib/glib-2.0 \
+  lib/libvips.lib \
+  lib/libglib-2.0.lib \
+  lib/libgobject-2.0.lib \
+  lib/*.dll \
+  *.json \
+  THIRD-PARTY-NOTICES.md
+
+# Recompress using AdvanceCOMP, ~5% smaller
+advdef --recompress --shrink-insane /packaging/libvips-${VERSION_VIPS}-${PLATFORM}.tar.gz
+
+# Recompress using Brotli, ~15% smaller
+gunzip -c /packaging/libvips-${VERSION_VIPS}-${PLATFORM}.tar.gz | brotli -o /packaging/libvips-${VERSION_VIPS}-${PLATFORM}.tar.br
+
+# Allow tarballs to be read outside container
+chmod 644 /packaging/libvips-${VERSION_VIPS}-${PLATFORM}.tar.*
+
+# Remove working directories
+rm -rf lib include *.json THIRD-PARTY-NOTICES.md

+ 9 - 0
darwin-x64/Toolchain.cmake

@@ -0,0 +1,9 @@
+SET(CMAKE_C_COMPILER clang)
+SET(CMAKE_CXX_COMPILER clang++)
+
+# 10.9 should be a good minimal release target
+SET(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

BIN
libvips-8.7.0-linux-armv6.tar.gz


BIN
libvips-8.7.0-linux-armv7.tar.gz


BIN
libvips-8.7.0-linux-armv8.tar.gz


BIN
libvips-8.7.0-linux-x64.tar.gz


BIN
libvips-8.7.0-linuxmusl-x64.tar.gz


+ 56 - 0
linux-arm64v8/Dockerfile

@@ -0,0 +1,56 @@
+FROM debian:bullseye
+LABEL maintainer="Lovell Fuller <npm@lovell.info>"
+
+# Create Debian-based container suitable for cross-compiling Linux ARM64v8-A binaries
+
+# Path settings
+ENV \
+  RUSTUP_HOME="/usr/local/rustup" \
+  CARGO_HOME="/usr/local/cargo" \
+  PATH="/usr/local/cargo/bin:$PATH"
+
+# Build dependencies
+RUN \
+  apt-get update && \
+  apt-get install -y curl && \
+  dpkg --add-architecture arm64 && \
+  apt-get update && \
+  apt-get install -y \
+    advancecomp \
+    autoconf \
+    autopoint \
+    brotli \
+    cmake \
+    crossbuild-essential-arm64 \
+    gettext \
+    git \
+    gobject-introspection \
+    gperf \
+    gtk-doc-tools \
+    intltool \
+    jq \
+    libglib2.0-dev \
+    libtool \
+    nasm \
+    ninja-build \
+    python3-pip \
+    texinfo \
+    && \
+  curl https://sh.rustup.rs -sSf | sh -s -- -y \
+    --no-modify-path \
+    --profile minimal \
+    && \
+  rustup target add aarch64-unknown-linux-gnu && \
+  pip3 install meson==0.55.3
+
+# Compiler settings
+ENV \
+  PKG_CONFIG="/usr/bin/aarch64-linux-gnu-pkg-config" \
+  PLATFORM="linux-arm64v8" \
+  CHOST="aarch64-linux-gnu" \
+  RUST_TARGET="aarch64-unknown-linux-gnu" \
+  FLAGS="-march=armv8-a -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0" \
+  MESON="--cross-file=/root/meson.ini"
+
+COPY Toolchain.cmake /root/
+COPY meson.ini /root/

+ 13 - 0
linux-arm64v8/Toolchain.cmake

@@ -0,0 +1,13 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_VERSION 1)
+set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+SET(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
+set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
+SET(CMAKE_AR /usr/bin/aarch64-linux-gnu-gcc-ar)
+SET(CMAKE_STRIP /usr/bin/aarch64-linux-gnu-gcc-strip)
+SET(CMAKE_RANLIB /usr/bin/aarch64-linux-gnu-gcc-ranlib)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

+ 18 - 0
linux-arm64v8/meson.ini

@@ -0,0 +1,18 @@
+[host_machine]
+system = 'linux'
+cpu_family = 'aarch64'
+cpu = 'armv8-a'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/aarch64-linux-gnu-gcc'
+cpp = '/usr/bin/aarch64-linux-gnu-g++'
+ar = '/usr/bin/aarch64-linux-gnu-gcc-ar'
+nm = '/usr/bin/aarch64-linux-gnu-gcc-nm'
+ld = '/usr/bin/aarch64-linux-gnu-gcc-ld'
+strip = '/usr/bin/aarch64-linux-gnu-strip'
+pkgconfig = '/usr/bin/aarch64-linux-gnu-pkg-config'
+ranlib = '/usr/bin/aarch64-linux-gnu-gcc-ranlib'
+
+[paths]
+libdir = 'lib'

+ 60 - 0
linux-armv6/Dockerfile

@@ -0,0 +1,60 @@
+FROM debian:buster
+LABEL maintainer="Lovell Fuller <npm@lovell.info>"
+
+# Create Debian-based container suitable for cross-compiling Linux ARMv6 binaries
+
+# Path settings
+ENV \
+  RUSTUP_HOME="/usr/local/rustup" \
+  CARGO_HOME="/usr/local/cargo" \
+  PATH="/usr/local/cargo/bin:/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin:$PATH"
+
+# Build dependencies
+RUN \
+  apt-get update && \
+  apt-get install -y curl && \
+  dpkg --add-architecture armhf && \
+  apt-get update && \
+  apt-get install -y \
+    advancecomp \
+    autoconf \
+    autopoint \
+    brotli \
+    cmake \
+    gettext \
+    git \
+    gobject-introspection \
+    gperf \
+    gtk-doc-tools \
+    intltool \
+    jq \
+    libglib2.0-dev \
+    libtool \
+    nasm \
+    ninja-build \
+    python3-pip \
+    texinfo \
+    && \
+  mkdir /root/tools && \
+  curl -Ls https://github.com/rvagg/rpi-newer-crosstools/archive/master.tar.gz | tar xzC /root/tools --strip-components=1 && \
+  curl https://sh.rustup.rs -sSf | sh -s -- -y \
+    --no-modify-path \
+    --profile minimal \
+    && \
+  # Downgrade to 1.43.0, see: https://github.com/rust-lang/compiler-builtins/issues/353
+  rustup toolchain install 1.43.0 && rustup default 1.43.0 && \
+  rustup target add arm-unknown-linux-gnueabihf && \
+  pip3 install meson==0.55.3
+
+# Compiler settings
+ENV \
+  PKG_CONFIG="/usr/bin/arm-linux-gnueabihf-pkg-config" \
+  PLATFORM="linux-armv6" \
+  CHOST="arm-rpi-linux-gnueabihf" \
+  RUST_TARGET="arm-unknown-linux-gnueabihf" \
+  FLAGS="-marm -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0" \
+  WITHOUT_NEON="true" \
+  MESON="--cross-file=/root/meson.ini"
+
+COPY Toolchain.cmake /root/
+COPY meson.ini /root/

+ 13 - 0
linux-armv6/Toolchain.cmake

@@ -0,0 +1,13 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_VERSION 1)
+set(CMAKE_SYSTEM_PROCESSOR armv6-a)
+
+SET(CMAKE_C_COMPILER /root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc)
+set(CMAKE_CXX_COMPILER /root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++)
+SET(CMAKE_AR /root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-ar)
+SET(CMAKE_STRIP /root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-strip)
+SET(CMAKE_RANLIB /root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-ranlib)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

+ 18 - 0
linux-armv6/meson.ini

@@ -0,0 +1,18 @@
+[host_machine]
+system = 'linux'
+cpu_family = 'arm'
+cpu = 'armv6-a'
+endian = 'little'
+
+[binaries]
+c = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc'
+cpp = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++'
+ar = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-ar'
+nm = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc-nm'
+ld = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc-ld'
+strip = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-strip'
+pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'
+ranlib = '/root/tools/x64-gcc-6.5.0/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc-ranlib'
+
+[paths]
+libdir = 'lib'

+ 58 - 0
linux-armv7/Dockerfile

@@ -0,0 +1,58 @@
+FROM debian:buster
+LABEL maintainer="Lovell Fuller <npm@lovell.info>"
+
+# Create Debian-based container suitable for cross-compiling Linux ARMv7-A binaries
+
+# Path settings
+ENV \
+  RUSTUP_HOME="/usr/local/rustup" \
+  CARGO_HOME="/usr/local/cargo" \
+  PATH="/usr/local/cargo/bin:$PATH"
+
+# Build dependencies
+RUN \
+  apt-get update && \
+  apt-get install -y curl && \
+  dpkg --add-architecture armhf && \
+  apt-get update && \
+  apt-get install -y \
+    advancecomp \
+    autoconf \
+    autopoint \
+    brotli \
+    cmake \
+    crossbuild-essential-armhf \
+    gettext \
+    git \
+    gobject-introspection \
+    gperf \
+    gtk-doc-tools \
+    intltool \
+    jq \
+    libglib2.0-dev \
+    libtool \
+    nasm \
+    ninja-build \
+    python3-pip \
+    texinfo \
+    && \
+  curl https://sh.rustup.rs -sSf | sh -s -- -y \
+    --no-modify-path \
+    --profile minimal \
+    && \
+  # Downgrade to 1.43.0, see: https://github.com/rust-lang/compiler-builtins/issues/353
+  rustup toolchain install 1.43.0 && rustup default 1.43.0 && \
+  rustup target add arm-unknown-linux-gnueabihf && \
+  pip3 install meson==0.55.3
+
+# Compiler settings
+ENV \
+  PKG_CONFIG="/usr/bin/arm-linux-gnueabihf-pkg-config" \
+  PLATFORM="linux-armv7" \
+  CHOST="arm-linux-gnueabihf" \
+  RUST_TARGET="arm-unknown-linux-gnueabihf" \
+  FLAGS="-marm -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0" \
+  MESON="--cross-file=/root/meson.ini"
+
+COPY Toolchain.cmake /root/
+COPY meson.ini /root/

+ 13 - 0
linux-armv7/Toolchain.cmake

@@ -0,0 +1,13 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_VERSION 1)
+set(CMAKE_SYSTEM_PROCESSOR armv7-a)
+
+SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)
+SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++)
+SET(CMAKE_AR /usr/bin/arm-linux-gnueabihf-gcc-ar)
+SET(CMAKE_STRIP /usr/bin/arm-linux-gnueabihf-gcc-strip)
+SET(CMAKE_RANLIB /usr/bin/arm-linux-gnueabihf-gcc-ranlib)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

+ 18 - 0
linux-armv7/meson.ini

@@ -0,0 +1,18 @@
+[host_machine]
+system = 'linux'
+cpu_family = 'arm'
+cpu = 'armv7-a'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/arm-linux-gnueabihf-gcc'
+cpp = '/usr/bin/arm-linux-gnueabihf-g++'
+ar = '/usr/bin/arm-linux-gnueabihf-gcc-ar'
+nm = '/usr/bin/arm-linux-gnueabihf-gcc-nm'
+ld = '/usr/bin/arm-linux-gnueabihf-gcc-ld'
+strip = '/usr/bin/arm-linux-gnueabihf-strip'
+pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'
+ranlib = '/usr/bin/arm-linux-gnueabihf-gcc-ranlib'
+
+[paths]
+libdir = 'lib'

+ 47 - 0
linux-x64/Dockerfile

@@ -0,0 +1,47 @@
+FROM centos:7
+LABEL maintainer="Lovell Fuller <npm@lovell.info>"
+
+# Create CentOS 7 (glibc 2.17) container suitable for building Linux x64 binaries
+
+# Path settings
+ENV \
+  RUSTUP_HOME="/usr/local/rustup" \
+  CARGO_HOME="/usr/local/cargo" \
+  PATH="/usr/local/cargo/bin:/opt/rh/devtoolset-9/root/usr/bin:$PATH"
+
+# Build dependencies
+RUN \
+  yum update -y && \
+  yum install -y epel-release centos-release-scl && \
+  yum group install -y "Development Tools" && \
+  yum install -y --setopt=tsflags=nodocs \
+    advancecomp \
+    brotli \
+    cmake3 \
+    devtoolset-9-gcc \
+    devtoolset-9-gcc-c++ \
+    glib2-devel \
+    gobject-introspection-devel \
+    gperf \
+    gtk-doc \
+    jq \
+    nasm \
+    ninja-build \
+    prelink \
+    python3 \
+    && \
+  curl https://sh.rustup.rs -sSf | sh -s -- -y \
+    --no-modify-path \
+    --profile minimal \
+    && \
+  ln -s /usr/bin/cmake3 /usr/bin/cmake && \
+  pip3 install meson==0.55.3
+
+# Compiler settings
+ENV \
+  PLATFORM="linux-x64" \
+  FLAGS="-O3 -fPIC" \
+  MESON="--cross-file=/root/meson.ini"
+
+COPY Toolchain.cmake /root/
+COPY meson.ini /root/

+ 3 - 0
linux-x64/Toolchain.cmake

@@ -0,0 +1,3 @@
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

+ 5 - 0
linux-x64/meson.ini

@@ -0,0 +1,5 @@
+[binaries]
+pkgconfig = '/usr/bin/pkg-config'
+
+[paths]
+libdir = 'lib'

+ 56 - 0
linuxmusl-x64/Dockerfile

@@ -0,0 +1,56 @@
+FROM alpine:3.11
+LABEL maintainer="Lovell Fuller <npm@lovell.info>"
+
+# Create Alpine 3.11 (musl 1.1.24) container suitable for building Linux x64 binaries
+
+# Path settings
+ENV \
+  RUSTUP_HOME="/usr/local/rustup" \
+  CARGO_HOME="/usr/local/cargo" \
+  PATH="/usr/local/cargo/bin:$PATH"
+
+# Build dependencies
+RUN \
+  apk update && apk upgrade && \
+  apk --update --no-cache add \
+    autoconf \
+    automake \
+    binutils \
+    brotli \
+    build-base \
+    cmake \
+    curl \
+    findutils \
+    git \
+    glib-dev \
+    gobject-introspection-dev \
+    gperf \
+    gtk-doc \
+    intltool \
+    jq \
+    libtool \
+    linux-headers \
+    nasm \
+    ninja \
+    python3 \
+    shared-mime-info \
+    texinfo \
+    && \
+  apk --update --no-cache --repository https://alpine.global.ssl.fastly.net/alpine/edge/community/ add advancecomp && \
+  curl https://sh.rustup.rs -sSf | sh -s -- -y \
+    --no-modify-path \
+    --profile minimal \
+    && \
+  pip3 install meson==0.55.3
+
+# Compiler settings
+ENV \
+  PLATFORM="linuxmusl-x64" \
+  FLAGS="-O3 -fPIC"
+
+# Musl defaults to static libs but we need them to be dynamic for host toolchain.
+# The toolchain will produce static libs by default.
+ENV \
+  RUSTFLAGS="-C target-feature=-crt-static"
+
+COPY Toolchain.cmake /root/

+ 3 - 0
linuxmusl-x64/Toolchain.cmake

@@ -0,0 +1,3 @@
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

+ 28 - 0
test-linux-arm.sh

@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+  echo "Usage: $0 IP"
+  echo "Test sharp on ARM using Docker, where IP is"
+  echo "the address of a Raspberry Pi running HypriotOS"
+  exit 1
+fi
+IP="$1"
+
+echo "Verifying connectivity to $IP"
+if ! ping -c 1 $IP; then
+  echo "Could not connect to $IP"
+  exit 1
+fi
+
+if ! type sshpass >/dev/null; then
+  echo "Please install sshpass"
+  exit 1
+fi
+
+export SSHPASS=hypriot
+
+echo "Copying sharp source to device"
+sshpass -e scp -o PreferredAuthentications=password -r ../../sharp pirate@${IP}:/home/pirate/sharp
+
+echo "Compile and test within container"
+sshpass -e ssh -o PreferredAuthentications=password -t pirate@${IP} "docker run --rm -v \${PWD}/sharp:/s hypriot/rpi-node:6 sh -c 'cd /s && npm install --unsafe-perm && npm test'"

+ 36 - 0
test-linux-x64.sh

@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Verify docker is available
+if ! type docker >/dev/null; then
+  echo "Please install docker"
+  exit 1
+fi
+
+test="npm run clean; npm install --unsafe-perm; npm test"
+
+# Debian 7, 8
+# Ubuntu 14.04, 16.04
+for dist in debian:jessie debian:stretch ubuntu:trusty ubuntu:xenial; do
+  echo "Testing $dist..."
+  docker pull $dist
+  if docker run -i -t --rm -v $PWD:/v $dist >packaging/$dist.log 2>&1 sh -c "cd /v; ./packaging/test/debian.sh; $test";
+  then echo "$dist OK"
+  else echo "$dist fail" && cat packaging/$dist.log
+  fi
+done
+
+# Centos 7
+echo "Testing centos7..."
+docker pull centos:7
+if docker run -i -t --rm -v $PWD:/v centos:7 >packaging/centos7.log 2>&1 sh -c "cd /v; ./packaging/test/centos.sh; $test";
+then echo "centos7 OK"
+else echo "centos7 fail" && cat packaging/centos7.log
+fi
+
+# Archlinux latest
+echo "Testing archlinux..."
+docker pull pritunl/archlinux:latest
+if docker run -i -t --rm -v $PWD:/v pritunl/archlinux:latest >packaging/archlinux.log 2>&1 sh -c "cd /v; ./packaging/test/archlinux.sh; $test";
+then echo "archlinux OK"
+else echo "archlinux fail" && cat packaging/archlinux.log
+fi

+ 5 - 0
test/archlinux.sh

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Install Node.js on Archlinux
+pacman -Sy --noconfirm gcc make python2 nodejs npm | cat
+ln -s /usr/bin/python2 /usr/bin/python

+ 4 - 0
test/centos.sh

@@ -0,0 +1,4 @@
+#!/bin/sh
+
+curl -sL https://rpm.nodesource.com/setup_6.x | bash -
+yum install -y gcc-c++ make nodejs

+ 6 - 0
test/debian.sh

@@ -0,0 +1,6 @@
+#!/bin/sh
+
+apt-get update
+apt-get install -y build-essential python pkg-config curl
+curl -sL https://deb.nodesource.com/setup_6.x | bash -
+apt-get install -y nodejs

+ 6 - 0
win32/Dockerfile

@@ -0,0 +1,6 @@
+FROM debian:buster
+LABEL maintainer="Lovell Fuller <npm@lovell.info>"
+
+# Create Debian-based container suitable for post-processing Windows binaries
+
+RUN apt-get update && apt-get install -y advancecomp brotli curl zip