From 1bbee519aa33205cee9da8f0ad26b26b08a5a520 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 7 Oct 2025 14:32:44 +0100 Subject: [PATCH] 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 --- .cirrus.yml | 7 +++-- .github/CONTRIBUTING.md | 2 +- .github/workflows/ci.yml | 12 +++++--- biome.json | 2 +- docs/src/content/docs/changelog/v0.34.5.md | 3 ++ docs/src/content/docs/install.md | 5 +-- install/build.js | 36 ++++++++++++++++++++++ install/check.js | 33 ++------------------ package.json | 9 +++--- test/bench/Dockerfile | 2 +- 10 files changed, 65 insertions(+), 46 deletions(-) create mode 100644 install/build.js diff --git a/.cirrus.yml b/.cirrus.yml index 0dbadc40..45f9c3df 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -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 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index eeb6dd19..6239e09a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3249f384..0211806d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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") diff --git a/biome.json b/biome.json index 2ed1c104..12cd1a9b 100644 --- a/biome.json +++ b/biome.json @@ -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", diff --git a/docs/src/content/docs/changelog/v0.34.5.md b/docs/src/content/docs/changelog/v0.34.5.md index bf762f87..a754c33a 100644 --- a/docs/src/content/docs/changelog/v0.34.5.md +++ b/docs/src/content/docs/changelog/v0.34.5.md @@ -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) diff --git a/docs/src/content/docs/install.md b/docs/src/content/docs/install.md index 6e14ab1c..d74d47a2 100644 --- a/docs/src/content/docs/install.md +++ b/docs/src/content/docs/install.md @@ -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 diff --git a/install/build.js b/install/build.js new file mode 100644 index 00000000..6af6541e --- /dev/null +++ b/install/build.js @@ -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); +} diff --git a/install/check.js b/install/check.js index 8e96da86..d526e088 100644 --- a/install/check.js +++ b/install/check.js @@ -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); diff --git a/package.json b/package.json index af1378d2..c15af175 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,8 @@ "Don Denton " ], "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", diff --git a/test/bench/Dockerfile b/test/bench/Dockerfile index fc23deab..290db857 100644 --- a/test/bench/Dockerfile +++ b/test/bench/Dockerfile @@ -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