bloomtime / heroku-buildpack-nodejs

Bloom's slightly modified buildpack for node.js on Heroku. Our modifications are in branches: prune is out of date; cairo is useful!
MIT License
3 stars 5 forks source link

Trouble with Node-Canvas `make` #1

Open bensheldon opened 12 years ago

bensheldon commented 12 years ago

I'm having trouble installing node-canvas using this buildpack. Below is the section of npm install log when it starts trying to build canvas and then barfs.

       make: Entering directory `/tmp/build_3h09nz7zqlyu5/node_modules/canvas/build'
         CXX(target) Release/obj.target/canvas/src/Canvas.o
       In file included from ../src/Canvas.cc:8:
       ../src/Canvas.h:19:25: warning: cairo/cairo.h: No such file or directory
       ../src/Canvas.cc:15:29: warning: cairo/cairo-pdf.h: No such file or directory
       In file included from ../src/Canvas.cc:8:
       ../src/Canvas.h:63: error: 'cairo_status_t' has not been declared
       ../src/Canvas.h:79: error: ISO C++ forbids declaration of 'cairo_surface_t' with no type
       ../src/Canvas.h:79: error: 'cairo_surface_t' declared as an 'inline' field
       ../src/Canvas.h:79: error: expected ';' before '*' token
       ../src/Canvas.h:80: error: expected ';' before 'inline'
       ../src/Canvas.h:88: error: ISO C++ forbids declaration of 'cairo_surface_t' with no type
       ../src/Canvas.h:88: error: expected ';' before '*' token
       ../src/Canvas.h: In member function 'uint8_t* Canvas::data()':
       ../src/Canvas.h:81: error: '_surface' was not declared in this scope
       ../src/Canvas.h:81: error: 'cairo_image_surface_get_data' was not declared in this scope
       ../src/Canvas.h: In member function 'int Canvas::stride()':
       ../src/Canvas.h:82: error: '_surface' was not declared in this scope
       ../src/Canvas.h:82: error: 'cairo_image_surface_get_stride' was not declared in this scope
       In file included from ../src/CanvasRenderingContext2d.h:13,
                        from ../src/Canvas.cc:9:
       ../src/CanvasGradient.h: At global scope:
       ../src/CanvasGradient.h:21: error: ISO C++ forbids declaration of 'cairo_pattern_t' with no type
       ../src/CanvasGradient.h:21: error: 'cairo_pattern_t' declared as an 'inline' field
       ../src/CanvasGradient.h:21: error: expected ';' before '*' token
       ../src/CanvasGradient.h:23: error: expected ';' before 'private'
       ../src/CanvasGradient.h:26: error: ISO C++ forbids declaration of 'cairo_pattern_t' with no type
       ../src/CanvasGradient.h:26: error: expected ';' before '*' token
       In file included from ../src/Canvas.cc:9:
       ../src/CanvasRenderingContext2d.h:30: error: 'cairo_filter_t' does not name a type
       ../src/CanvasRenderingContext2d.h:31: error: ISO C++ forbids declaration of 'cairo_pattern_t' with no type
       ../src/CanvasRenderingContext2d.h:31: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h:32: error: ISO C++ forbids declaration of 'cairo_pattern_t' with no type
       ../src/CanvasRenderingContext2d.h:32: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h:33: error: ISO C++ forbids declaration of 'cairo_pattern_t' with no type
       ../src/CanvasRenderingContext2d.h:33: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h:34: error: ISO C++ forbids declaration of 'cairo_pattern_t' with no type
       ../src/CanvasRenderingContext2d.h:34: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h:130: error: 'cairo_t' has not been declared
       ../src/CanvasRenderingContext2d.h:131: error: ISO C++ forbids declaration of 'cairo_t' with no type
       ../src/CanvasRenderingContext2d.h:131: error: 'cairo_t' declared as an 'inline' field
       ../src/CanvasRenderingContext2d.h:131: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h:132: error: expected ';' before 'inline'
       ../src/CanvasRenderingContext2d.h:136: error: 'cairo_surface_t' has not been declared
       ../src/CanvasRenderingContext2d.h:137: error: expected ',' or '...' before '(' token
       ../src/CanvasRenderingContext2d.h:137: error: 'fn' has incomplete type
       ../src/CanvasRenderingContext2d.h:137: error: invalid use of 'void'
       ../src/CanvasRenderingContext2d.h:157: error: ISO C++ forbids declaration of 'cairo_t' with no type
       ../src/CanvasRenderingContext2d.h:157: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h:158: error: ISO C++ forbids declaration of 'cairo_path_t' with no type
       ../src/CanvasRenderingContext2d.h:158: error: expected ';' before '*' token
       ../src/CanvasRenderingContext2d.h: In member function 'void Context2d::setContext(int*)':
       ../src/CanvasRenderingContext2d.h:130: error: '_context' was not declared in this scope
       In file included from ../src/Canvas.cc:16:
       ../src/closure.h: At global scope:
       ../src/closure.h:22: error: 'cairo_status_t' does not name a type
       ../src/closure.h:29: error: 'cairo_status_t' does not name a type
       In file included from ../src/Canvas.cc:19:
       ../src/JPEGStream.h:100: error: variable or field 'write_to_jpeg_stream' declared void
       ../src/JPEGStream.h:100: error: 'cairo_surface_t' was not declared in this scope
       ../src/JPEGStream.h:100: error: 'surface' was not declared in this scope
       ../src/JPEGStream.h:100: error: expected primary-expression before 'int'
       ../src/JPEGStream.h:100: error: expected primary-expression before 'int'
       ../src/JPEGStream.h:100: error: expected primary-expression before '*' token
       ../src/JPEGStream.h:100: error: 'closure' was not declared in this scope
       make: *** [Release/obj.target/canvas/src/Canvas.o] Error 1
       make: Leaving directory `/tmp/build_3h09nz7zqlyu5/node_modules/canvas/build'
       gyp ERR! build error 
       gyp ERR! stack Error: `make` failed with exit code: 2
       gyp ERR! stack     at ChildProcess.onExit (/tmp/node-npm-lDkc/node_modules/node-gyp/lib/build.js:215:23)
       gyp ERR! stack     at ChildProcess.EventEmitter.emit (events.js:91:17)
       gyp ERR! stack     at Process._handle.onexit (child_process.js:674:10)
       gyp ERR! System Linux 2.6.32-343-ec2
       gyp ERR! command "node" "/tmp/node-npm-lDkc/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
       gyp ERR! cwd /tmp/build_3h09nz7zqlyu5/node_modules/canvas
       gyp ERR! node -v v0.8.7
       gyp ERR! node-gyp -v v0.6.5
       gyp ERR! not ok 
       npm ERR! canvas@0.13.1 install: `node-gyp rebuild`
       npm ERR! `sh "-c" "node-gyp rebuild"` failed with 1
       npm ERR! 
       npm ERR! Failed at the canvas@0.13.1 install script.
       npm ERR! This is most likely a problem with the canvas package,
       npm ERR! not with npm itself.
       npm ERR! Tell the author that this fails on your system:
       npm ERR!     node-gyp rebuild
       npm ERR! You can get their info via:
       npm ERR!     npm owner ls canvas
       npm ERR! There is likely additional logging output above.

       npm ERR! System Linux 2.6.32-343-ec2
       npm ERR! command "/tmp/node-node-SXZt/bin/node" "/tmp/node-npm-lDkc/cli.js" "install" "--production"
       npm ERR! cwd /tmp/build_3h09nz7zqlyu5
       npm ERR! node -v v0.8.7
       npm ERR! npm -v 1.1.49
       npm ERR! code ELIFECYCLE
       npm ERR! 
       npm ERR! Additional logging details can be found in:
       npm ERR!     /tmp/build_3h09nz7zqlyu5/npm-debug.log
       npm ERR! not ok code 0
 !     Failed to install --production dependencies with npm

I'm not entirely sure what the problem is: if it's looking for the Cairo sourcefiles (and not finding them) or if it has something to do with the environment variables not being set. This is my environment on Heroku:


BUILDPACK_URL=git://github.com/bloomtime/heroku-buildpack-nodejs.git#cairo
TERM=xterm-256color
COLUMNS=204
PATH=bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin
PWD=/app
PS1=\[\033[01;34m\]\w\[\033[00m\] \[\033[01;32m\]$ \[\033[00m\]
LINES=24
HOME=/app
SHLVL=2
PORT=22974

And my package.json in case it's a version compatibility issue

Thanks for the help!

bensheldon commented 12 years ago

Looking into this further, it appears to only fail on the new node-canvas version 0.13.x which replaces node-waf with gyp. I need to look further into how gyp loads libraries, but you can see the changes that were made between the 0.12.x and 0.13.x node-canvas versions

RandomEtc commented 12 years ago

It looks like you forked this and tried to fix it? How did that go?

bensheldon commented 12 years ago

Didn't have much luck. I have it working with node-canvas v0.12.x. I think the problem is with the gyp configuration in node-canvas v0.13.x. It looks like others are having trouble in different environments; for example, this issue could be related.

But I do have the buildpack working beautifully on node-canvas v0.12.x and really appreciate the work you've done.

RandomEtc commented 12 years ago

Cool, thanks. Appreciate the research. Let me know if it becomes a blocker for you I'd be happy to jump on IM/IRC and try to work it out.

davidjrice commented 12 years ago

Yep, I'm having the exact same error when trying to push to heroku https://gist.github.com/3832964 So +1 on this!

Am using 0.13.x, as I couldn't get 0.12.x to build on OSX.

Will try and help further on this too. Secretly I was hoping someone would have fixed it already :)

bensheldon commented 12 years ago

@davidjrice sigh, I'm now having that problem too. This is by no means a pretty solution, but I have my package.json file set up like this:

  "dependencies": {
    "canvas": "0.12.x" // for heroku-buildpack
  },
  "devDependencies": {
    "canvas": "0.13.x", // for local development where v0.12.x won't install argh!
  }
nik9000 commented 11 years ago

I've worked around this issue by compiling my own version of pixman and cairo on a heroku instance, shipping the libraries back to my machine, checking them in to my repository, and then using a fork of the standard buildpack here: https://github.com/nik9000/heroku-buildpack-nodejs.

I'm not 100% sure but I think the compilation problem you are seeing is caused by the way node-canvas references most .h files (cairo/cairo.h) and the way the buildpack sets them up to be referenced (cairo.h). I don't think node-canvas is consistent with the way it references .h files - some of them don't use the directory, I believe. For that reason, I made my buildpack reference them in both ways.

Here is exactly what I did to build pixman and cairo

heroku run bash

cd /tmp
curl http://cairographics.org/releases/LATEST-pixman-0.28.2 > pixman-0.28.2.tar.gz
tar xf pixman-0.28.2.tar.gz
cd pixman-0.28.2
./configure --prefix=/app/vendor/pixman-0.28.2
make
make install
cd ..

curl http://cairographics.org/releases/LATEST-cairo-1.12.10 > cairo-1.12.10.tar.xz
unxz cairo-1.12.10.tar.xz
tar xf cairo-1.12.10.tar
cd cairo-1.12.10
export PKG_CONFIG_PATH=/app/vendor/pixman-0.28.2/lib/pkgconfig/
./configure --prefix=/app/vendor/cairo-1.12.10
make
make install

You can take the vendor library home with scp -r /app/vendor/ you@yourlaptop

mojodna commented 11 years ago

I followed @nik9000's lead and updated my fork of the buildpack to use the changed include paths while updating the library versions.

Cairo libraries (but not headers) are present on dynos, so care must be taken to set LD_LIBRARY_PATH to look for the vendored Cairo first, otherwise you may experience runtime errors as it attempts to call into missing functions. My fork of the buildpack writes $HOME/.profile.d/ld_library_path.sh with vendored libraries to take this into account.

davidjrice commented 11 years ago

Have this working thanks to davidjrice/heroku-buildpack-cairo

You'll also need my changes to heroku-buildpack-nodejs

Sorry I don't have time to document this better at this point in time

On Sunday, 14 April 2013 at 06:03, Seth Fitzsimmons wrote:

I followed @nik9000 (https://github.com/nik9000)'s lead and updated my fork of the buildpack (https://github.com/mojodna/heroku-buildpack-nodejs) to use the changed include paths while updating the library versions. Cairo libraries (but not headers) are present on dynos, so care must be taken to set LD_LIBRARY_PATH to look for the vendored Cairo first, otherwise you may experience runtime errors as it attempts to call into missing functions. My fork of the buildpack writes $HOME/.profile.d/ld_library_path.sh with vendored libraries to take this into account.

— Reply to this email directly or view it on GitHub (https://github.com/bloomtime/heroku-buildpack-nodejs/issues/1#issuecomment-16346085).

mojodna commented 11 years ago

(@davidjrice - to be clear, my buildpack is successfully working with node-canvas-1.0.2 having more or less followed the same road as you.)