aboutsummaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
authorCem Keylan <cem@ckyln.com>2019-12-09 19:17:24 +0300
committerCem Keylan <cem@ckyln.com>2019-12-09 19:17:24 +0300
commit03423e0583057cbe5a16f8439183e2dbc0e8dd7c (patch)
tree81fe3ba69d94146f83fb5541d1fb2da0ac4eac08 /extra
downloadrepository-03423e0583057cbe5a16f8439183e2dbc0e8dd7c.tar.gz
secondary commit
Diffstat (limited to 'extra')
-rwxr-xr-xextra/alsa-lib/build8
-rw-r--r--extra/alsa-lib/checksums1
-rw-r--r--extra/alsa-lib/sources1
-rw-r--r--extra/alsa-lib/version1
-rwxr-xr-xextra/alsa-utils/build11
-rw-r--r--extra/alsa-utils/checksums1
-rw-r--r--extra/alsa-utils/depends2
-rw-r--r--extra/alsa-utils/sources1
-rw-r--r--extra/alsa-utils/version1
-rwxr-xr-xextra/atk/build14
-rw-r--r--extra/atk/checksums1
-rw-r--r--extra/atk/depends3
-rw-r--r--extra/atk/sources1
-rw-r--r--extra/atk/version1
-rwxr-xr-xextra/autoconf/build7
-rw-r--r--extra/autoconf/checksums1
-rw-r--r--extra/autoconf/depends2
-rw-r--r--extra/autoconf/sources1
-rw-r--r--extra/autoconf/version1
-rwxr-xr-xextra/automake/build7
-rw-r--r--extra/automake/checksums1
-rw-r--r--extra/automake/depends2
-rw-r--r--extra/automake/sources1
-rw-r--r--extra/automake/version1
-rwxr-xr-xextra/cbindgen/build10
-rw-r--r--extra/cbindgen/checksums1
-rw-r--r--extra/cbindgen/depends1
-rw-r--r--extra/cbindgen/sources1
-rw-r--r--extra/cbindgen/version1
-rwxr-xr-xextra/ccache/build21
-rw-r--r--extra/ccache/checksums1
-rw-r--r--extra/ccache/depends1
-rwxr-xr-xextra/ccache/post-install10
-rw-r--r--extra/ccache/sources1
-rw-r--r--extra/ccache/version1
-rwxr-xr-xextra/clang/build17
-rw-r--r--extra/clang/checksums1
-rw-r--r--extra/clang/depends5
-rw-r--r--extra/clang/sources1
-rw-r--r--extra/clang/version1
-rwxr-xr-xextra/cmake/build38
-rw-r--r--extra/cmake/checksums1
-rw-r--r--extra/cmake/depends5
-rw-r--r--extra/cmake/sources1
-rw-r--r--extra/cmake/version1
-rwxr-xr-xextra/cryptsetup/build12
-rw-r--r--extra/cryptsetup/checksums1
-rw-r--r--extra/cryptsetup/depends4
-rw-r--r--extra/cryptsetup/sources1
-rw-r--r--extra/cryptsetup/version1
-rwxr-xr-xextra/efibootmgr/build10
-rw-r--r--extra/efibootmgr/checksums2
-rw-r--r--extra/efibootmgr/depends2
-rw-r--r--extra/efibootmgr/patches/efivar.patch14
-rw-r--r--extra/efibootmgr/sources2
-rw-r--r--extra/efibootmgr/version1
-rwxr-xr-xextra/efivar/build17
-rw-r--r--extra/efivar/checksums3
-rw-r--r--extra/efivar/patches/fix-gcc9-dp.h.patch56
-rw-r--r--extra/efivar/patches/fix-gcc9.patch168
-rw-r--r--extra/efivar/sources3
-rw-r--r--extra/efivar/version1
-rwxr-xr-xextra/expat/build7
-rw-r--r--extra/expat/checksums1
-rw-r--r--extra/expat/sources1
-rw-r--r--extra/expat/version1
-rwxr-xr-xextra/ffmpeg/build25
-rw-r--r--extra/ffmpeg/checksums1
-rw-r--r--extra/ffmpeg/depends15
-rw-r--r--extra/ffmpeg/sources1
-rw-r--r--extra/ffmpeg/version1
-rwxr-xr-xextra/firefox/build42
-rw-r--r--extra/firefox/checksums15
-rw-r--r--extra/firefox/depends53
-rw-r--r--extra/firefox/files/mozconfig59
-rw-r--r--extra/firefox/files/policies.json21
-rw-r--r--extra/firefox/files/stab.h71
-rw-r--r--extra/firefox/files/vendor.js619
-rw-r--r--extra/firefox/patches/firefox-71-no-accessibility.patch13
-rw-r--r--extra/firefox/patches/firefox-71-no-dbus.patch425
-rw-r--r--extra/firefox/patches/fix-fortify-system-wrappers.patch13
-rw-r--r--extra/firefox/patches/fix-sandbox-membarrier.patch54
-rw-r--r--extra/firefox/patches/fix-seccomp-bpf.patch14
-rw-r--r--extra/firefox/patches/fix-toolkit.patch90
-rw-r--r--extra/firefox/patches/fix-tools.patch37
-rw-r--r--extra/firefox/patches/fix-webrtc-glibcisms.patch20
-rw-r--r--extra/firefox/patches/mallinfo.patch34
-rw-r--r--extra/firefox/sources15
-rw-r--r--extra/firefox/version1
-rwxr-xr-xextra/fribidi/build7
-rw-r--r--extra/fribidi/checksums1
-rw-r--r--extra/fribidi/sources1
-rw-r--r--extra/fribidi/version1
-rwxr-xr-xextra/giflib/build4
-rw-r--r--extra/giflib/checksums1
-rw-r--r--extra/giflib/sources1
-rw-r--r--extra/giflib/version1
-rwxr-xr-xextra/glib/build18
-rw-r--r--extra/glib/checksums1
-rw-r--r--extra/glib/depends4
-rw-r--r--extra/glib/sources1
-rw-r--r--extra/glib/version1
-rwxr-xr-xextra/gnupg1/build9
-rw-r--r--extra/gnupg1/checksums1
-rw-r--r--extra/gnupg1/depends4
-rw-r--r--extra/gnupg1/sources1
-rw-r--r--extra/gnupg1/version1
-rwxr-xr-xextra/gperf/build7
-rw-r--r--extra/gperf/checksums1
-rw-r--r--extra/gperf/sources1
-rw-r--r--extra/gperf/version1
-rwxr-xr-xextra/json-c/build7
-rw-r--r--extra/json-c/checksums1
-rw-r--r--extra/json-c/depends1
-rw-r--r--extra/json-c/sources1
-rw-r--r--extra/json-c/version1
-rwxr-xr-xextra/lame/build9
-rw-r--r--extra/lame/checksums1
-rw-r--r--extra/lame/depends1
-rw-r--r--extra/lame/sources1
-rw-r--r--extra/lame/version1
-rwxr-xr-xextra/libaio/build4
-rw-r--r--extra/libaio/checksums1
-rw-r--r--extra/libaio/sources1
-rw-r--r--extra/libaio/version1
-rwxr-xr-xextra/libass/build8
-rw-r--r--extra/libass/checksums1
-rw-r--r--extra/libass/depends6
-rw-r--r--extra/libass/sources1
-rw-r--r--extra/libass/version1
-rwxr-xr-xextra/libffi/build17
-rw-r--r--extra/libffi/checksums1
-rw-r--r--extra/libffi/sources1
-rw-r--r--extra/libffi/version1
-rwxr-xr-xextra/libjpeg-turbo/build13
-rw-r--r--extra/libjpeg-turbo/checksums1
-rw-r--r--extra/libjpeg-turbo/depends2
-rw-r--r--extra/libjpeg-turbo/sources1
-rw-r--r--extra/libjpeg-turbo/version1
-rwxr-xr-xextra/libogg/build7
-rw-r--r--extra/libogg/checksums1
-rw-r--r--extra/libogg/sources1
-rw-r--r--extra/libogg/version1
-rwxr-xr-xextra/libpng/build9
-rw-r--r--extra/libpng/checksums2
-rw-r--r--extra/libpng/depends1
-rw-r--r--extra/libpng/patches/libpng-1.6.37-apng.patch1728
-rw-r--r--extra/libpng/sources2
-rw-r--r--extra/libpng/version1
-rwxr-xr-xextra/libtheora/build9
-rw-r--r--extra/libtheora/checksums2
-rw-r--r--extra/libtheora/depends1
-rw-r--r--extra/libtheora/patches/libtheora-1.1.1-libpng16.patch17
-rw-r--r--extra/libtheora/sources2
-rw-r--r--extra/libtheora/version1
-rwxr-xr-xextra/libtool/build7
-rw-r--r--extra/libtool/checksums1
-rw-r--r--extra/libtool/depends1
-rw-r--r--extra/libtool/sources1
-rw-r--r--extra/libtool/version1
-rwxr-xr-xextra/libvorbis/build7
-rw-r--r--extra/libvorbis/checksums1
-rw-r--r--extra/libvorbis/depends1
-rw-r--r--extra/libvorbis/sources1
-rw-r--r--extra/libvorbis/version1
-rwxr-xr-xextra/libvpx/build23
-rw-r--r--extra/libvpx/checksums2
-rw-r--r--extra/libvpx/depends2
-rw-r--r--extra/libvpx/patches/fix-busybox-diff.patch13
-rw-r--r--extra/libvpx/sources2
-rw-r--r--extra/libvpx/version1
-rwxr-xr-xextra/libwebp/build11
-rw-r--r--extra/libwebp/checksums1
-rw-r--r--extra/libwebp/depends3
-rw-r--r--extra/libwebp/sources1
-rw-r--r--extra/libwebp/version1
-rwxr-xr-xextra/libxml2/build11
-rw-r--r--extra/libxml2/checksums1
-rw-r--r--extra/libxml2/depends2
-rw-r--r--extra/libxml2/sources1
-rw-r--r--extra/libxml2/version1
-rwxr-xr-xextra/llvm/build19
-rw-r--r--extra/llvm/checksums1
-rw-r--r--extra/llvm/depends3
-rw-r--r--extra/llvm/sources1
-rw-r--r--extra/llvm/version1
-rwxr-xr-xextra/lvm2/build41
-rw-r--r--extra/lvm2/checksums3
-rw-r--r--extra/lvm2/depends3
-rw-r--r--extra/lvm2/patches/disable-symver.patch136
-rw-r--r--extra/lvm2/patches/fix-stdio-usage.patch58
-rw-r--r--extra/lvm2/sources3
-rw-r--r--extra/lvm2/version1
-rwxr-xr-xextra/meson/build7
-rw-r--r--extra/meson/checksums1
-rw-r--r--extra/meson/depends2
-rw-r--r--extra/meson/sources1
-rw-r--r--extra/meson/version1
-rwxr-xr-xextra/mpv/build13
-rw-r--r--extra/mpv/checksums2
-rw-r--r--extra/mpv/depends9
-rw-r--r--extra/mpv/sources2
-rw-r--r--extra/mpv/version1
-rwxr-xr-xextra/nasm/build7
-rw-r--r--extra/nasm/checksums1
-rw-r--r--extra/nasm/depends1
-rw-r--r--extra/nasm/sources1
-rw-r--r--extra/nasm/version1
-rwxr-xr-xextra/ncurses/build21
-rw-r--r--extra/ncurses/checksums1
-rw-r--r--extra/ncurses/sources1
-rw-r--r--extra/ncurses/version1
-rwxr-xr-xextra/nodejs/build10
-rw-r--r--extra/nodejs/checksums1
-rw-r--r--extra/nodejs/depends1
-rw-r--r--extra/nodejs/sources1
-rw-r--r--extra/nodejs/version1
-rwxr-xr-xextra/openssh/build25
-rw-r--r--extra/openssh/checksums2
-rw-r--r--extra/openssh/depends2
-rw-r--r--extra/openssh/files/sshd.run3
-rw-r--r--extra/openssh/sources2
-rw-r--r--extra/openssh/version1
-rwxr-xr-xextra/opus/build9
-rw-r--r--extra/opus/checksums1
-rw-r--r--extra/opus/sources1
-rw-r--r--extra/opus/version1
-rwxr-xr-xextra/popt/build7
-rw-r--r--extra/popt/checksums1
-rw-r--r--extra/popt/sources1
-rw-r--r--extra/popt/version1
-rwxr-xr-xextra/python/build19
-rw-r--r--extra/python/checksums2
-rw-r--r--extra/python/depends5
-rw-r--r--extra/python/patches/python3-always-pip.patch13
-rw-r--r--extra/python/sources2
-rw-r--r--extra/python/version1
-rwxr-xr-xextra/python2/build14
-rw-r--r--extra/python2/checksums1
-rw-r--r--extra/python2/depends3
-rw-r--r--extra/python2/sources1
-rw-r--r--extra/python2/version1
-rwxr-xr-xextra/rust/build56
-rw-r--r--extra/rust/checksums5
-rw-r--r--extra/rust/depends7
-rw-r--r--extra/rust/patches/musl-libressl.patch128
-rw-r--r--extra/rust/sources5
-rw-r--r--extra/rust/version1
-rwxr-xr-xextra/samurai/build6
-rw-r--r--extra/samurai/checksums1
-rw-r--r--extra/samurai/sources1
-rw-r--r--extra/samurai/version1
-rwxr-xr-xextra/shared-mime-info/build54
-rw-r--r--extra/shared-mime-info/checksums1
-rw-r--r--extra/shared-mime-info/depends4
-rwxr-xr-xextra/shared-mime-info/post-install3
-rw-r--r--extra/shared-mime-info/sources1
-rw-r--r--extra/shared-mime-info/version1
-rwxr-xr-xextra/sqlite/build12
-rw-r--r--extra/sqlite/checksums1
-rw-r--r--extra/sqlite/depends1
-rw-r--r--extra/sqlite/sources1
-rw-r--r--extra/sqlite/version1
-rwxr-xr-xextra/sudo/build20
-rw-r--r--extra/sudo/checksums1
-rw-r--r--extra/sudo/depends1
-rw-r--r--extra/sudo/sources1
-rw-r--r--extra/sudo/version1
-rwxr-xr-xextra/tiff/build9
-rw-r--r--extra/tiff/checksums1
-rw-r--r--extra/tiff/depends3
-rw-r--r--extra/tiff/sources1
-rw-r--r--extra/tiff/version1
-rwxr-xr-xextra/tzdata/build13
-rw-r--r--extra/tzdata/checksums1
-rw-r--r--extra/tzdata/sources1
-rw-r--r--extra/tzdata/version1
-rwxr-xr-xextra/vim/build21
-rw-r--r--extra/vim/checksums1
-rw-r--r--extra/vim/depends1
-rw-r--r--extra/vim/sources1
-rw-r--r--extra/vim/version1
-rwxr-xr-xextra/x264/build13
-rw-r--r--extra/x264/checksums2
-rw-r--r--extra/x264/depends2
-rw-r--r--extra/x264/patches/x264-no-bash.patch222
-rw-r--r--extra/x264/sources2
-rw-r--r--extra/x264/version1
-rwxr-xr-xextra/x265/build10
-rw-r--r--extra/x265/checksums1
-rw-r--r--extra/x265/depends2
-rw-r--r--extra/x265/sources1
-rw-r--r--extra/x265/version1
-rwxr-xr-xextra/xvidcore/build9
-rw-r--r--extra/xvidcore/checksums1
-rw-r--r--extra/xvidcore/depends1
-rw-r--r--extra/xvidcore/sources1
-rw-r--r--extra/xvidcore/version1
-rwxr-xr-xextra/yasm/build7
-rw-r--r--extra/yasm/checksums1
-rw-r--r--extra/yasm/sources1
-rw-r--r--extra/yasm/version1
-rwxr-xr-xextra/zip/build12
-rw-r--r--extra/zip/checksums1
-rw-r--r--extra/zip/depends1
-rw-r--r--extra/zip/sources1
-rw-r--r--extra/zip/version1
307 files changed, 5319 insertions, 0 deletions
diff --git a/extra/alsa-lib/build b/extra/alsa-lib/build
new file mode 100755
index 00000000..d6f70b3d
--- /dev/null
+++ b/extra/alsa-lib/build
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+./configure \
+ --without-debug \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/alsa-lib/checksums b/extra/alsa-lib/checksums
new file mode 100644
index 00000000..32fadbe8
--- /dev/null
+++ b/extra/alsa-lib/checksums
@@ -0,0 +1 @@
+c95ac63c0aad43a6ac457d960569096b0b2ef72dc4e3737e77e3e2de87022cec alsa-lib-1.2.1.1.tar.bz2
diff --git a/extra/alsa-lib/sources b/extra/alsa-lib/sources
new file mode 100644
index 00000000..766d1395
--- /dev/null
+++ b/extra/alsa-lib/sources
@@ -0,0 +1 @@
+https://www.alsa-project.org/files/pub/lib/alsa-lib-1.2.1.1.tar.bz2
diff --git a/extra/alsa-lib/version b/extra/alsa-lib/version
new file mode 100644
index 00000000..9a598df0
--- /dev/null
+++ b/extra/alsa-lib/version
@@ -0,0 +1 @@
+1.2.1.1 1
diff --git a/extra/alsa-utils/build b/extra/alsa-utils/build
new file mode 100755
index 00000000..9c4602c8
--- /dev/null
+++ b/extra/alsa-utils/build
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+
+./configure \
+ --disable-alsaconf \
+ --disable-bat \
+ --with-curses=ncursesw \
+ --disable-xmlto \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/alsa-utils/checksums b/extra/alsa-utils/checksums
new file mode 100644
index 00000000..4c3e9d37
--- /dev/null
+++ b/extra/alsa-utils/checksums
@@ -0,0 +1 @@
+0b110ba71ef41d3009db1bc4dcae0cf79efb99cb5426fa19d0312470560a2c0d alsa-utils-1.2.1.tar.bz2
diff --git a/extra/alsa-utils/depends b/extra/alsa-utils/depends
new file mode 100644
index 00000000..167d2c94
--- /dev/null
+++ b/extra/alsa-utils/depends
@@ -0,0 +1,2 @@
+alsa-lib
+ncurses
diff --git a/extra/alsa-utils/sources b/extra/alsa-utils/sources
new file mode 100644
index 00000000..4fd80f0b
--- /dev/null
+++ b/extra/alsa-utils/sources
@@ -0,0 +1 @@
+https://www.alsa-project.org/files/pub/utils/alsa-utils-1.2.1.tar.bz2
diff --git a/extra/alsa-utils/version b/extra/alsa-utils/version
new file mode 100644
index 00000000..cd3d02bc
--- /dev/null
+++ b/extra/alsa-utils/version
@@ -0,0 +1 @@
+1.2.1 1
diff --git a/extra/atk/build b/extra/atk/build
new file mode 100755
index 00000000..58e9cf84
--- /dev/null
+++ b/extra/atk/build
@@ -0,0 +1,14 @@
+#!/bin/sh -e
+
+export DESTDIR="$1"
+
+meson \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --mandir=/usr/share/man \
+ -Ddocs=false \
+ -Dintrospection=false \
+ . output
+
+ninja -C output
+ninja -C output install
diff --git a/extra/atk/checksums b/extra/atk/checksums
new file mode 100644
index 00000000..a4d52dc5
--- /dev/null
+++ b/extra/atk/checksums
@@ -0,0 +1 @@
+d4f0e3b3d21265fcf2bc371e117da51c42ede1a71f6db1c834e6976bb20997cb atk-2.34.1.tar.xz
diff --git a/extra/atk/depends b/extra/atk/depends
new file mode 100644
index 00000000..9e46ce22
--- /dev/null
+++ b/extra/atk/depends
@@ -0,0 +1,3 @@
+glib
+libffi
+meson make
diff --git a/extra/atk/sources b/extra/atk/sources
new file mode 100644
index 00000000..8d57b646
--- /dev/null
+++ b/extra/atk/sources
@@ -0,0 +1 @@
+https://ftp.gnome.org/pub/gnome/sources/atk/2.34/atk-2.34.1.tar.xz
diff --git a/extra/atk/version b/extra/atk/version
new file mode 100644
index 00000000..8f2581bf
--- /dev/null
+++ b/extra/atk/version
@@ -0,0 +1 @@
+2.34.1 1
diff --git a/extra/autoconf/build b/extra/autoconf/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/autoconf/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/autoconf/checksums b/extra/autoconf/checksums
new file mode 100644
index 00000000..821d9707
--- /dev/null
+++ b/extra/autoconf/checksums
@@ -0,0 +1 @@
+954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969 autoconf-2.69.tar.gz
diff --git a/extra/autoconf/depends b/extra/autoconf/depends
new file mode 100644
index 00000000..8fd1a89e
--- /dev/null
+++ b/extra/autoconf/depends
@@ -0,0 +1,2 @@
+m4
+perl
diff --git a/extra/autoconf/sources b/extra/autoconf/sources
new file mode 100644
index 00000000..399ad44a
--- /dev/null
+++ b/extra/autoconf/sources
@@ -0,0 +1 @@
+https://ftp.gnu.org/pub/gnu/autoconf/autoconf-2.69.tar.gz
diff --git a/extra/autoconf/version b/extra/autoconf/version
new file mode 100644
index 00000000..9c78dec0
--- /dev/null
+++ b/extra/autoconf/version
@@ -0,0 +1 @@
+2.69 2
diff --git a/extra/automake/build b/extra/automake/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/automake/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/automake/checksums b/extra/automake/checksums
new file mode 100644
index 00000000..0369191e
--- /dev/null
+++ b/extra/automake/checksums
@@ -0,0 +1 @@
+608a97523f97db32f1f5d5615c98ca69326ced2054c9f82e65bade7fc4c9dea8 automake-1.16.1.tar.gz
diff --git a/extra/automake/depends b/extra/automake/depends
new file mode 100644
index 00000000..ef9f132a
--- /dev/null
+++ b/extra/automake/depends
@@ -0,0 +1,2 @@
+autoconf
+perl
diff --git a/extra/automake/sources b/extra/automake/sources
new file mode 100644
index 00000000..9d75a485
--- /dev/null
+++ b/extra/automake/sources
@@ -0,0 +1 @@
+https://ftp.gnu.org/gnu/automake/automake-1.16.1.tar.gz
diff --git a/extra/automake/version b/extra/automake/version
new file mode 100644
index 00000000..541e5c6e
--- /dev/null
+++ b/extra/automake/version
@@ -0,0 +1 @@
+1.16.1 1
diff --git a/extra/cbindgen/build b/extra/cbindgen/build
new file mode 100755
index 00000000..c9cd72cf
--- /dev/null
+++ b/extra/cbindgen/build
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+cargo fetch \
+ --locked
+
+cargo build \
+ --release \
+ --frozen
+
+install -Dm755 target/release/cbindgen "$1/usr/bin/cbindgen"
diff --git a/extra/cbindgen/checksums b/extra/cbindgen/checksums
new file mode 100644
index 00000000..6a06579f
--- /dev/null
+++ b/extra/cbindgen/checksums
@@ -0,0 +1 @@
+95c68020e5563440c8264c29d0db9a193c47476f83cfd848a13526a50ac7f55e v0.10.0.tar.gz
diff --git a/extra/cbindgen/depends b/extra/cbindgen/depends
new file mode 100644
index 00000000..64fe06e5
--- /dev/null
+++ b/extra/cbindgen/depends
@@ -0,0 +1 @@
+rust make
diff --git a/extra/cbindgen/sources b/extra/cbindgen/sources
new file mode 100644
index 00000000..71a4adf8
--- /dev/null
+++ b/extra/cbindgen/sources
@@ -0,0 +1 @@
+https://github.com/eqrion/cbindgen/archive/v0.10.0.tar.gz
diff --git a/extra/cbindgen/version b/extra/cbindgen/version
new file mode 100644
index 00000000..9336e4d1
--- /dev/null
+++ b/extra/cbindgen/version
@@ -0,0 +1 @@
+0.10.0 1
diff --git a/extra/ccache/build b/extra/ccache/build
new file mode 100755
index 00000000..1b063cc2
--- /dev/null
+++ b/extra/ccache/build
@@ -0,0 +1,21 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --mandir=/usr/share/man \
+ --localstatedir=/var
+
+make
+
+install -Dm 755 ccache "$1/usr/bin/ccache"
+install -Dm 644 doc/ccache.1 "$1/usr/share/man/man1/ccache.1"
+
+mkdir -p "$1/usr/lib/ccache/bin"
+
+triplet=$(cc -dumpmachine)
+
+for link in cc gcc g++ cpp c++ "$triplet-cc" "$triplet-gcc" \
+ "$triplet-g++" "$triplet-cpp" "$triplet-c++"; do
+ ln -sf /usr/bin/ccache "$1/usr/lib/ccache/bin/$link"
+done
diff --git a/extra/ccache/checksums b/extra/ccache/checksums
new file mode 100644
index 00000000..37379cb0
--- /dev/null
+++ b/extra/ccache/checksums
@@ -0,0 +1 @@
+73e2633ac9bca387b5a39c72a8f85634670c4091dab639228c433898163c86c0 ccache-3.7.6.tar.xz
diff --git a/extra/ccache/depends b/extra/ccache/depends
new file mode 100644
index 00000000..f22003e8
--- /dev/null
+++ b/extra/ccache/depends
@@ -0,0 +1 @@
+zlib
diff --git a/extra/ccache/post-install b/extra/ccache/post-install
new file mode 100755
index 00000000..75fdb200
--- /dev/null
+++ b/extra/ccache/post-install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+cat <<EOF
+
+NOTE: To enable 'ccache' add this to your
+ '.shellrc' or '.profile'.
+
+-> export PATH=/usr/lib/ccache/bin:\$PATH
+
+EOF
diff --git a/extra/ccache/sources b/extra/ccache/sources
new file mode 100644
index 00000000..4bb82721
--- /dev/null
+++ b/extra/ccache/sources
@@ -0,0 +1 @@
+https://github.com/ccache/ccache/releases/download/v3.7.6/ccache-3.7.6.tar.xz
diff --git a/extra/ccache/version b/extra/ccache/version
new file mode 100644
index 00000000..d8833805
--- /dev/null
+++ b/extra/ccache/version
@@ -0,0 +1 @@
+3.7.6 1
diff --git a/extra/clang/build b/extra/clang/build
new file mode 100755
index 00000000..e241c57c
--- /dev/null
+++ b/extra/clang/build
@@ -0,0 +1,17 @@
+#!/bin/sh -e
+
+export DESTDIR="$1"
+
+cmake -B build \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLLVM_ENABLE_RTTI=ON \
+ -DLLVM_ENABLE_EH=ON \
+ -DCLANG_BUILD_EXAMPLES=OFF \
+ -DCLANG_INCLUDE_DOCS=OFF \
+ -DCLANG_INCLUDE_TESTS=OFF \
+ -DLIBCLANG_BUILD_STATIC=ON \
+ -Wno-dev
+
+cmake --build build
+cmake --install build
diff --git a/extra/clang/checksums b/extra/clang/checksums
new file mode 100644
index 00000000..53cd6a2f
--- /dev/null
+++ b/extra/clang/checksums
@@ -0,0 +1 @@
+7ba81eef7c22ca5da688fdf9d88c20934d2d6b40bfe150ffd338900890aa4610 cfe-9.0.0.src.tar.xz
diff --git a/extra/clang/depends b/extra/clang/depends
new file mode 100644
index 00000000..7a0f0b0e
--- /dev/null
+++ b/extra/clang/depends
@@ -0,0 +1,5 @@
+cmake make
+llvm
+python make
+xz
+zlib
diff --git a/extra/clang/sources b/extra/clang/sources
new file mode 100644
index 00000000..1c1883f3
--- /dev/null
+++ b/extra/clang/sources
@@ -0,0 +1 @@
+https://releases.llvm.org/9.0.0/cfe-9.0.0.src.tar.xz
diff --git a/extra/clang/version b/extra/clang/version
new file mode 100644
index 00000000..f8041b0a
--- /dev/null
+++ b/extra/clang/version
@@ -0,0 +1 @@
+9.0.0 1
diff --git a/extra/cmake/build b/extra/cmake/build
new file mode 100755
index 00000000..401a7c14
--- /dev/null
+++ b/extra/cmake/build
@@ -0,0 +1,38 @@
+#!/bin/sh -e
+
+# Use cmake to build cmake if installed.
+# This leads to a much faster build.
+if kiss l cmake; then
+ cmake -B build \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_INSTALL_LIBDIR=/usr/lib \
+ -DCMAKE_SHARED_LIBS=True \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_USE_SYSTEM_CURL=True \
+ -DCMAKE_USE_SYSTEM_EXPAT=True \
+ -DCMAKE_USE_SYSTEM_ZLIB=True \
+ -DCMAKE_USE_SYSTEM_BZIP2=True \
+ -DBUILD_TESTING=OFF
+
+ cmake --build build
+ DESTDIR="$1" cmake --install build
+
+else
+ ./configure \
+ --prefix=/usr \
+ --system-curl \
+ --system-expat \
+ --system-zlib \
+ --system-bzip2 \
+ --parallel="$(nproc)"
+
+ make
+ make DESTDIR="$1" install
+fi
+
+# Grab the package version.
+IFS=. read -r ver1 ver2 _ < "${0%/*}/version"
+
+# Remove docs.
+rm -rf "$1/usr/doc"
+rm -rf "$1/usr/share/cmake-$ver1.$ver2/Help"
diff --git a/extra/cmake/checksums b/extra/cmake/checksums
new file mode 100644
index 00000000..877837b6
--- /dev/null
+++ b/extra/cmake/checksums
@@ -0,0 +1 @@
+6da56556c63cab6e9a3e1656e8763ed4a841ac9859fefb63cbe79472e67e8c5f cmake-3.16.0.tar.gz
diff --git a/extra/cmake/depends b/extra/cmake/depends
new file mode 100644
index 00000000..ae18e004
--- /dev/null
+++ b/extra/cmake/depends
@@ -0,0 +1,5 @@
+bzip2
+curl
+expat
+libressl
+zlib
diff --git a/extra/cmake/sources b/extra/cmake/sources
new file mode 100644
index 00000000..2fc2b2cb
--- /dev/null
+++ b/extra/cmake/sources
@@ -0,0 +1 @@
+https://github.com/Kitware/CMake/releases/download/v3.16.0/cmake-3.16.0.tar.gz
diff --git a/extra/cmake/version b/extra/cmake/version
new file mode 100644
index 00000000..48e61399
--- /dev/null
+++ b/extra/cmake/version
@@ -0,0 +1 @@
+3.16.0 1
diff --git a/extra/cryptsetup/build b/extra/cryptsetup/build
new file mode 100755
index 00000000..6e6631df
--- /dev/null
+++ b/extra/cryptsetup/build
@@ -0,0 +1,12 @@
+#!/bin/sh -e
+
+machine=$(cc -dumpmachine)
+
+./configure \
+ --prefix=/usr \
+ --build="$machine" \
+ --host="$machine" \
+ --disable-blkid
+
+make
+make DESTDIR="$1" install
diff --git a/extra/cryptsetup/checksums b/extra/cryptsetup/checksums
new file mode 100644
index 00000000..c9227e47
--- /dev/null
+++ b/extra/cryptsetup/checksums
@@ -0,0 +1 @@
+2af0ec9551ab9c870074cae9d3f68d82cab004f4095fa89db0e4413713424a46 cryptsetup-2.2.2.tar.xz
diff --git a/extra/cryptsetup/depends b/extra/cryptsetup/depends
new file mode 100644
index 00000000..0590f3c2
--- /dev/null
+++ b/extra/cryptsetup/depends
@@ -0,0 +1,4 @@
+json-c
+lvm2
+popt
+util-linux
diff --git a/extra/cryptsetup/sources b/extra/cryptsetup/sources
new file mode 100644
index 00000000..653fa179
--- /dev/null
+++ b/extra/cryptsetup/sources
@@ -0,0 +1 @@
+https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.xz
diff --git a/extra/cryptsetup/version b/extra/cryptsetup/version
new file mode 100644
index 00000000..da648f8d
--- /dev/null
+++ b/extra/cryptsetup/version
@@ -0,0 +1 @@
+2.2.2 1
diff --git a/extra/efibootmgr/build b/extra/efibootmgr/build
new file mode 100755
index 00000000..e15840ed
--- /dev/null
+++ b/extra/efibootmgr/build
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+patch -p1 < efivar.patch
+
+make \
+ EXTRA_CFLAGS=-Os \
+ EFIDIR=/boot/EFI
+
+install -Dm0755 src/efibootmgr "$1/usr/bin/efibootmgr"
+install -Dm0644 src/efibootmgr.8 "$1/usr/share/man/man8/efibootmgr.8"
diff --git a/extra/efibootmgr/checksums b/extra/efibootmgr/checksums
new file mode 100644
index 00000000..cb79ce74
--- /dev/null
+++ b/extra/efibootmgr/checksums
@@ -0,0 +1,2 @@
+22a95ebe0d5c9fb2915b3a100450f8f37484d1dbb8b296f55b343cc84f10397d 17.tar.gz
+167ac36fb4bd59e90fede0422280117c0b50d0ac3c0c7d478fea427cb9a6944c efivar.patch
diff --git a/extra/efibootmgr/depends b/extra/efibootmgr/depends
new file mode 100644
index 00000000..a760e6c7
--- /dev/null
+++ b/extra/efibootmgr/depends
@@ -0,0 +1,2 @@
+efivar
+popt
diff --git a/extra/efibootmgr/patches/efivar.patch b/extra/efibootmgr/patches/efivar.patch
new file mode 100644
index 00000000..614195f3
--- /dev/null
+++ b/extra/efibootmgr/patches/efivar.patch
@@ -0,0 +1,14 @@
+diff --git a/src/efibootmgr.c b/src/efibootmgr.c
+index de38f01..4e1a680 100644
+--- a/src/efibootmgr.c
++++ b/src/efibootmgr.c
+@@ -1536,9 +1536,6 @@ parse_opts(int argc, char **argv)
+ "invalid numeric value %s\n",
+ optarg);
+ }
+- /* XXX efivar-36 accidentally doesn't have a public
+- * header for this */
+- extern int efi_set_verbose(int verbosity, FILE *errlog);
+ efi_set_verbose(opts.verbose - 2, stderr);
+ break;
+ case 'V':
diff --git a/extra/efibootmgr/sources b/extra/efibootmgr/sources
new file mode 100644
index 00000000..4afc6a0a
--- /dev/null
+++ b/extra/efibootmgr/sources
@@ -0,0 +1,2 @@
+https://github.com/rhboot/efibootmgr/archive/17.tar.gz
+patches/efivar.patch
diff --git a/extra/efibootmgr/version b/extra/efibootmgr/version
new file mode 100644
index 00000000..5e661b99
--- /dev/null
+++ b/extra/efibootmgr/version
@@ -0,0 +1 @@
+17 1
diff --git a/extra/efivar/build b/extra/efivar/build
new file mode 100755
index 00000000..eb4038ac
--- /dev/null
+++ b/extra/efivar/build
@@ -0,0 +1,17 @@
+#!/bin/sh -e
+
+patch -p1 < fix-gcc9-dp.h.patch
+patch -p1 < fix-gcc9.patch
+
+# Avoid repeating ourselves.
+mk() {
+ make \
+ libdir=/usr/lib/ \
+ bindir=/usr/bin/ \
+ mandir=/usr/share/man/ \
+ includedir=/usr/include/ \
+ "$@"
+}
+
+mk
+mk DESTDIR="$1" install
diff --git a/extra/efivar/checksums b/extra/efivar/checksums
new file mode 100644
index 00000000..119c5824
--- /dev/null
+++ b/extra/efivar/checksums
@@ -0,0 +1,3 @@
+3c67feb93f901b98fbb897d5ca82931a6698b5bcd6ac34f0815f670d77747b9f efivar-37.tar.bz2
+475ca086eecabeaaff6111c3e6766f7e31d88a4fb6e0d082e34201e2cfaf295a fix-gcc9-dp.h.patch
+7e72f92eb0d03558b9b14ede6a68e29c0051ffe745a8c7a84d06dce6af458351 fix-gcc9.patch
diff --git a/extra/efivar/patches/fix-gcc9-dp.h.patch b/extra/efivar/patches/fix-gcc9-dp.h.patch
new file mode 100644
index 00000000..f40942f4
--- /dev/null
+++ b/extra/efivar/patches/fix-gcc9-dp.h.patch
@@ -0,0 +1,56 @@
+From b98ba8921010d03f46704a476c69861515deb1ca Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 7 Jan 2019 10:30:59 -0500
+Subject: [PATCH] dp.h: make format_guid() handle misaligned guid pointers
+ safely.
+
+GCC 9 adds -Werror=address-of-packed-member, which causes us to see the
+build error reported at
+ https://bugzilla.opensuse.org/show_bug.cgi?id=1120862 .
+
+That bug report shows us the following:
+
+In file included from dp.c:26:
+dp.h: In function 'format_vendor_helper':
+dp.h:120:37: error: taking address of packed member of 'struct <anonymous>' may result in an unaligned pointer value [-Werror=address-of-packed-member]
+ 120 | format_guid(buf, size, off, label, &dp->hw_vendor.vendor_guid);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~
+dp.h:74:25: note: in definition of macro 'format_guid'
+ 74 | _rc = efi_guid_to_str(guid, &_guidstr); \
+ | ^~~~
+cc1: all warnings being treated as errors
+
+This patch makes format_guid() use a local variable as a bounce buffer
+in the case that the guid we're passed is aligned as chaotic neutral.
+
+Note that this only fixes this instance and there may be others that bz
+didn't show because it exited too soon, and I don't have a gcc 9 build
+in front of me right now.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ src/dp.h | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/src/dp.h b/src/dp.h
+index aa4e390..20cb608 100644
+--- a/src/dp.h
++++ b/src/dp.h
+@@ -70,8 +70,15 @@
+ #define format_guid(buf, size, off, dp_type, guid) ({ \
+ int _rc; \
+ char *_guidstr = NULL; \
+- \
+- _rc = efi_guid_to_str(guid, &_guidstr); \
++ efi_guid_t _guid; \
++ const efi_guid_t * const _guid_p = \
++ likely(__alignof__(guid) == sizeof(guid)) \
++ ? guid \
++ : &_guid; \
++ \
++ if (unlikely(__alignof__(guid) == sizeof(guid))) \
++ memmove(&_guid, guid, sizeof(_guid)); \
++ _rc = efi_guid_to_str(_guid_p, &_guidstr); \
+ if (_rc < 0) { \
+ efi_error("could not build %s GUID DP string", \
+ dp_type); \
diff --git a/extra/efivar/patches/fix-gcc9.patch b/extra/efivar/patches/fix-gcc9.patch
new file mode 100644
index 00000000..bbb6a99a
--- /dev/null
+++ b/extra/efivar/patches/fix-gcc9.patch
@@ -0,0 +1,168 @@
+From c3c553db85ff10890209d0fe48fb4856ad68e4e0 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Thu, 21 Feb 2019 15:20:12 -0500
+Subject: [PATCH] Fix all the places -Werror=address-of-packed-member catches.
+
+This gets rid of all the places GCC 9's -Werror=address-of-packed-member
+flags as problematic.
+
+Fixes github issue #123
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ src/dp-message.c | 6 ++++--
+ src/dp.h | 12 ++++--------
+ src/guid.c | 2 +-
+ src/include/efivar/efivar.h | 2 +-
+ src/ucs2.h | 27 +++++++++++++++++++--------
+ 5 files changed, 29 insertions(+), 20 deletions(-)
+
+diff --git a/src/dp-message.c b/src/dp-message.c
+index 3724e5f..9f96466 100644
+--- a/src/dp-message.c
++++ b/src/dp-message.c
+@@ -620,11 +620,13 @@ _format_message_dn(char *buf, size_t size, const_efidp dp)
+ ) / sizeof(efi_ip_addr_t);
+ format(buf, size, off, "Dns", "Dns(");
+ for (int i=0; i < end; i++) {
+- const efi_ip_addr_t *addr = &dp->dns.addrs[i];
++ efi_ip_addr_t addr;
++
++ memcpy(&addr, &dp->dns.addrs[i], sizeof(addr));
+ if (i != 0)
+ format(buf, size, off, "Dns", ",");
+ format_ip_addr(buf, size, off, "Dns",
+- dp->dns.is_ipv6, addr);
++ dp->dns.is_ipv6, &addr);
+ }
+ format(buf, size, off, "Dns", ")");
+ break;
+diff --git a/src/dp.h b/src/dp.h
+index 20cb608..1f921d5 100644
+--- a/src/dp.h
++++ b/src/dp.h
+@@ -71,13 +71,9 @@
+ int _rc; \
+ char *_guidstr = NULL; \
+ efi_guid_t _guid; \
+- const efi_guid_t * const _guid_p = \
+- likely(__alignof__(guid) == sizeof(guid)) \
+- ? guid \
+- : &_guid; \
+- \
+- if (unlikely(__alignof__(guid) == sizeof(guid))) \
+- memmove(&_guid, guid, sizeof(_guid)); \
++ const efi_guid_t * const _guid_p = &_guid; \
++ \
++ memmove(&_guid, guid, sizeof(_guid)); \
+ _rc = efi_guid_to_str(_guid_p, &_guidstr); \
+ if (_rc < 0) { \
+ efi_error("could not build %s GUID DP string", \
+@@ -86,7 +82,7 @@
+ _guidstr = onstack(_guidstr, \
+ strlen(_guidstr)+1); \
+ _rc = format(buf, size, off, dp_type, "%s", \
+- _guidstr); \
++ _guidstr); \
+ } \
+ _rc; \
+ })
+diff --git a/src/guid.c b/src/guid.c
+index 306c9ff..3156b3b 100644
+--- a/src/guid.c
++++ b/src/guid.c
+@@ -31,7 +31,7 @@
+ extern const efi_guid_t efi_guid_zero;
+
+ int NONNULL(1, 2) PUBLIC
+-efi_guid_cmp(const efi_guid_t *a, const efi_guid_t *b)
++efi_guid_cmp(const void * const a, const void * const b)
+ {
+ return memcmp(a, b, sizeof (efi_guid_t));
+ }
+diff --git a/src/include/efivar/efivar.h b/src/include/efivar/efivar.h
+index 316891c..ad6449d 100644
+--- a/src/include/efivar/efivar.h
++++ b/src/include/efivar/efivar.h
+@@ -128,7 +128,7 @@ extern int efi_symbol_to_guid(const char *symbol, efi_guid_t *guid)
+
+ extern int efi_guid_is_zero(const efi_guid_t *guid);
+ extern int efi_guid_is_empty(const efi_guid_t *guid);
+-extern int efi_guid_cmp(const efi_guid_t *a, const efi_guid_t *b);
++extern int efi_guid_cmp(const void * const a, const void * const b);
+
+ /* import / export functions */
+ typedef struct efi_variable efi_variable_t;
+diff --git a/src/ucs2.h b/src/ucs2.h
+index dbb5900..edd8367 100644
+--- a/src/ucs2.h
++++ b/src/ucs2.h
+@@ -23,16 +23,21 @@
+ (((val) & ((mask) << (shift))) >> (shift))
+
+ static inline size_t UNUSED
+-ucs2len(const uint16_t * const s, ssize_t limit)
++ucs2len(const void *vs, ssize_t limit)
+ {
+ ssize_t i;
+- for (i = 0; i < (limit >= 0 ? limit : i+1) && s[i] != (uint16_t)0; i++)
++ const uint16_t *s = vs;
++ const uint8_t *s8 = vs;
++
++ for (i = 0;
++ i < (limit >= 0 ? limit : i+1) && s8[0] != 0 && s8[1] != 0;
++ i++, s8 += 2, s++)
+ ;
+ return i;
+ }
+
+ static inline size_t UNUSED
+-ucs2size(const uint16_t * const s, ssize_t limit)
++ucs2size(const void *s, ssize_t limit)
+ {
+ size_t rc = ucs2len(s, limit);
+ rc *= sizeof (uint16_t);
+@@ -69,10 +74,11 @@ utf8size(uint8_t *s, ssize_t limit)
+ }
+
+ static inline unsigned char * UNUSED
+-ucs2_to_utf8(const uint16_t * const chars, ssize_t limit)
++ucs2_to_utf8(const void * const voidchars, ssize_t limit)
+ {
+ ssize_t i, j;
+ unsigned char *ret;
++ const uint16_t * const chars = voidchars;
+
+ if (limit < 0)
+ limit = ucs2len(chars, -1);
+@@ -124,10 +130,12 @@ ucs2_to_utf8(const uint16_t * const chars, ssize_t limit)
+ }
+
+ static inline ssize_t UNUSED NONNULL(4)
+-utf8_to_ucs2(uint16_t *ucs2, ssize_t size, int terminate, uint8_t *utf8)
++utf8_to_ucs2(void *ucs2void, ssize_t size, int terminate, uint8_t *utf8)
+ {
+ ssize_t req;
+ ssize_t i, j;
++ uint16_t *ucs2 = ucs2void;
++ uint16_t val16;
+
+ if (!ucs2 && size > 0) {
+ errno = EINVAL;
+@@ -162,10 +170,13 @@ utf8_to_ucs2(uint16_t *ucs2, ssize_t size, int terminate, uint8_t *utf8)
+ val = utf8[i] & 0x7f;
+ i += 1;
+ }
+- ucs2[j] = val;
++ val16 = val;
++ ucs2[j] = val16;
++ }
++ if (terminate) {
++ val16 = 0;
++ ucs2[j++] = val16;
+ }
+- if (terminate)
+- ucs2[j++] = (uint16_t)0;
+ return j;
+ };
+
diff --git a/extra/efivar/sources b/extra/efivar/sources
new file mode 100644
index 00000000..0f76dab3
--- /dev/null
+++ b/extra/efivar/sources
@@ -0,0 +1,3 @@
+https://github.com/rhboot/efivar/releases/download/37/efivar-37.tar.bz2
+patches/fix-gcc9-dp.h.patch
+patches/fix-gcc9.patch
diff --git a/extra/efivar/version b/extra/efivar/version
new file mode 100644
index 00000000..f1e16caf
--- /dev/null
+++ b/extra/efivar/version
@@ -0,0 +1 @@
+37 2
diff --git a/extra/expat/build b/extra/expat/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/expat/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/expat/checksums b/extra/expat/checksums
new file mode 100644
index 00000000..d6999e9e
--- /dev/null
+++ b/extra/expat/checksums
@@ -0,0 +1 @@
+f1063084dc4302a427dabcca499c8312b3a32a29b7d2506653ecc8f950a9a237 expat-2.2.9.tar.bz2
diff --git a/extra/expat/sources b/extra/expat/sources
new file mode 100644
index 00000000..f28df8e3
--- /dev/null
+++ b/extra/expat/sources
@@ -0,0 +1 @@
+https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.bz2
diff --git a/extra/expat/version b/extra/expat/version
new file mode 100644
index 00000000..d0111d82
--- /dev/null
+++ b/extra/expat/version
@@ -0,0 +1 @@
+2.2.9 1
diff --git a/extra/ffmpeg/build b/extra/ffmpeg/build
new file mode 100755
index 00000000..db997201
--- /dev/null
+++ b/extra/ffmpeg/build
@@ -0,0 +1,25 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --enable-shared \
+ --enable-gpl \
+ --enable-version3 \
+ --enable-libass \
+ --enable-libmp3lame \
+ --enable-libopus \
+ --enable-libvorbis \
+ --enable-libtheora \
+ --enable-libvpx \
+ --enable-libx264 \
+ --enable-libx265 \
+ --enable-libxvid \
+ --enable-libwebp \
+ --enable-libdrm \
+ --disable-debug
+
+make CC="${CC:-gcc}"
+make DESTDIR="$1" install
+
+# Remove examples.
+rm -rf "$1/usr/share/ffmpeg/examples"
diff --git a/extra/ffmpeg/checksums b/extra/ffmpeg/checksums
new file mode 100644
index 00000000..4344f014
--- /dev/null
+++ b/extra/ffmpeg/checksums
@@ -0,0 +1 @@
+cec7c87e9b60d174509e263ac4011b522385fd0775292e1670ecc1180c9bb6d4 ffmpeg-4.2.1.tar.xz
diff --git a/extra/ffmpeg/depends b/extra/ffmpeg/depends
new file mode 100644
index 00000000..529204d8
--- /dev/null
+++ b/extra/ffmpeg/depends
@@ -0,0 +1,15 @@
+pkgconf make
+perl make
+yasm make
+alsa-lib
+lame
+libass
+libogg
+libtheora
+libvorbis
+libwebp
+libvpx
+opus
+x264
+x265
+xvidcore
diff --git a/extra/ffmpeg/sources b/extra/ffmpeg/sources
new file mode 100644
index 00000000..44e660ce
--- /dev/null
+++ b/extra/ffmpeg/sources
@@ -0,0 +1 @@
+https://www.ffmpeg.org/releases/ffmpeg-4.2.1.tar.xz
diff --git a/extra/ffmpeg/version b/extra/ffmpeg/version
new file mode 100644
index 00000000..fa7b9c86
--- /dev/null
+++ b/extra/ffmpeg/version
@@ -0,0 +1 @@
+4.2.1 2
diff --git a/extra/firefox/build b/extra/firefox/build
new file mode 100755
index 00000000..fb862887
--- /dev/null
+++ b/extra/firefox/build
@@ -0,0 +1,42 @@
+#!/bin/sh -e
+
+# Build autoconf 2.13 for Firefox's sole use.
+# See: https://bugzilla.mozilla.org/show_bug.cgi?id=104642
+(
+ cd autoconf2.13
+
+ ./configure \
+ --prefix="$PWD/../autoconf" \
+ --program-suffix=-2.13
+
+ make
+ make install
+)
+
+export PATH=$PWD/autoconf/bin:$PATH
+export LDFLAGS="$LDFLAGS -Wl,-rpath=/usr/lib/firefox"
+export CC=${CC:-gcc}
+export CXX=${CXX:-g++}
+
+for patch in *.patch; do
+ patch -p1 < "$patch"
+done
+
+# Fix OOM errors.
+cores=$(nproc)
+printf '%s\n' "mk_add_options MOZ_MAKE_FLAGS=\"-j$cores -l$cores\"" >> mozconfig
+
+./mach build
+DESTDIR="$1" ./mach install
+
+rm -rf "$1/usr/include"
+rm -rf "$1/usr/lib/firefox-devel"
+rm -rf "$1/usr/share/idl"
+rm -rf "$1/usr/lib/firefox/gtk2"
+rm -f "$1/usr/lib/firefox/browser/features/fxmonitor@mozilla.org.xpi"
+rm -f "$1/usr/lib/firefox/browser/features/screenshots@mozilla.org.xpi"
+rm -f "$1/usr/lib/firefox/browser/features/webcompat-reporter@mozilla.org.xpi"
+rm -f "$1/usr/lib/firefox/browser/features/webcompat@mozilla.org.xpi"
+
+install -D vendor.js "$1/usr/lib/firefox/browser/defaults/preferences/vendor.js"
+install -D policies.json "$1/usr/lib/firefox/distribution/policies.json"
diff --git a/extra/firefox/checksums b/extra/firefox/checksums
new file mode 100644
index 00000000..30128dc0
--- /dev/null
+++ b/extra/firefox/checksums
@@ -0,0 +1,15 @@
+e67c448f9e82a19c737a72f9af1ccd325ba9e86fcbb1cd6839e6eda37d0f5410 firefox-71.0.source.tar.xz
+f0611136bee505811e9ca11ca7ac188ef5323a8e2ef19cffd3edb3cf08fd791e autoconf-2.13.tar.gz
+b5e70b12cc9dd18fffd7924a7d3a2e11574136fe0764359d08eba0755f1c5d4c mozconfig
+960d82bbfdc88c95f5cb4f2e1c1bf23dae7519b3b7203914d7b3ddbff1ba4c28 stab.h
+cfc7d5006a3381e1b04f642b518317e19790ee31d23757274fdfeaba65c98b0c vendor.js
+f4ce7ee2485256b3f8c2bc467445f14b4730a7b895b17de7a21711d78bcfedea policies.json
+315880530f09175788dfa48a1915bfa1e190bfd3e267988b9100cb93006c808c fix-fortify-system-wrappers.patch
+418a2a9f80c41ee004cb640968617cab283b99f3d109aaf6180b0088d60c84b0 fix-sandbox-membarrier.patch
+14f281ee323aa682e04479019171bde243ac6227820856aa03b162179b14bfd9 fix-seccomp-bpf.patch
+b19aaae7fc45db643f8d2540d96919c745ea341e36d9aea2df40e3e90eb951f0 fix-toolkit.patch
+e24f71a6a0d8d4637b2081780c66b01be4eeb4dd496031270d0ae0b898be94d2 fix-tools.patch
+5e0fcfde375837074baad21a8ab26aa442a7940617ebd074a6b238a48f2ceb63 fix-webrtc-glibcisms.patch
+1d4a8f110d34da478f5597727eda9acacebd443dd86cce5bb64f898c01feabce mallinfo.patch
+49b1c589bc3248fa6389c8b9ff9316c5c5f10cb7868436c9c47cab888bdc8df6 firefox-71-no-dbus.patch
+b050ee807c000f26d09ff0c3e79f0149f195d802efa92b8740a75e7f07267064 firefox-71-no-accessibility.patch
diff --git a/extra/firefox/depends b/extra/firefox/depends
new file mode 100644
index 00000000..7b3a39b9
--- /dev/null
+++ b/extra/firefox/depends
@@ -0,0 +1,53 @@
+alsa-lib
+atk
+bzip2
+cairo
+cbindgen make
+clang make
+expat
+ffmpeg
+fontconfig
+freetype-harfbuzz
+fribidi
+gdk-pixbuf
+glib
+gtk+2 make
+gtk+3
+hicolor-icon-theme
+libICE
+libSM
+libX11
+libXau
+libXcomposite
+libXcursor
+libXdamage
+libXext
+libXfixes
+libXi
+libXinerama
+libXrandr
+libXrender
+libXt
+libXxf86vm
+libdrm
+libepoxy
+libffi
+libjpeg-turbo
+libpng
+libvpx
+libxcb
+libxshmfence
+llvm make
+mesa
+nasm make
+nodejs make
+pango
+perl make
+pixman
+python make
+python2 make
+rust make
+util-linux
+yasm make
+zip make
+zlib
diff --git a/extra/firefox/files/mozconfig b/extra/firefox/files/mozconfig
new file mode 100644
index 00000000..fbfc81f5
--- /dev/null
+++ b/extra/firefox/files/mozconfig
@@ -0,0 +1,59 @@
+ac_add_options --prefix=/usr
+ac_add_options --libdir=/usr/lib
+
+ac_add_options --enable-official-branding
+ac_add_options --enable-optimize="$CFLAGS"
+ac_add_options --enable-install-strip
+ac_add_options --enable-strip
+
+ac_add_options --without-system-nspr
+ac_add_options --without-system-nss
+ac_add_options --with-system-jpeg
+ac_add_options --with-system-zlib
+ac_add_options --with-system-bz2
+ac_add_options --with-system-png
+
+# System 'libvpx' is too new.
+ac_add_options --without-system-libvpx
+
+ac_add_options --with-system-pixman
+ac_add_options --with-system-ffi
+
+ac_add_options --disable-gconf
+ac_add_options --disable-profiling
+ac_add_options --disable-accessibility
+ac_add_options --disable-tests
+ac_add_options --disable-system-extension-dirs
+ac_add_options --disable-parental-controls
+ac_add_options --disable-debug-symbols
+ac_add_options --disable-callgrind
+ac_add_options --disable-vtune
+
+# Settings for musl.
+ac_add_options --disable-elf-hack
+ac_add_options --disable-gold
+ac_add_options --disable-jemalloc
+ac_add_options --enable-release
+
+# ALSA/PulseAudio (removed in 70 (still present in 71b4(?!))
+ac_add_options --disable-pulseaudio
+ac_add_options --enable-alsa
+
+ac_add_options --disable-startup-notification
+
+# Respect the user.
+ac_add_options MOZ_SERVICES_METRICS=
+ac_add_options MOZ_PAY=
+ac_add_options MOZ_SERVICES_HEALTHREPORTER=
+ac_add_options MOZ_SERVICES_FXACCOUNTS=
+ac_add_options MOZ_SERVICES_METRICS=
+ac_add_options MOZ_DATA_REPORTING=
+ac_add_options MOZ_DEVICES=
+ac_add_options MOZ_REQUIRE_SIGNING=
+ac_add_options MOZ_TELEMETRY_REPORTING=
+ac_add_options --disable-crashreporter
+ac_add_options --disable-updater
+ac_add_options --disable-dbus
+ac_add_options --disable-eme
+ac_add_options --disable-necko-wifi
+ac_add_options --disable-webrtc
diff --git a/extra/firefox/files/policies.json b/extra/firefox/files/policies.json
new file mode 100644
index 00000000..f918c5b5
--- /dev/null
+++ b/extra/firefox/files/policies.json
@@ -0,0 +1,21 @@
+{
+ "policies": {
+ "DisableAppUpdate": true,
+ "DisableFirefoxStudies": true,
+ "DisablePocket": true,
+ "DisableTelemetry": true,
+ "DontCheckDefaultBrowser": true,
+ "DisableFeedbackCommands": true,
+ "DisableFirefoxAccounts": true,
+ "DisableFirefoxScreenshots": true,
+ "DisableFirefoxStudies": true,
+ "DisableMasterPasswordCreation": true,
+ "DisableSetDesktopBackground": true,
+ "DisableSystemAddonUpdate": true,
+ "DontCheckDefaultBrowser": true,
+ "ExtensionUpdate": false,
+ "NetworkPrediction": false,
+ "OverridePostUpdatePage": "",
+ "CaptivePortal": false
+ }
+}
diff --git a/extra/firefox/files/stab.h b/extra/firefox/files/stab.h
new file mode 100644
index 00000000..6f70af39
--- /dev/null
+++ b/extra/firefox/files/stab.h
@@ -0,0 +1,71 @@
+/* $OpenBSD: stab.h,v 1.3 2003/06/02 19:34:12 millert Exp $ */
+/* $NetBSD: stab.h,v 1.4 1994/10/26 00:56:25 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)stab.h 5.2 (Berkeley) 4/4/91
+ */
+
+#ifndef _STAB_H_
+#define _STAB_H_
+
+/*
+ * The following are symbols used by various debuggers and by the Pascal
+ * compiler. Each of them must have one (or more) of the bits defined by
+ * the N_STAB mask set.
+ */
+
+#define N_GSYM 0x20 /* global symbol */
+#define N_FNAME 0x22 /* F77 function name */
+#define N_FUN 0x24 /* procedure name */
+#define N_STSYM 0x26 /* data segment variable */
+#define N_LCSYM 0x28 /* bss segment variable */
+#define N_MAIN 0x2a /* main function name */
+#define N_PC 0x30 /* global Pascal symbol */
+#define N_RSYM 0x40 /* register variable */
+#define N_SLINE 0x44 /* text segment line number */
+#define N_DSLINE 0x46 /* data segment line number */
+#define N_BSLINE 0x48 /* bss segment line number */
+#define N_SSYM 0x60 /* structure/union element */
+#define N_SO 0x64 /* main source file name */
+#define N_LSYM 0x80 /* stack variable */
+#define N_BINCL 0x82 /* include file beginning */
+#define N_SOL 0x84 /* included source file name */
+#define N_PSYM 0xa0 /* parameter variable */
+#define N_EINCL 0xa2 /* include file end */
+#define N_ENTRY 0xa4 /* alternate entry point */
+#define N_LBRAC 0xc0 /* left bracket */
+#define N_EXCL 0xc2 /* deleted include file */
+#define N_RBRAC 0xe0 /* right bracket */
+#define N_BCOMM 0xe2 /* begin common */
+#define N_ECOMM 0xe4 /* end common */
+#define N_ECOML 0xe8 /* end common (local name) */
+#define N_LENG 0xfe /* length of preceding entry */
+
+#endif /* !_STAB_H_ */
diff --git a/extra/firefox/files/vendor.js b/extra/firefox/files/vendor.js
new file mode 100644
index 00000000..65bc0d95
--- /dev/null
+++ b/extra/firefox/files/vendor.js
@@ -0,0 +1,619 @@
+// KISS' vendor.js.
+//
+// Sources:
+// - GNU IceCat,
+// - OpenBSD,
+// - GHacks user.js
+// - pyllyukko/user.js
+// - anarcat/firefox-tmp
+// - Debian
+
+//
+// STARTUP
+//
+
+pref("browser.newtab.preload", false);
+pref("browser.newtabpage.directory.ping", "");
+pref("browser.newtabpage.directory.source", "data:application/json,{}");
+pref("browser.newtabpage.enabled", false);
+pref("browser.newtabpage.enhanced", false);
+pref("browser.newtabpage.introShown", false);
+pref("browser.newtabpage.activity-stream.feeds.telemetry", false);
+pref("browser.newtabpage.activity-stream.telemetry", false);
+pref("browser.newtabpage.activity-stream.telemetry.ping.endpoint", "");
+pref("browser.newtabpage.activity-stream.telemetry.ut.events", false);
+pref("browser.newtabpage.activity-stream.telemetry.structuredIngestion", false);
+pref("browser.newtabpage.activity-stream.feeds.snippets", false);
+pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "");
+pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
+pref("browser.newtabpage.activity-stream.section.highlights.includePocket", false);
+pref("browser.newtabpage.activity-stream.showSponsored", false);
+pref("browser.newtabpage.activity-stream.feeds.discoverystreamfeed", false);
+
+//
+// GEO
+//
+
+pref("geo.enabled", false);
+pref("geo.provider.use_gpsd", false);
+pref("geo.wifi.uri", "");
+pref("browser.search.geoip.url", "");
+pref("browser.search.geoSpecificDefaults", false);
+pref("browser.search.geoSpecificDefaults.url", "");
+
+//
+// LANGUAGE
+//
+
+pref("intl.accept_languages", "en-US, en");
+pref("javascript.use_us_english_locale", true);
+pref("intl.charset.fallback.override", "windows-1252");
+
+//
+// SILENT FIREFOX
+//
+
+pref("app.update.auto", false);
+pref("app.update.enabled", false);
+pref("browser.newtabbage.enabled", false);
+pref("browser.search.update", false);
+pref("extensions.getAddons.showPane", false);
+pref("extensions.htmlaboutaddons.recommendations.enabled", false);
+pref("toolkit.telemetry.unified", false);
+pref("toolkit.telemetry.server", "data:,");
+pref("toolkit.telemetry.archive.enabled", false);
+pref("toolkit.telemetry.newProfilePing.enabled", false);
+pref("toolkit.telemetry.shutdownPingSender.enabled", false);
+pref("toolkit.telemetry.updatePing.enabled", false);
+pref("toolkit.telemetry.bhrPing.enabled", false);
+pref("toolkit.telemetry.firstShutdownPing.enabled", false);
+pref("toolkit.telemetry.hybridContent.enabled", false);
+pref("toolkit.telemetry.coverage.opt-out", true);
+pref("toolkit.telemetry.shutdownPingSender.enabledFirstSession", false);
+pref("toolkit.telemetry.server_owner", "");
+pref("toolkit.telemetry.geckoview.streaming", false);
+pref("toolkit.telemetry.ecosystemtelemetry.enabled", false);
+pref("toolkit.telemetry.cachedClientID", "");
+pref("toolkit.telemetry.enabled", false);
+pref("toolkit.telemetry.rejected", true);
+pref("toolkit.telemetry.server", "");
+pref("toolkit.telemetry.unifiedIsOptIn", false);
+pref("toolkit.telemetry.prompted", 2);
+pref("security.protectionspopup.recordEventTelemetry", false);
+pref("security.identitypopup.recordEventTelemetry", false);
+pref("privacy.trackingprotection.origin_telemetry.enabled", false);
+pref("privacy.trackingprotection.pbmode.enabled", false);
+pref("permissions.eventTelemetry.enabled", false);
+pref("browser.urlbar.eventTelemetry.enabled", false);
+pref("toolkit.coverage.opt-out", true);
+pref("toolkit.coverage.endpoint.base", "");
+pref("datareporting.healthreport.uploadEnabled", false);
+pref("datareporting.policy.dataSubmissionEnabled", false);
+pref("datareporting.healthreport.about.reportUrl", "127.0.0.1");
+pref("datareporting.healthreport.documentServerURI", "127.0.0.1");
+pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
+pref("datareporting.policy.firstRunURL", "");
+pref("startup.homepage_welcome_url.additional", "");
+pref("browser.startup.firstrunSkipsHomepage", true);
+pref("healthreport.uploadEnabled", false);
+pref("social.toast-notifications.enabled", false);
+pref("datareporting.healthreport.service.enabled", false);
+pref("browser.slowStartup.notificationDisabled", true);
+pref("network.http.sendRefererHeader", 2);
+pref("network.http.referer.spoofSource", false);
+pref("app.shield.optoutstudies.enabled", false);
+pref("extensions.shield-recipe-client.enabled", false);
+pref("browser.discovery.enabled", false);
+pref("breakpad.reportURL", "");
+pref("browser.tabs.crashReporting.sendReport", false);
+pref("browser.crashReports.unsubmittedCheck.enabled", false);
+pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false);
+pref("captivedetect.canonicalURL", "");
+pref("network.captive-portal-service.enabled", false);
+pref("network.connectivity-service.enabled", false);
+pref("extensions.blocklist.enabled", false);
+pref("privacy.announcements.enabled", false);
+pref("browser.snippets.enabled", false);
+pref("browser.snippets.syncPromo.enabled", false);
+pref("browser.snippets.geoUrl", "http://127.0.0.1/");
+pref("browser.snippets.updateUrl", "http://127.0.0.1/");
+pref("browser.snippets.statsUrl", "http://127.0.0.1/");
+pref("datareporting.policy.firstRunTime", 0);
+pref("datareporting.policy.dataSubmissionPolicyVersion", 2);
+pref("browser.webapps.checkForUpdates", 0);
+pref("browser.webapps.updateCheckUrl", "http://127.0.0.1/");
+pref("dom.flyweb.enabled", false);
+pref("services.sync.autoconnect", false);
+pref("services.sync.engine.addons", false);
+pref("services.sync.engine.bookmarks", false);
+pref("services.sync.engine.history", false);
+pref("services.sync.engine.passwords", false);
+pref("services.sync.engine.prefs", false);
+pref("services.sync.engine.tabs", false);
+pref("extensions.webservice.discoverURL", "");
+pref("browser.shell.checkDefaultBrowser", false);
+pref("shell.checkDefaultClient", false);
+pref("browser.newtabpage.directory.source", 'data:application/json,{}');
+pref("browser.urlbar.suggest.searches", false);
+pref("geo.wifi.scan", false);
+pref("dom.push.connection.enabled", false);
+pref("extensions.update.url", "");
+pref("extensions.update.background.url", "");
+pref("extensions.blocklist.detailsURL", "");
+pref("extensions.blocklist.itemURL", "");
+pref("extensions.blocklist.url", "");
+pref("extensions.hotfix.url", "");
+pref("extensions.getAddons.get.url", "");
+pref("extensions.getAddons.getWithPerformance.url", "");
+pref("extensions.getAddons.search.browseURL", "");
+pref("services.settings.server", "");
+pref("datareporting.healthreport.documentServerURI", "");
+pref("general.useragent.updates.enabled", false);
+pref("general.useragent.updates.url", "");
+pref("identity.fxaccounts.auth.uri", "");
+pref("identity.fxaccounts.remote.root", "");
+pref("identity.fxaccounts.skipDeviceRegistration", true);
+pref("browser.translation.bing.authURL", "");
+pref("browser.translation.bing.translateArrayURL", "");
+pref("browser.translation.yandex.translateURLOverride", "");
+pref("browser.translation.engine", "bing");
+pref("browser.aboutHomeSnippets.updateUrl", "nonexistent://test");
+pref("browser.newtabpage.activity-stream.default.sites", "");
+pref("browser.newtabpage.activity-stream.tippyTop.service.endpoint", "");
+pref("browser.uitour.pinnedTabUrl", "");
+pref("browser.uitour.url", "");
+pref("browser.search.isUS", true);
+pref("browser.search.countryCode", "US");
+pref("browser.ping-centre.staging.endpoint", "");
+pref("browser.ping-centre.production.endpoint", "");
+pref("browser.contentblocking.report.monitor.sign_in_url", "");
+pref("browser.contentblocking.report.monitor.url", "");
+pref("identity.fxaccounts.service.monitorLoginUrl", "");
+pref("network.trr.resolvers", "");
+pref("network.trr.uri", "");
+pref("security.certerrors.mitm.priming.endpoint", "");
+pref("signon.management.page.breachAlertUrl", "");
+pref("network.connectivity-service.IPv4.url", "");
+pref("network.connectivity-service.IPv6.url", "");
+pref("accessibility.support.url", "");
+pref("app.feedback.baseURL", "");
+pref("app.normandy.shieldLearnMoreUrl", "");
+pref("app.update.url", "");
+pref("browser.chrome.errorReporter.infoURL", "");
+pref("browser.contentblocking.report.cookie.url", "");
+pref("browser.dictionaries.download.url", "");
+pref("browser.safebrowsing.provider.google.reportMalwareMistakeURL", "");
+pref("browser.safebrowsing.provider.google.reportPhishMistakeURL", "");
+pref("browser.safebrowsing.provider.google.reportURL", "");
+pref("browser.safebrowsing.provider.google4.dataSharingURL", "");
+pref("browser.safebrowsing.provider.google4.reportMalwareMistakeURL", "");
+pref("browser.safebrowsing.provider.google4.reportPhishMistakeURL", "");
+pref("browser.safebrowsing.provider.google4.reportURL", "");
+pref("browser.safebrowsing.reportPhishURL", "");
+pref("devtools.devices.url", "");
+pref("devtools.performance.recording.ui-base-url", "");
+pref("devtools.webide.templatesURL", "");
+pref("extensions.getAddons.compatOverides.url", "");
+pref("extensions.getAddons.discovery.api_url", "");
+pref("extensions.getAddons.langpacks.url", "");
+pref("extensions.recommendations.themeRecommendationUrl", "");
+pref("gecko.handlerService.schemes.webcal.0.name", "");
+pref("gecko.handlerService.schemes.webcal.0.uriTemplate", "");
+pref("gecko.handlerService.schemes.irc.0.name", "");
+pref("gecko.handlerService.schemes.irc.0.uriTemplate", "");
+pref("media.gmp-manager.url", "");
+
+// Firefox connects to cloudfront on startup unless
+// these are false/blank.
+pref("browser.selfsupport.url", "");
+
+//
+// "SAFE" BROWSING
+//
+
+pref("browser.safebrowsing.malware.enabled", false);
+pref("browser.safebrowsing.phishing.enabled", false);
+pref("browser.safebrowsing.downloads.enabled", false);
+pref("browser.safebrowsing.downloads.remote.enabled", false);
+pref("browser.safebrowsing.downloads.remote.url", "");
+pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
+pref("browser.safebrowsing.downloads.remote.block_uncommon", false);
+pref("browser.safebrowsing.provider.mozilla.updateURL", "");
+pref("browser.safebrowsing.provider.mozilla.gethashURL", "");
+pref("browser.safebrowsing.provider.google.gethashURL", "");
+pref("browser.safebrowsing.provider.google.updateURL", "");
+pref("browser.safebrowsing.provider.google4.gethashURL", "");
+pref("browser.safebrowsing.provider.google4.updateURL", "");
+pref("privacy.trackingprotection.introURL", "");
+
+//
+// EXPERIMENTS
+//
+
+pref("app.normandy.enabled", false);
+pref("app.normandy.api_url", "");
+pref("app.normandy.user_id", "");
+pref("extensions.systemAddon.update.url", "");
+pref("browser.ping-centre.telemetry", false);
+pref("extensions.screenshots.disabled", true);
+pref("extensions.screenshots.upload-disabled", true);
+pref("extensions.formautofill.addresses.enabled", false);
+pref("extensions.formautofill.available", "off");
+pref("extensions.formautofill.creditCards.enabled", false);
+pref("extensions.formautofill.heuristics.enabled", false);
+pref("extensions.webcompat-reporter.enabled", false);
+pref("experiments.supported", false);
+pref("experiments.enabled", false);
+pref("experiments.manifest.uri", "");
+pref("network.allow-experiments", false);
+pref("privacy.trackingprotection.enabled", false);
+
+//
+// IMPLICIT OUTBOUND CONNECTIONS
+//
+
+pref("network.prefetch-next", false);
+pref("network.dns.disablePrefetch", true);
+pref("network.dns.disablePrefetchFromHTTPS", true);
+pref("network.http.keep-alive.timeout", 15);
+pref("network.predictor.enabled", false);
+pref("network.predictor.enable-prefetch", false);
+pref("network.http.speculative-parallel-limit", 0);
+pref("browser.startup.page", 0);
+pref("browser.send_pings", false);
+pref("browser.send_pings.require_same_host", true);
+pref("network.dns.blockDotOnion", true);
+pref("browser.casting.enabled", false);
+
+//
+// PROTOCOLS
+//
+
+pref("network.dns.disableIPv6", true);
+pref("network.http.altsvc.enabled", false);
+pref("network.http.altsvc.oe", false);
+pref("network.proxy.socks_remote_dns", true);
+pref("network.trr.mode", 5);
+pref("network.file.disable_unc_paths", true);
+pref("network.gio.supported-protocols", "");
+pref("network.http.pipelining", true);
+pref("network.http.proxy.pipelining", true);
+pref("network.http.pipelining.maxrequests", 10);
+pref("nglayout.initialpaint.delay", 0);
+pref("network.protocol-handler.warn-external-default", true);
+pref("network.protocol-handler.external.http", false);
+pref("network.protocol-handler.external.https", false);
+pref("network.protocol-handler.external.javascript",false);
+pref("network.protocol-handler.external.moz-extension", false);
+pref("network.protocol-handler.external.ftp", false);
+pref("network.protocol-handler.external.file", false);
+pref("network.protocol-handler.external.about", false);
+pref("network.protocol-handler.external.chrome", false);
+pref("network.protocol-handler.external.blob", false);
+pref("network.protocol-handler.external.data", false);
+pref("network.protocol-handler.expose-all", false);
+pref("network.protocol-handler.expose.http", true);
+pref("network.protocol-handler.expose.https", true);
+pref("network.protocol-handler.expose.javascript", true);
+pref("network.protocol-handler.expose.moz-extension", true);
+pref("network.protocol-handler.expose.ftp", true);
+pref("network.protocol-handler.expose.file", true);
+pref("network.protocol-handler.expose.about", true);
+pref("network.protocol-handler.expose.chrome", true);
+pref("network.protocol-handler.expose.blob", true);
+pref("network.protocol-handler.expose.data", true);
+
+//
+// SEARCH / AUTOFILL / FORMS
+//
+
+pref("browser.fixup.alternate.enabled", false);
+pref("browser.urlbar.trimURLs", false);
+pref("browser.sessionhistory.max_entries", 10);
+pref("layout.css.visited_links_enabled", false);
+pref("browser.search.suggest.enabled", false);
+pref("browser.urlbar.usepreloadedtopurls.enabled", false);
+pref("browser.urlbar.speculativeConnect.enabled", false);
+pref("browser.formfill.enable", false);
+pref("browser.taskbar.lists.enabled", false);
+pref("browser.taskbar.lists.frequent.enabled", false);
+pref("browser.taskbar.lists.recent.enabled", false);
+pref("browser.taskbar.lists.tasks.enabled", false);
+pref("browser.taskbar.previews.enable", false);
+
+//
+// PASSWORDS
+//
+
+pref("signon.autofillForms", false);
+pref("signon.formlessCapture.enabled", false);
+pref("network.auth.subresource-http-auth-allow", 1);
+
+//
+// CACHE
+//
+
+pref("browser.cache.disk.enable", false);
+pref("browser.sessionstore.privacy_level", 2);
+pref("browser.sessionstore.interval", 30000);
+pref("toolkit.winRegisterApplicationRestart", false);
+pref("browser.shell.shortcutFavicons", false);
+pref("alerts.showFavicons", false);
+
+//
+// CIPHERS
+//
+
+pref("security.ssl.require_safe_negotiation", true);
+pref("security.ssl.disable_session_identifiers", true);
+pref("security.ssl.errorReporting.automatic", false);
+pref("security.tls.enable_0rtt_data", false);
+pref("security.ssl.enable_ocsp_stapling", true);
+pref("security.OCSP.enabled", 1);
+pref("security.OCSP.require", true);
+pref("security.pki.sha1_enforcement_level", 1);
+pref("security.family_safety.mode", 0);
+pref("security.cert_pinning.enforcement_level", 2);
+pref("security.ssl.errorReporting.enabled", false);
+pref("security.ssl.errorReporting.url", "");
+pref("security.mixed_content.block_active_content", true);
+pref("security.mixed_content.block_display_content", true);
+pref("security.mixed_content.block_object_subrequest", true);
+pref("security.ssl.treat_unsafe_negotiation_as_broken", true);
+pref("browser.ssl_override_behavior", 1);
+pref("browser.xul.error_pages.expert_bad_cert", true);
+pref("security.insecure_connection_icon.enabled", true);
+pref("security.insecure_connection_text.enabled", true);
+pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", false);
+pref("security.ssl3.ecdhe_rsa_rc4_128_sha", false);
+pref("security.ssl3.rsa_rc4_128_md5", false);
+pref("security.ssl3.rsa_rc4_128_sha", false);
+pref("security.tls.version.min", 1);
+pref("security.ssl3.dhe_rsa_aes_128_sha", false);
+pref("security.ssl3.dhe_rsa_aes_256_sha", false);
+
+//
+// FONTS
+//
+
+pref("gfx.font_rendering.opentype_svg.enabled", false);
+pref("gfx.font_rendering.graphite.enabled", false);
+
+//
+// HEADERS / REFERERS
+//
+
+pref("network.http.referer.XOriginPolicy", 2);
+pref("network.http.referer.XOriginTrimmingPolicy", 0);
+pref("network.http.referer.hideOnionSource", true);
+pref("privacy.donottrackheader.enabled", true);
+
+//
+// CONTAINERS
+//
+
+pref("privacy.userContext.ui.enabled", true);
+pref("privacy.userContext.enabled", true);
+pref("privacy.usercontext.about_newtab_segregation.enabled", true);
+pref("privacy.userContext.longPressBehavior", 2);
+
+//
+// PLUGINS
+//
+
+pref("plugin.state.flash", 0);
+pref("plugin.state.java", 0);
+pref("media.gmp-widevinecdm.visible", false);
+pref("media.gmp-widevinecdm.enabled", false);
+pref("media.eme.enabled", false);
+pref("media.gmp-manager.url.override", "data:text/plain,");
+pref("browser.eme.ui.enabled", false);
+pref("media.eme.apiVisible", false);
+pref("media.gmp-provider.enabled", false);
+pref("media.gmp-gmpopenh264.enabled", false);
+pref("media.gmp-gmpopenh264.provider.enabled", false);
+pref("plugins.hide_infobar_for_missing_plugin", true);
+pref("plugins.hide_infobar_for_outdated_plugin", true);
+pref("plugins.notifyMissingFlash", false);
+pref("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", false);
+pref("dom.ipc.plugins.reportCrashURL", false);
+pref("plugins.click_to_play", true);
+
+//
+// CAMERA / MIC
+//
+
+pref("media.peerconnection.enabled", false);
+pref("media.peerconnection.ice.default_address_only", true);
+pref("media.peerconnection.ice.no_host", true);
+pref("webgl.disabled", true);
+pref("webgl.dxgl.enabled", false);
+pref("webgl.enable-webgl2", false);
+pref("webgl.min_capability_mode", true);
+pref("webgl.disable-extensions", true);
+pref("webgl.disable-fail-if-major-performance-caveat", true);
+pref("media.getusermedia.screensharing.enabled", false);
+pref("media.getusermedia.browser.enabled", false);
+pref("media.getusermedia.audiocapture.enabled", false);
+pref("media.autoplay.enabled.user-gestures-needed", false);
+pref("media.block-autoplay-until-in-foreground", true);
+
+//
+// WINDOW MEDDLING / POPUPS
+//
+
+pref("dom.disable_window_open_feature.close", true);
+pref("dom.disable_window_open_feature.location", true);
+pref("dom.disable_window_open_feature.menubar", true);
+pref("dom.disable_window_open_feature.minimizable", true);
+pref("dom.disable_window_open_feature.personalbar", true);
+pref("dom.disable_window_open_feature.resizable", true);
+pref("dom.disable_window_open_feature.status", true);
+pref("dom.disable_window_open_feature.titlebar", true);
+pref("dom.disable_window_open_feature.toolbar", true);
+pref("dom.disable_window_move_resize", true);
+pref("browser.link.open_newwindow", 3);
+pref("browser.link.open_newwindow.restriction", 0);
+pref("dom.disable_open_during_load", true);
+pref("dom.popup_allowed_events", "click dblclick");
+
+//
+// WEB WORKERS
+//
+
+pref("dom.serviceWorkers.enabled", false);
+pref("dom.push.enabled", false);
+pref("dom.webnotifications.enabled", false);
+pref("dom.webnotifications.serviceworker.enabled", false);
+pref("permissions.default.desktop-notification", 2);
+
+//
+// DOM / JAVASCRIPT
+//
+
+pref("dom.event.clipboardevents.enabled", false);
+pref("middlemouse.paste", false);
+pref("dom.allow_cut_copy", false);
+pref("dom.disable_beforeunload", true);
+pref("dom.vibrator.enabled", false);
+pref("javascript.options.asmjs", false);
+pref("javascript.options.wasm", false);
+pref("dom.targetBlankNoOpener.enabled", true);
+
+//
+// HARDWARE FINGERPRINTING
+//
+
+pref("dom.battery.enabled", false);
+pref("dom.vr.enabled", false);
+pref("media.navigator.enabled", false);
+pref("dom.webaudio.enabled", false);
+
+//
+// MISC
+//
+
+pref("accessibility.force_disabled", 1);
+pref("beacon.enabled", false);
+pref("browser.helperApps.deleteTempFileOnExit", true);
+pref("browser.pagethumbnails.capturing_disabled", true);
+pref("browser.tabs.remote.allowLinkedWebInFileUriProcess", false);
+pref("browser.uitour.enabled", false);
+pref("devtools.chrome.enabled", false);
+pref("devtools.debugger.remote-enabled", false);
+pref("devtools.webide.enabled", false);
+pref("devtools.webide.autoinstallADBExtension", false);
+pref("middlemouse.contentLoadURL", false);
+pref("network.http.redirection-limit", 10);
+pref("permissions.manager.defaultsUrl", "");
+pref("webchannel.allowObject.urlWhitelist", "");
+pref("network.IDN_show_punycode", true);
+pref("social.whitelist", "");
+pref("social.directories", "");
+pref("social.shareDirectory", "");
+pref("browser.apps.URL", "");
+pref("dom.enable_user_timing", false);
+pref("dom.mozTCPSocket.enabled", false);
+pref("dom.netinfo.enabled", false);
+pref("dom.telephony.enabled", false);
+pref("media.webspeech.recognition.enable", false);
+pref("device.sensors.enabled", false);
+pref("media.webspeech.synth.enabled", false);
+pref("dom.gamepad.enabled", false);
+pref("dom.enable_resource_timing", false);
+pref("dom.archivereader.enabled", false);
+pref("camera.control.face_detection.enabled", false);
+pref("browser.search.region", "US");
+pref("intl.locale.matchOS", false);
+pref("clipboard.autocopy", false);
+pref("browser.fixup.alternate.enabled", false);
+pref("media.video_stats.enabled", false);
+pref("devtools.chrome.enabled", false);
+pref("devtools.debugger.force-local", true);
+pref("browser.startup.homepage_override.mstone", "ignore");
+
+// Taken from TOR browser.
+pref("general.buildID.override", "20100101");
+pref("browser.startup.homepage_override.buildID", "20100101");
+pref("toolkit.telemetry.previousBuildID", "20100101");
+
+//
+// DOWNLOADS
+//
+
+pref("browser.download.useDownloadDir", false);
+pref("browser.download.manager.addToRecentDocs", false);
+pref("browser.download.hide_plugins_without_extensions", false);
+
+//
+// EXTENSIONS
+//
+
+pref("extensions.enabledScopes", 5);
+pref("extensions.autoDisableScopes", 15);
+pref("extensions.update.enabled", false);
+pref("xpinstall.signatures.required", true);
+pref("extensions.getAddons.cache.enabled", false);
+pref("lightweightThemes.update.enabled", false);
+pref("extensions.systemAddon.update.enabled", false);
+pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr", false);
+pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", false);
+pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", false);
+
+//
+// STORAGE
+//
+
+pref("browser.cache.offline.enable", false);
+pref("offline-apps.allow_by_default", false);
+
+//
+// SHUTDOWN
+//
+
+pref("privacy.sanitize.sanitizeOnShutdown", true);
+pref("privacy.clearOnShutdown.formdata", true);
+pref("privacy.clearOnShutdown.offlineApps", true);
+pref("privacy.clearOnShutdown.sessions", true);
+pref("privacy.clearOnShutdown.siteSettings", false);
+pref("privacy.cpd.cache", true);
+pref("privacy.cpd.cookies", true);
+pref("privacy.cpd.formdata", true);
+pref("privacy.cpd.history", true);
+pref("privacy.cpd.offlineApps", true);
+pref("privacy.cpd.passwords", false);
+pref("privacy.cpd.sessions", true);
+pref("privacy.cpd.siteSettings", false);
+pref("privacy.sanitize.timeSpan", 0);
+
+//
+// ISOLATION
+//
+
+pref("privacy.firstparty.isolate", true);
+pref("privacy.firstparty.isolate.restrict_opener_access", true);
+pref("browser.startup.blankWindow", false);
+
+//
+// POCKET / HELLO
+//
+
+pref("loop.enabled", false);
+pref("loop.feedback.baseUrl", "");
+pref("loop.gettingStarted.url", "");
+pref("loop.learnMoreUrl", "");
+pref("loop.legal.ToS_url", "");
+pref("loop.legal.privacy_url", "");
+pref("loop.oauth.google.redirect_uri", "");
+pref("loop.oauth.google.scope", "");
+pref("loop.server", "");
+pref("loop.soft_start_hostname", "");
+pref("loop.support_url", "");
+pref("loop.throttled2", false);
+pref("loop.logDomains", false);
+pref("browser.pocket.enabled", false);
+pref("browser.pocket.api", "");
+pref("browser.pocket.site", "");
+pref("browser.pocket.oAuthConsumerKey", "");
+pref("browser.pocket.useLocaleList", false);
+pref("browser.pocket.enabledLocales", "");
diff --git a/extra/firefox/patches/firefox-71-no-accessibility.patch b/extra/firefox/patches/firefox-71-no-accessibility.patch
new file mode 100644
index 00000000..b744c577
--- /dev/null
+++ b/extra/firefox/patches/firefox-71-no-accessibility.patch
@@ -0,0 +1,13 @@
+diff -r 22ced1a079e0 accessible/ipc/extension/other/moz.build
+--- a/accessible/ipc/extension/other/moz.build Mon Sep 16 22:30:52 2019 +0300
++++ b/accessible/ipc/extension/other/moz.build Tue Sep 17 23:17:02 2019 +0200
+@@ -9,7 +9,8 @@
+
+ IPDL_SOURCES += ['PDocAccessiblePlatformExt.ipdl']
+
+-if CONFIG['ACCESSIBILITY']:
++#if CONFIG['ACCESSIBILITY']:
++if 1:
+ EXPORTS.mozilla.a11y += [
+ 'DocAccessiblePlatformExtChild.h',
+ 'DocAccessiblePlatformExtParent.h',
diff --git a/extra/firefox/patches/firefox-71-no-dbus.patch b/extra/firefox/patches/firefox-71-no-dbus.patch
new file mode 100644
index 00000000..0dba95a9
--- /dev/null
+++ b/extra/firefox/patches/firefox-71-no-dbus.patch
@@ -0,0 +1,425 @@
+diff --git a/Cargo.lock b/Cargo.lock
+index e0fd54008d..c8a3033238 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -72,24 +72,10 @@ dependencies = [
+ "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
+ ]
+
+-[[package]]
+-name = "audio_thread_priority"
+-version = "0.20.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "dbus 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mach 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
+-]
+-
+ [[package]]
+ name = "audioipc"
+ version = "0.2.4"
+ dependencies = [
+- "audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -117,7 +103,6 @@ dependencies = [
+ name = "audioipc-client"
+ version = "0.4.0"
+ dependencies = [
+- "audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "audioipc 0.2.4",
+ "cubeb-backend 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -130,7 +115,6 @@ dependencies = [
+ name = "audioipc-server"
+ version = "0.2.3"
+ dependencies = [
+- "audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "audioipc 0.2.4",
+ "cubeb-core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -837,15 +821,6 @@ dependencies = [
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ ]
+
+-[[package]]
+-name = "dbus"
+-version = "0.6.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libdbus-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+ [[package]]
+ name = "deflate"
+ version = "0.7.19"
+@@ -1219,7 +1194,6 @@ name = "gkrust-shared"
+ version = "0.1.0"
+ dependencies = [
+ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "audioipc-client 0.4.0",
+ "audioipc-server 0.2.3",
+ "authenticator 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -1559,14 +1533,6 @@ name = "libc"
+ version = "0.2.60"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+
+-[[package]]
+-name = "libdbus-sys"
+-version = "0.1.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+ [[package]]
+ name = "libloading"
+ version = "0.5.0"
+@@ -3811,7 +3777,6 @@ dependencies = [
+ "checksum atomic 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c210c1f4db048cda477b652d170572d84c9640695835f17663595d3bd543fc28"
+ "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
+ "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
+-"checksum audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)" = "197b2d259505d11c92d266e1784f01cc935eb764d2f54e16aedf4e5085197871"
+ "checksum authenticator 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ec149e5d5d4caa2c9ead53a8ce1ea9c4204c388c65bf3b96c2d1dc0fcf4aeb66"
+ "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
+ "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+@@ -3872,7 +3837,6 @@ dependencies = [
+ "checksum darling 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe629a532efad5526454efb0700f86d5ad7ff001acb37e431c8bf017a432a8e"
+ "checksum darling_core 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ee54512bec54b41cf2337a22ddfadb53c7d4c738494dc2a186d7b037ad683b85"
+ "checksum darling_macro 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cd3e432e52c0810b72898296a69d66b1d78d1517dff6cde7a130557a55a62c1"
+-"checksum dbus 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e1b39f3f6aa3d4a1522c4f0f9f1e9e9167bd93740a8690874caa7cf8ce47d7"
+ "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86"
+ "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
+ "checksum devd-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d009f166c0d9e9f9909dc751630b3a6411ab7f85a153d32d01deb364ffe52a7"
+@@ -3931,7 +3895,6 @@ dependencies = [
+ "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
+ "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
+ "checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
+-"checksum libdbus-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "18cb88963258d00f4962205dbb5933d82780d9962c8c8a064b651d2ad7189210"
+ "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
+ "checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe"
+ "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
+diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
+index 393fb53c02..15ddd2cf70 100644
+--- a/dom/ipc/ContentChild.cpp
++++ b/dom/ipc/ContentChild.cpp
+@@ -107,9 +107,7 @@
+ #include "nsIStringBundle.h"
+ #include "nsIWorkerDebuggerManager.h"
+ #include "nsGeolocation.h"
+-#include "audio_thread_priority.h"
+ #include "nsIConsoleService.h"
+-#include "audio_thread_priority.h"
+
+ #if !defined(XP_WIN)
+ # include "mozilla/Omnijar.h"
+@@ -1782,9 +1780,6 @@ mozilla::ipc::IPCResult ContentChild::RecvSetProcessSandbox(
+ } else {
+ // Pre-start audio before sandboxing; see bug 1443612.
+ if (Preferences::GetBool("media.cubeb.sandbox")) {
+- if (atp_set_real_time_limit(0, 48000)) {
+- NS_WARNING("could not set real-time limit at process startup");
+- }
+ InstallSoftRealTimeLimitHandler();
+ } else {
+ Unused << CubebUtils::GetCubebContext();
+diff --git a/dom/media/GraphRunner.cpp b/dom/media/GraphRunner.cpp
+index 8ff3391f4e..7a97faae76 100644
+--- a/dom/media/GraphRunner.cpp
++++ b/dom/media/GraphRunner.cpp
+@@ -13,7 +13,6 @@
+ #include "nsISupportsImpl.h"
+ #include "prthread.h"
+ #include "Tracing.h"
+-#include "audio_thread_priority.h"
+
+ namespace mozilla {
+
+@@ -93,9 +92,6 @@ bool GraphRunner::OneIteration(GraphTime aStateEnd) {
+ void GraphRunner::Run() {
+ PR_SetCurrentThreadName("GraphRunner");
+
+- atp_handle* handle =
+- atp_promote_current_thread_to_real_time(0, mGraph->GraphRate());
+-
+ MonitorAutoLock lock(mMonitor);
+ while (true) {
+ while (mThreadState == ThreadState::Wait) {
+@@ -111,10 +107,6 @@ void GraphRunner::Run() {
+ mMonitor.Notify();
+ }
+
+- if (handle) {
+- atp_demote_current_thread_from_real_time(handle);
+- }
+-
+ dom::WorkletThread::DeleteCycleCollectedJSContext();
+ }
+
+diff --git a/dom/media/UnderrunHandlerLinux.cpp b/dom/media/UnderrunHandlerLinux.cpp
+index af5c84538e..23bf97a31f 100644
+--- a/dom/media/UnderrunHandlerLinux.cpp
++++ b/dom/media/UnderrunHandlerLinux.cpp
+@@ -9,7 +9,6 @@
+
+ #include <mozilla/Sprintf.h>
+ #include <mozilla/Atomics.h>
+-#include "audio_thread_priority.h"
+
+ namespace mozilla {
+
+@@ -57,20 +56,6 @@ void InstallSoftRealTimeLimitHandler() {
+ }
+
+ void DemoteThreadFromRealTime() {
+- atp_thread_info* info = atp_get_current_thread_info();
+- if (!info) {
+- NS_WARNING("Could not get current thread info when demoting thread.");
+- return;
+- }
+- int rv = atp_demote_thread_from_real_time(info);
+- if (rv) {
+- NS_WARNING("Could not demote thread from real-time.");
+- return;
+- }
+- rv = atp_free_thread_info(info);
+- if (rv) {
+- NS_WARNING("Could not free atp_thread_info struct");
+- }
+ gRealtimeLimitReached = false;
+ }
+
+diff --git a/dom/media/moz.build b/dom/media/moz.build
+index 716c6a2322..840465f04a 100644
+--- a/dom/media/moz.build
++++ b/dom/media/moz.build
+@@ -101,7 +101,6 @@ XPIDL_SOURCES += [
+ XPIDL_MODULE = 'dom_media'
+
+ EXPORTS += [
+- '../../third_party/rust/audio_thread_priority/audio_thread_priority.h',
+ 'ADTSDecoder.h',
+ 'ADTSDemuxer.h',
+ 'AsyncLogger.h',
+diff --git a/media/audioipc/audioipc/Cargo.toml b/media/audioipc/audioipc/Cargo.toml
+index 286e16789b..c34775cea1 100644
+--- a/media/audioipc/audioipc/Cargo.toml
++++ b/media/audioipc/audioipc/Cargo.toml
+@@ -19,7 +19,6 @@ serde = "1.*.*"
+ serde_derive = "1.*.*"
+ tokio = "0.1"
+ tokio-io = "0.1"
+-audio_thread_priority = "0.20.2"
+
+ [target.'cfg(unix)'.dependencies]
+ iovec = "0.1"
+diff --git a/media/audioipc/audioipc/src/messages.rs b/media/audioipc/audioipc/src/messages.rs
+index 9a2ca4d59e..612e8d5050 100644
+--- a/media/audioipc/audioipc/src/messages.rs
++++ b/media/audioipc/audioipc/src/messages.rs
+@@ -9,8 +9,6 @@ use cubeb::{self, ffi};
+ use std::ffi::{CStr, CString};
+ use std::os::raw::{c_char, c_int, c_uint};
+ use std::ptr;
+-#[cfg(target_os = "linux")]
+-use audio_thread_priority::RtPriorityThreadInfo;
+
+ #[derive(Debug, Serialize, Deserialize)]
+ pub struct Device {
+@@ -209,9 +207,6 @@ pub enum ServerMessage {
+ StreamSetVolume(usize, f32),
+ StreamGetCurrentDevice(usize),
+ StreamRegisterDeviceChangeCallback(usize, bool),
+-
+- #[cfg(target_os = "linux")]
+- PromoteThreadToRealTime([u8; std::mem::size_of::<RtPriorityThreadInfo>()]),
+ }
+
+ // Server -> Client messages.
+diff --git a/media/audioipc/client/Cargo.toml b/media/audioipc/client/Cargo.toml
+index 866cde7e98..eaf9a62cc7 100644
+--- a/media/audioipc/client/Cargo.toml
++++ b/media/audioipc/client/Cargo.toml
+@@ -9,7 +9,6 @@ description = "Cubeb Backend for talking to remote cubeb server."
+ edition = "2018"
+
+ [dependencies]
+-audio_thread_priority = "0.20.2"
+ audioipc = { path="../audioipc" }
+ cubeb-backend = "0.6.0"
+ futures = { version="0.1.18", default-features=false, features=["use_std"] }
+diff --git a/media/audioipc/client/src/context.rs b/media/audioipc/client/src/context.rs
+index c20e281248..e13dbc2d8d 100644
+--- a/media/audioipc/client/src/context.rs
++++ b/media/audioipc/client/src/context.rs
+@@ -6,10 +6,6 @@
+ use crate::{assert_not_in_callback, run_in_callback};
+ use crate::stream;
+ use crate::{ClientStream, G_SERVER_FD, CPUPOOL_INIT_PARAMS};
+-#[cfg(not(target_os = "linux"))]
+-use audio_thread_priority::promote_current_thread_to_real_time;
+-#[cfg(target_os = "linux")]
+-use audio_thread_priority::get_current_thread_info;
+ use audioipc::codec::LengthDelimitedCodec;
+ use audioipc::frame::{framed, Framed};
+ use audioipc::platformhandle_passing::{framed_with_platformhandles, FramedWithPlatformHandles};
+@@ -91,34 +87,6 @@ fn open_server_stream() -> io::Result<audioipc::MessageStream> {
+ }
+ }
+
+-#[cfg(target_os = "linux")]
+-fn promote_thread(rpc: &rpc::ClientProxy<ServerMessage, ClientMessage>)
+-{
+- match get_current_thread_info() {
+- Ok(info) => {
+- let bytes = info.serialize();
+- // Don't wait for the response, this is on the callback thread, which must not block.
+- rpc.call(ServerMessage::PromoteThreadToRealTime(bytes));
+- }
+- Err(_) => {
+- warn!("Could not remotely promote thread to RT.");
+- }
+- }
+-}
+-
+-#[cfg(not(target_os = "linux"))]
+-fn promote_thread(_rpc: &rpc::ClientProxy<ServerMessage, ClientMessage>)
+-{
+- match promote_current_thread_to_real_time(0, 48000) {
+- Ok(_) => {
+- info!("Audio thread promoted to real-time.");
+- }
+- Err(_) => {
+- warn!("Could not promote thread to real-time.");
+- }
+- }
+-}
+-
+ fn register_thread(callback: Option<extern "C" fn(*const ::std::os::raw::c_char)>) {
+ if let Some(func) = callback {
+ let thr = thread::current();
+@@ -127,12 +95,6 @@ fn register_thread(callback: Option<extern "C" fn(*const ::std::os::raw::c_char)
+ }
+ }
+
+-fn promote_and_register_thread(rpc: &rpc::ClientProxy<ServerMessage, ClientMessage>,
+- callback: Option<extern "C" fn(*const ::std::os::raw::c_char)>) {
+- promote_thread(rpc);
+- register_thread(callback);
+-}
+-
+ #[derive(Default)]
+ struct DeviceCollectionCallback {
+ cb: ffi::cubeb_device_collection_changed_callback,
+@@ -235,7 +197,6 @@ impl ContextOps for ClientContext {
+
+ let cpu_pool = futures_cpupool::Builder::new()
+ .name_prefix("AudioIPC")
+- .after_start(move || promote_and_register_thread(&rpc2, params.thread_create_callback))
+ .pool_size(params.pool_size)
+ .stack_size(params.stack_size)
+ .create();
+diff --git a/media/audioipc/server/Cargo.toml b/media/audioipc/server/Cargo.toml
+index 8a628e7090..31f23cbe78 100644
+--- a/media/audioipc/server/Cargo.toml
++++ b/media/audioipc/server/Cargo.toml
+@@ -9,7 +9,6 @@ description = "Remote cubeb server"
+ edition = "2018"
+
+ [dependencies]
+-audio_thread_priority = "0.20.2"
+ audioipc = { path = "../audioipc" }
+ cubeb-core = "0.6.0"
+ futures = "0.1.18"
+diff --git a/media/audioipc/server/src/lib.rs b/media/audioipc/server/src/lib.rs
+index 63b373fe8f..75f8b99123 100644
+--- a/media/audioipc/server/src/lib.rs
++++ b/media/audioipc/server/src/lib.rs
+@@ -11,7 +11,6 @@ extern crate log;
+ #[macro_use]
+ extern crate lazy_static;
+
+-use audio_thread_priority::promote_current_thread_to_real_time;
+ use audioipc::core;
+ use audioipc::platformhandle_passing::framed_with_platformhandles;
+ use audioipc::rpc;
+@@ -64,12 +63,6 @@ fn run() -> Result<ServerWrapper> {
+ trace!("Starting up cubeb audio server event loop thread...");
+
+ let callback_thread = core::spawn_thread("AudioIPC Callback RPC", || {
+- match promote_current_thread_to_real_time(0, 48000) {
+- Ok(_) => {}
+- Err(_) => {
+- debug!("Failed to promote audio callback thread to real-time.");
+- }
+- }
+ trace!("Starting up cubeb audio callback event loop thread...");
+ Ok(())
+ })
+diff --git a/media/audioipc/server/src/server.rs b/media/audioipc/server/src/server.rs
+index 3d98c8fed2..35fff91130 100644
+--- a/media/audioipc/server/src/server.rs
++++ b/media/audioipc/server/src/server.rs
+@@ -30,8 +30,6 @@ use std::rc::Rc;
+ use std::{panic, slice};
+ use tokio::reactor;
+ use tokio::runtime::current_thread;
+-#[cfg(target_os = "linux")]
+-use audio_thread_priority::{RtPriorityThreadInfo, promote_thread_to_real_time};
+
+ use crate::errors::*;
+
+@@ -521,21 +519,6 @@ impl CubebServer {
+ )
+ .unwrap_or_else(error)
+ },
+-
+- #[cfg(target_os = "linux")]
+- ServerMessage::PromoteThreadToRealTime(thread_info) => {
+- let info = RtPriorityThreadInfo::deserialize(thread_info);
+- match promote_thread_to_real_time(info, 0, 48000) {
+- Ok(_) => {
+- info!("Promotion of content process thread to real-time OK");
+- }
+- Err(_) => {
+- warn!("Promotion of content process thread to real-time error");
+- }
+- }
+- ClientMessage::ThreadPromoted
+- },
+-
+ };
+
+ trace!("process_msg: req={:?}, resp={:?}", msg, resp);
+diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml
+index 190503e2ab..dd7f0a5234 100644
+--- a/toolkit/library/rust/shared/Cargo.toml
++++ b/toolkit/library/rust/shared/Cargo.toml
+@@ -40,7 +40,6 @@ bitsdownload = { path = "../../../components/bitsdownload", optional = true }
+ storage = { path = "../../../../storage/rust" }
+ bookmark_sync = { path = "../../../components/places/bookmark_sync", optional = true }
+ shift_or_euc_c = "0.1.0"
+-audio_thread_priority = "0.20.2"
+ mdns_service = { path="../../../../media/mtransport/mdns_service", optional = true }
+
+ [build-dependencies]
+diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs
+index f76f53436d..318f904703 100644
+--- a/toolkit/library/rust/shared/lib.rs
++++ b/toolkit/library/rust/shared/lib.rs
+@@ -48,8 +48,6 @@ extern crate shift_or_euc_c;
+
+ extern crate arrayvec;
+
+-extern crate audio_thread_priority;
+-
+ #[cfg(feature = "webrtc")]
+ extern crate mdns_service;
+
diff --git a/extra/firefox/patches/fix-fortify-system-wrappers.patch b/extra/firefox/patches/fix-fortify-system-wrappers.patch
new file mode 100644
index 00000000..17cf7e30
--- /dev/null
+++ b/extra/firefox/patches/fix-fortify-system-wrappers.patch
@@ -0,0 +1,13 @@
+The wrapper features.h gets pulled in by system headers causing thigns to
+break. We work around it by simply not wrap features.h
+
+--- ./config/system-headers.mozbuild.orig
++++ ./config/system-headers.mozbuild
+@@ -229,7 +229,6 @@
+ 'execinfo.h',
+ 'extras.h',
+ 'fcntl.h',
+- 'features.h',
+ 'fenv.h',
+ 'ffi.h',
+ 'fibdef.h',
diff --git a/extra/firefox/patches/fix-sandbox-membarrier.patch b/extra/firefox/patches/fix-sandbox-membarrier.patch
new file mode 100644
index 00000000..4bd3b80d
--- /dev/null
+++ b/extra/firefox/patches/fix-sandbox-membarrier.patch
@@ -0,0 +1,54 @@
+allow usage of SYS_membarrier, needed since musl-1.1.22
+
+Taken from voidlinux: https://github.com/void-linux/void-packages/commit/4198411ac3b9e2620e171c662df82008da0faebb
+
+--- a/security/sandbox/linux/SandboxFilter.cpp
++++ b/security/sandbox/linux/SandboxFilter.cpp
+@@ -572,6 +572,8 @@
+ case __NR_set_tid_address:
+ return Allow();
+ #endif
++ case __NR_membarrier:
++ return Allow();
+
+ // prctl
+ case __NR_prctl: {
+
+--- a/security/sandbox/chromium/sandbox/linux/system_headers/arm_linux_syscalls.h
++++ b/security/sandbox/chromium/sandbox/linux/system_headers/arm_linux_syscalls.h
+@@ -1385,6 +1385,10 @@
+ #define __NR_memfd_create (__NR_SYSCALL_BASE+385)
+ #endif
+
++#if !defined(__NR_membarrier)
++#define __NR_membarrier (__NR_SYSCALL_BASE+389)
++#endif
++
+ // ARM private syscalls.
+ #if !defined(__ARM_NR_BASE)
+ #define __ARM_NR_BASE (__NR_SYSCALL_BASE + 0xF0000)
+
+--- a/security/sandbox/chromium/sandbox/linux/system_headers/x86_64_linux_syscalls.h
++++ b/security/sandbox/chromium/sandbox/linux/system_headers/x86_64_linux_syscalls.h
+@@ -1290,5 +1290,9 @@
+ #define __NR_memfd_create 319
+ #endif
+
++#if !defined(__NR_membarrier)
++#define __NR_membarrier 324
++#endif
++
+ #endif // SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_SYSCALLS_H_
+
+--- a/security/sandbox/chromium/sandbox/linux/system_headers/x86_32_linux_syscalls.h
++++ b/security/sandbox/chromium/sandbox/linux/system_headers/x86_32_linux_syscalls.h
+@@ -1490,5 +1490,9 @@
+ #define __NR_shutdown 373
+ #endif
+
++#if !defined(__NR_membarrier)
++#define __NR_membarrier 375
++#endif
++
+ #endif // SANDBOX_LINUX_SYSTEM_HEADERS_X86_32_LINUX_SYSCALLS_H_
+
diff --git a/extra/firefox/patches/fix-seccomp-bpf.patch b/extra/firefox/patches/fix-seccomp-bpf.patch
new file mode 100644
index 00000000..da102b46
--- /dev/null
+++ b/extra/firefox/patches/fix-seccomp-bpf.patch
@@ -0,0 +1,14 @@
+--- a/security/sandbox/chromium/sandbox/linux/seccomp-bpf/trap.cc
++++ b/security/sandbox/chromium/sandbox/linux/seccomp-bpf/trap.cc
+@@ -25,6 +25,11 @@
+ #include "sandbox/linux/system_headers/linux_seccomp.h"
+ #include "sandbox/linux/system_headers/linux_signal.h"
+
++// musl libc defines siginfo_t __si_fields instead of _sifields
++#if defined(OS_LINUX) && !defined(__GLIBC__)
++#define _sifields __si_fields
++#endif
++
+ namespace {
+
+ struct arch_sigsys {
diff --git a/extra/firefox/patches/fix-toolkit.patch b/extra/firefox/patches/fix-toolkit.patch
new file mode 100644
index 00000000..414734df
--- /dev/null
+++ b/extra/firefox/patches/fix-toolkit.patch
@@ -0,0 +1,90 @@
+diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc
+index 4222ce3..4d40c6a 100644
+--- a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc
++++ b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc
+@@ -46,6 +46,7 @@
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#include <libgen.h>
+
+ #include <iostream>
+ #include <set>
+diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc
+index 6019fc7..5953e32 100644
+--- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc
++++ b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc
+@@ -41,6 +41,10 @@
+
+ #include "common/using_std_string.h"
+
++#ifndef N_UNDF
++#define N_UNDF 0
++#endif
++
+ using std::vector;
+
+ namespace google_breakpad {
+diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h
+index 98ee2dd..d57aa68 100644
+--- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h
++++ b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h
+@@ -55,7 +55,7 @@
+
+ #ifdef HAVE_MACH_O_NLIST_H
+ #include <mach-o/nlist.h>
+-#elif defined(HAVE_A_OUT_H)
++#elif 0
+ #include <a.out.h>
+ #endif
+
+diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h b/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h
+index 93fdad7..f34e5e0 100644
+--- a/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h
++++ b/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h
+@@ -1239,6 +1239,12 @@ struct kernel_statfs {
+ #ifndef __NR_fallocate
+ #define __NR_fallocate 285
+ #endif
++
++#undef __NR_pread
++#define __NR_pread __NR_pread64
++#undef __NR_pwrite
++#define __NR_pwrite __NR_pwrite64
++
+ /* End of x86-64 definitions */
+ #elif defined(__mips__)
+ #if _MIPS_SIM == _MIPS_SIM_ABI32
+diff --git a/toolkit/mozapps/update/common/updatedefines.h b/toolkit/mozapps/update/common/updatedefines.h
+index 79276f7..4c67976 100644
+--- a/toolkit/mozapps/update/common/updatedefines.h
++++ b/toolkit/mozapps/update/common/updatedefines.h
+@@ -87,7 +87,7 @@ static inline int mywcsprintf(WCHAR* dest, size_t count, const WCHAR* fmt,
+
+ # ifdef SOLARIS
+ # include <sys/stat.h>
+-# else
++# elif !defined(__linux__) || defined(__GLIBC__)
+ # include <fts.h>
+ # endif
+ # include <dirent.h>
+diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp
+index 257ccb4..01314e4 100644
+--- a/toolkit/mozapps/update/updater/updater.cpp
++++ b/toolkit/mozapps/update/updater/updater.cpp
+@@ -3978,6 +3978,7 @@
+
+ int add_dir_entries(const NS_tchar* dirpath, ActionList* list) {
+ int rv = OK;
++#if !defined(__linux__) || defined(__GLIBC__)
+ FTS* ftsdir;
+ FTSENT* ftsdirEntry;
+ mozilla::UniquePtr<NS_tchar[]> searchpath(get_full_path(dirpath));
+@@ -4085,6 +4086,7 @@
+ }
+
+ fts_close(ftsdir);
++#endif
+
+ return rv;
+ }
diff --git a/extra/firefox/patches/fix-tools.patch b/extra/firefox/patches/fix-tools.patch
new file mode 100644
index 00000000..93b9d19c
--- /dev/null
+++ b/extra/firefox/patches/fix-tools.patch
@@ -0,0 +1,37 @@
+diff --git a/tools/profiler/core/platform-linux-android.cpp b/tools/profiler/core/platform-linux-android.cpp
+index 19d0a5c56d..b64b543066 100644
+--- a/tools/profiler/core/platform-linux-android.cpp
++++ b/tools/profiler/core/platform-linux-android.cpp
+@@ -506,8 +506,10 @@ static void PlatformInit(PSLockRef aLock) {}
+ ucontext_t sSyncUContext;
+
+ void Registers::SyncPopulate() {
+- if (!getcontext(&sSyncUContext)) {
+- PopulateRegsFromContext(*this, &sSyncUContext);
+- }
++ #if defined(__GLIBC__)
++ if (!getcontext(&sSyncUContext)) {
++ PopulateRegsFromContext(*this, &sSyncUContext);
++ }
++ #endif
+ }
+ #endif
+diff --git a/tools/profiler/lul/LulElf.cpp b/tools/profiler/lul/LulElf.cpp
+index 9998d04d0d..348a7086fc 100644
+--- a/tools/profiler/lul/LulElf.cpp
++++ b/tools/profiler/lul/LulElf.cpp
+@@ -469,10 +469,10 @@ string FormatIdentifier(unsigned char identifier[16]) {
+ // Return the non-directory portion of FILENAME: the portion after the
+ // last slash, or the whole filename if there are no slashes.
+ string BaseFileName(const string& filename) {
+- // Lots of copies! basename's behavior is less than ideal.
+- char* c_filename = strdup(filename.c_str());
+- string base = basename(c_filename);
+- free(c_filename);
++ // basename's behavior is less than ideal so avoid it
++ const char *c_filename = filename.c_str();
++ const char *p = strrchr(c_filename, '/');
++ string base = p ? p+1 : c_filename;
+ return base;
+ }
+
diff --git a/extra/firefox/patches/fix-webrtc-glibcisms.patch b/extra/firefox/patches/fix-webrtc-glibcisms.patch
new file mode 100644
index 00000000..658b076d
--- /dev/null
+++ b/extra/firefox/patches/fix-webrtc-glibcisms.patch
@@ -0,0 +1,20 @@
+--- ./media/webrtc/trunk/webrtc/system_wrappers/source/cpu_features_linux.c.orig 2018-05-09 23:48:44.677389171 +0200
++++ ./media/webrtc/trunk/webrtc/system_wrappers/source/cpu_features_linux.c 2018-05-09 23:48:56.254373557 +0200
+@@ -14,7 +14,7 @@
+ #ifndef __GLIBC_PREREQ
+ #define __GLIBC_PREREQ(a, b) 0
+ #endif
+-#if __GLIBC_PREREQ(2, 16)
++#if !__GLIBC__ || __GLIBC_PREREQ(2, 16)
+ #include <sys/auxv.h>
+ #else
+ #include <fcntl.h>
+@@ -32,7 +32,7 @@
+ int architecture = 0;
+ unsigned long hwcap = 0;
+ const char* platform = NULL;
+-#if __GLIBC_PREREQ(2, 16)
++#if !__GLIBC__ || __GLIBC_PREREQ(2, 16)
+ hwcap = getauxval(AT_HWCAP);
+ platform = (const char*)getauxval(AT_PLATFORM);
+ #else
diff --git a/extra/firefox/patches/mallinfo.patch b/extra/firefox/patches/mallinfo.patch
new file mode 100644
index 00000000..0649413c
--- /dev/null
+++ b/extra/firefox/patches/mallinfo.patch
@@ -0,0 +1,34 @@
+--- a/xpcom/base/nsMemoryReporterManager.cpp.orig 2019-03-19 17:12:20.844810044 +0100
++++ b/xpcom/base/nsMemoryReporterManager.cpp 2019-03-19 17:13:32.505133615 +0100
+@@ -123,6 +123,7 @@
+ return GetProcSelfSmapsPrivate(aN);
+ }
+
++#ifdef __GLIBC__
+ # ifdef HAVE_MALLINFO
+ # define HAVE_SYSTEM_HEAP_REPORTER 1
+ static MOZ_MUST_USE nsresult SystemHeapSize(int64_t* aSizeOut) {
+@@ -142,6 +143,7 @@
+ return NS_OK;
+ }
+ # endif
++#endif // __GLIBC__
+
+ #elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
+ defined(__OpenBSD__) || defined(__FreeBSD_kernel__)
+@@ -642,6 +644,7 @@
+ return NS_OK;
+ }
+
++#ifdef __GLIBC__
+ # define HAVE_SYSTEM_HEAP_REPORTER 1
+ // Windows can have multiple separate heaps. During testing there were multiple
+ // heaps present but the non-default ones had sizes no more than a few 10s of
+@@ -698,6 +701,7 @@
+ *aSizeOut = heapsSize;
+ return NS_OK;
+ }
++#endif // __GLIBC__
+
+ struct SegmentKind {
+ DWORD mState;
diff --git a/extra/firefox/sources b/extra/firefox/sources
new file mode 100644
index 00000000..99c2a787
--- /dev/null
+++ b/extra/firefox/sources
@@ -0,0 +1,15 @@
+https://archive.mozilla.org/pub/firefox/candidates/71.0-candidates/build2/source/firefox-71.0.source.tar.xz
+https://ftp.gnu.org/gnu/autoconf/autoconf-2.13.tar.gz autoconf2.13/
+files/mozconfig
+files/stab.h toolkit/crashreporter/google-breakpad/src/
+files/vendor.js
+files/policies.json
+patches/fix-fortify-system-wrappers.patch
+patches/fix-sandbox-membarrier.patch
+patches/fix-seccomp-bpf.patch
+patches/fix-toolkit.patch
+patches/fix-tools.patch
+patches/fix-webrtc-glibcisms.patch
+patches/mallinfo.patch
+patches/firefox-71-no-dbus.patch
+patches/firefox-71-no-accessibility.patch
diff --git a/extra/firefox/version b/extra/firefox/version
new file mode 100644
index 00000000..4f95e8e6
--- /dev/null
+++ b/extra/firefox/version
@@ -0,0 +1 @@
+71.0 1
diff --git a/extra/fribidi/build b/extra/fribidi/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/fribidi/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/fribidi/checksums b/extra/fribidi/checksums
new file mode 100644
index 00000000..30209904
--- /dev/null
+++ b/extra/fribidi/checksums
@@ -0,0 +1 @@
+5ab5f21e9f2fc57b4b40f8ea8f14dba78a5cc46d9cf94bc5e00a58e6886a935d fribidi-1.0.7.tar.bz2
diff --git a/extra/fribidi/sources b/extra/fribidi/sources
new file mode 100644
index 00000000..44e55b13
--- /dev/null
+++ b/extra/fribidi/sources
@@ -0,0 +1 @@
+https://github.com/fribidi/fribidi/releases/download/v1.0.7/fribidi-1.0.7.tar.bz2
diff --git a/extra/fribidi/version b/extra/fribidi/version
new file mode 100644
index 00000000..5c9722cd
--- /dev/null
+++ b/extra/fribidi/version
@@ -0,0 +1 @@
+1.0.7 1
diff --git a/extra/giflib/build b/extra/giflib/build
new file mode 100755
index 00000000..431cc725
--- /dev/null
+++ b/extra/giflib/build
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+
+make
+make DESTDIR="$1" PREFIX=/usr install
diff --git a/extra/giflib/checksums b/extra/giflib/checksums
new file mode 100644
index 00000000..023118b3
--- /dev/null
+++ b/extra/giflib/checksums
@@ -0,0 +1 @@
+31da5562f44c5f15d63340a09a4fd62b48c45620cd302f77a6d9acf0077879bd giflib-5.2.1.tar.gz
diff --git a/extra/giflib/sources b/extra/giflib/sources
new file mode 100644
index 00000000..dc1326bc
--- /dev/null
+++ b/extra/giflib/sources
@@ -0,0 +1 @@
+https://downloads.sourceforge.net/giflib/giflib-5.2.1.tar.gz
diff --git a/extra/giflib/version b/extra/giflib/version
new file mode 100644
index 00000000..a06ff620
--- /dev/null
+++ b/extra/giflib/version
@@ -0,0 +1 @@
+5.2.1 1
diff --git a/extra/glib/build b/extra/glib/build
new file mode 100755
index 00000000..60f19b1f
--- /dev/null
+++ b/extra/glib/build
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+
+export DESTDIR="$1"
+
+# Remove 'libelf' dependency.
+sed -i 's/if have_libelf/if not have_libelf/' gio/meson.build
+
+meson \
+ --prefix=/usr \
+ -Dman=false \
+ -Dfam=false \
+ . build
+
+ninja -C build
+ninja -C build install
+
+# Purge gdbus.
+rm -rf "$1/usr/bin/gdbus"
diff --git a/extra/glib/checksums b/extra/glib/checksums
new file mode 100644
index 00000000..05674c45
--- /dev/null
+++ b/extra/glib/checksums
@@ -0,0 +1 @@
+4400adc9f0d3ffcfe8e84225210370ce3f9853afb81812ddadb685325aa655c4 glib-2.62.3.tar.xz
diff --git a/extra/glib/depends b/extra/glib/depends
new file mode 100644
index 00000000..9612cfb2
--- /dev/null
+++ b/extra/glib/depends
@@ -0,0 +1,4 @@
+libffi
+meson make
+util-linux
+zlib
diff --git a/extra/glib/sources b/extra/glib/sources
new file mode 100644
index 00000000..2d4e0fde
--- /dev/null
+++ b/extra/glib/sources
@@ -0,0 +1 @@
+https://ftp.gnome.org/pub/gnome/sources/glib/2.62/glib-2.62.3.tar.xz
diff --git a/extra/glib/version b/extra/glib/version
new file mode 100644
index 00000000..9609cbd8
--- /dev/null
+++ b/extra/glib/version
@@ -0,0 +1 @@
+2.62.3 1
diff --git a/extra/gnupg1/build b/extra/gnupg1/build
new file mode 100755
index 00000000..2f29dbb8
--- /dev/null
+++ b/extra/gnupg1/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --enable-noexecstack
+
+make
+make DESTDIR="$1" install
diff --git a/extra/gnupg1/checksums b/extra/gnupg1/checksums
new file mode 100644
index 00000000..e7ce497c
--- /dev/null
+++ b/extra/gnupg1/checksums
@@ -0,0 +1 @@
+c9462f17e651b6507848c08c430c791287cd75491f8b5a8b50c6ed46b12678ba gnupg-1.4.23.tar.bz2
diff --git a/extra/gnupg1/depends b/extra/gnupg1/depends
new file mode 100644
index 00000000..82362fae
--- /dev/null
+++ b/extra/gnupg1/depends
@@ -0,0 +1,4 @@
+bzip2
+curl
+libressl
+zlib
diff --git a/extra/gnupg1/sources b/extra/gnupg1/sources
new file mode 100644
index 00000000..40bad2e7
--- /dev/null
+++ b/extra/gnupg1/sources
@@ -0,0 +1 @@
+https://gnupg.org/ftp/gcrypt/gnupg/gnupg-1.4.23.tar.bz2
diff --git a/extra/gnupg1/version b/extra/gnupg1/version
new file mode 100644
index 00000000..53ea88f3
--- /dev/null
+++ b/extra/gnupg1/version
@@ -0,0 +1 @@
+1.4.23 1
diff --git a/extra/gperf/build b/extra/gperf/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/gperf/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/gperf/checksums b/extra/gperf/checksums
new file mode 100644
index 00000000..96f73ecf
--- /dev/null
+++ b/extra/gperf/checksums
@@ -0,0 +1 @@
+588546b945bba4b70b6a3a616e80b4ab466e3f33024a352fc2198112cdbb3ae2 gperf-3.1.tar.gz
diff --git a/extra/gperf/sources b/extra/gperf/sources
new file mode 100644
index 00000000..2ead637b
--- /dev/null
+++ b/extra/gperf/sources
@@ -0,0 +1 @@
+https://ftp.gnu.org/gnu/gperf/gperf-3.1.tar.gz
diff --git a/extra/gperf/version b/extra/gperf/version
new file mode 100644
index 00000000..122d3a0a
--- /dev/null
+++ b/extra/gperf/version
@@ -0,0 +1 @@
+3.1 3
diff --git a/extra/json-c/build b/extra/json-c/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/json-c/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/json-c/checksums b/extra/json-c/checksums
new file mode 100644
index 00000000..19095f80
--- /dev/null
+++ b/extra/json-c/checksums
@@ -0,0 +1 @@
+b87e608d4d3f7bfdd36ef78d56d53c74e66ab278d318b71e6002a369d36f4873 json-c-0.13.1.tar.gz
diff --git a/extra/json-c/depends b/extra/json-c/depends
new file mode 100644
index 00000000..cf0a2427
--- /dev/null
+++ b/extra/json-c/depends
@@ -0,0 +1 @@
+automake
diff --git a/extra/json-c/sources b/extra/json-c/sources
new file mode 100644
index 00000000..1e88a0fd
--- /dev/null
+++ b/extra/json-c/sources
@@ -0,0 +1 @@
+https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.1.tar.gz
diff --git a/extra/json-c/version b/extra/json-c/version
new file mode 100644
index 00000000..95070198
--- /dev/null
+++ b/extra/json-c/version
@@ -0,0 +1 @@
+0.13.1 1
diff --git a/extra/lame/build b/extra/lame/build
new file mode 100755
index 00000000..10210baf
--- /dev/null
+++ b/extra/lame/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --enable-nasm \
+ --enable-shared
+
+make
+make DESTDIR="$1" install
diff --git a/extra/lame/checksums b/extra/lame/checksums
new file mode 100644
index 00000000..3b885b2e
--- /dev/null
+++ b/extra/lame/checksums
@@ -0,0 +1 @@
+ddfe36cab873794038ae2c1210557ad34857a4b6bdc515785d1da9e175b1da1e lame-3.100.tar.gz
diff --git a/extra/lame/depends b/extra/lame/depends
new file mode 100644
index 00000000..116f6b27
--- /dev/null
+++ b/extra/lame/depends
@@ -0,0 +1 @@
+nasm make
diff --git a/extra/lame/sources b/extra/lame/sources
new file mode 100644
index 00000000..8cc28356
--- /dev/null
+++ b/extra/lame/sources
@@ -0,0 +1 @@
+https://downloads.sourceforge.net/lame/lame-3.100.tar.gz
diff --git a/extra/lame/version b/extra/lame/version
new file mode 100644
index 00000000..a8af8af4
--- /dev/null
+++ b/extra/lame/version
@@ -0,0 +1 @@
+3.100 2
diff --git a/extra/libaio/build b/extra/libaio/build
new file mode 100755
index 00000000..133d511b
--- /dev/null
+++ b/extra/libaio/build
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+
+make
+make prefix="$1/usr" install
diff --git a/extra/libaio/checksums b/extra/libaio/checksums
new file mode 100644
index 00000000..8494bb94
--- /dev/null
+++ b/extra/libaio/checksums
@@ -0,0 +1 @@
+ab0462f2c9d546683e5147b1ce9c195fe95d07fac5bf362f6c01637955c3b492 libaio-0.3.112.tar.gz
diff --git a/extra/libaio/sources b/extra/libaio/sources
new file mode 100644
index 00000000..08e538e1
--- /dev/null
+++ b/extra/libaio/sources
@@ -0,0 +1 @@
+https://releases.pagure.org/libaio/libaio-0.3.112.tar.gz
diff --git a/extra/libaio/version b/extra/libaio/version
new file mode 100644
index 00000000..267ccb33
--- /dev/null
+++ b/extra/libaio/version
@@ -0,0 +1 @@
+0.3.112 1
diff --git a/extra/libass/build b/extra/libass/build
new file mode 100755
index 00000000..11938895
--- /dev/null
+++ b/extra/libass/build
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --enable-fontconfig
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libass/checksums b/extra/libass/checksums
new file mode 100644
index 00000000..6a8bc2da
--- /dev/null
+++ b/extra/libass/checksums
@@ -0,0 +1 @@
+881f2382af48aead75b7a0e02e65d88c5ebd369fe46bc77d9270a94aa8fd38a2 libass-0.14.0.tar.xz
diff --git a/extra/libass/depends b/extra/libass/depends
new file mode 100644
index 00000000..3b0ec96c
--- /dev/null
+++ b/extra/libass/depends
@@ -0,0 +1,6 @@
+expat
+fontconfig
+freetype-harfbuzz
+fribidi
+pkgconf make
+yasm make
diff --git a/extra/libass/sources b/extra/libass/sources
new file mode 100644
index 00000000..12135230
--- /dev/null
+++ b/extra/libass/sources
@@ -0,0 +1 @@
+https://github.com/libass/libass/releases/download/0.14.0/libass-0.14.0.tar.xz
diff --git a/extra/libass/version b/extra/libass/version
new file mode 100644
index 00000000..0f78dbcf
--- /dev/null
+++ b/extra/libass/version
@@ -0,0 +1 @@
+0.14.0 1
diff --git a/extra/libffi/build b/extra/libffi/build
new file mode 100755
index 00000000..b2747a3d
--- /dev/null
+++ b/extra/libffi/build
@@ -0,0 +1,17 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --with-pic
+
+make
+make DESTDIR="$1" install
+
+# Maintain compatibility and avoid the need
+# for rebuilds of all packages linking to
+# libffi.
+#
+# ABI incompatibility only affects AArch64.
+# See: https://github.com/libffi/libffi/commit/c02c341
+# https://github.com/libffi/libffi/issues/528
+ln -s libffi.so.7 "$1/usr/lib/libffi.so.6"
diff --git a/extra/libffi/checksums b/extra/libffi/checksums
new file mode 100644
index 00000000..635bf88b
--- /dev/null
+++ b/extra/libffi/checksums
@@ -0,0 +1 @@
+72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056 libffi-3.3.tar.gz
diff --git a/extra/libffi/sources b/extra/libffi/sources
new file mode 100644
index 00000000..c4dceb60
--- /dev/null
+++ b/extra/libffi/sources
@@ -0,0 +1 @@
+https://sourceware.org/pub/libffi/libffi-3.3.tar.gz
diff --git a/extra/libffi/version b/extra/libffi/version
new file mode 100644
index 00000000..ef8da5d7
--- /dev/null
+++ b/extra/libffi/version
@@ -0,0 +1 @@
+3.3 1
diff --git a/extra/libjpeg-turbo/build b/extra/libjpeg-turbo/build
new file mode 100755
index 00000000..650b25f5
--- /dev/null
+++ b/extra/libjpeg-turbo/build
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+
+export DESTDIR="$1"
+
+cmake -B build \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_INSTALL_LIBDIR=/usr/lib \
+ -DCMAKE_SHARED_LIBS=True \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DWITH_JPEG8=1
+
+cmake --build build
+cmake --install build
diff --git a/extra/libjpeg-turbo/checksums b/extra/libjpeg-turbo/checksums
new file mode 100644
index 00000000..6ad81b85
--- /dev/null
+++ b/extra/libjpeg-turbo/checksums
@@ -0,0 +1 @@
+a69598bf079463b34d45ca7268462a18b6507fdaa62bb1dfd212f02041499b5d 2.0.3.tar.gz
diff --git a/extra/libjpeg-turbo/depends b/extra/libjpeg-turbo/depends
new file mode 100644
index 00000000..ae4e5b53
--- /dev/null
+++ b/extra/libjpeg-turbo/depends
@@ -0,0 +1,2 @@
+cmake make
+yasm make
diff --git a/extra/libjpeg-turbo/sources b/extra/libjpeg-turbo/sources
new file mode 100644
index 00000000..81eadb64
--- /dev/null
+++ b/extra/libjpeg-turbo/sources
@@ -0,0 +1 @@
+https://github.com/libjpeg-turbo/libjpeg-turbo/archive/2.0.3.tar.gz
diff --git a/extra/libjpeg-turbo/version b/extra/libjpeg-turbo/version
new file mode 100644
index 00000000..c103c3ec
--- /dev/null
+++ b/extra/libjpeg-turbo/version
@@ -0,0 +1 @@
+2.0.3 1
diff --git a/extra/libogg/build b/extra/libogg/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/libogg/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libogg/checksums b/extra/libogg/checksums
new file mode 100644
index 00000000..6324e2ef
--- /dev/null
+++ b/extra/libogg/checksums
@@ -0,0 +1 @@
+c163bc12bc300c401b6aa35907ac682671ea376f13ae0969a220f7ddf71893fe libogg-1.3.4.tar.xz
diff --git a/extra/libogg/sources b/extra/libogg/sources
new file mode 100644
index 00000000..6d21083e
--- /dev/null
+++ b/extra/libogg/sources
@@ -0,0 +1 @@
+https://downloads.xiph.org/releases/ogg/libogg-1.3.4.tar.xz
diff --git a/extra/libogg/version b/extra/libogg/version
new file mode 100644
index 00000000..737bdf49
--- /dev/null
+++ b/extra/libogg/version
@@ -0,0 +1 @@
+1.3.4 1
diff --git a/extra/libpng/build b/extra/libpng/build
new file mode 100755
index 00000000..5be67a84
--- /dev/null
+++ b/extra/libpng/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+patch -p1 < libpng-1.6.37-apng.patch
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libpng/checksums b/extra/libpng/checksums
new file mode 100644
index 00000000..d0278b60
--- /dev/null
+++ b/extra/libpng/checksums
@@ -0,0 +1,2 @@
+ca74a0dace179a8422187671aee97dd3892b53e168627145271cad5b5ac81307 v1.6.37.tar.gz
+18b71dcd329af6ddb483cb6d145535861e04918f7eb95e8051545f0bbce7d517 libpng-1.6.37-apng.patch
diff --git a/extra/libpng/depends b/extra/libpng/depends
new file mode 100644
index 00000000..f22003e8
--- /dev/null
+++ b/extra/libpng/depends
@@ -0,0 +1 @@
+zlib
diff --git a/extra/libpng/patches/libpng-1.6.37-apng.patch b/extra/libpng/patches/libpng-1.6.37-apng.patch
new file mode 100644
index 00000000..8aaa50b9
--- /dev/null
+++ b/extra/libpng/patches/libpng-1.6.37-apng.patch
@@ -0,0 +1,1728 @@
+diff -Naru libpng-1.6.37.org/png.h libpng-1.6.37/png.h
+--- libpng-1.6.37.org/png.h 2019-04-19 07:21:37.398024800 +0900
++++ libpng-1.6.37/png.h 2019-04-19 07:22:37.871245630 +0900
+@@ -330,6 +330,10 @@
+ # include "pnglibconf.h"
+ #endif
+
++#define PNG_APNG_SUPPORTED
++#define PNG_READ_APNG_SUPPORTED
++#define PNG_WRITE_APNG_SUPPORTED
++
+ #ifndef PNG_VERSION_INFO_ONLY
+ /* Machine specific configuration. */
+ # include "pngconf.h"
+@@ -425,6 +429,17 @@
+ * See pngconf.h for base types that vary by machine/system
+ */
+
++#ifdef PNG_APNG_SUPPORTED
++/* dispose_op flags from inside fcTL */
++#define PNG_DISPOSE_OP_NONE 0x00U
++#define PNG_DISPOSE_OP_BACKGROUND 0x01U
++#define PNG_DISPOSE_OP_PREVIOUS 0x02U
++
++/* blend_op flags from inside fcTL */
++#define PNG_BLEND_OP_SOURCE 0x00U
++#define PNG_BLEND_OP_OVER 0x01U
++#endif /* PNG_APNG_SUPPORTED */
++
+ /* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+@@ -746,6 +761,10 @@
+ #define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */
+ #define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */
+ #define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
++#ifdef PNG_APNG_SUPPORTED
++#define PNG_INFO_acTL 0x20000U
++#define PNG_INFO_fcTL 0x40000U
++#endif
+
+ /* This is used for the transformation routines, as some of them
+ * change these values for the row. It also should enable using
+@@ -783,6 +802,10 @@
+ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
+ typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
++#ifdef PNG_APNG_SUPPORTED
++typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp,
++ png_uint_32));
++#endif
+
+ /* The following callback receives png_uint_32 row_number, int pass for the
+ * png_bytep data of the row. When transforming an interlaced image the
+@@ -3226,6 +3249,74 @@
+ /*******************************************************************************
+ * END OF HARDWARE AND SOFTWARE OPTIONS
+ ******************************************************************************/
++#ifdef PNG_APNG_SUPPORTED
++PNG_EXPORT(250, png_uint_32, png_get_acTL, (png_structp png_ptr,
++ png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
++
++PNG_EXPORT(251, png_uint_32, png_set_acTL, (png_structp png_ptr,
++ png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
++
++PNG_EXPORT(252, png_uint_32, png_get_num_frames, (png_structp png_ptr,
++ png_infop info_ptr));
++
++PNG_EXPORT(253, png_uint_32, png_get_num_plays, (png_structp png_ptr,
++ png_infop info_ptr));
++
++PNG_EXPORT(254, png_uint_32, png_get_next_frame_fcTL,
++ (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
++ png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
++ png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
++ png_byte *blend_op));
++
++PNG_EXPORT(255, png_uint_32, png_set_next_frame_fcTL,
++ (png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
++ png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
++ png_byte blend_op));
++
++PNG_EXPORT(256, png_uint_32, png_get_next_frame_width,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(257, png_uint_32, png_get_next_frame_height,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(258, png_uint_32, png_get_next_frame_x_offset,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(259, png_uint_32, png_get_next_frame_y_offset,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(260, png_uint_16, png_get_next_frame_delay_num,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(261, png_uint_16, png_get_next_frame_delay_den,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(262, png_byte, png_get_next_frame_dispose_op,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(263, png_byte, png_get_next_frame_blend_op,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(264, png_byte, png_get_first_frame_is_hidden,
++ (png_structp png_ptr, png_infop info_ptr));
++PNG_EXPORT(265, png_uint_32, png_set_first_frame_is_hidden,
++ (png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
++
++#ifdef PNG_READ_APNG_SUPPORTED
++PNG_EXPORT(266, void, png_read_frame_head, (png_structp png_ptr,
++ png_infop info_ptr));
++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
++PNG_EXPORT(267, void, png_set_progressive_frame_fn, (png_structp png_ptr,
++ png_progressive_frame_ptr frame_info_fn,
++ png_progressive_frame_ptr frame_end_fn));
++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
++#endif /* PNG_READ_APNG_SUPPORTED */
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++PNG_EXPORT(268, void, png_write_frame_head, (png_structp png_ptr,
++ png_infop info_ptr, png_bytepp row_pointers,
++ png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
++ png_byte blend_op));
++
++PNG_EXPORT(269, void, png_write_frame_tail, (png_structp png_ptr,
++ png_infop info_ptr));
++#endif /* PNG_WRITE_APNG_SUPPORTED */
++#endif /* PNG_APNG_SUPPORTED */
+
+ /* Maintainer: Put new public prototypes here ^, in libpng.3, in project
+ * defs, and in scripts/symbols.def.
+@@ -3235,7 +3326,11 @@
+ * one to use is one more than this.)
+ */
+ #ifdef PNG_EXPORT_LAST_ORDINAL
++#ifdef PNG_APNG_SUPPORTED
++ PNG_EXPORT_LAST_ORDINAL(269);
++#else
+ PNG_EXPORT_LAST_ORDINAL(249);
++#endif /* PNG_APNG_SUPPORTED */
+ #endif
+
+ #ifdef __cplusplus
+diff -Naru libpng-1.6.37.org/pngget.c libpng-1.6.37/pngget.c
+--- libpng-1.6.37.org/pngget.c 2019-04-19 07:21:37.399024787 +0900
++++ libpng-1.6.37/pngget.c 2019-04-19 07:22:37.850245901 +0900
+@@ -1246,4 +1246,166 @@
+ # endif
+ #endif
+
++#ifdef PNG_APNG_SUPPORTED
++png_uint_32 PNGAPI
++png_get_acTL(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 *num_frames, png_uint_32 *num_plays)
++{
++ png_debug1(1, "in %s retrieval function", "acTL");
++
++ if (png_ptr != NULL && info_ptr != NULL &&
++ (info_ptr->valid & PNG_INFO_acTL) &&
++ num_frames != NULL && num_plays != NULL)
++ {
++ *num_frames = info_ptr->num_frames;
++ *num_plays = info_ptr->num_plays;
++ return (1);
++ }
++
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_num_frames()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->num_frames);
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_num_plays()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->num_plays);
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 *width, png_uint_32 *height,
++ png_uint_32 *x_offset, png_uint_32 *y_offset,
++ png_uint_16 *delay_num, png_uint_16 *delay_den,
++ png_byte *dispose_op, png_byte *blend_op)
++{
++ png_debug1(1, "in %s retrieval function", "fcTL");
++
++ if (png_ptr != NULL && info_ptr != NULL &&
++ (info_ptr->valid & PNG_INFO_fcTL) &&
++ width != NULL && height != NULL &&
++ x_offset != NULL && y_offset != NULL &&
++ delay_num != NULL && delay_den != NULL &&
++ dispose_op != NULL && blend_op != NULL)
++ {
++ *width = info_ptr->next_frame_width;
++ *height = info_ptr->next_frame_height;
++ *x_offset = info_ptr->next_frame_x_offset;
++ *y_offset = info_ptr->next_frame_y_offset;
++ *delay_num = info_ptr->next_frame_delay_num;
++ *delay_den = info_ptr->next_frame_delay_den;
++ *dispose_op = info_ptr->next_frame_dispose_op;
++ *blend_op = info_ptr->next_frame_blend_op;
++ return (1);
++ }
++
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_width()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_width);
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_height()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_height);
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_x_offset()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_x_offset);
++ return (0);
++}
++
++png_uint_32 PNGAPI
++png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_y_offset()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_y_offset);
++ return (0);
++}
++
++png_uint_16 PNGAPI
++png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_delay_num()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_delay_num);
++ return (0);
++}
++
++png_uint_16 PNGAPI
++png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_delay_den()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_delay_den);
++ return (0);
++}
++
++png_byte PNGAPI
++png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_dispose_op()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_dispose_op);
++ return (0);
++}
++
++png_byte PNGAPI
++png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_get_next_frame_blend_op()");
++
++ if (png_ptr != NULL && info_ptr != NULL)
++ return (info_ptr->next_frame_blend_op);
++ return (0);
++}
++
++png_byte PNGAPI
++png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_first_frame_is_hidden()");
++
++ if (png_ptr != NULL)
++ return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
++
++ PNG_UNUSED(info_ptr)
++
++ return 0;
++}
++#endif /* PNG_APNG_SUPPORTED */
+ #endif /* READ || WRITE */
+diff -Naru libpng-1.6.37.org/pnginfo.h libpng-1.6.37/pnginfo.h
+--- libpng-1.6.37.org/pnginfo.h 2019-04-19 07:21:37.399024787 +0900
++++ libpng-1.6.37/pnginfo.h 2019-04-19 07:22:37.850245901 +0900
+@@ -263,5 +263,18 @@
+ png_bytepp row_pointers; /* the image bits */
+ #endif
+
++#ifdef PNG_APNG_SUPPORTED
++ png_uint_32 num_frames; /* including default image */
++ png_uint_32 num_plays;
++ png_uint_32 next_frame_width;
++ png_uint_32 next_frame_height;
++ png_uint_32 next_frame_x_offset;
++ png_uint_32 next_frame_y_offset;
++ png_uint_16 next_frame_delay_num;
++ png_uint_16 next_frame_delay_den;
++ png_byte next_frame_dispose_op;
++ png_byte next_frame_blend_op;
++#endif
++
+ };
+ #endif /* PNGINFO_H */
+diff -Naru libpng-1.6.37.org/pngpread.c libpng-1.6.37/pngpread.c
+--- libpng-1.6.37.org/pngpread.c 2019-04-19 07:21:37.399024787 +0900
++++ libpng-1.6.37/pngpread.c 2019-04-19 07:22:37.850245901 +0900
+@@ -195,6 +195,106 @@
+
+ chunk_name = png_ptr->chunk_name;
+
++#ifdef PNG_READ_APNG_SUPPORTED
++ if (png_ptr->num_frames_read > 0 &&
++ png_ptr->num_frames_read < info_ptr->num_frames)
++ {
++ if (chunk_name == png_IDAT)
++ {
++ /* Discard trailing IDATs for the first frame */
++ if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
++ png_error(png_ptr, "out of place IDAT");
++
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++
++ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
++ return;
++ }
++ else if (chunk_name == png_fdAT)
++ {
++ if (png_ptr->buffer_size < 4)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++
++ png_ensure_sequence_number(png_ptr, 4);
++
++ if (!(png_ptr->mode & PNG_HAVE_fcTL))
++ {
++ /* Discard trailing fdATs for frames other than the first */
++ if (png_ptr->num_frames_read < 2)
++ png_error(png_ptr, "out of place fdAT");
++
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++
++ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
++ return;
++ }
++
++ else
++ {
++ /* frame data follows */
++ png_ptr->idat_size = png_ptr->push_length - 4;
++ png_ptr->mode |= PNG_HAVE_IDAT;
++ png_ptr->process_mode = PNG_READ_IDAT_MODE;
++
++ return;
++ }
++ }
++
++ else if (chunk_name == png_fcTL)
++ {
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++
++ png_read_reset(png_ptr);
++ png_ptr->mode &= ~PNG_HAVE_fcTL;
++
++ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
++
++ if (!(png_ptr->mode & PNG_HAVE_fcTL))
++ png_error(png_ptr, "missing required fcTL chunk");
++
++ png_read_reinit(png_ptr, info_ptr);
++ png_progressive_read_reset(png_ptr);
++
++ if (png_ptr->frame_info_fn != NULL)
++ (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
++
++ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
++
++ return;
++ }
++
++ else
++ {
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++ png_warning(png_ptr, "Skipped (ignored) a chunk "
++ "between APNG chunks");
++ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
++ return;
++ }
++
++ return;
++ }
++#endif /* PNG_READ_APNG_SUPPORTED */
++
+ if (chunk_name == png_IDAT)
+ {
+ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+@@ -261,6 +361,9 @@
+
+ else if (chunk_name == png_IDAT)
+ {
++#ifdef PNG_READ_APNG_SUPPORTED
++ png_have_info(png_ptr, info_ptr);
++#endif
+ png_ptr->idat_size = png_ptr->push_length;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+ png_push_have_info(png_ptr, info_ptr);
+@@ -406,6 +509,30 @@
+ png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ #endif
++#ifdef PNG_READ_APNG_SUPPORTED
++ else if (chunk_name == png_acTL)
++ {
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++
++ png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
++ }
++
++ else if (chunk_name == png_fcTL)
++ {
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++
++ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
++ }
++
++#endif /* PNG_READ_APNG_SUPPORTED */
+
+ else
+ {
+@@ -539,7 +666,11 @@
+ png_byte chunk_tag[4];
+
+ /* TODO: this code can be commoned up with the same code in push_read */
++#ifdef PNG_READ_APNG_SUPPORTED
++ PNG_PUSH_SAVE_BUFFER_IF_LT(12)
++#else
+ PNG_PUSH_SAVE_BUFFER_IF_LT(8)
++#endif
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+@@ -547,17 +678,64 @@
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
++#ifdef PNG_READ_APNG_SUPPORTED
++ if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
++ {
++ if (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)
++ {
++ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
++ if (png_ptr->frame_end_fn != NULL)
++ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
++ png_ptr->num_frames_read++;
++ return;
++ }
++ else
++ {
++ if (png_ptr->chunk_name == png_IEND)
++ png_error(png_ptr, "Not enough image data");
++ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
++ {
++ png_push_save_buffer(png_ptr);
++ return;
++ }
++ png_warning(png_ptr, "Skipping (ignoring) a chunk between "
++ "APNG chunks");
++ png_crc_finish(png_ptr, png_ptr->push_length);
++ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
++ return;
++ }
++ }
++ else
++#endif
++#ifdef PNG_READ_APNG_SUPPORTED
++ if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0)
++#else
+ if (png_ptr->chunk_name != png_IDAT)
++#endif
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ png_error(png_ptr, "Not enough compressed data");
+
++#ifdef PNG_READ_APNG_SUPPORTED
++ if (png_ptr->frame_end_fn != NULL)
++ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
++ png_ptr->num_frames_read++;
++#endif
++
+ return;
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
++
++#ifdef PNG_READ_APNG_SUPPORTED
++ if (png_ptr->num_frames_read > 0)
++ {
++ png_ensure_sequence_number(png_ptr, 4);
++ png_ptr->idat_size -= 4;
++ }
++#endif
+ }
+
+ if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
+@@ -631,6 +809,15 @@
+ if (!(buffer_length > 0) || buffer == NULL)
+ png_error(png_ptr, "No IDAT data (internal error)");
+
++#ifdef PNG_READ_APNG_SUPPORTED
++ /* If the app is not APNG-aware, decode only the first frame */
++ if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
++ {
++ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
++ return;
++ }
++#endif
++
+ /* This routine must process all the data it has been given
+ * before returning, calling the row callback as required to
+ * handle the uncompressed results.
+@@ -1085,6 +1272,18 @@
+ png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+ }
+
++#ifdef PNG_READ_APNG_SUPPORTED
++void PNGAPI
++png_set_progressive_frame_fn(png_structp png_ptr,
++ png_progressive_frame_ptr frame_info_fn,
++ png_progressive_frame_ptr frame_end_fn)
++{
++ png_ptr->frame_info_fn = frame_info_fn;
++ png_ptr->frame_end_fn = frame_end_fn;
++ png_ptr->apng_flags |= PNG_APNG_APP;
++}
++#endif
++
+ png_voidp PNGAPI
+ png_get_progressive_ptr(png_const_structrp png_ptr)
+ {
+diff -Naru libpng-1.6.37.org/pngpriv.h libpng-1.6.37/pngpriv.h
+--- libpng-1.6.37.org/pngpriv.h 2019-04-19 07:21:37.399024787 +0900
++++ libpng-1.6.37/pngpriv.h 2019-04-19 07:22:37.850245901 +0900
+@@ -637,6 +637,10 @@
+ #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
+ /* 0x4000U (unused) */
+ #define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */
++#ifdef PNG_APNG_SUPPORTED
++#define PNG_HAVE_acTL 0x10000U
++#define PNG_HAVE_fcTL 0x20000U
++#endif
+
+ /* Flags for the transformations the PNG library does on the image data */
+ #define PNG_BGR 0x0001U
+@@ -873,6 +877,16 @@
+ #define png_tRNS PNG_U32(116, 82, 78, 83)
+ #define png_zTXt PNG_U32(122, 84, 88, 116)
+
++#ifdef PNG_APNG_SUPPORTED
++#define png_acTL PNG_U32( 97, 99, 84, 76)
++#define png_fcTL PNG_U32(102, 99, 84, 76)
++#define png_fdAT PNG_U32(102, 100, 65, 84)
++
++/* For png_struct.apng_flags: */
++#define PNG_FIRST_FRAME_HIDDEN 0x0001U
++#define PNG_APNG_APP 0x0002U
++#endif
++
+ /* The following will work on (signed char*) strings, whereas the get_uint_32
+ * macro will fail on top-bit-set values because of the sign extension.
+ */
+@@ -1644,6 +1658,47 @@
+ */
+ #endif
+
++#ifdef PNG_APNG_SUPPORTED
++PNG_INTERNAL_FUNCTION(void,png_ensure_fcTL_is_valid,(png_structp png_ptr,
++ png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den,
++ png_byte dispose_op, png_byte blend_op), PNG_EMPTY);
++
++#ifdef PNG_READ_APNG_SUPPORTED
++PNG_INTERNAL_FUNCTION(void,png_handle_acTL,(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_handle_fcTL,(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_handle_fdAT,(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_have_info,(png_structp png_ptr, png_infop info_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_ensure_sequence_number,(png_structp png_ptr,
++ png_uint_32 length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_read_reset,(png_structp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_read_reinit,(png_structp png_ptr,
++ png_infop info_ptr),PNG_EMPTY);
++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
++PNG_INTERNAL_FUNCTION(void,png_progressive_read_reset,(png_structp png_ptr),PNG_EMPTY);
++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
++#endif /* PNG_READ_APNG_SUPPORTED */
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++PNG_INTERNAL_FUNCTION(void,png_write_acTL,(png_structp png_ptr,
++ png_uint_32 num_frames, png_uint_32 num_plays),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_write_fcTL,(png_structp png_ptr,
++ png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den,
++ png_byte dispose_op, png_byte blend_op),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_write_fdAT,(png_structp png_ptr,
++ png_const_bytep data, png_size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_write_reset,(png_structp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void,png_write_reinit,(png_structp png_ptr,
++ png_infop info_ptr, png_uint_32 width, png_uint_32 height),PNG_EMPTY);
++#endif /* PNG_WRITE_APNG_SUPPORTED */
++#endif /* PNG_APNG_SUPPORTED */
++
+ /* Added at libpng version 1.4.0 */
+ #ifdef PNG_COLORSPACE_SUPPORTED
+ /* These internal functions are for maintaining the colorspace structure within
+diff -Naru libpng-1.6.37.org/pngread.c libpng-1.6.37/pngread.c
+--- libpng-1.6.37.org/pngread.c 2019-04-19 07:21:37.400024774 +0900
++++ libpng-1.6.37/pngread.c 2019-04-19 07:22:37.851245887 +0900
+@@ -161,6 +161,9 @@
+
+ else if (chunk_name == png_IDAT)
+ {
++#ifdef PNG_READ_APNG_SUPPORTED
++ png_have_info(png_ptr, info_ptr);
++#endif
+ png_ptr->idat_size = length;
+ break;
+ }
+@@ -255,6 +258,17 @@
+ png_handle_iTXt(png_ptr, info_ptr, length);
+ #endif
+
++#ifdef PNG_READ_APNG_SUPPORTED
++ else if (chunk_name == png_acTL)
++ png_handle_acTL(png_ptr, info_ptr, length);
++
++ else if (chunk_name == png_fcTL)
++ png_handle_fcTL(png_ptr, info_ptr, length);
++
++ else if (chunk_name == png_fdAT)
++ png_handle_fdAT(png_ptr, info_ptr, length);
++#endif
++
+ else
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+@@ -262,6 +276,72 @@
+ }
+ #endif /* SEQUENTIAL_READ */
+
++#ifdef PNG_READ_APNG_SUPPORTED
++void PNGAPI
++png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
++{
++ png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
++
++ png_debug(0, "Reading frame head");
++
++ if (!(png_ptr->mode & PNG_HAVE_acTL))
++ png_error(png_ptr, "attempt to png_read_frame_head() but "
++ "no acTL present");
++
++ /* do nothing for the main IDAT */
++ if (png_ptr->num_frames_read == 0)
++ return;
++
++ png_read_reset(png_ptr);
++ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
++ png_ptr->mode &= ~PNG_HAVE_fcTL;
++
++ have_chunk_after_DAT = 0;
++ for (;;)
++ {
++ png_uint_32 length = png_read_chunk_header(png_ptr);
++
++ if (png_ptr->chunk_name == png_IDAT)
++ {
++ /* discard trailing IDATs for the first frame */
++ if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
++ png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
++ png_crc_finish(png_ptr, length);
++ }
++
++ else if (png_ptr->chunk_name == png_fcTL)
++ {
++ png_handle_fcTL(png_ptr, info_ptr, length);
++ have_chunk_after_DAT = 1;
++ }
++
++ else if (png_ptr->chunk_name == png_fdAT)
++ {
++ png_ensure_sequence_number(png_ptr, length);
++
++ /* discard trailing fdATs for frames other than the first */
++ if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
++ png_crc_finish(png_ptr, length - 4);
++ else if(png_ptr->mode & PNG_HAVE_fcTL)
++ {
++ png_ptr->idat_size = length - 4;
++ png_ptr->mode |= PNG_HAVE_IDAT;
++
++ break;
++ }
++ else
++ png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
++ }
++ else
++ {
++ png_warning(png_ptr, "Skipped (ignored) a chunk "
++ "between APNG chunks");
++ png_crc_finish(png_ptr, length);
++ }
++ }
++}
++#endif /* PNG_READ_APNG_SUPPORTED */
++
+ /* Optional call to update the users info_ptr structure */
+ void PNGAPI
+ png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
+diff -Naru libpng-1.6.37.org/pngrutil.c libpng-1.6.37/pngrutil.c
+--- libpng-1.6.37.org/pngrutil.c 2019-04-19 07:21:37.401024761 +0900
++++ libpng-1.6.37/pngrutil.c 2019-04-19 07:22:37.853245862 +0900
+@@ -865,6 +865,11 @@
+ filter_type = buf[11];
+ interlace_type = buf[12];
+
++#ifdef PNG_READ_APNG_SUPPORTED
++ png_ptr->first_frame_width = width;
++ png_ptr->first_frame_height = height;
++#endif
++
+ /* Set internal variables */
+ png_ptr->width = width;
+ png_ptr->height = height;
+@@ -2857,6 +2862,179 @@
+ }
+ #endif
+
++#ifdef PNG_READ_APNG_SUPPORTED
++void /* PRIVATE */
++png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
++{
++ png_byte data[8];
++ png_uint_32 num_frames;
++ png_uint_32 num_plays;
++ png_uint_32 didSet;
++
++ png_debug(1, "in png_handle_acTL");
++
++ if (!(png_ptr->mode & PNG_HAVE_IHDR))
++ {
++ png_error(png_ptr, "Missing IHDR before acTL");
++ }
++ else if (png_ptr->mode & PNG_HAVE_IDAT)
++ {
++ png_warning(png_ptr, "Invalid acTL after IDAT skipped");
++ png_crc_finish(png_ptr, length);
++ return;
++ }
++ else if (png_ptr->mode & PNG_HAVE_acTL)
++ {
++ png_warning(png_ptr, "Duplicate acTL skipped");
++ png_crc_finish(png_ptr, length);
++ return;
++ }
++ else if (length != 8)
++ {
++ png_warning(png_ptr, "acTL with invalid length skipped");
++ png_crc_finish(png_ptr, length);
++ return;
++ }
++
++ png_crc_read(png_ptr, data, 8);
++ png_crc_finish(png_ptr, 0);
++
++ num_frames = png_get_uint_31(png_ptr, data);
++ num_plays = png_get_uint_31(png_ptr, data + 4);
++
++ /* the set function will do error checking on num_frames */
++ didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
++ if(didSet)
++ png_ptr->mode |= PNG_HAVE_acTL;
++}
++
++void /* PRIVATE */
++png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
++{
++ png_byte data[22];
++ png_uint_32 width;
++ png_uint_32 height;
++ png_uint_32 x_offset;
++ png_uint_32 y_offset;
++ png_uint_16 delay_num;
++ png_uint_16 delay_den;
++ png_byte dispose_op;
++ png_byte blend_op;
++
++ png_debug(1, "in png_handle_fcTL");
++
++ png_ensure_sequence_number(png_ptr, length);
++
++ if (!(png_ptr->mode & PNG_HAVE_IHDR))
++ {
++ png_error(png_ptr, "Missing IHDR before fcTL");
++ }
++ else if (png_ptr->mode & PNG_HAVE_IDAT)
++ {
++ /* for any frames other then the first this message may be misleading,
++ * but correct. PNG_HAVE_IDAT is unset before the frame head is read
++ * i can't think of a better message */
++ png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
++ png_crc_finish(png_ptr, length-4);
++ return;
++ }
++ else if (png_ptr->mode & PNG_HAVE_fcTL)
++ {
++ png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
++ png_crc_finish(png_ptr, length-4);
++ return;
++ }
++ else if (length != 26)
++ {
++ png_warning(png_ptr, "fcTL with invalid length skipped");
++ png_crc_finish(png_ptr, length-4);
++ return;
++ }
++
++ png_crc_read(png_ptr, data, 22);
++ png_crc_finish(png_ptr, 0);
++
++ width = png_get_uint_31(png_ptr, data);
++ height = png_get_uint_31(png_ptr, data + 4);
++ x_offset = png_get_uint_31(png_ptr, data + 8);
++ y_offset = png_get_uint_31(png_ptr, data + 12);
++ delay_num = png_get_uint_16(data + 16);
++ delay_den = png_get_uint_16(data + 18);
++ dispose_op = data[20];
++ blend_op = data[21];
++
++ if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
++ {
++ png_warning(png_ptr, "fcTL for the first frame must have zero offset");
++ return;
++ }
++
++ if (info_ptr != NULL)
++ {
++ if (png_ptr->num_frames_read == 0 &&
++ (width != info_ptr->width || height != info_ptr->height))
++ {
++ png_warning(png_ptr, "size in first frame's fcTL must match "
++ "the size in IHDR");
++ return;
++ }
++
++ /* The set function will do more error checking */
++ png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
++ x_offset, y_offset, delay_num, delay_den,
++ dispose_op, blend_op);
++
++ png_read_reinit(png_ptr, info_ptr);
++
++ png_ptr->mode |= PNG_HAVE_fcTL;
++ }
++}
++
++void /* PRIVATE */
++png_have_info(png_structp png_ptr, png_infop info_ptr)
++{
++ if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
++ {
++ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
++ info_ptr->num_frames++;
++ }
++}
++
++void /* PRIVATE */
++png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
++{
++ png_ensure_sequence_number(png_ptr, length);
++
++ /* This function is only called from png_read_end(), png_read_info(),
++ * and png_push_read_chunk() which means that:
++ * - the user doesn't want to read this frame
++ * - or this is an out-of-place fdAT
++ * in either case it is safe to ignore the chunk with a warning */
++ png_warning(png_ptr, "ignoring fdAT chunk");
++ png_crc_finish(png_ptr, length - 4);
++ PNG_UNUSED(info_ptr)
++}
++
++void /* PRIVATE */
++png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
++{
++ png_byte data[4];
++ png_uint_32 sequence_number;
++
++ if (length < 4)
++ png_error(png_ptr, "invalid fcTL or fdAT chunk found");
++
++ png_crc_read(png_ptr, data, 4);
++ sequence_number = png_get_uint_31(png_ptr, data);
++
++ if (sequence_number != png_ptr->next_seq_num)
++ png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
++ "number found");
++
++ png_ptr->next_seq_num++;
++}
++#endif /* PNG_READ_APNG_SUPPORTED */
++
+ #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
+ static int
+@@ -4165,7 +4343,38 @@
+ {
+ uInt avail_in;
+ png_bytep buffer;
++#ifdef PNG_READ_APNG_SUPPORTED
++ png_uint_32 bytes_to_skip = 0;
++
++ while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
++ {
++ png_crc_finish(png_ptr, bytes_to_skip);
++ bytes_to_skip = 0;
+
++ png_ptr->idat_size = png_read_chunk_header(png_ptr);
++ if (png_ptr->num_frames_read == 0)
++ {
++ if (png_ptr->chunk_name != png_IDAT)
++ png_error(png_ptr, "Not enough image data");
++ }
++ else
++ {
++ if (png_ptr->chunk_name == png_IEND)
++ png_error(png_ptr, "Not enough image data");
++ if (png_ptr->chunk_name != png_fdAT)
++ {
++ png_warning(png_ptr, "Skipped (ignored) a chunk "
++ "between APNG chunks");
++ bytes_to_skip = png_ptr->idat_size;
++ continue;
++ }
++
++ png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
++
++ png_ptr->idat_size -= 4;
++ }
++ }
++#else
+ while (png_ptr->idat_size == 0)
+ {
+ png_crc_finish(png_ptr, 0);
+@@ -4177,7 +4386,7 @@
+ if (png_ptr->chunk_name != png_IDAT)
+ png_error(png_ptr, "Not enough image data");
+ }
+-
++#endif /* PNG_READ_APNG_SUPPORTED */
+ avail_in = png_ptr->IDAT_read_size;
+
+ if (avail_in > png_ptr->idat_size)
+@@ -4240,6 +4449,9 @@
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
++#ifdef PNG_READ_APNG_SUPPORTED
++ png_ptr->num_frames_read++;
++#endif
+
+ if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
+ png_chunk_benign_error(png_ptr, "Extra compressed data");
+@@ -4678,4 +4890,80 @@
+
+ png_ptr->flags |= PNG_FLAG_ROW_INIT;
+ }
++
++#ifdef PNG_READ_APNG_SUPPORTED
++/* This function is to be called after the main IDAT set has been read and
++ * before a new IDAT is read. It resets some parts of png_ptr
++ * to make them usable by the read functions again */
++void /* PRIVATE */
++png_read_reset(png_structp png_ptr)
++{
++ png_ptr->mode &= ~PNG_HAVE_IDAT;
++ png_ptr->mode &= ~PNG_AFTER_IDAT;
++ png_ptr->row_number = 0;
++ png_ptr->pass = 0;
++}
++
++void /* PRIVATE */
++png_read_reinit(png_structp png_ptr, png_infop info_ptr)
++{
++ png_ptr->width = info_ptr->next_frame_width;
++ png_ptr->height = info_ptr->next_frame_height;
++ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
++ png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
++ png_ptr->width);
++ if (png_ptr->prev_row)
++ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
++}
++
++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
++/* same as png_read_reset() but for the progressive reader */
++void /* PRIVATE */
++png_progressive_read_reset(png_structp png_ptr)
++{
++#ifdef PNG_READ_INTERLACING_SUPPORTED
++ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
++
++ /* Start of interlace block */
++ const int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
++
++ /* Offset to next interlace block */
++ const int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
++
++ /* Start of interlace block in the y direction */
++ const int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
++
++ /* Offset to next interlace block in the y direction */
++ const int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
++
++ if (png_ptr->interlaced)
++ {
++ if (!(png_ptr->transformations & PNG_INTERLACE))
++ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
++ png_pass_ystart[0]) / png_pass_yinc[0];
++ else
++ png_ptr->num_rows = png_ptr->height;
++
++ png_ptr->iwidth = (png_ptr->width +
++ png_pass_inc[png_ptr->pass] - 1 -
++ png_pass_start[png_ptr->pass]) /
++ png_pass_inc[png_ptr->pass];
++ }
++ else
++#endif /* PNG_READ_INTERLACING_SUPPORTED */
++ {
++ png_ptr->num_rows = png_ptr->height;
++ png_ptr->iwidth = png_ptr->width;
++ }
++ png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED;
++ if (inflateReset(&(png_ptr->zstream)) != Z_OK)
++ png_error(png_ptr, "inflateReset failed");
++ png_ptr->zstream.avail_in = 0;
++ png_ptr->zstream.next_in = 0;
++ png_ptr->zstream.next_out = png_ptr->row_buf;
++ png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
++ png_ptr->iwidth) + 1;
++}
++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
++#endif /* PNG_READ_APNG_SUPPORTED */
+ #endif /* READ */
+diff -Naru libpng-1.6.37.org/pngset.c libpng-1.6.37/pngset.c
+--- libpng-1.6.37.org/pngset.c 2019-04-19 07:21:37.401024761 +0900
++++ libpng-1.6.37/pngset.c 2019-04-19 07:22:37.858245798 +0900
+@@ -288,6 +288,11 @@
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
++
++#ifdef PNG_APNG_SUPPORTED
++ /* for non-animated png. this may be overwritten from an acTL chunk later */
++ info_ptr->num_frames = 1;
++#endif
+ }
+
+ #ifdef PNG_oFFs_SUPPORTED
+@@ -1158,6 +1163,147 @@
+ }
+ #endif /* sPLT */
+
++#ifdef PNG_APNG_SUPPORTED
++png_uint_32 PNGAPI
++png_set_acTL(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 num_frames, png_uint_32 num_plays)
++{
++ png_debug1(1, "in %s storage function", "acTL");
++
++ if (png_ptr == NULL || info_ptr == NULL)
++ {
++ png_warning(png_ptr,
++ "Call to png_set_acTL() with NULL png_ptr "
++ "or info_ptr ignored");
++ return (0);
++ }
++ if (num_frames == 0)
++ {
++ png_warning(png_ptr,
++ "Ignoring attempt to set acTL with num_frames zero");
++ return (0);
++ }
++ if (num_frames > PNG_UINT_31_MAX)
++ {
++ png_warning(png_ptr,
++ "Ignoring attempt to set acTL with num_frames > 2^31-1");
++ return (0);
++ }
++ if (num_plays > PNG_UINT_31_MAX)
++ {
++ png_warning(png_ptr,
++ "Ignoring attempt to set acTL with num_plays "
++ "> 2^31-1");
++ return (0);
++ }
++
++ info_ptr->num_frames = num_frames;
++ info_ptr->num_plays = num_plays;
++
++ info_ptr->valid |= PNG_INFO_acTL;
++
++ return (1);
++}
++
++/* delay_num and delay_den can hold any 16-bit values including zero */
++png_uint_32 PNGAPI
++png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den,
++ png_byte dispose_op, png_byte blend_op)
++{
++ png_debug1(1, "in %s storage function", "fcTL");
++
++ if (png_ptr == NULL || info_ptr == NULL)
++ {
++ png_warning(png_ptr,
++ "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
++ "ignored");
++ return (0);
++ }
++
++ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
++ delay_num, delay_den, dispose_op, blend_op);
++
++ if (blend_op == PNG_BLEND_OP_OVER)
++ {
++ if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
++ !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
++ {
++ png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless "
++ "and wasteful for opaque images, ignored");
++ blend_op = PNG_BLEND_OP_SOURCE;
++ }
++ }
++
++ info_ptr->next_frame_width = width;
++ info_ptr->next_frame_height = height;
++ info_ptr->next_frame_x_offset = x_offset;
++ info_ptr->next_frame_y_offset = y_offset;
++ info_ptr->next_frame_delay_num = delay_num;
++ info_ptr->next_frame_delay_den = delay_den;
++ info_ptr->next_frame_dispose_op = dispose_op;
++ info_ptr->next_frame_blend_op = blend_op;
++
++ info_ptr->valid |= PNG_INFO_fcTL;
++
++ return (1);
++}
++
++void /* PRIVATE */
++png_ensure_fcTL_is_valid(png_structp png_ptr,
++ png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den,
++ png_byte dispose_op, png_byte blend_op)
++{
++ if (width == 0 || width > PNG_UINT_31_MAX)
++ png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
++ if (height == 0 || height > PNG_UINT_31_MAX)
++ png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
++ if (x_offset > PNG_UINT_31_MAX)
++ png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
++ if (y_offset > PNG_UINT_31_MAX)
++ png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
++ if (width + x_offset > png_ptr->first_frame_width ||
++ height + y_offset > png_ptr->first_frame_height)
++ png_error(png_ptr, "dimensions of a frame are greater than"
++ "the ones in IHDR");
++
++ if (dispose_op != PNG_DISPOSE_OP_NONE &&
++ dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
++ dispose_op != PNG_DISPOSE_OP_PREVIOUS)
++ png_error(png_ptr, "invalid dispose_op in fcTL");
++
++ if (blend_op != PNG_BLEND_OP_SOURCE &&
++ blend_op != PNG_BLEND_OP_OVER)
++ png_error(png_ptr, "invalid blend_op in fcTL");
++
++ PNG_UNUSED(delay_num)
++ PNG_UNUSED(delay_den)
++}
++
++png_uint_32 PNGAPI
++png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
++ png_byte is_hidden)
++{
++ png_debug(1, "in png_first_frame_is_hidden()");
++
++ if (png_ptr == NULL)
++ return 0;
++
++ if (is_hidden)
++ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
++ else
++ png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
++
++ PNG_UNUSED(info_ptr)
++
++ return 1;
++}
++#endif /* PNG_APNG_SUPPORTED */
++
+ #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ static png_byte
+ check_location(png_const_structrp png_ptr, int location)
+diff -Naru libpng-1.6.37.org/pngstruct.h libpng-1.6.37/pngstruct.h
+--- libpng-1.6.37.org/pngstruct.h 2019-04-19 07:21:37.401024761 +0900
++++ libpng-1.6.37/pngstruct.h 2019-04-19 07:22:37.854245849 +0900
+@@ -409,6 +409,27 @@
+ png_byte filter_type;
+ #endif
+
++#ifdef PNG_APNG_SUPPORTED
++ png_uint_32 apng_flags;
++ png_uint_32 next_seq_num; /* next fcTL/fdAT chunk sequence number */
++ png_uint_32 first_frame_width;
++ png_uint_32 first_frame_height;
++
++#ifdef PNG_READ_APNG_SUPPORTED
++ png_uint_32 num_frames_read; /* incremented after all image data of */
++ /* a frame is read */
++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
++ png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
++ png_progressive_frame_ptr frame_end_fn; /* frame data read callback */
++#endif
++#endif
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ png_uint_32 num_frames_to_write;
++ png_uint_32 num_frames_written;
++#endif
++#endif /* PNG_APNG_SUPPORTED */
++
+ /* New members added in libpng-1.2.0 */
+
+ /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+diff -Naru libpng-1.6.37.org/pngtest.c libpng-1.6.37/pngtest.c
+--- libpng-1.6.37.org/pngtest.c 2019-04-19 07:21:37.401024761 +0900
++++ libpng-1.6.37/pngtest.c 2019-04-19 07:22:37.854245849 +0900
+@@ -875,6 +875,10 @@
+ volatile int num_passes;
+ int pass;
+ int bit_depth, color_type;
++#ifdef PNG_APNG_SUPPORTED
++ png_uint_32 num_frames;
++ png_uint_32 num_plays;
++#endif
+
+ row_buf = NULL;
+ error_parameters.file_name = inname;
+@@ -1383,6 +1387,22 @@
+ }
+ }
+ #endif
++
++#ifdef PNG_APNG_SUPPORTED
++ if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
++ {
++ if (png_get_acTL(read_ptr, read_info_ptr, &num_frames, &num_plays))
++ {
++ png_byte is_hidden;
++ pngtest_debug2("Handling acTL chunks (frames %ld, plays %ld)",
++ num_frames, num_plays);
++ png_set_acTL(write_ptr, write_info_ptr, num_frames, num_plays);
++ is_hidden = png_get_first_frame_is_hidden(read_ptr, read_info_ptr);
++ png_set_first_frame_is_hidden(write_ptr, write_info_ptr, is_hidden);
++ }
++ }
++#endif
++
+ #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ {
+ png_unknown_chunkp unknowns;
+@@ -1463,6 +1483,110 @@
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+ #endif
++#ifdef PNG_APNG_SUPPORTED
++ if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
++ {
++ png_uint_32 frame;
++ for (frame = 0; frame < num_frames; frame++)
++ {
++ png_uint_32 frame_width;
++ png_uint_32 frame_height;
++ png_uint_32 x_offset;
++ png_uint_32 y_offset;
++ png_uint_16 delay_num;
++ png_uint_16 delay_den;
++ png_byte dispose_op;
++ png_byte blend_op;
++ png_read_frame_head(read_ptr, read_info_ptr);
++ if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_fcTL))
++ {
++ png_get_next_frame_fcTL(read_ptr, read_info_ptr,
++ &frame_width, &frame_height,
++ &x_offset, &y_offset,
++ &delay_num, &delay_den,
++ &dispose_op, &blend_op);
++ }
++ else
++ {
++ frame_width = width;
++ frame_height = height;
++ x_offset = 0;
++ y_offset = 0;
++ delay_num = 1;
++ delay_den = 1;
++ dispose_op = PNG_DISPOSE_OP_NONE;
++ blend_op = PNG_BLEND_OP_SOURCE;
++ }
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ png_write_frame_head(write_ptr, write_info_ptr, (png_bytepp)&row_buf,
++ frame_width, frame_height,
++ x_offset, y_offset,
++ delay_num, delay_den,
++ dispose_op, blend_op);
++#endif
++ for (pass = 0; pass < num_passes; pass++)
++ {
++# ifdef calc_pass_height
++ png_uint_32 pass_height;
++
++ if (num_passes == 7) /* interlaced */
++ {
++ if (PNG_PASS_COLS(frame_width, pass) > 0)
++ pass_height = PNG_PASS_ROWS(frame_height, pass);
++
++ else
++ pass_height = 0;
++ }
++
++ else /* not interlaced */
++ pass_height = frame_height;
++# else
++# define pass_height frame_height
++# endif
++
++ pngtest_debug1("Writing row data for pass %d", pass);
++ for (y = 0; y < pass_height; y++)
++ {
++#ifndef SINGLE_ROWBUF_ALLOC
++ pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
++
++ row_buf = (png_bytep)png_malloc(read_ptr,
++ png_get_rowbytes(read_ptr, read_info_ptr));
++
++ pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
++ (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
++
++#endif /* !SINGLE_ROWBUF_ALLOC */
++ png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
++
++#ifdef PNG_WRITE_SUPPORTED
++#ifdef PNGTEST_TIMING
++ t_stop = (float)clock();
++ t_decode += (t_stop - t_start);
++ t_start = t_stop;
++#endif
++ png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
++#ifdef PNGTEST_TIMING
++ t_stop = (float)clock();
++ t_encode += (t_stop - t_start);
++ t_start = t_stop;
++#endif
++#endif /* PNG_WRITE_SUPPORTED */
++
++#ifndef SINGLE_ROWBUF_ALLOC
++ pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
++ png_free(read_ptr, row_buf);
++ row_buf = NULL;
++#endif /* !SINGLE_ROWBUF_ALLOC */
++ }
++ }
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ png_write_frame_tail(write_ptr, write_info_ptr);
++#endif
++ }
++ }
++ else
++#endif
+ for (pass = 0; pass < num_passes; pass++)
+ {
+ # ifdef calc_pass_height
+diff -Naru libpng-1.6.37.org/pngwrite.c libpng-1.6.37/pngwrite.c
+--- libpng-1.6.37.org/pngwrite.c 2019-04-19 07:21:37.402024748 +0900
++++ libpng-1.6.37/pngwrite.c 2019-04-19 07:22:37.855245836 +0900
+@@ -128,6 +128,10 @@
+ * the application continues writing the PNG. So check the 'invalid'
+ * flag here too.
+ */
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ if (info_ptr->valid & PNG_INFO_acTL)
++ png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
++#endif
+ #ifdef PNG_GAMMA_SUPPORTED
+ # ifdef PNG_WRITE_gAMA_SUPPORTED
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+@@ -370,6 +374,11 @@
+ png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
+ #endif
+
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
++ png_error(png_ptr, "Not enough frames written");
++#endif
++
+ /* See if user wants us to write information chunks */
+ if (info_ptr != NULL)
+ {
+@@ -1461,6 +1470,43 @@
+ }
+ #endif
+
++#ifdef PNG_WRITE_APNG_SUPPORTED
++void PNGAPI
++png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
++ png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
++ png_byte blend_op)
++{
++ png_debug(1, "in png_write_frame_head");
++
++ /* there is a chance this has been set after png_write_info was called,
++ * so it would be set but not written. is there a way to be sure? */
++ if (!(info_ptr->valid & PNG_INFO_acTL))
++ png_error(png_ptr, "png_write_frame_head(): acTL not set");
++
++ png_write_reset(png_ptr);
++
++ png_write_reinit(png_ptr, info_ptr, width, height);
++
++ if ( !(png_ptr->num_frames_written == 0 &&
++ (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
++ png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
++ delay_num, delay_den, dispose_op, blend_op);
++
++ PNG_UNUSED(row_pointers)
++}
++
++void PNGAPI
++png_write_frame_tail(png_structp png_ptr, png_infop info_ptr)
++{
++ png_debug(1, "in png_write_frame_tail");
++
++ png_ptr->num_frames_written++;
++
++ PNG_UNUSED(info_ptr)
++}
++#endif /* PNG_WRITE_APNG_SUPPORTED */
+
+ #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+ /* Initialize the write structure - general purpose utility. */
+diff -Naru libpng-1.6.37.org/pngwutil.c libpng-1.6.37/pngwutil.c
+--- libpng-1.6.37.org/pngwutil.c 2019-04-19 07:21:37.402024748 +0900
++++ libpng-1.6.37/pngwutil.c 2019-04-19 07:22:37.867245682 +0900
+@@ -821,6 +821,11 @@
+ /* Write the chunk */
+ png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
+
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ png_ptr->first_frame_width = width;
++ png_ptr->first_frame_height = height;
++#endif
++
+ if ((png_ptr->do_filter) == PNG_NO_FILTERS)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+@@ -1002,8 +1007,17 @@
+ optimize_cmf(data, png_image_size(png_ptr));
+ #endif
+
+- if (size > 0)
+- png_write_complete_chunk(png_ptr, png_IDAT, data, size);
++ if (size > 0)
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ {
++ if (png_ptr->num_frames_written == 0)
++#endif
++ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ else
++ png_write_fdAT(png_ptr, data, size);
++ }
++#endif /* PNG_WRITE_APNG_SUPPORTED */
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ png_ptr->zstream.next_out = data;
+@@ -1050,7 +1064,17 @@
+ #endif
+
+ if (size > 0)
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ {
++ if (png_ptr->num_frames_written == 0)
++#endif
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
++#ifdef PNG_WRITE_APNG_SUPPORTED
++ else
++ png_write_fdAT(png_ptr, data, size);
++ }
++#endif /* PNG_WRITE_APNG_SUPPORTED */
++
+ png_ptr->zstream.avail_out = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
+@@ -1885,6 +1909,82 @@
+ }
+ #endif
+
++#ifdef PNG_WRITE_APNG_SUPPORTED
++void /* PRIVATE */
++png_write_acTL(png_structp png_ptr,
++ png_uint_32 num_frames, png_uint_32 num_plays)
++{
++ png_byte buf[8];
++
++ png_debug(1, "in png_write_acTL");
++
++ png_ptr->num_frames_to_write = num_frames;
++
++ if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
++ num_frames--;
++
++ png_save_uint_32(buf, num_frames);
++ png_save_uint_32(buf + 4, num_plays);
++
++ png_write_complete_chunk(png_ptr, png_acTL, buf, (png_size_t)8);
++}
++
++void /* PRIVATE */
++png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
++ png_uint_32 x_offset, png_uint_32 y_offset,
++ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
++ png_byte blend_op)
++{
++ png_byte buf[26];
++
++ png_debug(1, "in png_write_fcTL");
++
++ if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
++ png_error(png_ptr, "x and/or y offset for the first frame aren't 0");
++ if (png_ptr->num_frames_written == 0 &&
++ (width != png_ptr->first_frame_width ||
++ height != png_ptr->first_frame_height))
++ png_error(png_ptr, "width and/or height in the first frame's fcTL "
++ "don't match the ones in IHDR");
++
++ /* more error checking */
++ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
++ delay_num, delay_den, dispose_op, blend_op);
++
++ png_save_uint_32(buf, png_ptr->next_seq_num);
++ png_save_uint_32(buf + 4, width);
++ png_save_uint_32(buf + 8, height);
++ png_save_uint_32(buf + 12, x_offset);
++ png_save_uint_32(buf + 16, y_offset);
++ png_save_uint_16(buf + 20, delay_num);
++ png_save_uint_16(buf + 22, delay_den);
++ buf[24] = dispose_op;
++ buf[25] = blend_op;
++
++ png_write_complete_chunk(png_ptr, png_fcTL, buf, (png_size_t)26);
++
++ png_ptr->next_seq_num++;
++}
++
++void /* PRIVATE */
++png_write_fdAT(png_structp png_ptr,
++ png_const_bytep data, png_size_t length)
++{
++ png_byte buf[4];
++
++ png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length));
++
++ png_save_uint_32(buf, png_ptr->next_seq_num);
++ png_write_chunk_data(png_ptr, buf, 4);
++
++ png_write_chunk_data(png_ptr, data, length);
++
++ png_write_chunk_end(png_ptr);
++
++ png_ptr->next_seq_num++;
++}
++#endif /* PNG_WRITE_APNG_SUPPORTED */
++
+ /* Initializes the row writing capability of libpng */
+ void /* PRIVATE */
+ png_write_start_row(png_structrp png_ptr)
+@@ -2778,4 +2878,39 @@
+ }
+ #endif /* WRITE_FLUSH */
+ }
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++void /* PRIVATE */
++png_write_reset(png_structp png_ptr)
++{
++ png_ptr->row_number = 0;
++ png_ptr->pass = 0;
++ png_ptr->mode &= ~PNG_HAVE_IDAT;
++}
++
++void /* PRIVATE */
++png_write_reinit(png_structp png_ptr, png_infop info_ptr,
++ png_uint_32 width, png_uint_32 height)
++{
++ if (png_ptr->num_frames_written == 0 &&
++ (width != png_ptr->first_frame_width ||
++ height != png_ptr->first_frame_height))
++ png_error(png_ptr, "width and/or height in the first frame's fcTL "
++ "don't match the ones in IHDR");
++ if (width > png_ptr->first_frame_width ||
++ height > png_ptr->first_frame_height)
++ png_error(png_ptr, "width and/or height for a frame greater than"
++ "the ones in IHDR");
++
++ png_set_IHDR(png_ptr, info_ptr, width, height,
++ info_ptr->bit_depth, info_ptr->color_type,
++ info_ptr->interlace_type, info_ptr->compression_type,
++ info_ptr->filter_type);
++
++ png_ptr->width = width;
++ png_ptr->height = height;
++ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
++ png_ptr->usr_width = png_ptr->width;
++}
++#endif /* PNG_WRITE_APNG_SUPPORTED */
+ #endif /* WRITE */
+diff -Naru libpng-1.6.37.org/scripts/symbols.def libpng-1.6.37/scripts/symbols.def
+--- libpng-1.6.37.org/scripts/symbols.def 2019-04-19 07:21:37.405024710 +0900
++++ libpng-1.6.37/scripts/symbols.def 2019-04-19 07:22:37.856245823 +0900
+@@ -253,3 +253,23 @@
+ png_set_eXIf @247
+ png_get_eXIf_1 @248
+ png_set_eXIf_1 @249
++ png_get_acTL @250
++ png_set_acTL @251
++ png_get_num_frames @252
++ png_get_num_plays @253
++ png_get_next_frame_fcTL @254
++ png_set_next_frame_fcTL @255
++ png_get_next_frame_width @256
++ png_get_next_frame_height @257
++ png_get_next_frame_x_offset @258
++ png_get_next_frame_y_offset @259
++ png_get_next_frame_delay_num @260
++ png_get_next_frame_delay_den @261
++ png_get_next_frame_dispose_op @262
++ png_get_next_frame_blend_op @263
++ png_get_first_frame_is_hidden @264
++ png_set_first_frame_is_hidden @265
++ png_read_frame_head @266
++ png_set_progressive_frame_fn @267
++ png_write_frame_head @268
++ png_write_frame_tail @269
diff --git a/extra/libpng/sources b/extra/libpng/sources
new file mode 100644
index 00000000..d6556f0c
--- /dev/null
+++ b/extra/libpng/sources
@@ -0,0 +1,2 @@
+https://github.com/glennrp/libpng/archive/v1.6.37.tar.gz
+patches/libpng-1.6.37-apng.patch
diff --git a/extra/libpng/version b/extra/libpng/version
new file mode 100644
index 00000000..d61fa1c5
--- /dev/null
+++ b/extra/libpng/version
@@ -0,0 +1 @@
+1.6.37 2
diff --git a/extra/libtheora/build b/extra/libtheora/build
new file mode 100755
index 00000000..288944dc
--- /dev/null
+++ b/extra/libtheora/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+patch -p0 < libtheora-1.1.1-libpng16.patch
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libtheora/checksums b/extra/libtheora/checksums
new file mode 100644
index 00000000..9286d3eb
--- /dev/null
+++ b/extra/libtheora/checksums
@@ -0,0 +1,2 @@
+40952956c47811928d1e7922cda3bc1f427eb75680c3c37249c91e949054916b libtheora-1.1.1.tar.gz
+e4c9a8dc798c596ed32a2a720020ae27a0e72f5add1a47cb8fadebe0e7180d7e libtheora-1.1.1-libpng16.patch
diff --git a/extra/libtheora/depends b/extra/libtheora/depends
new file mode 100644
index 00000000..b6a6854a
--- /dev/null
+++ b/extra/libtheora/depends
@@ -0,0 +1 @@
+libogg
diff --git a/extra/libtheora/patches/libtheora-1.1.1-libpng16.patch b/extra/libtheora/patches/libtheora-1.1.1-libpng16.patch
new file mode 100644
index 00000000..93da700c
--- /dev/null
+++ b/extra/libtheora/patches/libtheora-1.1.1-libpng16.patch
@@ -0,0 +1,17 @@
+http://bugs.gentoo.org/465450
+http://trac.xiph.org/ticket/1947
+
+--- examples/png2theora.c
++++ examples/png2theora.c
+@@ -462,9 +462,9 @@
+ png_set_strip_alpha(png_ptr);
+
+ row_data = (png_bytep)png_malloc(png_ptr,
+- 3*height*width*png_sizeof(*row_data));
++ 3*height*width*sizeof(*row_data));
+ row_pointers = (png_bytep *)png_malloc(png_ptr,
+- height*png_sizeof(*row_pointers));
++ height*sizeof(*row_pointers));
+ for(y = 0; y < height; y++) {
+ row_pointers[y] = row_data + y*(3*width);
+ }
diff --git a/extra/libtheora/sources b/extra/libtheora/sources
new file mode 100644
index 00000000..c5eaf319
--- /dev/null
+++ b/extra/libtheora/sources
@@ -0,0 +1,2 @@
+https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.gz
+patches/libtheora-1.1.1-libpng16.patch
diff --git a/extra/libtheora/version b/extra/libtheora/version
new file mode 100644
index 00000000..d9f65d2e
--- /dev/null
+++ b/extra/libtheora/version
@@ -0,0 +1 @@
+1.1.1 2
diff --git a/extra/libtool/build b/extra/libtool/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/libtool/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libtool/checksums b/extra/libtool/checksums
new file mode 100644
index 00000000..238a49a3
--- /dev/null
+++ b/extra/libtool/checksums
@@ -0,0 +1 @@
+7c87a8c2c8c0fc9cd5019e402bed4292462d00a718a7cd5f11218153bf28b26f libtool-2.4.6.tar.xz
diff --git a/extra/libtool/depends b/extra/libtool/depends
new file mode 100644
index 00000000..0a3b5170
--- /dev/null
+++ b/extra/libtool/depends
@@ -0,0 +1 @@
+perl make
diff --git a/extra/libtool/sources b/extra/libtool/sources
new file mode 100644
index 00000000..5f32de1a
--- /dev/null
+++ b/extra/libtool/sources
@@ -0,0 +1 @@
+https://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.xz
diff --git a/extra/libtool/version b/extra/libtool/version
new file mode 100644
index 00000000..c2d12dbd
--- /dev/null
+++ b/extra/libtool/version
@@ -0,0 +1 @@
+2.4.6 1
diff --git a/extra/libvorbis/build b/extra/libvorbis/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/libvorbis/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libvorbis/checksums b/extra/libvorbis/checksums
new file mode 100644
index 00000000..eba280a4
--- /dev/null
+++ b/extra/libvorbis/checksums
@@ -0,0 +1 @@
+6ed40e0241089a42c48604dc00e362beee00036af2d8b3f46338031c9e0351cb libvorbis-1.3.6.tar.gz
diff --git a/extra/libvorbis/depends b/extra/libvorbis/depends
new file mode 100644
index 00000000..b6a6854a
--- /dev/null
+++ b/extra/libvorbis/depends
@@ -0,0 +1 @@
+libogg
diff --git a/extra/libvorbis/sources b/extra/libvorbis/sources
new file mode 100644
index 00000000..4e617a19
--- /dev/null
+++ b/extra/libvorbis/sources
@@ -0,0 +1 @@
+https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.6.tar.gz
diff --git a/extra/libvorbis/version b/extra/libvorbis/version
new file mode 100644
index 00000000..d71e5cf9
--- /dev/null
+++ b/extra/libvorbis/version
@@ -0,0 +1 @@
+1.3.6 2
diff --git a/extra/libvpx/build b/extra/libvpx/build
new file mode 100755
index 00000000..04d7a732
--- /dev/null
+++ b/extra/libvpx/build
@@ -0,0 +1,23 @@
+#!/bin/sh -e
+
+patch -p1 < fix-busybox-diff.patch
+
+./configure \
+ --prefix=/usr \
+ --enable-vp8 \
+ --enable-vp9 \
+ --disable-tools \
+ --disable-examples \
+ --disable-docs \
+ --enable-experimental \
+ --enable-runtime-cpu-detect \
+ --enable-shared \
+ --enable-postproc \
+ --enable-pic \
+ --disable-install-docs \
+ --disable-install-srcs \
+ --disable-install-bins \
+ --as=yasm
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libvpx/checksums b/extra/libvpx/checksums
new file mode 100644
index 00000000..819af214
--- /dev/null
+++ b/extra/libvpx/checksums
@@ -0,0 +1,2 @@
+df19b8f24758e90640e1ab228ab4a4676ec3df19d23e4593375e6f3847dee03e v1.8.1.tar.gz
+ce802d64bcbeb4230527aea2b4284d9844fb12fa5aca868a94e03982f85ec45b fix-busybox-diff.patch
diff --git a/extra/libvpx/depends b/extra/libvpx/depends
new file mode 100644
index 00000000..30287002
--- /dev/null
+++ b/extra/libvpx/depends
@@ -0,0 +1,2 @@
+perl make
+yasm make
diff --git a/extra/libvpx/patches/fix-busybox-diff.patch b/extra/libvpx/patches/fix-busybox-diff.patch
new file mode 100644
index 00000000..fa93b0a6
--- /dev/null
+++ b/extra/libvpx/patches/fix-busybox-diff.patch
@@ -0,0 +1,13 @@
+diff --git a/configure b/configure
+index e5a74c6..11f660d 100755
+--- a/configure
++++ b/configure
+@@ -170,7 +170,7 @@ for t in ${all_targets}; do
+ [ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
+ done
+
+-if ! diff --version >/dev/null; then
++if ! command -v diff >/dev/null; then
+ die "diff missing: Try installing diffutils via your package manager."
+ fi
+
diff --git a/extra/libvpx/sources b/extra/libvpx/sources
new file mode 100644
index 00000000..1927b430
--- /dev/null
+++ b/extra/libvpx/sources
@@ -0,0 +1,2 @@
+https://github.com/webmproject/libvpx/archive/v1.8.1.tar.gz
+patches/fix-busybox-diff.patch
diff --git a/extra/libvpx/version b/extra/libvpx/version
new file mode 100644
index 00000000..8aa37bcd
--- /dev/null
+++ b/extra/libvpx/version
@@ -0,0 +1 @@
+1.8.1 1
diff --git a/extra/libwebp/build b/extra/libwebp/build
new file mode 100755
index 00000000..9b42927e
--- /dev/null
+++ b/extra/libwebp/build
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --disable-static \
+ --enable-libwebpmux \
+ --enable-libwebpdemux \
+ --enable-libwebpdecoder
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libwebp/checksums b/extra/libwebp/checksums
new file mode 100644
index 00000000..b51a743b
--- /dev/null
+++ b/extra/libwebp/checksums
@@ -0,0 +1 @@
+e20a07865c8697bba00aebccc6f54912d6bc333bb4d604e6b07491c1a226b34f libwebp-1.0.3.tar.gz
diff --git a/extra/libwebp/depends b/extra/libwebp/depends
new file mode 100644
index 00000000..901a7cd2
--- /dev/null
+++ b/extra/libwebp/depends
@@ -0,0 +1,3 @@
+pkgconf make
+libpng
+libjpeg-turbo
diff --git a/extra/libwebp/sources b/extra/libwebp/sources
new file mode 100644
index 00000000..57061577
--- /dev/null
+++ b/extra/libwebp/sources
@@ -0,0 +1 @@
+https://downloads.webmproject.org/releases/webp/libwebp-1.0.3.tar.gz
diff --git a/extra/libwebp/version b/extra/libwebp/version
new file mode 100644
index 00000000..4ee872a0
--- /dev/null
+++ b/extra/libwebp/version
@@ -0,0 +1 @@
+1.0.3 1
diff --git a/extra/libxml2/build b/extra/libxml2/build
new file mode 100755
index 00000000..a568fbde
--- /dev/null
+++ b/extra/libxml2/build
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --with-threads \
+ --with-history \
+ --without-python \
+ --without-icu
+
+make
+make DESTDIR="$1" install
diff --git a/extra/libxml2/checksums b/extra/libxml2/checksums
new file mode 100644
index 00000000..767c08ad
--- /dev/null
+++ b/extra/libxml2/checksums
@@ -0,0 +1 @@
+aafee193ffb8fe0c82d4afef6ef91972cbaf5feea100edc2f262750611b4be1f libxml2-2.9.10.tar.gz
diff --git a/extra/libxml2/depends b/extra/libxml2/depends
new file mode 100644
index 00000000..8c249387
--- /dev/null
+++ b/extra/libxml2/depends
@@ -0,0 +1,2 @@
+xz
+zlib
diff --git a/extra/libxml2/sources b/extra/libxml2/sources
new file mode 100644
index 00000000..2077d565
--- /dev/null
+++ b/extra/libxml2/sources
@@ -0,0 +1 @@
+https://fossies.org/linux/www/libxml2-2.9.10.tar.gz
diff --git a/extra/libxml2/version b/extra/libxml2/version
new file mode 100644
index 00000000..af4c1a1f
--- /dev/null
+++ b/extra/libxml2/version
@@ -0,0 +1 @@
+2.9.10 1
diff --git a/extra/llvm/build b/extra/llvm/build
new file mode 100755
index 00000000..337ebeb3
--- /dev/null
+++ b/extra/llvm/build
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+
+export DESTDIR="$1"
+
+cmake -B build \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLLVM_BUILD_LLVM_DYLIB=ON \
+ -DLLVM_LINK_LLVM_DYLIB=ON \
+ -DLLVM_TARGETS_TO_BUILD="host;AMDGPU" \
+ -DLLVM_ENABLE_RTTI=ON \
+ -DLLVM_HOST_TRIPLE="$(cc -dumpmachine)" \
+ -DLLVM_BUILD_EXAMPLES=OFF \
+ -DLLVM_BUILD_DOCS=OFF \
+ -DLLVM_BUILD_TESTS=OFF \
+ -Wno-dev
+
+cmake --build build
+cmake --install build
diff --git a/extra/llvm/checksums b/extra/llvm/checksums
new file mode 100644
index 00000000..74fbcfb0
--- /dev/null
+++ b/extra/llvm/checksums
@@ -0,0 +1 @@
+d6a0565cf21f22e9b4353b2eb92622e8365000a9e90a16b09b56f8157eabfe84 llvm-9.0.0.src.tar.xz
diff --git a/extra/llvm/depends b/extra/llvm/depends
new file mode 100644
index 00000000..126422ec
--- /dev/null
+++ b/extra/llvm/depends
@@ -0,0 +1,3 @@
+cmake make
+python make
+zlib
diff --git a/extra/llvm/sources b/extra/llvm/sources
new file mode 100644
index 00000000..2aa9c3ce
--- /dev/null
+++ b/extra/llvm/sources
@@ -0,0 +1 @@
+https://releases.llvm.org/9.0.0/llvm-9.0.0.src.tar.xz
diff --git a/extra/llvm/version b/extra/llvm/version
new file mode 100644
index 00000000..f8041b0a
--- /dev/null
+++ b/extra/llvm/version
@@ -0,0 +1 @@
+9.0.0 1
diff --git a/extra/lvm2/build b/extra/lvm2/build
new file mode 100755
index 00000000..ffa71785
--- /dev/null
+++ b/extra/lvm2/build
@@ -0,0 +1,41 @@
+#!/bin/sh -e
+
+patch -p1 < fix-stdio-usage.patch
+patch -p1 < disable-symver.patch
+
+# LVM2 calls 'fmt -1' throughout the build process.
+# Busybox doesn't provide this command, however
+# all it does is split words one per line and
+# 'tr' can be used in its place.
+sed -i 's/fmt -1/tr " " "\\n"/' \
+ make.tmpl.in libdm/make.tmpl.in
+
+# The build fails when using busybox's 'mkdir'(?),
+# swap to using 'install -d' instead which works.
+export MKDIR_P="install -d"
+
+./configure \
+ --prefix=/usr \
+ --sbindir=/usr/bin \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --disable-selinux \
+ --enable-pkgconfig \
+ --enable-fsadm \
+ --enable-dmeventd \
+ --enable-cmdlib \
+ --enable-udev_sync \
+ --enable-udev_rules \
+ --enable-symvers=no \
+ --disable-symvers \
+ --with-default-dm-run-dir=/run \
+ --with-default-locking-dir=/run/lock/lvm \
+ --with-default-pid-dir=/run \
+ --with-default-run-dir=/run/lvm
+
+make DESTDIR="$1" install
+
+# Make all libraries and binaries writable.
+chmod -v u+w "$1/usr/lib/"* \
+ "$1/usr/include/"* \
+ "$1/usr/bin/"*
diff --git a/extra/lvm2/checksums b/extra/lvm2/checksums
new file mode 100644
index 00000000..c5677346
--- /dev/null
+++ b/extra/lvm2/checksums
@@ -0,0 +1,3 @@
+91753976ea1b9d94475781680be667a61fe611e89050fc73e1edbebbdc87ed44 LVM2.2.03.06.tgz
+36b598a65d24b18ae7b7657b37343788c96ae56cb9673a13a09423c031002b32 fix-stdio-usage.patch
+0eafb3464043c81644c919e42c79f7fbd614ca27a4bf5665b658856008147e59 disable-symver.patch
diff --git a/extra/lvm2/depends b/extra/lvm2/depends
new file mode 100644
index 00000000..95359853
--- /dev/null
+++ b/extra/lvm2/depends
@@ -0,0 +1,3 @@
+eudev
+libaio
+util-linux
diff --git a/extra/lvm2/patches/disable-symver.patch b/extra/lvm2/patches/disable-symver.patch
new file mode 100644
index 00000000..6216c061
--- /dev/null
+++ b/extra/lvm2/patches/disable-symver.patch
@@ -0,0 +1,136 @@
+diff --git a/configure b/configure
+index 6dd7eda..ef6a416 100755
+--- a/configure
++++ b/configure
+@@ -959,6 +959,7 @@ enable_fsadm
+ enable_blkdeactivate
+ enable_dmeventd
+ enable_selinux
++enable_symvers
+ enable_nls
+ with_localedir
+ with_confdir
+@@ -1677,6 +1678,9 @@ Optional Features:
+ --disable-blkdeactivate disable blkdeactivate
+ --enable-dmeventd enable the device-mapper event daemon
+ --disable-selinux disable selinux support
++ --enable-symvers[=STYLE]
++ enables symbol versioning of the shared library
++ [default=gnu]
+ --enable-nls enable Native Language Support
+
+ Optional Packages:
+@@ -3077,7 +3081,6 @@ if test -z "$CFLAGS"; then :
+ fi
+ case "$host_os" in
+ linux*)
+- CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
+ # equivalent to -rdynamic
+ ELDFLAGS="-Wl,--export-dynamic"
+ # FIXME Generate list and use --dynamic-list=.dlopen.sym
+@@ -12969,6 +12972,33 @@ done
+ LIBS=$lvm_saved_libs
+ fi
+
++################################################################################
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable symbol versioning" >&5
++$as_echo_n "checking whether to enable symbol versioning... " >&6; }
++# Check whether --enable-symvers was given.
++if test "${enable_symvers+set}" = set; then :
++ enableval=$enable_symvers;
++ case "$enableval" in
++ gnu|no) ;;
++ *) as_fn_error $? "Unknown argument to enable/disable symvers" "$LINENO" 5 ;;
++ esac
++else
++ enable_symvers=gnu
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_symvers" >&5
++$as_echo "$enable_symvers" >&6; }
++
++if test x$GCC = xyes && test x$enable_symvers = xgnu ; then
++
++$as_echo "#define GNU_SYMVER 1" >>confdefs.h
++
++ case "$host_os" in
++ linux*) CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym" ;;
++ esac
++fi
++
++
+ ################################################################################
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable internationalisation" >&5
+ $as_echo_n "checking whether to enable internationalisation... " >&6; }
+diff --git a/lib/misc/lib.h b/lib/misc/lib.h
+index c14f437..79b36a3 100644
+--- a/lib/misc/lib.h
++++ b/lib/misc/lib.h
+@@ -62,7 +62,7 @@
+ * versions of library symbols prior to the introduction of symbol
+ * versioning: it must never be used for new symbols.
+ */
+-#if defined(__GNUC__)
++#if defined(GNU_SYMVER)
+ #define DM_EXPORT_SYMBOL(func, ver) \
+ __asm__(".symver " #func "_v" #ver ", " #func "@DM_" #ver )
+ #define DM_EXPORT_SYMBOL_BASE(func) \
+diff --git a/libdm/datastruct/bitset.c b/libdm/datastruct/bitset.c
+index 06bd31a..8f36ec7 100644
+--- a/libdm/datastruct/bitset.c
++++ b/libdm/datastruct/bitset.c
+@@ -242,7 +242,7 @@ bad:
+ return NULL;
+ }
+
+-#if defined(__GNUC__)
++#if defined(GNU_SYMVER)
+ /*
+ * Maintain backward compatibility with older versions that did not
+ * accept a 'min_num_bits' argument to dm_bitset_parse_list().
+@@ -254,6 +254,4 @@ dm_bitset_t dm_bitset_parse_list_v1_02_129(const char *str, struct dm_pool *mem)
+ }
+ DM_EXPORT_SYMBOL(dm_bitset_parse_list, 1_02_129);
+
+-#else /* if defined(__GNUC__) */
+-
+ #endif
+diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
+index dd46b67..b09abdc 100644
+--- a/libdm/ioctl/libdm-iface.c
++++ b/libdm/ioctl/libdm-iface.c
+@@ -2176,7 +2176,7 @@ void dm_lib_exit(void)
+ _version_checked = 0;
+ }
+
+-#if defined(__GNUC__)
++#if defined(GNU_SYMVER)
+ /*
+ * Maintain binary backward compatibility.
+ * Version script mechanism works with 'gcc' compatible compilers only.
+diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
+index ee12da2..08829c5 100644
+--- a/libdm/libdm-deptree.c
++++ b/libdm/libdm-deptree.c
+@@ -3811,7 +3811,7 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
+ dnode->callback_data = data;
+ }
+
+-#if defined(__GNUC__)
++#if defined(GNU_SYMVER)
+ /*
+ * Backward compatible implementations.
+ *
+diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
+index 420e3e1..066bcdf 100644
+--- a/libdm/libdm-stats.c
++++ b/libdm/libdm-stats.c
+@@ -5067,7 +5067,7 @@ int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path,
+ * current dm_stats_create_region() version.
+ */
+
+-#if defined(__GNUC__)
++#if defined(GNU_SYMVER)
+ int dm_stats_create_region_v1_02_106(struct dm_stats *dms, uint64_t *region_id,
+ uint64_t start, uint64_t len, int64_t step,
+ int precise, const char *program_id,
diff --git a/extra/lvm2/patches/fix-stdio-usage.patch b/extra/lvm2/patches/fix-stdio-usage.patch
new file mode 100644
index 00000000..3fd80f64
--- /dev/null
+++ b/extra/lvm2/patches/fix-stdio-usage.patch
@@ -0,0 +1,58 @@
+diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
+index 479d499..7681a5b 100644
+--- a/lib/commands/toolcontext.c
++++ b/lib/commands/toolcontext.c
+@@ -1599,7 +1599,7 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
+ /* FIXME Make this configurable? */
+ reset_lvm_errno(1);
+
+-#ifndef VALGRIND_POOL
++#if defined(__GLIBC__) && !defined(VALGRIND_POOL)
+ /* Set in/out stream buffering before glibc */
+ if (set_buffering
+ #ifdef SYS_gettid
+@@ -1980,7 +1980,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
+
+ if (cmd->pending_delete_mem)
+ dm_pool_destroy(cmd->pending_delete_mem);
+-#ifndef VALGRIND_POOL
++#if defined(__GLIBC__) && !defined(VALGRIND_POOL)
+ if (cmd->linebuffer) {
+ /* Reset stream buffering to defaults */
+ if (is_valid_fd(STDIN_FILENO) &&
+diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
+index 860e6de..c7539bd 100644
+--- a/tools/lvmcmdline.c
++++ b/tools/lvmcmdline.c
+@@ -3209,6 +3209,7 @@ int lvm_split(char *str, int *argc, char **argv, int max)
+ /* Make sure we have always valid filedescriptors 0,1,2 */
+ static int _check_standard_fds(void)
+ {
++#ifdef __GLIBC__
+ int err = is_valid_fd(STDERR_FILENO);
+
+ if (!is_valid_fd(STDIN_FILENO) &&
+@@ -3236,6 +3237,12 @@ static int _check_standard_fds(void)
+ return 0;
+ }
+
++#else
++ if (!is_valid_fd(STDERR_FILENO) ||
++ !is_valid_fd(STDOUT_FILENO) ||
++ !is_valid_fd(STDIN_FILENO))
++ return 0;
++#endif
+ return 1;
+ }
+
+--- ./lib/mm/memlock.c.orig 2015-03-09 11:18:41.560028850 -0100
++++ ./lib/mm/memlock.c 2015-03-09 11:19:54.504373309 -0100
+@@ -137,7 +137,7 @@
+
+ static void _allocate_memory(void)
+ {
+-#ifndef VALGRIND_POOL
++#if !defined(VALGRIND_POOL) && defined(__GLIBC__)
+ void *stack_mem;
+ struct rlimit limit;
+ int i, area = 0, missing = _size_malloc_tmp, max_areas = 32, hblks;
diff --git a/extra/lvm2/sources b/extra/lvm2/sources
new file mode 100644
index 00000000..34dd5d35
--- /dev/null
+++ b/extra/lvm2/sources
@@ -0,0 +1,3 @@
+https://mirrors.kernel.org/sourceware/lvm2/releases/LVM2.2.03.06.tgz
+patches/fix-stdio-usage.patch
+patches/disable-symver.patch
diff --git a/extra/lvm2/version b/extra/lvm2/version
new file mode 100644
index 00000000..7ddcde45
--- /dev/null
+++ b/extra/lvm2/version
@@ -0,0 +1 @@
+2.03.06 1
diff --git a/extra/meson/build b/extra/meson/build
new file mode 100755
index 00000000..366c5443
--- /dev/null
+++ b/extra/meson/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+python setup.py build
+python setup.py install \
+ --root="$1" \
+ --optimize=1 \
+ --skip-build
diff --git a/extra/meson/checksums b/extra/meson/checksums
new file mode 100644
index 00000000..20613f9d
--- /dev/null
+++ b/extra/meson/checksums
@@ -0,0 +1 @@
+0f426ed1362c38bcc5b9027ec6aec3445d6db88e8d7249ed992e9af88a42d0e0 0.52.0.tar.gz
diff --git a/extra/meson/depends b/extra/meson/depends
new file mode 100644
index 00000000..35f08097
--- /dev/null
+++ b/extra/meson/depends
@@ -0,0 +1,2 @@
+python
+samurai
diff --git a/extra/meson/sources b/extra/meson/sources
new file mode 100644
index 00000000..c8fbc601
--- /dev/null
+++ b/extra/meson/sources
@@ -0,0 +1 @@
+https://github.com/mesonbuild/meson/archive/0.52.0.tar.gz
diff --git a/extra/meson/version b/extra/meson/version
new file mode 100644
index 00000000..3255ab0c
--- /dev/null
+++ b/extra/meson/version
@@ -0,0 +1 @@
+0.52.0 2
diff --git a/extra/mpv/build b/extra/mpv/build
new file mode 100755
index 00000000..9d61d973
--- /dev/null
+++ b/extra/mpv/build
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+
+ln -s waf-2.0.18 waf
+
+python waf configure \
+ --prefix=/usr \
+ --mandir=/usr/share/man \
+ --confdir=/etc/mpv \
+ --enable-alsa \
+ --enable-libass
+
+python waf build
+python waf install --destdir="$1"
diff --git a/extra/mpv/checksums b/extra/mpv/checksums
new file mode 100644
index 00000000..a8fab458
--- /dev/null
+++ b/extra/mpv/checksums
@@ -0,0 +1,2 @@
+33a1bcb7e74ff17f070e754c15c52228cf44f2cefbfd8f34886ae81df214ca35 v0.30.0.tar.gz
+2e0cf83a63843da127610420cef1d3126f1187d8e572b6b3a28052fc2250d4bf waf-2.0.18
diff --git a/extra/mpv/depends b/extra/mpv/depends
new file mode 100644
index 00000000..334650cf
--- /dev/null
+++ b/extra/mpv/depends
@@ -0,0 +1,9 @@
+alsa-lib
+ffmpeg
+freetype-harfbuzz
+libass
+libXScrnSaver
+libXinerama
+libXrandr
+mesa
+python make
diff --git a/extra/mpv/sources b/extra/mpv/sources
new file mode 100644
index 00000000..7355aa8e
--- /dev/null
+++ b/extra/mpv/sources
@@ -0,0 +1,2 @@
+https://github.com/mpv-player/mpv/archive/v0.30.0.tar.gz
+https://waf.io/waf-2.0.18
diff --git a/extra/mpv/version b/extra/mpv/version
new file mode 100644
index 00000000..b05fc3ac
--- /dev/null
+++ b/extra/mpv/version
@@ -0,0 +1 @@
+0.30.0 1
diff --git a/extra/nasm/build b/extra/nasm/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/nasm/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/nasm/checksums b/extra/nasm/checksums
new file mode 100644
index 00000000..f7d8373b
--- /dev/null
+++ b/extra/nasm/checksums
@@ -0,0 +1 @@
+e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5 nasm-2.14.02.tar.xz
diff --git a/extra/nasm/depends b/extra/nasm/depends
new file mode 100644
index 00000000..97a95494
--- /dev/null
+++ b/extra/nasm/depends
@@ -0,0 +1 @@
+perl make
diff --git a/extra/nasm/sources b/extra/nasm/sources
new file mode 100644
index 00000000..79bc0487
--- /dev/null
+++ b/extra/nasm/sources
@@ -0,0 +1 @@
+https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.xz
diff --git a/extra/nasm/version b/extra/nasm/version
new file mode 100644
index 00000000..bb3f3253
--- /dev/null
+++ b/extra/nasm/version
@@ -0,0 +1 @@
+2.14.02 1
diff --git a/extra/ncurses/build b/extra/ncurses/build
new file mode 100755
index 00000000..6798aa43
--- /dev/null
+++ b/extra/ncurses/build
@@ -0,0 +1,21 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --mandir=/usr/share/man \
+ --enable-pc-files \
+ --disable-rpath-hack \
+ --with-pkg-config-libdir=/usr/lib/pkgconfig \
+ --with-shared \
+ --enable-widec \
+ --without-ada \
+ --without-tests \
+ --without-debug \
+ --without-cxx-binding
+
+make
+make DESTDIR="$1" install
+
+# These conflict with busybox's.
+rm -f "$1/usr/bin/clear"
+rm -f "$1/usr/bin/reset"
diff --git a/extra/ncurses/checksums b/extra/ncurses/checksums
new file mode 100644
index 00000000..c65d894d
--- /dev/null
+++ b/extra/ncurses/checksums
@@ -0,0 +1 @@
+aa057eeeb4a14d470101eff4597d5833dcef5965331be3528c08d99cebaa0d17 ncurses-6.1.tar.gz
diff --git a/extra/ncurses/sources b/extra/ncurses/sources
new file mode 100644
index 00000000..30a20483
--- /dev/null
+++ b/extra/ncurses/sources
@@ -0,0 +1 @@
+https://ftp.gnu.org/gnu/ncurses/ncurses-6.1.tar.gz
diff --git a/extra/ncurses/version b/extra/ncurses/version
new file mode 100644
index 00000000..1143f417
--- /dev/null
+++ b/extra/ncurses/version
@@ -0,0 +1 @@
+6.1 1
diff --git a/extra/nodejs/build b/extra/nodejs/build
new file mode 100755
index 00000000..59b7ad09
--- /dev/null
+++ b/extra/nodejs/build
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+# Python 3 support (but not for > 3.5).
+sed -i 's/(3, 5)/(3, 8)/' configure
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/nodejs/checksums b/extra/nodejs/checksums
new file mode 100644
index 00000000..f9f60c26
--- /dev/null
+++ b/extra/nodejs/checksums
@@ -0,0 +1 @@
+22b095bd70a8923d7281733bc546f9e3b388cde6cb948f45fa7413ac805243ce v13.2.0.tar.gz
diff --git a/extra/nodejs/depends b/extra/nodejs/depends
new file mode 100644
index 00000000..ecc77727
--- /dev/null
+++ b/extra/nodejs/depends
@@ -0,0 +1 @@
+python make
diff --git a/extra/nodejs/sources b/extra/nodejs/sources
new file mode 100644
index 00000000..e788e0e1
--- /dev/null
+++ b/extra/nodejs/sources
@@ -0,0 +1 @@
+https://github.com/nodejs/node/archive/v13.2.0.tar.gz
diff --git a/extra/nodejs/version b/extra/nodejs/version
new file mode 100644
index 00000000..510ef747
--- /dev/null
+++ b/extra/nodejs/version
@@ -0,0 +1 @@
+13.2.0 1
diff --git a/extra/openssh/build b/extra/openssh/build
new file mode 100755
index 00000000..cdd68702
--- /dev/null
+++ b/extra/openssh/build
@@ -0,0 +1,25 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --datadir=/usr/share/openssh \
+ --sysconfdir=/etc/ssh \
+ --without-selinux \
+ --with-privsep-user=nobody \
+ --with-mantype=doc \
+ --without-rpath \
+ --disable-strip \
+ --with-ssl-engine \
+ --with-pid-dir=/run \
+ --disable-wtmp \
+ --disable-utmp
+
+make
+make DESTDIR="$1" install
+
+install -m 755 contrib/ssh-copy-id "$1/usr/bin/ssh-copy-id"
+install -m 644 contrib/ssh-copy-id.1 "$1/usr/share/man/man8/ssh-copy-id.1"
+
+# Install runit services.
+install -Dm 755 sshd.run "$1/etc/sv/sshd/run"
+ln -s /run/runit/supervise.sshd "$1/etc/sv/sshd/supervise"
diff --git a/extra/openssh/checksums b/extra/openssh/checksums
new file mode 100644
index 00000000..22451ba5
--- /dev/null
+++ b/extra/openssh/checksums
@@ -0,0 +1,2 @@
+02f5dbef3835d0753556f973cd57b4c19b6b1f6cd24c03445e23ac77ca1b93ff openssh-8.1p1.tar.gz
+5d32a817344ac444424063d75e49afd95d7eb76d972ef5c5cfad355c8e8b1ff1 sshd.run
diff --git a/extra/openssh/depends b/extra/openssh/depends
new file mode 100644
index 00000000..9ee911ae
--- /dev/null
+++ b/extra/openssh/depends
@@ -0,0 +1,2 @@
+libressl
+zlib
diff --git a/extra/openssh/files/sshd.run b/extra/openssh/files/sshd.run
new file mode 100644
index 00000000..04f7adbb
--- /dev/null
+++ b/extra/openssh/files/sshd.run
@@ -0,0 +1,3 @@
+#!/bin/sh
+ssh-keygen -A >/dev/null 2>&1 # Will generate host keys if they don't already exist.
+exec /usr/bin/sshd -D
diff --git a/extra/openssh/sources b/extra/openssh/sources
new file mode 100644
index 00000000..29b23857
--- /dev/null
+++ b/extra/openssh/sources
@@ -0,0 +1,2 @@
+https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.1p1.tar.gz
+files/sshd.run
diff --git a/extra/openssh/version b/extra/openssh/version
new file mode 100644
index 00000000..faa64dd7
--- /dev/null
+++ b/extra/openssh/version
@@ -0,0 +1 @@
+8.1p1 1
diff --git a/extra/opus/build b/extra/opus/build
new file mode 100755
index 00000000..23f46765
--- /dev/null
+++ b/extra/opus/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --enable-custom-modes \
+ --enable-float-approx
+
+make
+make DESTDIR="$1" install
diff --git a/extra/opus/checksums b/extra/opus/checksums
new file mode 100644
index 00000000..77a9ad97
--- /dev/null
+++ b/extra/opus/checksums
@@ -0,0 +1 @@
+65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d opus-1.3.1.tar.gz
diff --git a/extra/opus/sources b/extra/opus/sources
new file mode 100644
index 00000000..d11f0722
--- /dev/null
+++ b/extra/opus/sources
@@ -0,0 +1 @@
+https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz
diff --git a/extra/opus/version b/extra/opus/version
new file mode 100644
index 00000000..957d07e2
--- /dev/null
+++ b/extra/opus/version
@@ -0,0 +1 @@
+1.3.1 1
diff --git a/extra/popt/build b/extra/popt/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/popt/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/popt/checksums b/extra/popt/checksums
new file mode 100644
index 00000000..e9a82a58
--- /dev/null
+++ b/extra/popt/checksums
@@ -0,0 +1 @@
+e728ed296fe9f069a0e005003c3d6b2dde3d9cad453422a10d6558616d304cc8 popt-1.16.tar.gz
diff --git a/extra/popt/sources b/extra/popt/sources
new file mode 100644
index 00000000..e1aab68b
--- /dev/null
+++ b/extra/popt/sources
@@ -0,0 +1 @@
+https://fossies.org/linux/misc/popt-1.16.tar.gz
diff --git a/extra/popt/version b/extra/popt/version
new file mode 100644
index 00000000..d1d913ed
--- /dev/null
+++ b/extra/popt/version
@@ -0,0 +1 @@
+1.16 1
diff --git a/extra/python/build b/extra/python/build
new file mode 100755
index 00000000..19d7173b
--- /dev/null
+++ b/extra/python/build
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+
+patch -p1 < python3-always-pip.patch
+
+./configure \
+ --prefix=/usr \
+ --enable-shared \
+ --with-system-expat \
+ --with-system-ffi \
+ --with-ensurepip=yes
+
+make
+make DESTDIR="$1" install
+
+ln -s python3 "$1/usr/bin/python"
+ln -s pip3 "$1/usr/bin/pip"
+
+# Make static library writable.
+chmod -v u+w "$1/usr/lib/libpython"*
diff --git a/extra/python/checksums b/extra/python/checksums
new file mode 100644
index 00000000..50298dba
--- /dev/null
+++ b/extra/python/checksums
@@ -0,0 +1,2 @@
+b356244e13fb5491da890b35b13b2118c3122977c2cd825e3eb6e7d462030d84 Python-3.8.0.tar.xz
+1a184c64f85d7a2fb57642135ea298ddd005684c5bd3e601b932cf31b82b9417 python3-always-pip.patch
diff --git a/extra/python/depends b/extra/python/depends
new file mode 100644
index 00000000..f5fadfec
--- /dev/null
+++ b/extra/python/depends
@@ -0,0 +1,5 @@
+bzip2
+expat
+libffi
+sqlite
+zlib
diff --git a/extra/python/patches/python3-always-pip.patch b/extra/python/patches/python3-always-pip.patch
new file mode 100644
index 00000000..91789c98
--- /dev/null
+++ b/extra/python/patches/python3-always-pip.patch
@@ -0,0 +1,13 @@
+diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py
+index 526dfd0..d85dc33 100644
+--- a/Lib/ensurepip/__init__.py
++++ b/Lib/ensurepip/__init__.py
+@@ -104,7 +104,7 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
+ additional_paths.append(os.path.join(tmpdir, wheel_name))
+
+ # Construct the arguments to be passed to the pip command
+- args = ["install", "--no-index", "--find-links", tmpdir]
++ args = ["install", "-I", "--no-index", "--find-links", tmpdir]
+ if root:
+ args += ["--root", root]
+ if upgrade:
diff --git a/extra/python/sources b/extra/python/sources
new file mode 100644
index 00000000..63dc186b
--- /dev/null
+++ b/extra/python/sources
@@ -0,0 +1,2 @@
+https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tar.xz
+patches/python3-always-pip.patch
diff --git a/extra/python/version b/extra/python/version
new file mode 100644
index 00000000..2af7c7b2
--- /dev/null
+++ b/extra/python/version
@@ -0,0 +1 @@
+3.8.0 1
diff --git a/extra/python2/build b/extra/python2/build
new file mode 100755
index 00000000..3b3866ff
--- /dev/null
+++ b/extra/python2/build
@@ -0,0 +1,14 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --without-ensurepip
+
+make
+make DESTDIR="$1" install
+
+rm "$1/usr/bin/2to3"
+rm "$1/usr/bin/python"
+
+# Make static library writable.
+chmod -v u+w "$1/usr/lib/libpython"*.a
diff --git a/extra/python2/checksums b/extra/python2/checksums
new file mode 100644
index 00000000..01c6883e
--- /dev/null
+++ b/extra/python2/checksums
@@ -0,0 +1 @@
+4d43f033cdbd0aa7b7023c81b0e986fd11e653b5248dac9144d508f11812ba41 Python-2.7.17.tar.xz
diff --git a/extra/python2/depends b/extra/python2/depends
new file mode 100644
index 00000000..4711f7dd
--- /dev/null
+++ b/extra/python2/depends
@@ -0,0 +1,3 @@
+bzip2
+sqlite
+zlib
diff --git a/extra/python2/sources b/extra/python2/sources
new file mode 100644
index 00000000..af09d116
--- /dev/null
+++ b/extra/python2/sources
@@ -0,0 +1 @@
+https://www.python.org/ftp/python/2.7.17/Python-2.7.17.tar.xz
diff --git a/extra/python2/version b/extra/python2/version
new file mode 100644
index 00000000..6b274355
--- /dev/null
+++ b/extra/python2/version
@@ -0,0 +1 @@
+2.7.17 1
diff --git a/extra/rust/build b/extra/rust/build
new file mode 100755
index 00000000..f02d3b3e
--- /dev/null
+++ b/extra/rust/build
@@ -0,0 +1,56 @@
+#!/bin/sh -e
+
+# This package mimics the download process of rust's 'x.py'
+# bootstrap library to allow for the removal of the internet
+# connection requirement per build further enabling checksums
+# and signature verification by KISS.
+{
+ cache_dir=build/cache/2019-09-26
+ mkdir -p "$cache_dir"
+
+ for tarball in *.tar.gz\?no-extract; do
+ mv -f "$tarball" "$cache_dir/${tarball%%\?no-extract}"
+ done
+}
+
+patch -p1 < musl-libressl.patch
+
+# 'rust' checksums files in 'vendor/', but we patch a few files.
+for vendor in libc openssl-sys; do
+ sed -i 's/\("files":{\)[^}]*/\1/' "vendor/$vendor/.cargo-checksum.json"
+done
+
+cat > config.toml <<EOF
+[llvm]
+link-shared = true
+
+[build]
+build = "x86_64-unknown-linux-musl"
+host = [ "x86_64-unknown-linux-musl" ]
+target = [ "x86_64-unknown-linux-musl" ]
+docs = false
+extended = true
+submodules = false
+python = "python3"
+locked-deps = true
+vendor = true
+
+[install]
+prefix = "/usr"
+
+[rust]
+channel = "stable"
+rpath = false
+codegen-units = 1
+debuginfo-level = 0
+backtrace = false
+jemalloc = false
+codegen-tests = false
+
+[target.x86_64-unknown-linux-musl]
+llvm-config = "/usr/bin/llvm-config"
+crt-static = false
+EOF
+
+python3 ./x.py build -j "$(nproc)"
+DESTDIR="$1" python3 ./x.py install
diff --git a/extra/rust/checksums b/extra/rust/checksums
new file mode 100644
index 00000000..6570ccd3
--- /dev/null
+++ b/extra/rust/checksums
@@ -0,0 +1,5 @@
+b4a1f6b6a93931f270691aba4fc85eee032fecda973e6b9c774cd06857609357 rustc-1.39.0-src.tar.gz
+56b87fdca1f41b634285593cae42fdbd5fe9632ef502336679362b283ed53c22 rust-std-1.38.0-x86_64-unknown-linux-musl.tar.gz?no-extract
+bb0166cbb1d31bcb09d79224e7ac43a80d9448b7199b5392a3852b3ec71840aa rustc-1.38.0-x86_64-unknown-linux-musl.tar.gz?no-extract
+bbf58bf638c5c4cf86caaa1bfe2835b3856d4ef46447c9942d5e59cc7654c5e4 cargo-0.39.0-x86_64-unknown-linux-musl.tar.gz?no-extract
+122b5d9b83778882bdd64d40fea98982f7d1db510e09fc64a4ece5add4fd99a2 musl-libressl.patch
diff --git a/extra/rust/depends b/extra/rust/depends
new file mode 100644
index 00000000..058f23c8
--- /dev/null
+++ b/extra/rust/depends
@@ -0,0 +1,7 @@
+cmake make
+curl make
+libressl
+llvm
+python make
+xz
+zlib
diff --git a/extra/rust/patches/musl-libressl.patch b/extra/rust/patches/musl-libressl.patch
new file mode 100644
index 00000000..ed1f2404
--- /dev/null
+++ b/extra/rust/patches/musl-libressl.patch
@@ -0,0 +1,128 @@
+diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
+index 6ea32edfb..9d6d10f7f 100644
+--- a/src/bootstrap/compile.rs
++++ b/src/bootstrap/compile.rs
+@@ -122,7 +122,7 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
+ // with a glibc-targeting toolchain, given we have the appropriate startup
+ // files. As those shipped with glibc won't work, copy the ones provided by
+ // musl so we have them on linux-gnu hosts.
+- if target.contains("musl") {
++ if target.contains("noop") {
+ for &obj in &["crt1.o", "crti.o", "crtn.o"] {
+ builder.copy(
+ &builder.musl_root(target).unwrap().join("lib").join(obj),
+diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
+index bffe748f3..40f9f597f 100644
+--- a/src/bootstrap/sanity.rs
++++ b/src/bootstrap/sanity.rs
+@@ -188,7 +188,7 @@ pub fn check(build: &mut Build) {
+ }
+
+ // Make sure musl-root is valid
+- if target.contains("musl") {
++ if target.contains("noop") {
+ // If this is a native target (host is also musl) and no musl-root is given,
+ // fall back to the system toolchain in /usr before giving up
+ if build.musl_root(*target).is_none() && build.config.build == *target {
+diff --git a/src/librustc_target/spec/linux_musl_base.rs b/src/librustc_target/spec/linux_musl_base.rs
+index e294e6398..17fecb3b2 100644
+--- a/src/librustc_target/spec/linux_musl_base.rs
++++ b/src/librustc_target/spec/linux_musl_base.rs
+@@ -26,7 +26,7 @@ pub fn opts() -> TargetOptions {
+ base.post_link_objects_crt.push("crtn.o".to_string());
+
+ // These targets statically link libc by default
+- base.crt_static_default = true;
++ base.crt_static_default = false;
+ // These targets allow the user to choose between static and dynamic linking.
+ base.crt_static_respected = true;
+
+diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs
+index f24d957d6..4632212fd 100644
+--- a/src/libunwind/build.rs
++++ b/src/libunwind/build.rs
+@@ -10,7 +10,7 @@ fn main() {
+ // Build the unwinding from libunwind C/C++ source code.
+ llvm_libunwind::compile();
+ } else if target.contains("linux") {
+- if target.contains("musl") {
++ if target.contains("noop") {
+ // linking for musl is handled in lib.rs
+ llvm_libunwind::compile();
+ } else if !target.contains("android") {
+diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs
+index 8d9164471..3adaaf43d 100644
+--- a/src/libunwind/lib.rs
++++ b/src/libunwind/lib.rs
+@@ -20,7 +20,7 @@ cfg_if::cfg_if! {
+ }
+ }
+
+-#[cfg(target_env = "musl")]
++#[cfg(target_env = "noop")]
+ #[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
+ #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
+ extern {}
+diff --git a/vendor/libc/src/unix/mod.rs b/vendor/libc/src/unix/mod.rs
+index 721d24116..26bf271cd 100644
+--- a/vendor/libc/src/unix/mod.rs
++++ b/vendor/libc/src/unix/mod.rs
+@@ -296,7 +296,7 @@ cfg_if! {
+ } else if #[cfg(feature = "std")] {
+ // cargo build, don't pull in anything extra as the libstd dep
+ // already pulls in all libs.
+- } else if #[cfg(target_env = "musl")] {
++ } else if #[cfg(target_env = "noop")] {
+ #[cfg_attr(feature = "rustc-dep-of-std",
+ link(name = "c", kind = "static",
+ cfg(target_feature = "crt-static")))]
+diff --git a/vendor/openssl-sys/build/main.rs b/vendor/openssl-sys/build/main.rs
+index 02b93b90a..27deca5fe 100644
+--- a/vendor/openssl-sys/build/main.rs
++++ b/vendor/openssl-sys/build/main.rs
+@@ -183,27 +183,30 @@ See rust-openssl README for more information:
+ if let Some(libressl_version) = libressl_version {
+ println!("cargo:libressl_version_number={:x}", libressl_version);
+
++ let major = (libressl_version >> 28) as u8;
+ let minor = (libressl_version >> 20) as u8;
+ let fix = (libressl_version >> 12) as u8;
+- let (minor, fix) = match (minor, fix) {
+- (5, 0) => ('5', '0'),
+- (5, 1) => ('5', '1'),
+- (5, 2) => ('5', '2'),
+- (5, _) => ('5', 'x'),
+- (6, 0) => ('6', '0'),
+- (6, 1) => ('6', '1'),
+- (6, 2) => ('6', '2'),
+- (6, _) => ('6', 'x'),
+- (7, _) => ('7', 'x'),
+- (8, 0) => ('8', '0'),
+- (8, 1) => ('8', '1'),
+- (8, _) => ('8', 'x'),
+- (9, 0) => ('9', '0'),
++ let (major, minor, fix) = match (major, minor, fix) {
++ (2, 5, 0) => ('2', '5', '0'),
++ (2, 5, 1) => ('2', '5', '1'),
++ (2, 5, 2) => ('2', '5', '2'),
++ (2, 5, _) => ('2', '5', 'x'),
++ (2, 6, 0) => ('2', '6', '0'),
++ (2, 6, 1) => ('2', '6', '1'),
++ (2, 6, 2) => ('2', '6', '2'),
++ (2, 6, _) => ('2', '6', 'x'),
++ (2, 7, _) => ('2', '7', 'x'),
++ (2, 8, 0) => ('2', '8', '0'),
++ (2, 8, 1) => ('2', '8', '1'),
++ (3, 0, _) => ('3', '0', 'x'),
++ (2, 9, 0) => ('2', '9', '0'),
++ (2, 9, _) => ('2', '9', 'x'),
++ (3, 0, 0) => ('3', '0', '0'),
+ _ => version_error(),
+ };
+
+ println!("cargo:libressl=true");
+- println!("cargo:libressl_version=2{}{}", minor, fix);
++ println!("cargo:libressl_version={}{}{}", major, minor, fix);
+ println!("cargo:version=101");
+ Version::Libressl
+ } else {
diff --git a/extra/rust/sources b/extra/rust/sources
new file mode 100644
index 00000000..a1e63232
--- /dev/null
+++ b/extra/rust/sources
@@ -0,0 +1,5 @@
+https://static.rust-lang.org/dist/rustc-1.39.0-src.tar.gz
+https://static.rust-lang.org/dist/2019-09-26/rust-std-1.38.0-x86_64-unknown-linux-musl.tar.gz?no-extract
+https://static.rust-lang.org/dist/2019-09-26/rustc-1.38.0-x86_64-unknown-linux-musl.tar.gz?no-extract
+https://static.rust-lang.org/dist/2019-09-26/cargo-0.39.0-x86_64-unknown-linux-musl.tar.gz?no-extract
+patches/musl-libressl.patch
diff --git a/extra/rust/version b/extra/rust/version
new file mode 100644
index 00000000..07fabd51
--- /dev/null
+++ b/extra/rust/version
@@ -0,0 +1 @@
+1.39.0 1
diff --git a/extra/samurai/build b/extra/samurai/build
new file mode 100755
index 00000000..1dd11b38
--- /dev/null
+++ b/extra/samurai/build
@@ -0,0 +1,6 @@
+#!/bin/sh -e
+
+make PREFIX=/usr
+make PREFIX=/usr DESTDIR="$1" install
+
+ln -s samu "$1/usr/bin/ninja"
diff --git a/extra/samurai/checksums b/extra/samurai/checksums
new file mode 100644
index 00000000..a3da810f
--- /dev/null
+++ b/extra/samurai/checksums
@@ -0,0 +1 @@
+e079e8de3b07ba0f1fffe2dff31c1fcb3be357c523abc6937108635a081a11f0 samurai-0.7.tar.gz
diff --git a/extra/samurai/sources b/extra/samurai/sources
new file mode 100644
index 00000000..b3b4891c
--- /dev/null
+++ b/extra/samurai/sources
@@ -0,0 +1 @@
+https://github.com/michaelforney/samurai/releases/download/0.7/samurai-0.7.tar.gz
diff --git a/extra/samurai/version b/extra/samurai/version
new file mode 100644
index 00000000..a7542609
--- /dev/null
+++ b/extra/samurai/version
@@ -0,0 +1 @@
+0.7 1
diff --git a/extra/shared-mime-info/build b/extra/shared-mime-info/build
new file mode 100755
index 00000000..58dddbe2
--- /dev/null
+++ b/extra/shared-mime-info/build
@@ -0,0 +1,54 @@
+#!/bin/sh -e
+#
+# We bypass the build system entirely as it has
+# a mandatory dependency on gettext.
+
+# Grab the package version.
+read -r version _ < "${0%/*}/version"
+
+mkdir -p "$1/usr/share/mime/packages" \
+ "$1/usr/share/pkgconfig" \
+ "$1/usr/bin"
+
+# Install with only English support.
+sed -e 's/_comment/comment/g' freedesktop.org.xml.in \
+ > "$1/usr/share/mime/packages/freedesktop.org.xml"
+
+# Replace markers in the file.
+sed -e 's|@prefix@|/usr|' -e "s|@VERSION@|$version|" shared-mime-info.pc.in \
+ > "$1/usr/share/pkgconfig/shared-mime-info.pc"
+
+# Define our own config.h statically.
+cat << EOF > config.h
+#define HAVE_BIND_TEXTDOMAIN_CODESET 1
+#define HAVE_FDATASYNC 1
+#define HAVE_GETTEXT 0
+#define HAVE_INTTYPES_H 1
+#define HAVE_LC_MESSAGES 1
+#define HAVE_LOCALE_H 1
+#define HAVE_MEMORY_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_UNISTD_H 1
+#define PACKAGE "shared-mime-info"
+#define PACKAGE_BUGREPORT ""
+#define PACKAGE_NAME "shared-mime-info"
+#define PACKAGE_STRING "shared-mime-info $version"
+#define PACKAGE_TARNAME "shared-mime-info"
+#define PACKAGE_URL ""
+#define PACKAGE_VERSION "$version"
+#define STDC_HEADERS 1
+#define VERSION "$version"
+EOF
+
+# Fix config.h include.
+sed -i 's/<config.h>/"config.h"/' update-mime-database.c
+
+# shellcheck disable=2046
+"${CC:-gcc}" -o "$1/usr/bin/update-mime-database" \
+ $(pkg-config --libs --cflags glib-2.0 libxml-2.0) \
+ update-mime-database.c
diff --git a/extra/shared-mime-info/checksums b/extra/shared-mime-info/checksums
new file mode 100644
index 00000000..4c76dfe4
--- /dev/null
+++ b/extra/shared-mime-info/checksums
@@ -0,0 +1 @@
+2df77d547fa0548def38614f318282bc9937e7bde5f139d35053b605f7fd34df Release-1-15.tar.gz
diff --git a/extra/shared-mime-info/depends b/extra/shared-mime-info/depends
new file mode 100644
index 00000000..4919fada
--- /dev/null
+++ b/extra/shared-mime-info/depends
@@ -0,0 +1,4 @@
+glib
+libxml2
+xz
+zlib
diff --git a/extra/shared-mime-info/post-install b/extra/shared-mime-info/post-install
new file mode 100755
index 00000000..e9dffaad
--- /dev/null
+++ b/extra/shared-mime-info/post-install
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+update-mime-database -V /usr/share/mime
diff --git a/extra/shared-mime-info/sources b/extra/shared-mime-info/sources
new file mode 100644
index 00000000..4ad8576c
--- /dev/null
+++ b/extra/shared-mime-info/sources
@@ -0,0 +1 @@
+https://github.com/freedesktop/xdg-shared-mime-info/archive/Release-1-15.tar.gz
diff --git a/extra/shared-mime-info/version b/extra/shared-mime-info/version
new file mode 100644
index 00000000..b5a3e89c
--- /dev/null
+++ b/extra/shared-mime-info/version
@@ -0,0 +1 @@
+1.15 1
diff --git a/extra/sqlite/build b/extra/sqlite/build
new file mode 100755
index 00000000..b5c79fd1
--- /dev/null
+++ b/extra/sqlite/build
@@ -0,0 +1,12 @@
+#!/bin/sh -e
+
+sed -i 's/ -ltinfo//g' configure
+
+./configure \
+ --prefix=/usr \
+ --enable-threadsafe \
+ --enable-dynamic-extensions \
+ --enable-fts5
+
+make -j 1
+make DESTDIR="$1" install
diff --git a/extra/sqlite/checksums b/extra/sqlite/checksums
new file mode 100644
index 00000000..a0bf9e77
--- /dev/null
+++ b/extra/sqlite/checksums
@@ -0,0 +1 @@
+8c5a50db089bd2a1b08dbc5b00d2027602ca7ff238ba7658fabca454d4298e60 sqlite-autoconf-3300100.tar.gz
diff --git a/extra/sqlite/depends b/extra/sqlite/depends
new file mode 100644
index 00000000..f22003e8
--- /dev/null
+++ b/extra/sqlite/depends
@@ -0,0 +1 @@
+zlib
diff --git a/extra/sqlite/sources b/extra/sqlite/sources
new file mode 100644
index 00000000..5e0c7a82
--- /dev/null
+++ b/extra/sqlite/sources
@@ -0,0 +1 @@
+https://sqlite.org/2019/sqlite-autoconf-3300100.tar.gz
diff --git a/extra/sqlite/version b/extra/sqlite/version
new file mode 100644
index 00000000..9fc15b14
--- /dev/null
+++ b/extra/sqlite/version
@@ -0,0 +1 @@
+3.30.1 1
diff --git a/extra/sudo/build b/extra/sudo/build
new file mode 100755
index 00000000..64dd511c
--- /dev/null
+++ b/extra/sudo/build
@@ -0,0 +1,20 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --disable-pam-session \
+ --disable-root-mailer \
+ --enable-pie \
+ --without-pam \
+ --without-sendmail \
+ --with-ignore-dot \
+ --with-insults=disabled \
+ --with-logfac=auth \
+ --with-passprompt="[sudo] password for %p: "
+
+make
+make \
+ DESTDIR="$1" \
+ install_uid="$(id -u)" \
+ install_gid="$(id -g)" \
+ install
diff --git a/extra/sudo/checksums b/extra/sudo/checksums
new file mode 100644
index 00000000..5613e8ec
--- /dev/null
+++ b/extra/sudo/checksums
@@ -0,0 +1 @@
+ce53ffac9604e23321334d8ba8ac59ded2bcf624fdb9dbde097ab2049bf29c7c sudo-1.8.29.tar.gz
diff --git a/extra/sudo/depends b/extra/sudo/depends
new file mode 100644
index 00000000..f22003e8
--- /dev/null
+++ b/extra/sudo/depends
@@ -0,0 +1 @@
+zlib
diff --git a/extra/sudo/sources b/extra/sudo/sources
new file mode 100644
index 00000000..3fa1c188
--- /dev/null
+++ b/extra/sudo/sources
@@ -0,0 +1 @@
+https://www.sudo.ws/dist/sudo-1.8.29.tar.gz
diff --git a/extra/sudo/version b/extra/sudo/version
new file mode 100644
index 00000000..fda497b7
--- /dev/null
+++ b/extra/sudo/version
@@ -0,0 +1 @@
+1.8.29 1
diff --git a/extra/tiff/build b/extra/tiff/build
new file mode 100755
index 00000000..eb4850d7
--- /dev/null
+++ b/extra/tiff/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --enable-cxx \
+ --without-x
+
+make
+make DESTDIR="$1" install
diff --git a/extra/tiff/checksums b/extra/tiff/checksums
new file mode 100644
index 00000000..a08eb7db
--- /dev/null
+++ b/extra/tiff/checksums
@@ -0,0 +1 @@
+5d29f32517dadb6dbcd1255ea5bbc93a2b54b94fbf83653b4d65c7d6775b8634 tiff-4.1.0.tar.gz
diff --git a/extra/tiff/depends b/extra/tiff/depends
new file mode 100644
index 00000000..59e71142
--- /dev/null
+++ b/extra/tiff/depends
@@ -0,0 +1,3 @@
+libjpeg-turbo
+xz
+zlib
diff --git a/extra/tiff/sources b/extra/tiff/sources
new file mode 100644
index 00000000..c031708b
--- /dev/null
+++ b/extra/tiff/sources
@@ -0,0 +1 @@
+https://download.osgeo.org/libtiff/tiff-4.1.0.tar.gz
diff --git a/extra/tiff/version b/extra/tiff/version
new file mode 100644
index 00000000..1bc2766f
--- /dev/null
+++ b/extra/tiff/version
@@ -0,0 +1 @@
+4.1.0 1
diff --git a/extra/tzdata/build b/extra/tzdata/build
new file mode 100755
index 00000000..369842d0
--- /dev/null
+++ b/extra/tzdata/build
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+
+pkg_dir=$1
+
+make CC="${CC:-gcc}"
+make DESTDIR="$1" install
+
+set -- africa asia australasia europe northamerica southamerica
+
+./zic -d "$pkg_dir/usr/share/zoneinfo" "$@"
+./zic -d "$pkg_dir/usr/share/zoneinfo/posix" "$@"
+./zic -d "$pkg_dir/usr/share/zoneinfo/right" -L leapseconds "$@"
+./zic -d "$pkg_dir/usr/share/zoneinfo" -p America/New_York
diff --git a/extra/tzdata/checksums b/extra/tzdata/checksums
new file mode 100644
index 00000000..dbdca45e
--- /dev/null
+++ b/extra/tzdata/checksums
@@ -0,0 +1 @@
+38b1f7c7a050daa14fb07f6b72cdde1fc895fece40758d4d55736847041ad9e2 2019c.tar.gz
diff --git a/extra/tzdata/sources b/extra/tzdata/sources
new file mode 100644
index 00000000..f809f894
--- /dev/null
+++ b/extra/tzdata/sources
@@ -0,0 +1 @@
+https://github.com/eggert/tz/archive/2019c.tar.gz
diff --git a/extra/tzdata/version b/extra/tzdata/version
new file mode 100644
index 00000000..6e4135ec
--- /dev/null
+++ b/extra/tzdata/version
@@ -0,0 +1 @@
+2019c 1
diff --git a/extra/vim/build b/extra/vim/build
new file mode 100755
index 00000000..f6149590
--- /dev/null
+++ b/extra/vim/build
@@ -0,0 +1,21 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr \
+ --enable-cscope \
+ --enable-multibyte \
+ --with-tlib=ncursesw \
+ --with-ex-name=vim-ex \
+ --with-view-name=vim-view \
+ --disable-perlinterp \
+ --disable-pythoninterp \
+ --disable-rubyinterp \
+ --disable-netbeans \
+ --disable-gpm \
+ --disable-hangulinput \
+ --disable-xim \
+ --disable-gui \
+ --without-x
+
+make
+make DESTDIR="$1" install
diff --git a/extra/vim/checksums b/extra/vim/checksums
new file mode 100644
index 00000000..9251fd31
--- /dev/null
+++ b/extra/vim/checksums
@@ -0,0 +1 @@
+a1c8078fe14b07dd874ac82d5776bfab1d325e8d792e7b9b1fd3475868285130 v8.1.2352.tar.gz
diff --git a/extra/vim/depends b/extra/vim/depends
new file mode 100644
index 00000000..6a470ffa
--- /dev/null
+++ b/extra/vim/depends
@@ -0,0 +1 @@
+ncurses
diff --git a/extra/vim/sources b/extra/vim/sources
new file mode 100644
index 00000000..6c1914e4
--- /dev/null
+++ b/extra/vim/sources
@@ -0,0 +1 @@
+https://github.com/vim/vim/archive/v8.1.2352.tar.gz
diff --git a/extra/vim/version b/extra/vim/version
new file mode 100644
index 00000000..1674897b
--- /dev/null
+++ b/extra/vim/version
@@ -0,0 +1 @@
+8.1.2352 1
diff --git a/extra/x264/build b/extra/x264/build
new file mode 100755
index 00000000..73cc54a0
--- /dev/null
+++ b/extra/x264/build
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+
+patch -p1 < x264-no-bash.patch
+
+./configure \
+ --prefix=/usr \
+ --disable-swscale \
+ --enable-static \
+ --enable-pic \
+ --enable-shared
+
+make
+make DESTDIR="$1" install
diff --git a/extra/x264/checksums b/extra/x264/checksums
new file mode 100644
index 00000000..2243eefc
--- /dev/null
+++ b/extra/x264/checksums
@@ -0,0 +1,2 @@
+404e7ba61123720a7b2cc45356ace6859860ef4ce3503758465e92c1ce11995e x264-snapshot-20190812-2245-stable.tar.bz2
+a78a518c3685813fdfdc8813acd48e292968892e6ff5ea60d91f5c514c35acee x264-no-bash.patch
diff --git a/extra/x264/depends b/extra/x264/depends
new file mode 100644
index 00000000..f56f4f37
--- /dev/null
+++ b/extra/x264/depends
@@ -0,0 +1,2 @@
+nasm make
+perl make
diff --git a/extra/x264/patches/x264-no-bash.patch b/extra/x264/patches/x264-no-bash.patch
new file mode 100644
index 00000000..07e8dd2b
--- /dev/null
+++ b/extra/x264/patches/x264-no-bash.patch
@@ -0,0 +1,222 @@
+diff --git a/configure b/configure-posix
+index 3cf63e0..1e1fce5 100755
+--- a/configure-posix
++++ b/configure
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+
+ if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
+ cat <<EOF
+@@ -59,7 +59,7 @@ exit 1
+ fi
+
+ log_check() {
+- echo -n "checking $1... " >> config.log
++ echo "checking $1... " >> config.log
+ }
+
+ log_ok() {
+@@ -78,13 +78,12 @@ cc_cflags() {
+ # several non gcc compilers issue an incredibly large number of warnings on high warning levels,
+ # suppress them by reducing the warning level rather than having to use #pragmas
+ for arg in $*; do
+- [[ "$arg" = -falign-loops* ]] && arg=
++ case $arg in
++ -falign-loops*|-mpreferred-stack-boundary*|-l*|-L*) arg=
++ esac
+ [ "$arg" = -fno-tree-vectorize ] && arg=
+ [ "$arg" = -Wshadow ] && arg=
+ [ "$arg" = -Wno-maybe-uninitialized ] && arg=
+- [[ "$arg" = -mpreferred-stack-boundary* ]] && arg=
+- [[ "$arg" = -l* ]] && arg=
+- [[ "$arg" = -L* ]] && arg=
+ if [ $compiler_style = MS ]; then
+ [ "$arg" = -ffast-math ] && arg="-fp:fast"
+ [ "$arg" = -Wall ] && arg=
+@@ -100,14 +99,14 @@ cc_cflags() {
+ fi
+ [ $compiler = CL -a "$arg" = -O3 ] && arg=-O2
+
+- [ -n "$arg" ] && echo -n "$arg "
++ [ -n "$arg" ] && printf %s "$arg "
+ done
+ }
+
+ cl_ldflags() {
+ for arg in $*; do
+- arg=${arg/LIBPATH/libpath}
+- [ "${arg#-libpath:}" == "$arg" -a "${arg#-l}" != "$arg" ] && arg=${arg#-l}.lib
++ arg=$(echo "$arg" | sed -e 's/LIBPATH/libpath/')
++ [ "${arg#-libpath:}" = "$arg" -a "${arg#-l}" != "$arg" ] && arg=${arg#-l}.lib
+ [ "${arg#-L}" != "$arg" ] && arg=-libpath:${arg#-L}
+ [ "$arg" = -Wl,--large-address-aware ] && arg=-largeaddressaware
+ [ "$arg" = -s ] && arg=
+@@ -116,14 +115,17 @@ cl_ldflags() {
+ [ "$arg" = -Werror ] && arg=
+ [ "$arg" = -Wshadow ] && arg=
+ [ "$arg" = -Wmaybe-uninitialized ] && arg=
+- [[ "$arg" = -Qdiag-error* ]] && arg=
+
+- arg=${arg/pthreadGC/pthreadVC}
++ case $arg in
++ -Qdiag-error*) arg=
++ esac
++
++ arg=$(echo "$arg" | sed -e 's/pthreadGC/pthreadVC/')
+ [ "$arg" = avifil32.lib ] && arg=vfw32.lib
+ [ "$arg" = gpac_static.lib ] && arg=libgpac_static.lib
+ [ "$arg" = x264.lib ] && arg=libx264.lib
+
+- [ -n "$arg" ] && echo -n "$arg "
++ [ -n "$arg" ] && printf %s "$arg "
+ done
+ }
+
+@@ -180,7 +182,7 @@ cpp_check() {
+ for arg in $1; do
+ echo "#include <$arg>" >> conftest.c
+ done
+- echo -e "#if !($3) \n#error $4 \n#endif " >> conftest.c
++ printf '%b\n' "#if !($3) \n#error $4 \n#endif " >> conftest.c
+ if [ $compiler_style = MS ]; then
+ cpp_cmd="$CC conftest.c $(cc_cflags $CFLAGS $2) -P"
+ else
+@@ -329,11 +331,15 @@ rm -rf conftest*
+
+ # Construct a path to the specified directory relative to the working directory
+ relative_path() {
+- local base="${PWD%/}"
+- local path="$(cd "$1" >/dev/null; printf '%s/.' "${PWD%/}")"
+- local up=''
++ base="${PWD%/}"
++ path="$(cd "$1" >/dev/null; printf '%s/.' "${PWD%/}")"
++ up=''
++
++ while :; do
++ case $path in
++ "$base/"*) break ;;
++ esac
+
+- while [[ $path != "$base/"* ]]; do
+ base="${base%/*}"
+ up="../$up"
+ done
+@@ -564,48 +570,6 @@ trap 'rm -rf conftest*' EXIT
+ # test for use of compilers that require specific handling
+ cc_base="$(basename "$CC")"
+ QPRE="-"
+-if [[ $host_os = mingw* || $host_os = cygwin* ]]; then
+- if [[ "$cc_base" = icl || "$cc_base" = icl[\ .]* ]]; then
+- # Windows Intel Compiler creates dependency generation with absolute Windows paths, Cygwin's make does not support Windows paths.
+- [[ $host_os = cygwin* ]] && die "Windows Intel Compiler support requires MSYS"
+- compiler=ICL
+- compiler_style=MS
+- CFLAGS="$CFLAGS -Qstd=c99 -nologo -Qms0 -DHAVE_STRING_H -I\$(SRCPATH)/extras"
+- QPRE="-Q"
+- cpp_check '' '' '_MSC_VER >= 1400' || die "Windows Intel Compiler support requires Visual Studio 2005 or newer"
+- if cpp_check '' '' 'defined(_M_AMD64) || defined(_M_X64)' ; then
+- host_cpu=x86_64
+- elif cpp_check '' '' 'defined(_M_IX86)' ; then
+- host_cpu=i486
+- fi
+- if cc_check '' -Qdiag-error:10006,10157 ; then
+- CHECK_CFLAGS="$CHECK_CFLAGS -Qdiag-error:10006,10157"
+- fi
+- elif [[ "$cc_base" = cl || "$cc_base" = cl[\ .]* ]]; then
+- # Standard Microsoft Visual Studio
+- compiler=CL
+- compiler_style=MS
+- CFLAGS="$CFLAGS -nologo -GS- -DHAVE_STRING_H -I\$(SRCPATH)/extras"
+- cpp_check '' '' '_MSC_VER > 1800 || (_MSC_VER == 1800 && _MSC_FULL_VER >= 180030324)' || die "Microsoft Visual Studio support requires Visual Studio 2013 Update 2 or newer"
+- if cpp_check '' '' 'defined(_M_AMD64) || defined(_M_X64)' ; then
+- host_cpu=x86_64
+- elif cpp_check '' '' 'defined(_M_IX86)' ; then
+- host_cpu=i486
+- elif cpp_check '' '' 'defined(_M_ARM64)' ; then
+- host_cpu=aarch64
+- elif cpp_check '' '' 'defined(_M_ARM)' ; then
+- host_cpu=arm
+- fi
+- else
+- # MinGW uses broken pre-VS2015 Microsoft printf functions unless it's told to use the POSIX ones.
+- CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112L"
+- fi
+-else
+- if [[ "$cc_base" = icc || "$cc_base" = icc[\ .]* ]]; then
+- AR="xiar"
+- compiler=ICC
+- fi
+-fi
+
+ if [ $compiler = GNU ]; then
+ if cc_check '' -Werror=unknown-warning-option ; then
+@@ -653,18 +617,6 @@ case $host_os in
+ define HAVE_MALLOC_H
+ libm="-lm"
+ ;;
+- cygwin*|mingw*|msys*)
+- EXE=".exe"
+- if [[ $host_os = cygwin* ]] && cpp_check "" "" "defined(__CYGWIN__)" ; then
+- SYS="CYGWIN"
+- define HAVE_MALLOC_H
+- else
+- SYS="WINDOWS"
+- DEVNULL="NUL"
+- cc_check '' -lshell32 && LDFLAGSCLI="$LDFLAGSCLI -lshell32"
+- [ $compiler = GNU ] && RC="${RC-${cross_prefix}windres}" || RC="${RC-rc.exe}"
+- fi
+- ;;
+ sunos*|solaris*)
+ SYS="SunOS"
+ define HAVE_MALLOC_H
+@@ -705,30 +657,6 @@ LDFLAGS="$LDFLAGS $libm"
+ stack_alignment=4
+ case $host_cpu in
+ i*86)
+- ARCH="X86"
+- AS="${AS-nasm}"
+- AS_EXT=".asm"
+- ASFLAGS="$ASFLAGS -DARCH_X86_64=0 -I\$(SRCPATH)/common/x86/"
+- if [ $compiler = GNU ]; then
+- if [[ "$asm" == auto && "$CFLAGS" != *-march* ]]; then
+- CFLAGS="$CFLAGS -march=i686"
+- fi
+- if [[ "$asm" == auto && "$CFLAGS" != *-mfpmath* ]]; then
+- CFLAGS="$CFLAGS -mfpmath=sse -msse -msse2"
+- fi
+- CFLAGS="-m32 $CFLAGS"
+- LDFLAGS="-m32 $LDFLAGS"
+- fi
+- if [ "$SYS" = MACOSX ]; then
+- ASFLAGS="$ASFLAGS -f macho32 -DPREFIX"
+- elif [ "$SYS" = WINDOWS -o "$SYS" = CYGWIN ]; then
+- ASFLAGS="$ASFLAGS -f win32 -DPREFIX"
+- LDFLAGS="$LDFLAGS -Wl,--large-address-aware"
+- [ $compiler = GNU ] && LDFLAGS="$LDFLAGS -Wl,--dynamicbase,--nxcompat,--tsaware"
+- [ $compiler = GNU ] && RCFLAGS="--target=pe-i386 $RCFLAGS"
+- else
+- ASFLAGS="$ASFLAGS -f elf32"
+- fi
+ ;;
+ x86_64)
+ ARCH="X86_64"
+@@ -931,7 +859,7 @@ fi
+
+ if [ $asm = auto -a $ARCH = ARM ] ; then
+ # set flags so neon is built by default
+- [ $compiler == CL ] || echo $CFLAGS | grep -Eq '(-mcpu|-march|-mfpu)' || CFLAGS="$CFLAGS -mcpu=cortex-a8 -mfpu=neon"
++ [ $compiler = CL ] || echo $CFLAGS | grep -Eq '(-mcpu|-march|-mfpu)' || CFLAGS="$CFLAGS -mcpu=cortex-a8 -mfpu=neon"
+
+ cc_check '' '' '__asm__("add r0, r1, r2");' && define HAVE_ARM_INLINE_ASM
+ if [ $compiler = CL ] && cpp_check '' '' 'defined(_M_ARM) && _M_ARM >= 7' ; then
+@@ -1576,7 +1504,8 @@ cat conftest.log >> config.log
+ cat conftest.log
+
+ [ "$SRCPATH" != "." ] && ln -sf ${SRCPATH}/Makefile ./Makefile
+-mkdir -p common/{aarch64,arm,mips,ppc,x86} encoder extras filters/video input output tools
++mkdir -p common/aarch64 common/arm common/mips common/ppc common/x86
++mkdir -p encoder extras filters/video input output tools
+
+ echo
+ echo "You can run 'make' or 'make fprofiled' now."
diff --git a/extra/x264/sources b/extra/x264/sources
new file mode 100644
index 00000000..ec3be5cb
--- /dev/null
+++ b/extra/x264/sources
@@ -0,0 +1,2 @@
+https://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20190812-2245-stable.tar.bz2
+patches/x264-no-bash.patch
diff --git a/extra/x264/version b/extra/x264/version
new file mode 100644
index 00000000..c416a334
--- /dev/null
+++ b/extra/x264/version
@@ -0,0 +1 @@
+20190812-2245 4
diff --git a/extra/x265/build b/extra/x265/build
new file mode 100755
index 00000000..2bc1c919
--- /dev/null
+++ b/extra/x265/build
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+export DESTDIR="$1"
+
+cmake source \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_BUILD_TYPE=Release
+
+cmake --build .
+cmake --install .
diff --git a/extra/x265/checksums b/extra/x265/checksums
new file mode 100644
index 00000000..2ee5aac0
--- /dev/null
+++ b/extra/x265/checksums
@@ -0,0 +1 @@
+fb9badcf92364fd3567f8b5aa0e5e952aeea7a39a2b864387cec31e3b58cbbcc x265_3.2.1.tar.gz
diff --git a/extra/x265/depends b/extra/x265/depends
new file mode 100644
index 00000000..8e82f959
--- /dev/null
+++ b/extra/x265/depends
@@ -0,0 +1,2 @@
+cmake make
+nasm make
diff --git a/extra/x265/sources b/extra/x265/sources
new file mode 100644
index 00000000..2e1eeee4
--- /dev/null
+++ b/extra/x265/sources
@@ -0,0 +1 @@
+https://bitbucket.org/multicoreware/x265/downloads/x265_3.2.1.tar.gz
diff --git a/extra/x265/version b/extra/x265/version
new file mode 100644
index 00000000..b7c90c2c
--- /dev/null
+++ b/extra/x265/version
@@ -0,0 +1 @@
+3.2.1 1
diff --git a/extra/xvidcore/build b/extra/xvidcore/build
new file mode 100755
index 00000000..ac4edecd
--- /dev/null
+++ b/extra/xvidcore/build
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+cd build/generic
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/xvidcore/checksums b/extra/xvidcore/checksums
new file mode 100644
index 00000000..2d965add
--- /dev/null
+++ b/extra/xvidcore/checksums
@@ -0,0 +1 @@
+7c20f279f9d8e89042e85465d2bcb1b3130ceb1ecec33d5448c4589d78f010b4 xvidcore-1.3.5.tar.bz2
diff --git a/extra/xvidcore/depends b/extra/xvidcore/depends
new file mode 100644
index 00000000..116f6b27
--- /dev/null
+++ b/extra/xvidcore/depends
@@ -0,0 +1 @@
+nasm make
diff --git a/extra/xvidcore/sources b/extra/xvidcore/sources
new file mode 100644
index 00000000..b6f08bba
--- /dev/null
+++ b/extra/xvidcore/sources
@@ -0,0 +1 @@
+https://downloads.xvid.com/downloads/xvidcore-1.3.5.tar.bz2
diff --git a/extra/xvidcore/version b/extra/xvidcore/version
new file mode 100644
index 00000000..a06f6a21
--- /dev/null
+++ b/extra/xvidcore/version
@@ -0,0 +1 @@
+1.3.5 1
diff --git a/extra/yasm/build b/extra/yasm/build
new file mode 100755
index 00000000..6daf22f8
--- /dev/null
+++ b/extra/yasm/build
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+
+./configure \
+ --prefix=/usr
+
+make
+make DESTDIR="$1" install
diff --git a/extra/yasm/checksums b/extra/yasm/checksums
new file mode 100644
index 00000000..ff95d85c
--- /dev/null
+++ b/extra/yasm/checksums
@@ -0,0 +1 @@
+3dce6601b495f5b3d45b59f7d2492a340ee7e84b5beca17e48f862502bd5603f yasm-1.3.0.tar.gz
diff --git a/extra/yasm/sources b/extra/yasm/sources
new file mode 100644
index 00000000..f1b23c34
--- /dev/null
+++ b/extra/yasm/sources
@@ -0,0 +1 @@
+https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
diff --git a/extra/yasm/version b/extra/yasm/version
new file mode 100644
index 00000000..0a2d7f2b
--- /dev/null
+++ b/extra/yasm/version
@@ -0,0 +1 @@
+1.3.0 1
diff --git a/extra/zip/build b/extra/zip/build
new file mode 100755
index 00000000..bb3316b4
--- /dev/null
+++ b/extra/zip/build
@@ -0,0 +1,12 @@
+#!/bin/sh -e
+
+make \
+ prefix=/usr \
+ CC="${CC:-gcc} $CFLAGS $CXXFLAGS" \
+ -f unix/Makefile generic
+
+make \
+ prefix="$1/usr" \
+ MANDIR="$1/usr/share/man/man1" \
+ -f unix/Makefile install
+
diff --git a/extra/zip/checksums b/extra/zip/checksums
new file mode 100644
index 00000000..3337c644
--- /dev/null
+++ b/extra/zip/checksums
@@ -0,0 +1 @@
+f0e8bb1f9b7eb0b01285495a2699df3a4b766784c1765a8f1aeedf63c0806369 zip30.tar.gz
diff --git a/extra/zip/depends b/extra/zip/depends
new file mode 100644
index 00000000..7a457127
--- /dev/null
+++ b/extra/zip/depends
@@ -0,0 +1 @@
+bzip2
diff --git a/extra/zip/sources b/extra/zip/sources
new file mode 100644
index 00000000..49a21688
--- /dev/null
+++ b/extra/zip/sources
@@ -0,0 +1 @@
+https://downloads.sourceforge.net/infozip/zip30.tar.gz
diff --git a/extra/zip/version b/extra/zip/version
new file mode 100644
index 00000000..f90f0a39
--- /dev/null
+++ b/extra/zip/version
@@ -0,0 +1 @@
+3.0 2