On Windows, when comparing the canvas.node binary obtained from:
- building locally following the instructions vs.
- a regular npm install which uses available pre-builds.
I noticed that the local build happens against an older version of cairo which leads to conditional exclusion of the compilation of the cairo_pdf_surface_set_metadata not available in older versions of cairo, see Canvas.cc#L312.
Going through the releases of canvas this discrepancy has always existed going back to canvas 2.11.2 at least. This is problematic in the following case of a project using Node.js 22 and 2 different versions of canvas:
- canvas@3.2.0 : Windows x64 binary available on npm as pre-built native add-on.
- canvas@2.11.2 : Windows x64 binary not available on npm as as pre-built native add-on, local build with node-gyp required.
npm ls canvas
+-- canvas@3.2.0
+-- fabric@5.5.2
| +-- canvas@2.11.2
| `-- jsdom@19.0.0
| `-- canvas@2.11.2 deduped
+-- jsdom@26.1.0
| `-- canvas@3.2.0 deduped
`-- svg2img@0.9.4
+-- canvas@2.11.2
`-- jsdom@16.7.0
`-- canvas@2.11.2 deduped
Both canvas versions depend on libcairo-2.dll, however in my case, when the application starts the top level canvas@3.2.0's canvas.node binary seems to be linked to the wrong (older) libcairo-2.dll from my local canvas@2.11.2 build which misses cairo_pdf_surface_set_metadata, see WinDbg output below:
461c:3a88 @ 267532843 - LdrpNameToOrdinal - WARNING: Procedure "cairo_pdf_surface_set_metadata" could not be located in DLL at base 0x0000000068DC0000.
461c:3a88 @ 267532843 - LdrpReportError - ERROR: Locating export "cairo_pdf_surface_set_metadata" for DLL "\\?\C:\Users\<redacted>\Work\<redacted>\webapp\node_modules\canvas\build\Release\canvas.node" failed with status: 0xc0000139. (461c.3a88): Unknown exception - code c0000139 (first chance) 461c:3a88 @ 267532843 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapModule raised exception 0xc0000139 Exception record: .exr 0000009F1E7E5C30 Context record: .cxr 0000009F1E7E5740 461c:3a88 @ 267532843 - LdrpLoadDllInternal - RETURN: Status: 0xc0000139
461c:3a88 @ 267532843 - LdrpLoadDllInternal - RETURN: c0000139
461c:3a88 @ 267532843 - LdrLoadDll - RETURN: Status: 0xc0000139 461c:3a88 @ 267532843 - LdrLoadDll - RETURN: c0000139
Would it be possible to update the Windows build instructions to contain a link to a location which contains sufficiently reasonable cairo binaries - such as MYSYS2 which is used for the release pipeline? The expected default location for the libraries which currently defaults to --GTK_Root=C:\GTK during compilation could also be changed and ideally renamed. This way the conflict can be avoided when building locally?
If you know a better fix I am interested in hearing about it as well.
Regards,
David
On Windows, when comparing the
canvas.nodebinary obtained from:I noticed that the local build happens against an older version of cairo which leads to conditional exclusion of the compilation of the
cairo_pdf_surface_set_metadatanot available in older versions of cairo, see Canvas.cc#L312.Going through the releases of canvas this discrepancy has always existed going back to canvas 2.11.2 at least. This is problematic in the following case of a project using Node.js 22 and 2 different versions of canvas:
Both canvas versions depend on
libcairo-2.dll, however in my case, when the application starts the top level canvas@3.2.0'scanvas.nodebinary seems to be linked to the wrong (older)libcairo-2.dllfrom my local canvas@2.11.2 build which missescairo_pdf_surface_set_metadata, see WinDbg output below:Would it be possible to update the Windows build instructions to contain a link to a location which contains sufficiently reasonable cairo binaries - such as MYSYS2 which is used for the release pipeline? The expected default location for the libraries which currently defaults to
--GTK_Root=C:\GTKduring compilation could also be changed and ideally renamed. This way the conflict can be avoided when building locally?If you know a better fix I am interested in hearing about it as well.
Regards,
David