Separate build script from install script #4458

The --build-from-source flag is now deprecated and will soon
be removed along with the need to define an install script.

This will remove a whole category of package manager
warnings about install scripts and "built" dependencies.

Most people don't need to build sharp from source, but for
those that do, a suitable method is now something like:

$ npm install package-that-depends-on-sharp
$ npm explore sharp -- npm run build
This commit is contained in:
Lovell Fuller 2025-10-07 14:32:44 +01:00
parent 2324d75f7f
commit 1bbee519aa
10 changed files with 65 additions and 46 deletions

View File

@ -1,5 +1,5 @@
freebsd_instance:
image_family: freebsd-15-0-snap
image_family: freebsd-15-0
task:
name: FreeBSD
@ -9,9 +9,10 @@ task:
prerequisites_script:
- pkg update -f
- pkg upgrade -y
- pkg install -y devel/git devel/pkgconf graphics/vips www/node20 www/npm
- pkg install -y devel/git devel/pkgconf graphics/vips www/node22 www/npm
- pkg-config --modversion vips-cpp
install_script:
- npm install --build-from-source
- npm install
- npm run build
test_script:
- node --test test/unit/io.js

View File

@ -25,7 +25,7 @@ Please select the `main` branch as the destination for your Pull Request so your
Please squash your changes into a single commit using a command like `git rebase -i upstream/main`.
To test C++ changes, you can compile the module using `npm install --build-from-source` and then run the tests using `npm test`.
To test C++ changes, you can compile the module using `npm run build` and then run the tests using `npm test`.
## Submit a Pull Request with a new feature

View File

@ -169,7 +169,8 @@ jobs:
node-version: ${{ matrix.nodejs_version }}
architecture: ${{ matrix.nodejs_arch }}
- uses: actions/checkout@v4
- run: npm install --build-from-source
- run: npm install
- run: npm run build
- run: npm run test-unit
- if: matrix.package
run: npm run package-from-local-build
@ -211,7 +212,8 @@ jobs:
- name: Dependencies
run: apk add build-base git python3 font-noto --update-cache
- uses: actions/checkout@v4
- run: npm install --build-from-source
- run: npm install
- run: npm run build
- run: npm run test-unit
- if: matrix.package
run: npm run package-from-local-build
@ -265,7 +267,8 @@ jobs:
mkdir /opt/nodejs
curl --silent https://${{ matrix.nodejs_hostname }}/download/release/v${{ matrix.nodejs_version}}/node-v${{ matrix.nodejs_version}}-linux-${{ matrix.nodejs_arch }}.tar.xz | tar xJC /opt/nodejs --strip-components=1
export PATH=$PATH:/opt/nodejs/bin
npm install --build-from-source
npm install
npm run build
node --test test/unit/io.js
npm run package-from-local-build
- uses: actions/upload-artifact@v4
@ -289,7 +292,8 @@ jobs:
uses: actions/setup-node@v5
with:
node-version: "20"
- run: emmake npm install --build-from-source
- run: npm install
- run: emmake npm run build
- name: Verify emscripten versions match
run: |
EMSCRIPTEN_VERSION_LIBVIPS=$(node -p "require('@img/sharp-libvips-dev-wasm32/versions').emscripten")

View File

@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"$schema": "https://biomejs.dev/schemas/2.2.5/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",

View File

@ -3,6 +3,9 @@ title: v0.34.5 - TBD
slug: changelog/v0.34.5
---
* Support building from source with npm v12+, deprecate `--build-from-source` flag.
[#4458](https://github.com/lovell/sharp/issues/4458)
* Add support for BigTIFF output.
[#4459](https://github.com/lovell/sharp/pull/4459)
[@throwbi](https://github.com/throwbi)

View File

@ -111,10 +111,11 @@ and on macOS when running Node.js under Rosetta.
## Building from source
This module will be compiled from source at `npm install` time when:
This module will be compiled from source when:
* a globally-installed libvips is detected, or
* when the `npm install --build-from-source` flag is used.
* using `npm explore sharp -- npm run build`, or
* using the deprecated `npm run --build-from-source` at `npm install` time.
The logic to detect a globally-installed libvips can be skipped by setting the
`SHARP_IGNORE_GLOBAL_LIBVIPS` (never try to use it) or

36
install/build.js Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
const {
useGlobalLibvips,
globalLibvipsVersion,
log,
spawnRebuild,
} = require('../lib/libvips');
log('Attempting to build from source via node-gyp');
log('See https://sharp.pixelplumbing.com/install#building-from-source');
try {
const addonApi = require('node-addon-api');
log(`Found node-addon-api ${addonApi.version || ''}`);
} catch (_err) {
log('Please add node-addon-api to your dependencies');
process.exit(1);
}
try {
const gyp = require('node-gyp');
log(`Found node-gyp ${gyp().version}`);
} catch (_err) {
log('Please add node-gyp to your dependencies');
process.exit(1);
}
if (useGlobalLibvips(log)) {
log(`Detected globally-installed libvips v${globalLibvipsVersion()}`);
}
const status = spawnRebuild();
if (status !== 0) {
process.exit(status);
}

View File

@ -2,36 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
try {
const { useGlobalLibvips, globalLibvipsVersion, log, spawnRebuild } = require('../lib/libvips');
const buildFromSource = (msg) => {
log(msg);
log('Attempting to build from source via node-gyp');
try {
const addonApi = require('node-addon-api');
log(`Found node-addon-api ${addonApi.version || ''}`);
} catch (_err) {
log('Please add node-addon-api to your dependencies');
return;
}
try {
const gyp = require('node-gyp');
log(`Found node-gyp ${gyp().version}`);
} catch (_err) {
log('Please add node-gyp to your dependencies');
return;
}
log('See https://sharp.pixelplumbing.com/install#building-from-source');
const status = spawnRebuild();
if (status !== 0) {
process.exit(status);
}
};
if (useGlobalLibvips(log)) {
buildFromSource(`Detected globally-installed libvips v${globalLibvipsVersion()}`);
} else if (process.env.npm_config_build_from_source) {
buildFromSource('Detected --build-from-source flag');
const { useGlobalLibvips } = require('../lib/libvips');
if (useGlobalLibvips() || process.env.npm_config_build_from_source) {
process.exit(1);
}
} catch (err) {
const summary = err.message.split(/\n/).slice(0, 1);

View File

@ -92,7 +92,8 @@
"Don Denton <don@happycollision.com>"
],
"scripts": {
"install": "node install/check.js",
"build": "node install/build.js",
"install": "node install/check.js || npm run build",
"clean": "rm -rf src/build/ .nyc_output/ coverage/ test/fixtures/output.*",
"test": "npm run lint && npm run test-unit",
"lint": "npm run lint-cpp && npm run lint-js && npm run lint-types",
@ -139,7 +140,7 @@
],
"dependencies": {
"@img/colour": "^1.0.0",
"detect-libc": "^2.1.0",
"detect-libc": "^2.1.1",
"semver": "^7.7.2"
},
"optionalDependencies": {
@ -167,7 +168,7 @@
"@img/sharp-win32-x64": "0.34.4"
},
"devDependencies": {
"@biomejs/biome": "^2.2.4",
"@biomejs/biome": "^2.2.5",
"@cpplint/cli": "^0.1.0",
"@emnapi/runtime": "^1.5.0",
"@img/sharp-libvips-dev": "1.2.3",
@ -180,7 +181,7 @@
"exif-reader": "^2.0.2",
"extract-zip": "^2.0.1",
"icc": "^3.0.0",
"jsdoc-to-markdown": "^9.1.2",
"jsdoc-to-markdown": "^9.1.3",
"node-addon-api": "^8.5.0",
"node-gyp": "^11.4.2",
"tar-fs": "^3.1.1",

View File

@ -15,7 +15,7 @@ RUN apt-get install -y imagemagick libmagick++-dev graphicsmagick
# Install sharp
RUN mkdir /tmp/sharp
RUN cd /tmp && git clone --single-branch --branch $BRANCH https://github.com/lovell/sharp.git
RUN cd /tmp/sharp && npm install --build-from-source
RUN cd /tmp/sharp && npm install && npm run build
# Install benchmark test
RUN cd /tmp/sharp/test/bench && npm install --omit optional