mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
If you want to build sharp from source against a globally-installed libvips then you will now need to add both node-addon-api and node-gyp to the dependencies section of your package.json file. The binding.gyp file is "hidden" inside the src directory to prevent various build and package manager tooling from assuming that everyone is going to build from source every time.
154 lines
4.2 KiB
JavaScript
154 lines
4.2 KiB
JavaScript
// Copyright 2013 Lovell Fuller and others.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
'use strict';
|
|
|
|
const { spawnSync } = require('node:child_process');
|
|
const semverCoerce = require('semver/functions/coerce');
|
|
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
|
const detectLibc = require('detect-libc');
|
|
|
|
const { engines } = require('../package.json');
|
|
|
|
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */
|
|
engines.libvips;
|
|
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
|
|
|
const prebuiltPlatforms = [
|
|
'darwin-arm64', 'darwin-x64',
|
|
'linux-arm', 'linux-arm64', 'linux-x64',
|
|
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
'win32-ia32', 'win32-x64'
|
|
];
|
|
|
|
const spawnSyncOptions = {
|
|
encoding: 'utf8',
|
|
shell: true
|
|
};
|
|
|
|
const log = (item) => {
|
|
if (item instanceof Error) {
|
|
console.error(`sharp: Installation error: ${item.message}`);
|
|
} else {
|
|
console.log(`sharp: ${item}`);
|
|
}
|
|
};
|
|
|
|
/* istanbul ignore next */
|
|
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
|
|
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
|
|
/* istanbul ignore next */
|
|
const buildPlatformArch = () => {
|
|
/* eslint camelcase: ["error", { allow: ["^npm_config_"] }] */
|
|
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
|
return `${npm_config_platform || process.platform}${npm_config_libc || runtimeLibc()}-${npm_config_arch || process.arch}`;
|
|
};
|
|
|
|
const buildSharpLibvipsIncludeDir = () => {
|
|
try {
|
|
return require('@sharpen/sharp-libvips-dev/include');
|
|
} catch {}
|
|
/* istanbul ignore next */
|
|
return '';
|
|
};
|
|
|
|
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
try {
|
|
return require('@sharpen/sharp-libvips-dev/cplusplus');
|
|
} catch {}
|
|
/* istanbul ignore next */
|
|
return '';
|
|
};
|
|
|
|
const buildSharpLibvipsLibDir = () => {
|
|
try {
|
|
return require(`@sharpen/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
} catch {}
|
|
/* istanbul ignore next */
|
|
return '';
|
|
};
|
|
|
|
const isRosetta = () => {
|
|
/* istanbul ignore next */
|
|
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
|
return (translated || '').trim() === 'sysctl.proc_translated: 1';
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/* istanbul ignore next */
|
|
const spawnRebuild = () =>
|
|
spawnSync('node-gyp rebuild --directory=src', {
|
|
...spawnSyncOptions,
|
|
stdio: 'inherit'
|
|
}).status;
|
|
|
|
const globalLibvipsVersion = () => {
|
|
if (process.platform !== 'win32') {
|
|
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
|
...spawnSyncOptions,
|
|
env: {
|
|
...process.env,
|
|
PKG_CONFIG_PATH: pkgConfigPath()
|
|
}
|
|
}).stdout;
|
|
/* istanbul ignore next */
|
|
return (globalLibvipsVersion || '').trim();
|
|
} else {
|
|
return '';
|
|
}
|
|
};
|
|
|
|
/* istanbul ignore next */
|
|
const pkgConfigPath = () => {
|
|
if (process.platform !== 'win32') {
|
|
const brewPkgConfigPath = spawnSync(
|
|
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
|
spawnSyncOptions
|
|
).stdout || '';
|
|
return [
|
|
brewPkgConfigPath.trim(),
|
|
process.env.PKG_CONFIG_PATH,
|
|
'/usr/local/lib/pkgconfig',
|
|
'/usr/lib/pkgconfig',
|
|
'/usr/local/libdata/pkgconfig',
|
|
'/usr/libdata/pkgconfig'
|
|
].filter(Boolean).join(':');
|
|
} else {
|
|
return '';
|
|
}
|
|
};
|
|
|
|
const useGlobalLibvips = () => {
|
|
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
|
log('Detected SHARP_IGNORE_GLOBAL_LIBVIPS, skipping search for globally-installed libvips');
|
|
return false;
|
|
}
|
|
/* istanbul ignore next */
|
|
if (isRosetta()) {
|
|
log('Detected Rosetta, skipping search for globally-installed libvips');
|
|
return false;
|
|
}
|
|
const globalVipsVersion = globalLibvipsVersion();
|
|
return !!globalVipsVersion && /* istanbul ignore next */
|
|
semverGreaterThanOrEqualTo(globalVipsVersion, minimumLibvipsVersion);
|
|
};
|
|
|
|
module.exports = {
|
|
minimumLibvipsVersion,
|
|
prebuiltPlatforms,
|
|
buildPlatformArch,
|
|
buildSharpLibvipsIncludeDir,
|
|
buildSharpLibvipsCPlusPlusDir,
|
|
buildSharpLibvipsLibDir,
|
|
runtimePlatformArch,
|
|
log,
|
|
spawnRebuild,
|
|
globalLibvipsVersion,
|
|
pkgConfigPath,
|
|
useGlobalLibvips
|
|
};
|