Add support for pre-compiled libvips on ARM CPUs

Uses a HypriotOS-managed docker container for this
This commit is contained in:
Lovell Fuller 2016-01-06 15:50:36 +00:00
parent 3c7cbf8685
commit a0e034a9e9
9 changed files with 219 additions and 11 deletions

View File

@ -13,7 +13,7 @@ Bicubic interpolation with Lanczos anti-alias filtering ensures quality is not s
As well as image resizing, operations such as As well as image resizing, operations such as
rotation, extraction, compositing and gamma correction are available. rotation, extraction, compositing and gamma correction are available.
64-bit Windows and recent Linux systems do not require Most Windows (x64), Linux and ARMv6+ systems do not require
the installation of any external runtime dependencies. the installation of any external runtime dependencies.
Use with OS X is as simple as running `brew install homebrew/science/vips` Use with OS X is as simple as running `brew install homebrew/science/vips`
@ -36,7 +36,7 @@ covers reporting bugs, requesting features and submitting code changes.
### Licence ### Licence
Copyright 2013, 2014, 2015 Lovell Fuller and contributors. Copyright 2013, 2014, 2015, 2016 Lovell Fuller and contributors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -54,9 +54,9 @@ var error = function(msg) {
module.exports.download_vips = function() { module.exports.download_vips = function() {
// Has vips been installed locally? // Has vips been installed locally?
if (!isFile(vipsHeaderPath)) { if (!isFile(vipsHeaderPath)) {
// Ensure 64-bit // Ensure Intel 64-bit or ARM
if (process.arch !== 'x64') { if (process.arch === 'ia32') {
error('ARM and 32-bit systems require manual installation - please see http://sharp.dimens.io/en/stable/install/'); error('Intel Architecture 32-bit systems require manual installation - please see http://sharp.dimens.io/en/stable/install/');
} }
// Ensure libc >= 2.15 // Ensure libc >= 2.15
var lddVersion = process.env.LDD_VERSION; var lddVersion = process.env.LDD_VERSION;
@ -66,8 +66,9 @@ module.exports.download_vips = function() {
error('libc version ' + libcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/'); error('libc version ' + libcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
} }
} }
// Platform-specific .tar.gz // Arch/platform-specific .tar.gz
var tarFilename = ['libvips', process.env.npm_package_config_libvips, process.platform.substr(0, 3)].join('-') + '.tar.gz'; var platform = (process.arch === 'arm') ? 'arm' : process.platform.substr(0, 3);
var tarFilename = ['libvips', process.env.npm_package_config_libvips, platform].join('-') + '.tar.gz';
var tarPath = path.join(__dirname, 'packaging', tarFilename); var tarPath = path.join(__dirname, 'packaging', tarFilename);
if (isFile(tarPath)) { if (isFile(tarPath)) {
unpack(tarPath); unpack(tarPath);

View File

@ -635,7 +635,7 @@ var counters = sharp.counters(); // { queue: 2, process: 4 }
_Requires libvips to have been compiled with liborc support_ _Requires libvips to have been compiled with liborc support_
Improves the performance of `resize`, `blur` and `sharpen` operations Improves the performance of `resize`, `blur` and `sharpen` operations
by taking advantage of the SIMD vector unit of the CPU. by taking advantage of the SIMD vector unit of the CPU, e.g. Intel SSE and ARM NEON.
* `enable`, if present, is a boolean where `true` enables and `false` disables the use of SIMD. * `enable`, if present, is a boolean where `true` enables and `false` disables the use of SIMD.
@ -650,7 +650,7 @@ have been known to crash under heavy load.
```javascript ```javascript
var simd = sharp.simd(); var simd = sharp.simd();
// simd is `true` is SIMD is currently enabled // simd is `true` if SIMD is currently enabled
``` ```
```javascript ```javascript

View File

@ -4,6 +4,10 @@
#### v0.12.2 - TBD #### v0.12.2 - TBD
* Upgrade libvips to v8.2.0 for improved vips_shrink.
* Add pre-compiled libvips for ARMv6+ CPUs.
* Ensure 16-bit input images work with embed option. * Ensure 16-bit input images work with embed option.
[#325](https://github.com/lovell/sharp/issues/325) [#325](https://github.com/lovell/sharp/issues/325)
[@janaz](https://github.com/janaz) [@janaz](https://github.com/janaz)

View File

@ -17,7 +17,7 @@ npm install sharp
libvips and its dependencies are fetched and stored within `node_modules/sharp` during `npm install`. libvips and its dependencies are fetched and stored within `node_modules/sharp` during `npm install`.
This involves an automated HTTPS download of approximately 6MB. This involves an automated HTTPS download of approximately 6MB.
Most recent 64-bit Linux-based operating systems should "just work", e.g.: Most recent Linux-based operating systems running on x64 and ARMv6+ CPUs should "just work", e.g.:
* Debian 7, 8 * Debian 7, 8
* Ubuntu 12.04, 14.04, 14.10, 15.04, 15.10 * Ubuntu 12.04, 14.04, 14.10, 15.04, 15.10
@ -25,12 +25,13 @@ Most recent 64-bit Linux-based operating systems should "just work", e.g.:
* Fedora 21, 22, 23 * Fedora 21, 22, 23
* openSUSE 13.2 * openSUSE 13.2
* Archlinux 2015.06.01 * Archlinux 2015.06.01
* Raspbian Jessie
Preference will be given to an existing globally-installed (via `pkg-config`) Preference will be given to an existing globally-installed (via `pkg-config`)
version of libvips that meets the minimum version requirement. version of libvips that meets the minimum version requirement.
This allows the use of newer versions of libvips with older versions of sharp. This allows the use of newer versions of libvips with older versions of sharp.
For older and 32-bit Linux-based operating systems, For older Linux-based operating systems and 32-bit Intel CPUs,
a system-wide installation of the most suitable version of a system-wide installation of the most suitable version of
libvips and its dependencies can be achieved by running libvips and its dependencies can be achieved by running
the following command as a user with `sudo` access the following command as a user with `sudo` access

34
packaging/arm-build.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
if [ $# -lt 1 ]; then
echo "Usage: $0 IP"
echo "Build libvips for ARM using Docker, where IP is"
echo "the address of a Raspberry Pi running HypriotOS"
exit 1
fi
IP="$1"
echo "Verifying connectivity to $IP"
if ! ping -c 1 $IP; then
echo "Could not connect to $IP"
exit 1
fi
if ! type sshpass >/dev/null; then
echo "Please install sshpass"
exit 1
fi
export SSHPASS=hypriot
echo "Copying arm/Dockerfile and arm/build.sh to device"
sshpass -e scp -o PreferredAuthentications=password -r arm root@${IP}:/root
echo "Building Raspbian-based container"
sshpass -e ssh -o PreferredAuthentications=password -t root@${IP} "docker build -t vips-dev-arm arm"
echo "Running arm/build.sh within container"
sshpass -e ssh -o PreferredAuthentications=password -t root@${IP} "docker run -i -t --rm -v \${PWD}/arm:/arm vips-dev-arm sh -c 'cd /arm && ./build.sh' | tee arm/build.log"
echo "Copying resultant tar.gz file from device"
sshpass -e scp -o PreferredAuthentications=password root@${IP}:/root/arm/*.tar.gz .

28
packaging/arm-test.sh Executable file
View File

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

5
packaging/arm/Dockerfile Normal file
View File

@ -0,0 +1,5 @@
FROM resin/rpi-raspbian:jessie
MAINTAINER Lovell Fuller <npm@lovell.info>
# Build dependencies
RUN apt-get update && apt-get install -y build-essential autoconf libtool nasm gtk-doc-tools texinfo curl

135
packaging/arm/build.sh Executable file
View File

@ -0,0 +1,135 @@
#!/bin/sh
# To be run inside a Raspbian container
# Working directories
DEPS=/deps
TARGET=/target
mkdir ${DEPS}
mkdir ${TARGET}
# Common build paths and flags
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${TARGET}/lib/pkgconfig"
export PATH="${PATH}:${TARGET}/bin"
export CPPFLAGS="-I${TARGET}/include"
export LDFLAGS="-L${TARGET}/lib"
# Dependency version numbers
VERSION_ZLIB=1.2.8
VERSION_FFI=3.2.1
VERSION_GLIB=2.46.2
VERSION_XML2=2.9.3
VERSION_GSF=1.14.34
VERSION_EXIF=0.6.21
VERSION_JPEG=1.4.2
VERSION_PNG16=1.6.20
VERSION_LCMS2=2.7
VERSION_WEBP=0.5.0
VERSION_TIFF=4.0.6
VERSION_MAGICK=6.9.2-10
VERSION_ORC=0.4.24
VERSION_VIPS=8.2.0
mkdir ${DEPS}/zlib
curl -Ls http://zlib.net/zlib-${VERSION_ZLIB}.tar.xz | tar xJC ${DEPS}/zlib --strip-components=1
cd ${DEPS}/zlib
./configure --prefix=${TARGET} && make install
rm ${TARGET}/lib/libz.a
mkdir ${DEPS}/ffi
curl -Ls ftp://sourceware.org/pub/libffi/libffi-${VERSION_FFI}.tar.gz | tar xzC ${DEPS}/ffi --strip-components=1
cd ${DEPS}/ffi
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-builddir && make install-strip
mkdir ${DEPS}/glib
curl -Ls http://ftp.gnome.org/pub/gnome/sources/glib/2.46/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1
cd ${DEPS}/glib
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/xml2
curl -Ls http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1
cd ${DEPS}/xml2
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-python --with-zlib=${TARGET} && make install-strip
mkdir ${DEPS}/gsf
curl -Ls http://ftp.gnome.org/pub/GNOME/sources/libgsf/1.14/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1
cd ${DEPS}/gsf
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/exif
curl -Ls http://heanet.dl.sourceforge.net/project/libexif/libexif/${VERSION_EXIF}/libexif-${VERSION_EXIF}.tar.bz2 | tar xjC ${DEPS}/exif --strip-components=1
cd ${DEPS}/exif
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/jpeg
curl -Ls http://heanet.dl.sourceforge.net/project/libjpeg-turbo/${VERSION_JPEG}/libjpeg-turbo-${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1
cd ${DEPS}/jpeg
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-jpeg8 --without-turbojpeg && make install-strip
mkdir ${DEPS}/png16
curl -Ls http://heanet.dl.sourceforge.net/project/libpng/libpng16/${VERSION_PNG16}/libpng-${VERSION_PNG16}.tar.xz | tar xJC ${DEPS}/png16 --strip-components=1
cd ${DEPS}/png16
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/lcms2
curl -Ls http://heanet.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1
cd ${DEPS}/lcms2
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/webp
curl -Ls http://downloads.webmproject.org/releases/webp/libwebp-${VERSION_WEBP}.tar.gz | tar xzC ${DEPS}/webp --strip-components=1
cd ${DEPS}/webp
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/tiff
curl -Ls http://download.osgeo.org/libtiff/tiff-${VERSION_TIFF}.tar.gz /deps/tiff.tar.gz | tar xzC ${DEPS}/tiff --strip-components=1
cd ${DEPS}/tiff
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
rm ${TARGET}/lib/libtiffxx*
mkdir ${DEPS}/magick
curl -Ls http://www.imagemagick.org/download/releases/ImageMagick-${VERSION_MAGICK}.tar.xz | tar xJC ${DEPS}/magick --strip-components=1
cd ${DEPS}/magick
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-magick-plus-plus && make install-strip
mkdir ${DEPS}/orc
curl -Ls http://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1
cd ${DEPS}/orc
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/vips
curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.2/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1
cd ${DEPS}/vips
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \
--disable-debug --disable-introspection --without-python --without-fftw \
--with-zip-includes=${TARGET}/include --with-zip-libraries=${TARGET}/lib \
--with-jpeg-includes=${TARGET}/include --with-jpeg-libraries=${TARGET}/lib \
&& make install-strip
# Remove the C++ bindings
cd ${TARGET}/include
rm -rf vips/vipsc++.h vips/vipscpp.h vips/V*.h
cd ${TARGET}/lib
rm -rf pkgconfig .libs *.la libvipsCC* libvips-cpp.*
# Create JSON file of version numbers
cd ${TARGET}
echo "{\n\
\"zlib\": \"${VERSION_ZLIB}\",\n\
\"ffi\": \"${VERSION_FFI}\",\n\
\"glib\": \"${VERSION_GLIB}\",\n\
\"xml\": \"${VERSION_XML2}\",\n\
\"gsf\": \"${VERSION_GSF}\",\n\
\"exif\": \"${VERSION_EXIF}\",\n\
\"jpeg\": \"${VERSION_JPEG}\",\n\
\"png\": \"${VERSION_PNG16}\",\n\
\"lcms\": \"${VERSION_LCMS2}\",\n\
\"webp\": \"${VERSION_WEBP}\",\n\
\"tiff\": \"${VERSION_TIFF}\",\n\
\"magick\": \"${VERSION_MAGICK}\",\n\
\"orc\": \"${VERSION_ORC}\",\n\
\"vips\": \"${VERSION_VIPS}\"\n\
}" >lib/versions.json
# Create .tar.gz
GZIP=-9 tar czf /arm/libvips-${VERSION_VIPS}-arm.tar.gz include lib