lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.31k stars 1.3k forks source link

/usr/include/vips/vips8:35:10: fatal error: glib-object.h: No such file or directory #4273

Closed jenssegers closed 4 days ago

jenssegers commented 4 days ago

Possible install-time or require-time problem

You must confirm both of these before continuing.

Are you using the latest version of sharp?

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

Are you using a supported runtime?

If you cannot confirm any of these, please upgrade to the latest version and try again before opening an issue.

Are you using a supported package manager and installing optional dependencies?

If you cannot confirm any of these, please upgrade to the latest version of your chosen package manager and ensure you are allowing the installation of optional or multi-platform dependencies before opening an issue.

What is the complete error message, including the full stack trace?

 > [sharp 4/5] RUN npm install --no-package-lock --save-dev node-addon-api node-gyp &&     npm install --no-package-lock --build-from-source --include=optional --verbose --foreground-scripts --platform=linux --libc=musl --arch=arm64 sharp &&     npm prune --production &&     npm cache clean --force:                                                                              
...
10.16 gyp verb get node dir target node version installed: 20.18.0
10.16 gyp verb build dir attempting to create "build" dir: /sharp/node_modules/sharp/src/build
10.16 gyp verb build dir "build" dir needed to be created? Yes
10.16 gyp verb build/config.gypi creating config file
10.16 gyp verb build/config.gypi writing out config file: /sharp/node_modules/sharp/src/build/config.gypi
10.17 gyp verb config.gypi checking for gypi file: /sharp/node_modules/sharp/src/config.gypi
10.17 gyp verb common.gypi checking for gypi file: /sharp/node_modules/sharp/src/common.gypi
10.17 gyp verb gyp gyp format was not specified; forcing "make"
10.17 gyp info spawn /usr/bin/python3
10.17 gyp info spawn args [
10.17 gyp info spawn args '/sharp/node_modules/node-gyp/gyp/gyp_main.py',
10.17 gyp info spawn args 'binding.gyp',
10.17 gyp info spawn args '-f',
10.17 gyp info spawn args 'make',
10.17 gyp info spawn args '-I',
10.17 gyp info spawn args '/sharp/node_modules/sharp/src/build/config.gypi',
10.17 gyp info spawn args '-I',
10.17 gyp info spawn args '/sharp/node_modules/node-gyp/addon.gypi',
10.17 gyp info spawn args '-I',
10.17 gyp info spawn args '/root/.cache/node-gyp/20.18.0/include/node/common.gypi',
10.17 gyp info spawn args '-Dlibrary=shared_library',
10.17 gyp info spawn args '-Dvisibility=default',
10.17 gyp info spawn args '-Dnode_root_dir=/root/.cache/node-gyp/20.18.0',
10.17 gyp info spawn args '-Dnode_gyp_dir=/sharp/node_modules/node-gyp',
10.17 gyp info spawn args '-Dnode_lib_file=/root/.cache/node-gyp/20.18.0/<(target_arch)/node.lib',
10.17 gyp info spawn args '-Dmodule_root_dir=/sharp/node_modules/sharp/src',
10.17 gyp info spawn args '-Dnode_engine=v8',
10.17 gyp info spawn args '--depth=.',
10.17 gyp info spawn args '--no-parallel',
10.17 gyp info spawn args '--generator-output',
10.17 gyp info spawn args 'build',
10.17 gyp info spawn args '-Goutput_dir=.'
10.17 gyp info spawn args ]
10.61 gyp verb build type Release
10.61 gyp verb architecture arm64
10.61 gyp verb node dev dir /root/.cache/node-gyp/20.18.0
10.61 gyp verb python /usr/bin/python3
10.61 gyp verb `which` succeeded for `make` /usr/bin/make
10.61 gyp verb bin symlinks created symlink to "/usr/bin/python3" in "/sharp/node_modules/sharp/src/build/node_gyp_bins" and added to PATH
10.62 gyp info spawn make
10.62 gyp info spawn args [ 'V=1', 'BUILDTYPE=Release', '-C', 'build' ]
10.62 make: Entering directory '/sharp/node_modules/sharp/src/build'
10.62   cc -o Release/obj.target/nothing/../../node-addon-api/nothing.o ../../../node-addon-api/nothing.c '-DNODE_GYP_MODULE_NAME=nothing' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' -I/root/.cache/node-gyp/20.18.0/include/node -I/root/.cache/node-gyp/20.18.0/src -I/root/.cache/node-gyp/20.18.0/deps/openssl/config -I/root/.cache/node-gyp/20.18.0/deps/openssl/openssl/include -I/root/.cache/node-gyp/20.18.0/deps/uv/include -I/root/.cache/node-gyp/20.18.0/deps/zlib -I/root/.cache/node-gyp/20.18.0/deps/v8/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -O3 -fno-omit-frame-pointer  -MMD -MF ./Release/.deps/Release/obj.target/nothing/../../node-addon-api/nothing.o.d.raw   -c
10.65 rm -f Release/obj.target/../../node-addon-api/nothing.a Release/obj.target/../../node-addon-api/nothing.a.ar-file-list; mkdir -p `dirname Release/obj.target/../../node-addon-api/nothing.a`
10.66 ar crs Release/obj.target/../../node-addon-api/nothing.a @Release/obj.target/../../node-addon-api/nothing.a.ar-file-list
10.66   ln -f "Release/obj.target/../../node-addon-api/nothing.a" "Release/nothing.a" 2>/dev/null || (rm -rf "Release/nothing.a" && cp -af "Release/obj.target/../../node-addon-api/nothing.a" "Release/nothing.a")
10.66   touch Release/obj.target/libvips-cpp.stamp
10.66   g++ -o Release/obj.target/sharp-linuxmusl-arm64/common.o ../common.cc '-DNODE_GYP_MODULE_NAME=sharp-linuxmusl-arm64' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNAPI_VERSION=9' '-DNODE_ADDON_API_DISABLE_DEPRECATED' '-DNODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS' '-DBUILDING_NODE_EXTENSION' -I/root/.cache/node-gyp/20.18.0/include/node -I/root/.cache/node-gyp/20.18.0/src -I/root/.cache/node-gyp/20.18.0/deps/openssl/config -I/root/.cache/node-gyp/20.18.0/deps/openssl/openssl/include -I/root/.cache/node-gyp/20.18.0/deps/uv/include -I/root/.cache/node-gyp/20.18.0/deps/zlib -I/root/.cache/node-gyp/20.18.0/deps/v8/include -I../../../node-addon-api -I../. -I/glib-2.0 -I/sharp/node_modules/@img/sharp-libvips-linuxmusl-arm64/lib/glib-2.0/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++17 -std=c++0x -fexceptions -Wall -Os -MMD -MF ./Release/.deps/Release/obj.target/sharp-linuxmusl-arm64/common.o.d.raw   -c
10.73 In file included from ../common.cc:13:
10.73 /usr/include/vips/vips8:35:10: fatal error: glib-object.h: No such file or directory
10.73    35 | #include <glib-object.h>
10.73       |          ^~~~~~~~~~~~~~~
10.73 compilation terminated.
10.73 make: Leaving directory '/sharp/node_modules/sharp/src/build'
10.73 make: *** [sharp-linuxmusl-arm64.target.mk:135: Release/obj.target/sharp-linuxmusl-arm64/common.o] Error 1
10.73 gyp ERR! build error 
10.73 gyp ERR! stack Error: `make` failed with exit code: 2
10.73 gyp ERR! stack at ChildProcess.<anonymous> (/sharp/node_modules/node-gyp/lib/build.js:216:23)
10.73 gyp ERR! System Linux 6.10.4-linuxkit
10.73 gyp ERR! command "/usr/local/bin/node" "/sharp/node_modules/.bin/node-gyp" "rebuild" "--directory=src"
10.73 gyp ERR! cwd /sharp/node_modules/sharp/src
10.73 gyp ERR! node -v v20.18.0
10.73 gyp ERR! node-gyp -v v10.2.0
10.73 gyp ERR! not ok 
10.74 npm info run sharp@0.33.5 install { code: 1, signal: null }
10.75 npm verbose stack Error: command failed
10.75 npm verbose stack     at promiseSpawn (/usr/local/lib/node_modules/npm/node_modules/@npmcli/promise-spawn/lib/index.js:22:22)
10.75 npm verbose stack     at spawnWithShell (/usr/local/lib/node_modules/npm/node_modules/@npmcli/promise-spawn/lib/index.js:124:10)
10.75 npm verbose stack     at promiseSpawn (/usr/local/lib/node_modules/npm/node_modules/@npmcli/promise-spawn/lib/index.js:12:12)
10.75 npm verbose stack     at runScriptPkg (/usr/local/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js:77:13)
10.75 npm verbose stack     at runScript (/usr/local/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/run-script.js:9:12)
10.75 npm verbose stack     at /usr/local/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js:329:17
10.75 npm verbose stack     at run (/usr/local/lib/node_modules/npm/node_modules/promise-call-limit/dist/commonjs/index.js:67:22)
10.75 npm verbose stack     at /usr/local/lib/node_modules/npm/node_modules/promise-call-limit/dist/commonjs/index.js:84:9
10.75 npm verbose stack     at new Promise (<anonymous>)
10.75 npm verbose stack     at callLimit (/usr/local/lib/node_modules/npm/node_modules/promise-call-limit/dist/commonjs/index.js:35:69)
10.75 npm verbose pkgid sharp@0.33.5
10.75 npm error code 1
10.75 npm error path /sharp/node_modules/sharp
10.75 npm error command failed
10.75 npm error command sh -c node install/check
10.75 npm verbose cwd /sharp
10.75 npm verbose os Linux 6.10.4-linuxkit
10.75 npm verbose node v20.18.0
10.75 npm verbose npm  v10.8.2
10.75 npm verbose exit 1
10.75 npm verbose code 1

What is the complete output of running npm install --verbose --foreground-scripts sharp in an empty directory?

See above.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

  System:
    OS: Linux 6.10 Alpine Linux
    CPU: (6) arm64 unknown
    Memory: 3.10 GB / 3.83 GB
    Container: Yes
    Shell: 1.36.1 - /bin/ash
  Binaries:
    Node: 20.18.0 - /usr/local/bin/node
    Yarn: 1.22.22 - /usr/local/bin/yarn
    npm: 10.8.2 - /usr/local/bin/npm
  npmPackages:
    sharp: ^0.33.5 => 0.33.5 

Dependencies installed within the container

FROM node:20.18.0-alpine3.19

RUN apk add --no-cache --update \
    vips \
    vips-dev \
    vips-heif \
    libheif \
    libpng \
    libjpeg-turbo \
    libde265 \
    libwebp \
    g++ \
    make \
    gcc \
    build-base \
    glib-dev
jenssegers commented 4 days ago

Setting SHARP_FORCE_GLOBAL_LIBVIPS=1 seems to have fixed the issue. The installation instructions suggested that this was not required if a global libvips was detected.

This did uncover that the alpine 3.20 libvips version was not sufficient so I had to change to:

RUN apk add --no-cache --update \
    --repository=https://dl-cdn.alpinelinux.org/alpine/edge/main \
    --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community \
    --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing \
    vips \
    vips-dev \
    vips-heif \
    libheif \
    libpng \
    libjpeg-turbo \
    libde265 \
    libwebp \
    g++ \
    make \
    gcc \
    build-base
lovell commented 4 days ago

The part of the installation log just before the section you've provided here should have included entries with information about what sharp discovered and the decisions it made when attempting to build from source.

As you've seen, the version of the vips-dev package provided by Alpine 3.19 is not recent enough for the latest sharp v0.33.5. You don't need to set (and I recommend against setting) SHARP_FORCE_GLOBAL_LIBVIPS unless you know that version mismatches should be ignored.

If you don't need to use a globally-installed libvips then I'd suggest not installing it and letting sharp using its prebuilt binaries, which removes a whole class of possible installation error.

jenssegers commented 3 days ago

@lovell As you can see from the dependencies, I needed support for heif images.

If anyone hits this post from a search, this is my current (simplified) multi-layer Dockerfile to build Sharp with heif support on Alpine:

FROM node:20-alpine AS sharp

# Force global libvips
ENV SHARP_FORCE_GLOBAL_LIBVIPS=1

# Set working directory
WORKDIR /sharp

# Install dependencies
RUN apk add --no-cache --update \
    --repository=https://dl-cdn.alpinelinux.org/alpine/edge/main \
    --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community \
    --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing \
    vips \
    vips-dev \
    vips-heif \
    libheif \
    libpng \
    libjpeg-turbo \
    libde265 \
    libwebp \
    g++ \
    make \
    gcc \
    build-base

# Install Sharp
RUN npm install --no-package-lock --save-dev node-addon-api node-gyp && \
    npm install --no-package-lock --build-from-source --include=optional --verbose --foreground-scripts --platform=linux --libc=musl --arch=arm64 sharp && \
    npm prune --production && \
    npm cache clean --force

# Remove build dependencies
RUN apk del \
    g++ \
    make \
    gcc \
    build-base

# ------------------------------------------------------------

FROM node:20-alpine

# Copy Sharp
COPY --from=sharp /sharp/node_modules ${LAMBDA_TASK_ROOT}/node_modules
COPY --from=sharp /usr/lib /usr/lib
lovell commented 3 days ago

Warning: please be very, very careful when mixing Alpine packages from edge with stable (non-edge) versions.

https://wiki.alpinelinux.org/wiki/Edge