Skip to content

Commit

Permalink
Prebuild WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Jan 22, 2018
1 parent 73edfb3 commit 4d0712b
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 145 deletions.
43 changes: 6 additions & 37 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
['OS == "win"', {
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
'type': 'shared_library',
'variables': {
'download_vips': '<!(node -e "require(\'./binding\').download_vips()")'
},
'defines': [
'VIPS_CPLUSPLUS_EXPORTS',
'_ALLOW_KEYWORD_MACROS'
Expand Down Expand Up @@ -49,37 +46,15 @@
'dependencies': [
'libvips-cpp'
],
# Nested variables "pattern" borrowed from http://src.chromium.org/viewvc/chrome/trunk/src/build/common.gypi
'variables': {
'variables': {
'variables': {
'conditions': [
['OS != "win"', {
# Build the PKG_CONFIG_PATH environment variable with all possible combinations
'pkg_config_path': '<!(which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR || true):$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig'
}, {
'pkg_config_path': ''
}]
],
},
'conditions': [
['OS != "win"', {
# Which version, if any, of libvips is available globally via pkg-config?
'global_vips_version': '<!(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --modversion vips-cpp 2>/dev/null || true)'
}, {
'global_vips_version': ''
}]
],
'pkg_config_path%': '<(pkg_config_path)'
},
'pkg_config_path%': '<(pkg_config_path)',
'runtime_link%': 'shared',
'conditions': [
['OS != "win"', {
# Does the globally available version of libvips, if any, meet the minimum version requirement?
'use_global_vips': '<!(GLOBAL_VIPS_VERSION="<(global_vips_version)" node -e "require(\'./binding\').use_global_vips()")'
'pkg_config_path': '<!(node -e "console.log(require(\'./lib/libvips\').pkgConfigPath())")',
'use_global_libvips': '<!(node -e "console.log(Boolean(require(\'./lib/libvips\').useGlobalLibvips()).toString())")'
}, {
'use_global_vips': ''
'pkg_config_path': '',
'use_global_libvips': ''
}]
]
},
Expand All @@ -96,7 +71,7 @@
'<!(node -e "require(\'nan\')")'
],
'conditions': [
['use_global_vips == "true"', {
['use_global_libvips == "true"', {
# Use pkg-config for include and lib
'include_dirs': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --cflags-only-I vips-cpp vips glib-2.0 | sed s\/-I//g)'],
'conditions': [
Expand All @@ -113,7 +88,7 @@
}]
]
}, {
# Attempt to download pre-built libvips and install locally within node_modules
# Use pre-built libvips stored locally within node_modules
'include_dirs': [
'vendor/include',
'vendor/include/glib-2.0',
Expand All @@ -131,9 +106,6 @@
]
}],
['OS == "mac"', {
'variables': {
'download_vips': '<!(node -e "require(\'./binding\').download_vips()")'
},
'libraries': [
'../vendor/lib/libvips-cpp.42.dylib',
'../vendor/lib/libvips.42.dylib',
Expand All @@ -144,9 +116,6 @@
]
}],
['OS == "linux"', {
'variables': {
'download_vips': '<!(node -e "require(\'./binding\').download_vips()")'
},
'defines': [
'_GLIBCXX_USE_CXX11_ABI=0'
],
Expand Down
108 changes: 0 additions & 108 deletions binding.js

This file was deleted.

59 changes: 59 additions & 0 deletions lib/libvips.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

const path = require('path');
const spawnSync = require('child_process').spawnSync;
const semver = require('semver');
const platform = require('./platform');

const minimumLibvipsVersion = process.env.npm_package_config_libvips || require('../package.json').config.libvips;

const spawnSyncOptions = {
encoding: 'utf8',
shell: true
};

const globalLibvipsVersion = function () {
if (process.platform !== 'win32') {
const globalLibvipsVersion = spawnSync(`PKG_CONFIG_PATH="${pkgConfigPath()}" pkg-config --modversion vips-cpp`, spawnSyncOptions).stdout || '';
return globalLibvipsVersion.trim();
} else {
return '';
}
};

const hasVendoredLibvips = function () {
const currentPlatformId = platform();
try {
const vendorPlatformId = require(path.join(__dirname, '..', 'vendor', 'platform.json'));
if (currentPlatformId === vendorPlatformId) {
return true;
} else {
throw new Error(`'${vendorPlatformId}' binaries cannot be used on the '${currentPlatformId}' platform. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.`);
}
} catch (err) {}
return false;
};

const pkgConfigPath = function () {
if (process.platform !== 'win32') {
const brewPkgConfigPath = spawnSync('which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR', spawnSyncOptions).stdout || '';
return [brewPkgConfigPath.trim(), process.env.PKG_CONFIG_PATH, '/usr/local/lib/pkgconfig', '/usr/lib/pkgconfig']
.filter(function (p) { return !!p; })
.join(':');
} else {
return '';
}
};

const useGlobalLibvips = function () {
const globalVipsVersion = globalLibvipsVersion();
return !!globalVipsVersion && semver.gte(globalVipsVersion, minimumLibvipsVersion);
};

module.exports = {
minimumLibvipsVersion: minimumLibvipsVersion,
globalLibvipsVersion: globalLibvipsVersion,
hasVendoredLibvips: hasVendoredLibvips,
pkgConfigPath: pkgConfigPath,
useGlobalLibvips: useGlobalLibvips
};
76 changes: 76 additions & 0 deletions libvips-install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use strict';

const fs = require('fs');
const os = require('os');
const path = require('path');

const detectLibc = require('detect-libc');
const npmLog = require('npmlog');
const semver = require('semver');
const simpleGet = require('simple-get');
const tar = require('tar');

const agent = require('./lib/agent');
const libvips = require('./lib/libvips');
const platform = require('./lib/platform');

const minimumLibvipsVersion = libvips.minimumLibvipsVersion;
const distBaseUrl = process.env.SHARP_DIST_BASE_URL || `https://github.com/lovell/sharp-libvips/releases/download/v${minimumLibvipsVersion}/`;

try {
const globalLibvipsVersion = libvips.globalLibvipsVersion();
if (globalLibvipsVersion) {
npmLog.info('sharp', `Using globally-installed libvips v${globalLibvipsVersion}`);
} else if (libvips.hasVendoredLibvips()) {
npmLog.info('sharp', `Using existing vendored libvips v${minimumLibvipsVersion}`);
} else {
// Is this arch/platform supported?
const arch = process.env.npm_config_arch || process.arch;
if (arch === 'ia32') {
throw new Error(`Intel Architecture 32-bit systems require manual installation of libvips >= ${minimumLibvipsVersion}\n`);
}
if (detectLibc.isNonGlibcLinux) {
throw new Error(`Use with ${detectLibc.family} libc requires manual installation of libvips >= ${minimumLibvipsVersion}`);
}
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.13.0')) {
throw new Error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
}
// Download to per-process temporary file
const tarFilename = ['libvips', minimumLibvipsVersion, platform()].join('-') + '.tar.gz';
const tarPathTemp = path.join(os.tmpdir(), `${process.pid}-${tarFilename}`);
const tmpFile = fs.createWriteStream(tarPathTemp);
const url = distBaseUrl + tarFilename;
npmLog.info('sharp', `Downloading ${url}`);
simpleGet({ url: url, agent: agent() }, function (err, response) {
if (err) {
throw err;
}
if (response.statusCode !== 200) {
throw new Error(`Status ${response.statusCode}`);
}
response.pipe(tmpFile);
});
tmpFile.on('close', function () {
const vendorPath = path.join(__dirname, 'vendor');
fs.mkdirSync(vendorPath);
tar
.extract({
file: tarPathTemp,
cwd: vendorPath,
strict: true
})
.then(function () {
try {
fs.unlinkSync(tarPathTemp);
} catch (err) {}
})
.catch(function (err) {
throw err;
});
});
}
} catch (err) {
npmLog.error('sharp', err.message);
npmLog.error('sharp', 'Please see http://sharp.pixelplumbing.com/page/install');
process.exit(1);
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"Oleh Aleinyk <oleg.aleynik@gmail.com>"
],
"scripts": {
"install": "node libvips-install && node-gyp rebuild",
"clean": "rm -rf node_modules/ build/ vendor/ coverage/ test/fixtures/output.*",
"test": "semistandard && cc && nyc --reporter=lcov --branches=99 mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
"coverage": "./test/coverage/report.sh",
Expand Down Expand Up @@ -76,6 +77,7 @@
"color": "^2.0.1",
"detect-libc": "^1.0.3",
"nan": "^2.8.0",
"npmlog": "^4.1.2",
"semver": "^5.4.1",
"simple-get": "^2.7.0",
"tar": "^4.2.0",
Expand Down
Loading

0 comments on commit 4d0712b

Please sign in to comment.