diff --git a/docs/install.md b/docs/install.md index c40785ac..ec6e7f63 100644 --- a/docs/install.md +++ b/docs/install.md @@ -60,7 +60,13 @@ Check the output of running `npm install --verbose sharp` for useful error messa ## Apple M1 -libvips must currently be installed via Homebrew before installing sharp. +If you are using ARM64 Node.js, which can be checked using: + +```sh +node -p "process.arch === 'arm64'" +``` + +then libvips must currently be installed via Homebrew before installing sharp. ```sh brew install vips diff --git a/install/libvips.js b/install/libvips.js index 8c0f4a6b..b6026e28 100644 --- a/install/libvips.js +++ b/install/libvips.js @@ -74,6 +74,9 @@ try { if (arch === 'ia32' && !platformAndArch.startsWith('win32')) { throw new Error(`Intel Architecture 32-bit systems require manual installation of libvips >= ${minimumLibvipsVersion}`); } + if (platformAndArch === 'darwin-arm64') { + throw new Error("Please run 'brew install vips' to install libvips on Apple M1 (ARM64) systems"); + } if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') { throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`); } diff --git a/lib/libvips.js b/lib/libvips.js index 87e9bc44..6316f96f 100644 --- a/lib/libvips.js +++ b/lib/libvips.js @@ -37,6 +37,15 @@ const cachePath = function () { return libvipsCachePath; }; +const isRosetta = function () { + /* 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; +}; + const globalLibvipsVersion = function () { if (process.platform !== 'win32') { const globalLibvipsVersion = spawnSync(`PKG_CONFIG_PATH="${pkgConfigPath()}" pkg-config --modversion vips-cpp`, spawnSyncOptions).stdout; @@ -82,7 +91,10 @@ const useGlobalLibvips = function () { if (Boolean(env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) { return false; } - + /* istanbul ignore next */ + if (isRosetta()) { + return false; + } const globalVipsVersion = globalLibvipsVersion(); return !!globalVipsVersion && /* istanbul ignore next */ semver.gte(globalVipsVersion, minimumLibvipsVersion);