diff --git a/.github/workflows/prebuild.yaml b/.github/workflows/prebuild.yaml index fd6ee8879..204e09b21 100644 --- a/.github/workflows/prebuild.yaml +++ b/.github/workflows/prebuild.yaml @@ -32,283 +32,236 @@ # "edit" and delete any assets that are in purgatory (have a /!\ next to them). name: Make Prebuilds -on: workflow_dispatch - -# UPLOAD_TO can be specified to upload the release assets under a different tag -# name (e.g. for testing). If omitted, the assets are published under the same -# release tag as the canvas version being built. -# env: -# UPLOAD_TO: "v0.0.1" -# -# Node 19 requires a recent node-gyp -# Node 10, 11 require 8 -# Node 8, 9 require 6.1 -# Manually set this file depending on what you're building!! +on: + workflow_dispatch: + inputs: + buildVersion: + description: 'Version to build' + required: true + default: 'v3.0.0-rc2' + # UPLOAD_TO can be specified to upload the release assets under a different tag + # name (e.g. for testing). If omitted, the assets are published under the same + # release tag as the canvas version being built. + uploadTo: + description: 'Upload artefacts to version' + required: false + default: '' + +env: + CANVAS_VERSION_TO_BUILD: ${{inputs.buildVersion}} + UPLOAD_TO: ${{inputs.uploadTo}} jobs: - Linux: + Debian: strategy: fail-fast: false matrix: - node: [21] - canvas_tag: ["v3.0.0-rc1b"] # e.g. "v2.6.1" - name: ${{ matrix.canvas_tag }}, Node.js ${{ matrix.node }}, Linux + node: [ 18, 20, 22 ] runs-on: ubuntu-latest - container: - image: ${{ matrix.node < 18 && 'chearon/canvas-prebuilt:9' || 'zbbjornson/canvas-prebuilt:10' }} - env: - CANVAS_VERSION_TO_BUILD: ${{ matrix.canvas_tag }} + # container: + # image: node:${{ matrix.node }}-slim + name: Node.js ${{ matrix.node }}, Debian steps: - - uses: actions/checkout@v2 + - name: Checkout Prebuild + uses: actions/checkout@v4 + - name: Checkout Source + uses: actions/checkout@v4 with: - ref: ${{ matrix.canvas_tag }} - - # Use the files in the prebuild/ directory from the commit that was used - # to trigger the prebuild workflow. The version of git that's installed on - # this Linux here doesn't support the method used on Mac and Win, so we - # checkout the prebuild branch and copy the files from the prebuild/ - # directory in the Build step. - - uses: actions/checkout@v2 + ref: ${{ env.CANVAS_VERSION_TO_BUILD }} + path: source + - name: Install Dependencies + run: | + npm install + . ./Debian/preinstall.sh + working-directory: ./prebuild + - name: Build + run: npm install --build-from-source + working-directory: ./source + - name: Test + run: npm test + working-directory: ./source + - name: Bundle + run: . ./prebuild/Debian/bundle.sh + - name: Uninstall Dependencies + run: . ./prebuild/Debian/uninstall.sh + - name: Test binary + run: npm test + working-directory: ./source + - name: Make asset + id: make_asset + run: . ./prebuild/tarball.sh + - name: Upload asset + uses: ncipollo/release-action@v1 with: - ref: ${{ env.GITHUB_SHA }} - path: prebuild-branch + tag: ${{ env.UPLOAD_TO || env.CANVAS_VERSION_TO_BUILD }} + allowUpdates: true + artifacts: ${{ steps.make_asset.outputs.asset_name }} + artifactContentType: application/tar+gz - - uses: actions/setup-node@v1 + Alpine: + strategy: + fail-fast: false + matrix: + # FIXME: no 22 image yet + node: [ 18, 20 ] + canvas_tag: [ "v3.0.0-rc1" ] # e.g. "v2.6.1" + runs-on: ubuntu-latest + container: + image: node:${{ matrix.node }}-alpine + name: Node.js ${{ matrix.node }}, Alpine + steps: + - name: Checkout Prebuild + uses: actions/checkout@v4 + - name: Checkout Source + uses: actions/checkout@v4 with: - node-version: ${{ matrix.node }} - - - name: Build + ref: ${{ env.CANVAS_VERSION_TO_BUILD }} + path: source + - name: Install Dependencies run: | - set -ex - mkdir -p prebuild - cp -rfv ./prebuild-branch/prebuild/* ./prebuild/ - npm install -g node-gyp - npm install --ignore-scripts - . prebuild/Linux/preinstall.sh - cp prebuild/Linux/binding.gyp binding.gyp - node-gyp rebuild -j 2 - . prebuild/Linux/bundle.sh - + npm install + . ./Alpine/preinstall.sh + working-directory: ./prebuild + - name: Build + run: npm install --build-from-source + working-directory: ./source + - name: Test + # some tests failed + continue-on-error: true + run: npm test + working-directory: ./source + - name: Bundle + run: . ./prebuild/Debian/bundle.sh + - name: Uninstall Dependencies + run: . ./prebuild/Alpine/uninstall.sh - name: Test binary + # some tests failed continue-on-error: true - run: | - set -ex - cd /root/harfbuzz-* && make uninstall - cd /root/cairo-* && make uninstall - cd /root/pango-* && cd _build && ninja uninstall - cd /root/libpng-* && make uninstall - cd /root/libjpeg-* && cd b && make uninstall - cd /root/giflib-* && make uninstall - - cd $GITHUB_WORKSPACE - ls build/Release - ldd build/Release/canvas.node - npx mocha test/*.test.js - - - name: Make bundle - id: make_bundle - run: . prebuild/tarball.sh - - - name: Upload - uses: actions/github-script@v2 + run: npm test + working-directory: ./source + - name: Make asset + id: make_asset + run: . ./prebuild/tarball.sh + - name: Upload asset + uses: ncipollo/release-action@v1 with: - script: | - const fs = require("fs"); - const assetName = "${{ steps.make_bundle.outputs.asset_name }}"; - const tagName = process.env.UPLOAD_TO || process.env.CANVAS_VERSION_TO_BUILD; - const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/"); - - const releases = await github.repos.listReleases({owner, repo}); - const release = releases.data.find(r => r.tag_name === tagName); - if (!release) - throw new Error(`Tag ${tagName} not found. Did you make the GitHub release?`); - - const oldAsset = release.assets.find(a => a.name === assetName); - if (oldAsset) - await github.repos.deleteReleaseAsset({owner, repo, asset_id: oldAsset.id}); - - // (This is equivalent to actions/upload-release-asset. We're - // already in a script, so might as well do it here.) - const r = await github.repos.uploadReleaseAsset({ - url: release.upload_url, - headers: { - "content-type": "application/x-gzip", - "content-length": `${fs.statSync(assetName).size}` - }, - name: assetName, - data: fs.readFileSync(assetName) - }); + tag: ${{ env.UPLOAD_TO || env.CANVAS_VERSION_TO_BUILD }} + allowUpdates: true + artifacts: ${{ steps.make_asset.outputs.asset_name }} + artifactContentType: application/tar+gz macOS: strategy: fail-fast: false matrix: - node: [21] - canvas_tag: ["v3.0.0-rc1b"] # e.g. "v2.6.1" - name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, macOS - runs-on: macos-latest - env: - CANVAS_VERSION_TO_BUILD: ${{ matrix.canvas_tag }} + node: [ 18, 20, 22 ] + os: + - runner: macos-latest + arch: x64 + # - runner: macos-latest-xlarge # GitHub's Apple Silicon runner + # arch: arm64 + runs-on: ${{ matrix.os.runner }} + name: Node.js ${{ matrix.node }}, macOS ${{ matrix.os.arch }} steps: - - uses: actions/checkout@v2 + - name: Checkout Prebuild + uses: actions/checkout@v4 + - name: Checkout Source + uses: actions/checkout@v4 with: - ref: ${{ matrix.canvas_tag }} - # Fetch all commits/all branches so we can checkout the prebuild - # branch's files - fetch-depth: 0 - - - uses: actions/setup-node@v1 + ref: ${{ env.CANVAS_VERSION_TO_BUILD }} + path: source + - name: Install Node.JS + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - + - name: Install Dependencies + run: | + npm install + . ./macOS/preinstall.sh + working-directory: ./prebuild - name: Build + run: npm install --build-from-source + working-directory: ./source + - name: Test + run: npm test + working-directory: ./source + - name: Bundle run: | - set -Eeuxo pipefail - git checkout ${{ matrix.canvas_tag }} - git checkout $GITHUB_SHA -- prebuild/ - npm install -g node-gyp - npm install --ignore-scripts - . prebuild/macOS/preinstall.sh - cp prebuild/macOS/binding.gyp binding.gyp - node-gyp rebuild -j 2 - . prebuild/macOS/bundle.sh - + . ./prebuild/macOS/prebundle.sh + . ./prebuild/macOS/bundle.sh + - name: Uninstall Dependencies + run: . ./prebuild/macOS/uninstall.sh - name: Test binary - run: | - brew uninstall --force --ignore-dependencies cairo pango librsvg giflib harfbuzz - npm test - + run: npm test + working-directory: ./source - name: Make bundle id: make_bundle run: . prebuild/tarball.sh - - - name: Upload - uses: actions/github-script@v2 + - name: Make asset + id: make_asset + run: . ./prebuild/tarball.sh + - name: Upload asset + uses: ncipollo/release-action@v1 with: - script: | - const fs = require("fs"); - const assetName = "${{ steps.make_bundle.outputs.asset_name }}"; - const tagName = process.env.UPLOAD_TO || process.env.CANVAS_VERSION_TO_BUILD; - const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/"); - - const releases = await github.repos.listReleases({owner, repo}); - const release = releases.data.find(r => r.tag_name === tagName); - if (!release) - throw new Error(`Tag ${tagName} not found. Did you make the GitHub release?`); - - const oldAsset = release.assets.find(a => a.name === assetName); - if (oldAsset) - await github.repos.deleteReleaseAsset({owner, repo, asset_id: oldAsset.id}); + tag: ${{ env.UPLOAD_TO || env.CANVAS_VERSION_TO_BUILD }} + allowUpdates: true + artifacts: ${{ steps.make_asset.outputs.asset_name }} + artifactContentType: application/tar+gz - // (This is equivalent to actions/upload-release-asset. We're - // already in a script, so might as well do it here.) - const r = await github.repos.uploadReleaseAsset({ - url: release.upload_url, - headers: { - "content-type": "application/x-gzip", - "content-length": `${fs.statSync(assetName).size}` - }, - name: assetName, - data: fs.readFileSync(assetName) - }); - - Win: + Windows: strategy: fail-fast: false matrix: - node: [21] - canvas_tag: ["v3.0.0-rc1b"] # e.g. "v2.6.1" - name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, Windows - runs-on: windows-2019 - env: - CANVAS_VERSION_TO_BUILD: ${{ matrix.canvas_tag }} + node: [ 18, 20, 22 ] + name: Node.js ${{ matrix.node }}, Windows + runs-on: windows-latest steps: - # GitHub runners now have msys2 installed, but msys is not on the path and - # is apparently slow to start. - # https://github.com/msys2/setup-msys2#setup-msys2 - # https://github.com/actions/virtual-environments/pull/632 - - uses: msys2/setup-msys2@v2 + - name: Checkout Prebuild + uses: actions/checkout@v4 + - name: Checkout Source + uses: actions/checkout@v4 with: - msystem: UCRT64 - update: true - path-type: inherit - - - uses: actions/setup-node@v3 + ref: ${{ env.CANVAS_VERSION_TO_BUILD }} + path: source + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - - - uses: actions/checkout@v3 + - uses: msys2/setup-msys2@v2 with: - ref: ${{ matrix.canvas_tag }} - # Fetch all commits/all branches so we can checkout the prebuild - # branch's files - fetch-depth: 0 - - - name: Build - run: | - git checkout ${{ matrix.canvas_tag }} - git checkout $env:GITHUB_SHA -- prebuild/ - npm install -g node-gyp - npm prefix -g | % {npm config set node_gyp "$_\node_modules\node-gyp\bin\node-gyp.js"} - npm install --ignore-scripts - msys2 -c ". prebuild/Windows/preinstall.sh" - msys2 -c "cp prebuild/Windows/binding.gyp binding.gyp" - npm install --build-from-source - - - name: Install Depends - run: | - Invoke-WebRequest "http://www.dependencywalker.com/depends22_x64.zip" -OutFile depends22_x64.zip - 7z e depends22_x64.zip - - name: Bundle pt 2 + msystem: UCRT64 + path-type: inherit + - name: Install Dependencies shell: msys2 {0} run: | - ./depends.exe -c -oc depends.csv build\\Release\\canvas.node || true - [ -f depends.csv ] || { echo "error invoking depends.exe"; exit 1; } - - copies=$(comm -12 \ - <(cat depends.csv | cut -d ',' -f2 | sed 's/"//g' | tr '[:upper:]' '[:lower:]' | sort) \ - <(find /ucrt64/bin -name '*.dll' -printf "%f\n" | tr '[:upper:]' '[:lower:]' | sort) \ - ) - - for dll in $copies; do - cp /ucrt64/bin/$dll build/Release - done; - + npm install + . ./Windows/preinstall.sh + working-directory: ./prebuild + - name: Build + shell: msys2 {0} + run: npm install --build-from-source + working-directory: ./source + - name: Test + shell: msys2 {0} + working-directory: ./source + run: npm test + - name: Bundle + shell: msys2 {0} + run: . ./prebuild/Windows/bundle.sh - name: Test binary # By not running in msys2, this doesn't have access to the msys2 libs run: npm test - + # broke on Node 22 + continue-on-error: true + working-directory: ./source - name: Make asset - id: make_bundle + id: make_asset + shell: msys2 {0} # I can't figure out why this isn't an env var already. It shows up with `env`. - run: msys2 -c "UPLOAD_TO=${{ env.UPLOAD_TO }} CANVAS_VERSION_TO_BUILD=${{ env.CANVAS_VERSION_TO_BUILD}} . prebuild/tarball.sh" - - - name: Upload - uses: actions/github-script@v2 + run: . ./prebuild/tarball.sh + - name: Upload asset + uses: ncipollo/release-action@v1 with: - script: | - const fs = require("fs"); - const assetName = "${{ steps.make_bundle.outputs.asset_name }}"; - const tagName = process.env.UPLOAD_TO || process.env.CANVAS_VERSION_TO_BUILD; - const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/"); - - const releases = await github.repos.listReleases({owner, repo}); - const release = releases.data.find(r => r.tag_name === tagName); - if (!release) - throw new Error(`Tag ${tagName} not found. Did you make the GitHub release?`); - - const oldAsset = release.assets.find(a => a.name === assetName); - if (oldAsset) - await github.repos.deleteReleaseAsset({owner, repo, asset_id: oldAsset.id}); - - // (This is equivalent to actions/upload-release-asset. We're - // already in a script, so might as well do it here.) - const r = await github.repos.uploadReleaseAsset({ - url: release.upload_url, - headers: { - "content-type": "application/x-gzip", - "content-length": `${fs.statSync(assetName).size}` - }, - name: assetName, - data: fs.readFileSync(assetName) - }); + tag: ${{ env.UPLOAD_TO || env.CANVAS_VERSION_TO_BUILD }} + allowUpdates: true + artifacts: ${{ steps.make_asset.outputs.asset_name }} + artifactContentType: application/tar+gz diff --git a/.gitignore b/.gitignore index e5e14d5b6..5a71f1a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,7 @@ build .DS_Store .lock-wscript -test/images/*.png -examples/*.png -examples/*.jpg -testing -out.png -out.pdf -out.svg -.pomo + node_modules package-lock.json diff --git a/prebuild/Alpine/preinstall.sh b/prebuild/Alpine/preinstall.sh new file mode 100644 index 000000000..508041506 --- /dev/null +++ b/prebuild/Alpine/preinstall.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +apk --no-cache add build-base cairo-dev jpeg-dev pango-dev giflib-dev librsvg-dev pixman-dev patchelf diff --git a/prebuild/Alpine/uninstall.sh b/prebuild/Alpine/uninstall.sh new file mode 100644 index 000000000..932f0389d --- /dev/null +++ b/prebuild/Alpine/uninstall.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +apk --purge del build-base cairo* jpeg* pango* giflib* librsvg* pixman* diff --git a/prebuild/Debian/bundle.sh b/prebuild/Debian/bundle.sh new file mode 100644 index 000000000..5d2cfec97 --- /dev/null +++ b/prebuild/Debian/bundle.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +TARGET=./source/build/Release + +for lib in $(ldd "${TARGET}/canvas.node" | grep '=>' | cut -d " " -f 3); do + echo "Copy ${lib}" + cp -L "${lib}" "${TARGET}" + patchelf --force-rpath --set-rpath '$ORIGIN' "${TARGET}/$(basename -- "${lib}")" +done diff --git a/prebuild/Debian/preinstall.sh b/prebuild/Debian/preinstall.sh new file mode 100644 index 000000000..edac90989 --- /dev/null +++ b/prebuild/Debian/preinstall.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +sudo apt-get update +sudo apt-get install -y build-essential libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev libpixman-1-dev patchelf diff --git a/prebuild/Debian/uninstall.sh b/prebuild/Debian/uninstall.sh new file mode 100644 index 000000000..7396a5d3b --- /dev/null +++ b/prebuild/Debian/uninstall.sh @@ -0,0 +1,3 @@ +# FIXME: error if removing with build-essential libcairo2* libjpeg* libpango1.0* libgif* librsvg2* libpixman-1* +sudo apt-get purge -y build-essential libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev libpixman-1-dev +sudo apt-get autoremove --purge -y diff --git a/prebuild/Linux/Dockerfile b/prebuild/Linux/Dockerfile deleted file mode 100644 index 80614a171..000000000 --- a/prebuild/Linux/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -FROM debian:10 -RUN apt-get update && apt-get -y install curl git cmake make gcc g++ nasm wget gperf bzip2 meson uuid-dev perl libxml-parser-perl - -RUN bash -c 'cd; curl -LO https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz; tar -xvf pkg-config-0.29.2.tar.gz; cd pkg-config-0.29.2; ./configure --with-internal-glib; make -j8; make install' -RUN bash -c 'cd; curl -O https://zlib.net/fossils/zlib-1.2.11.tar.gz; tar -xvf zlib-1.2.11.tar.gz; cd zlib-1.2.11; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -LO https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz; tar -xvf libffi-3.3.tar.gz; cd libffi-3.3; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -O https://www.openssl.org/source/openssl-1.1.1i.tar.gz; tar -xvf openssl-1.1.1i.tar.gz; cd openssl-1.1.1i; ./config; make -j8; make install' -RUN ldconfig -RUN bash -c 'cd; curl -O https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tgz; tar -xvf Python-3.9.1.tgz; cd Python-3.9.1; ./configure --enable-shared --with-ensurepip=yes; make -j8; make install' -RUN ldconfig -RUN pip3 install meson -RUN bash -c 'cd; curl -LO https://download.sourceforge.net/giflib/giflib-5.2.1.tar.gz; tar -xvf giflib-5.2.1.tar.gz; cd giflib-5.2.1; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -LO https://download.sourceforge.net/libpng/libpng-1.6.37.tar.gz; tar -xvf libpng-1.6.37.tar.gz; cd libpng-1.6.37; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -LO https://github.com/libjpeg-turbo/libjpeg-turbo/archive/2.0.6.tar.gz; tar -xvf 2.0.6.tar.gz; cd libjpeg-turbo-2.0.6; mkdir b; cd b; cmake -G"Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/usr/local ..; make -j8; make install' -RUN bash -c 'cd; curl -LO https://downloads.sourceforge.net/project/pcre/pcre/8.44/pcre-8.44.tar.bz2; tar -xvf pcre-8.44.tar.bz2; cd pcre-8.44; ./configure --enable-pcre16 --enable-pcre32 --enable-utf --enable-unicode-properties; make -j8; make install ' -RUN ldconfig -RUN bash -c 'cd; curl -LO https://download.gnome.org/sources/glib/2.67/glib-2.67.1.tar.xz; tar -xvf glib-2.67.1.tar.xz; cd glib-2.67.1; meson _build; cd _build; ninja; ninja install' -RUN ldconfig -RUN bash -c 'cd; curl -LO https://download.sourceforge.net/freetype/freetype-2.10.4.tar.gz; tar -xvf freetype-2.10.4.tar.gz; cd freetype-2.10.4; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -LO https://github.com/harfbuzz/harfbuzz/releases/download/2.7.4/harfbuzz-2.7.4.tar.xz; tar -xvf harfbuzz-2.7.4.tar.xz; cd harfbuzz-2.7.4; ./configure; make -j8; make install;' -RUN bash -c 'cd; curl -LO https://github.com/libexpat/libexpat/releases/download/R_2_2_10/expat-2.2.10.tar.gz; tar -xvf expat-2.2.10.tar.gz; cd expat-2.2.10; ./configure; make -j8; make install' -RUN ldconfig -RUN ls -l /usr/include -RUN bash -c 'cd; curl -O https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.1.tar.bz2; tar -xvf fontconfig-2.13.1.tar.bz2; cd fontconfig-2.13.1; UUID_LIBS="-L/lib/x86_64-linux-gnu -luuid" UUID_CFLAGS="-I/include" ./configure --enable-static --sysconfdir=/etc --localstatedir=/var; make -j8; make install' -RUN bash -c 'cd; curl -O https://www.cairographics.org/releases/pixman-0.40.0.tar.gz; tar -xvf pixman-0.40.0.tar.gz; cd pixman-0.40.0; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -O https://cairographics.org/releases/cairo-1.16.0.tar.xz; tar -xvf cairo-1.16.0.tar.xz; cd cairo-1.16.0; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -LO https://github.com/fribidi/fribidi/releases/download/v1.0.10/fribidi-1.0.10.tar.xz; tar -xvf fribidi-1.0.10.tar.xz; cd fribidi-1.0.10; ./configure; make -j8; make install' -RUN bash -c 'cd; curl -LO https://download.gnome.org/sources/pango/1.48/pango-1.48.0.tar.xz; tar -xvf pango-1.48.0.tar.xz; cd pango-1.48.0; meson -Dharfbuzz:docs=disabled -Dgtk_doc=false _build; cd _build; ninja; ninja install' -RUN ldconfig - -# librsvg -RUN bash -c 'curl https://sh.rustup.rs -sSf | sh -s -- -y'; -RUN bash -c 'curl -O http://xmlsoft.org/sources/libxml2-2.9.10.tar.gz; tar -xvf libxml2-2.9.10.tar.gz; cd libxml2-2.9.10; ./configure --without-python; make -j8; make install' -RUN bash -c 'curl -O https://ftp.gnu.org/pub/gnu/gettext/gettext-0.21.tar.gz; tar -xvf gettext-0.21.tar.gz; cd gettext-0.21; ./configure; make -j8; make install' -RUN ldconfig -RUN bash -c 'curl -LO https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz; tar -xvf intltool-0.51.0.tar.gz; cd intltool-0.51.0; ./configure; make -j8; make install' -# using an old version of shared-mime-info because 2.1 has a ridiculous number of dependencies for what is essentially just a database -RUN bash -c 'curl -O https://people.freedesktop.org/~hadess/shared-mime-info-1.8.tar.xz; tar -xvf shared-mime-info-1.8.tar.xz; cd shared-mime-info-1.8; ./configure; make -j8; make install' -RUN bash -c 'curl -LO https://download.gnome.org/sources/gdk-pixbuf/2.42/gdk-pixbuf-2.42.2.tar.xz; tar -xvf gdk-pixbuf-2.42.2.tar.xz; cd gdk-pixbuf-2.42.2; meson _build; cd _build; ninja install'; -RUN ldconfig -RUN bash -c 'curl -LO https://download.gnome.org/sources/libcroco/0.6/libcroco-0.6.13.tar.xz; tar -xvf libcroco-0.6.13.tar.xz; cd libcroco-0.6.13; ./configure; make -j8; make install' -RUN bash -c 'cd; . .cargo/env; curl -LO https://download.gnome.org/sources/librsvg/2.50/librsvg-2.50.2.tar.xz; tar -xvf librsvg-2.50.2.tar.xz; cd librsvg-2.50.2; ./configure --enable-introspection=no; make -j8; make install' -RUN ldconfig diff --git a/prebuild/Linux/binding.gyp b/prebuild/Linux/binding.gyp deleted file mode 100644 index 6117e608f..000000000 --- a/prebuild/Linux/binding.gyp +++ /dev/null @@ -1,55 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'canvas', - 'sources': [ - 'src/backend/Backend.cc', - 'src/backend/ImageBackend.cc', - 'src/backend/PdfBackend.cc', - 'src/backend/SvgBackend.cc', - 'src/bmp/BMPParser.cc', - 'src/Backends.cc', - 'src/Canvas.cc', - 'src/CanvasGradient.cc', - 'src/CanvasPattern.cc', - 'src/CanvasRenderingContext2d.cc', - 'src/closure.cc', - 'src/color.cc', - 'src/Image.cc', - 'src/ImageData.cc', - 'src/init.cc', - 'src/register_font.cc' - ], - 'defines': [ - 'HAVE_GIF', - 'HAVE_JPEG', - 'HAVE_RSVG', - 'NAPI_DISABLE_CPP_EXCEPTIONS', - 'NODE_ADDON_API_ENABLE_MAYBE' - ], - 'libraries': [ - '' | cut -d " " -f 3); do +# if [[ "${lib}" == "${WINDIR}"* ]]; then +# : +# else +# echo "copy ${lib} to destination" +# cp "${lib}" "${TARGET}" +# fi +#done + +shopt -s nocasematch +function addToLibs() { + local lib=${1} && shift + if [[ "$(which "${lib}")" == "${WINDIR}"* ]]; then + : + else + for libItem in ${LIBS[@]}; do + if [[ "${libItem}" == "${lib}" ]]; then + return + fi + done + echo $lib + fi +} + +RECURSE_INDEX=0 + +function getLibsForBinary() { + local binary=$1 && shift + + local -i count=0 + for binLib in $(objdump -p "$(cygpath -u "${binary}")" | grep "DLL Name:" | sed -e 's/^\s*DLL\sName:\s*//'); do + if [[ ! -z "$(addToLibs ${binLib})" ]]; then + echo "added ${binLib}" + count=$count+1 + LIBS+=("${binLib}") + fi + done + + if [[ count -gt 0 ]]; then + local currentIndex=${RECURSE_INDEX} + RECURSE_INDEX=${#LIBS[@]} + # recurse if any added from last checked + echo "recurse check after ${count} added" + for lib in ${LIBS[@]:${currentIndex}}; do + getLibsForBinary "$(which "${lib}")" + done + fi +} + +function copyLibs() { + local DEST=$1 && shift + local DEST_PATH=$(cygpath -u "${DEST}") + for lib in ${LIBS[@]}; do + echo "copy ${lib} to destination" + cp "$(which "${lib}")" "${DEST_PATH}" + done +} + +getLibsForBinary "${TARGET}/canvas.node" +copyLibs "${TARGET}" diff --git a/prebuild/Windows/preinstall.sh b/prebuild/Windows/preinstall.sh index a53c704fb..8b786a7f1 100644 --- a/prebuild/Windows/preinstall.sh +++ b/prebuild/Windows/preinstall.sh @@ -1,34 +1,36 @@ +#!/usr/bin/env sh # expects node, VS, and MSYS environments to be set up already. does everything else. -deps="cairo-2 png16-16 jpeg-8 pango-1.0-0 pangocairo-1.0-0 gobject-2.0-0 glib-2.0-0 turbojpeg gif-7 freetype-6 rsvg-2-2 gsf-1-114"; +deps="cairo-2 png16-16 jpeg-8 pango-1.0-0 pangocairo-1.0-0 gobject-2.0-0 glib-2.0-0 turbojpeg gif-7 freetype-6 rsvg-2-2"; # install cairo and tools to create .lib -pacman --noconfirm -S \ - wget \ - unzip \ - ucrt64/mingw-w64-ucrt-x86_64-binutils \ - ucrt64/mingw-w64-ucrt-x86_64-tools \ - ucrt64/mingw-w64-ucrt-x86_64-libjpeg-turbo \ - ucrt64/mingw-w64-ucrt-x86_64-pango \ - ucrt64/mingw-w64-ucrt-x86_64-cairo \ - ucrt64/mingw-w64-ucrt-x86_64-giflib \ - ucrt64/mingw-w64-ucrt-x86_64-freetype \ - ucrt64/mingw-w64-ucrt-x86_64-fontconfig \ - ucrt64/mingw-w64-ucrt-x86_64-librsvg \ - ucrt64/mingw-w64-ucrt-x86_64-libxml2 \ - ucrt64/mingw-w64-ucrt-x86_64-libgsf +prefix=${MSYSTEM,,} +arch=${MSYSTEM_CARCH} + +pacman --noconfirm --needed -S \ + ${prefix}/mingw-w64-ucrt-${arch}-binutils \ + ${prefix}/mingw-w64-ucrt-${arch}-tools \ + ${prefix}/mingw-w64-ucrt-${arch}-libjpeg-turbo \ + ${prefix}/mingw-w64-ucrt-${arch}-pango \ + ${prefix}/mingw-w64-ucrt-${arch}-cairo \ + ${prefix}/mingw-w64-ucrt-${arch}-giflib \ + ${prefix}/mingw-w64-ucrt-${arch}-harfbuzz \ + ${prefix}/mingw-w64-ucrt-${arch}-freetype \ + ${prefix}/mingw-w64-ucrt-${arch}-fontconfig \ + ${prefix}/mingw-w64-ucrt-${arch}-librsvg \ + ${prefix}/mingw-w64-ucrt-${arch}-libxml2 # create .lib files for vc++ -echo "generating lib files for the MSYS2 UCRT64 dlls" +echo "generating lib files for the MSYS2 dlls" for lib in $deps; do - gendef /ucrt64/bin/lib$lib.dll > /dev/null 2>&1 || { + gendef /${prefix}/bin/lib$lib.dll > /dev/null 2>&1 || { echo "could not find lib$lib.dll, have to skip "; continue; } - dlltool -d lib$lib.def -l /ucrt64/lib/lib$lib.lib > /dev/null 2>&1 || { + dlltool -d lib$lib.def -l /${prefix}/lib/lib$lib.lib > /dev/null 2>&1 || { echo "could not create dll for lib$lib.dll"; continue; } diff --git a/prebuild/macOS/binding.gyp b/prebuild/macOS/binding.gyp deleted file mode 100644 index 718844ac8..000000000 --- a/prebuild/macOS/binding.gyp +++ /dev/null @@ -1,55 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'canvas', - 'sources': [ - 'src/backend/Backend.cc', - 'src/backend/ImageBackend.cc', - 'src/backend/PdfBackend.cc', - 'src/backend/SvgBackend.cc', - 'src/bmp/BMPParser.cc', - 'src/Backends.cc', - 'src/Canvas.cc', - 'src/CanvasGradient.cc', - 'src/CanvasPattern.cc', - 'src/CanvasRenderingContext2d.cc', - 'src/closure.cc', - 'src/color.cc', - 'src/Image.cc', - 'src/ImageData.cc', - 'src/init.cc', - 'src/register_font.cc' - ], - 'defines': [ - 'HAVE_GIF', - 'HAVE_JPEG', - 'HAVE_RSVG', - 'NAPI_DISABLE_CPP_EXCEPTIONS', - 'NODE_ADDON_API_ENABLE_MAYBE' - ], - 'libraries': [ - ' { + console.log(['canvas', tagName, 'node-v' + modules, platform, (await libc.family()) || 'unknown', arch].join('-')) +})() diff --git a/prebuild/package.json b/prebuild/package.json new file mode 100644 index 000000000..59d46f34e --- /dev/null +++ b/prebuild/package.json @@ -0,0 +1,31 @@ +{ + "name": "canvas/prebuild", + "description": "Canvas graphics API backed by Cairo", + "version": "0.0.0", + "author": "TJ Holowaychuk ", + "contributors": [ + "Nathan Rajlich ", + "Rod Vagg ", + "Juriy Zaytsev " + ], + "keywords": [ + "canvas", + "graphic", + "graphics", + "pixman", + "cairo", + "image", + "images", + "pdf" + ], + "homepage": "https://github.com/Automattic/node-canvas", + "repository": "git://github.com/Automattic/node-canvas.git", + "private": "true", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >= 21" + }, + "license": "MIT" +} diff --git a/prebuild/tarball.sh b/prebuild/tarball.sh index 6526c7e1b..7ba1d48f4 100644 --- a/prebuild/tarball.sh +++ b/prebuild/tarball.sh @@ -1,19 +1,20 @@ -# Generate the prebuild-install formatted filename from the node environment -FILENAME=$( - node -e " - var p = process, v = p.versions, libc = require('detect-libc').familySync() || 'unknown'; - if (libc === 'glibc') libc = ''; - const tagName = p.env.UPLOAD_TO || p.env.CANVAS_VERSION_TO_BUILD; - console.log('canvas-v' + tagName + '-napi-v7-' + p.platform + libc + '-' + p.arch); - " -).tar.gz; +#!/usr/bin/env sh +# Generate the node-gyp formatted filename from the node environment +FILENAME=$(node ./prebuild/node-gyp-filename.js).tar.gz; # Zip up the release -tar -C build -czvf $FILENAME Release +tar -C ./source/build \ + --exclude='obj.target' \ + --exclude='.deps' \ + --exclude 'obj' \ + --exclude '*.pdb' \ + --exclude '*.ipdb' \ + --exclude '*.iobj' \ + -czvf $FILENAME Release if [ $? -ne 0 ]; then echo "failed to make tarball $FILENAME from node-canvas/build" exit 1; else - echo "::set-output name=asset_name::$FILENAME" + echo "asset_name=${FILENAME}" >> $GITHUB_OUTPUT fi