linux(CentOS6)安装canvas(nodejs)的踩坑之旅

某需求需要在服务器上生成可视化的数据图,第一感觉就是通过熟悉得再熟悉不过的canvas来实现,于是便开始了一条为期3天的踩坑之旅。

windows 放弃

公司的电脑是windows的系统,首先想到在本地安装试试水后再布到服务器上,于是打开了node-canvas在windows上的安装说明:https://github.com/Automattic/node-canvas/wiki/Installation:-Windows。
先装Python,再装node-gyp,再。。。我的天,太麻烦了直接放弃。。。

Ubuntu 分分钟

还好有一台装了Ubuntu系统的电脑,首先安装依赖插件

1
2
3
4
5
6
7
8
sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
``

一路yes之后依赖就装完了

然后安装canvas的包
``` sh
npm i -g canvas

没报错,找个项目试一试

1
2
3
4
mkdir canvastest
cd canvastest
npm init -y
npm i -D canvas

在canvastest目录下新增一个index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Canvas = require('canvas');

let canvas = Canvas.createCanvas(400, 400);
let ctx = canvas.getContext('2d');
let fs = require('fs');

let out = fs.createWriteStream('./test.png');
let stream = canvas.createPNGStream();

stream.on('data', chunk => {
out.write(chunk);
});

ctx.fillStyle = '#A00';
ctx.fillRect(0, 30, 50, 50);

见证奇迹

1
node test

唉呦,活生生一个test.png就这么生成了,打开一看,矩形也在。然后试了各种文字、直线、圆、渐变等等,都ok。不要太完美,准备搭服务器。

CentOS 6天坑

CentOS属Fedora,按照文档上的说明,先安装依赖

1
sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel

一路yes之后依赖就装完了

然后安装canvas的包

1
cnpm i -g canvas

好像报错了,不管它,找个项目试一试

1
2
3
4
mkdir canvastest
cd canvastest
npm init -y
npm i -D canvas

在canvastest目录下新增一个index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Canvas = require('canvas');

let canvas = Canvas.createCanvas(400, 400);
let ctx = canvas.getContext('2d');
let fs = require('fs');

let out = fs.createWriteStream('./test.png');
let stream = canvas.createPNGStream();

stream.on('data', chunk => {
out.write(chunk);
});

ctx.fillStyle = '#A00';
ctx.fillRect(0, 30, 50, 50);

见证奇迹

1
node test

嗯。。。果然报错了,找了下原因,CentOS6通过yum安装的gcc为4.4.7版本,而我们需要的gcc必须支持C++11,也就是4.7以上的版本。好吧,我们需要编译升级安装gcc了。

网上各种方法试了,只发现一个是有用的。如下

编译安装gcc

没安装依赖的依赖(gcc也有依赖)的系统需要先装下依赖的依赖:gmpmpfrmpc

1
yum install gmp mpfr mpc

下载安装包

1
wget http://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2

解压

1
tar -jxvf gcc-4.8.2.tar.bz2

执行脚本下载依赖

1
2
cd gcc-4.8.2 
./contrib/download_prerequisites

建立一个目录供编译出的文件存放

1
2
mkdir gcc-build-4.8.2
cd gcc-build-4.8.2

生成Makefile文件(可能要几分钟)

1
../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib

编译(可能要好几十分钟)

1
make -j4

安装

1
sudo make install

查看版本

1
gcc -v

版本输出4.8.2。安装成功,也算是踩了不少坑。

再执行node test,又报错:

1
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found

查,说是软链接有问题。

重新建立libstdc++.so软链接

在安装的目录(gcc-4.8.2)下搜索libstdc++.so

1
find ./ -name "libstdc++.so"

结果

1
2
3
4
5
6
7
8
9
./gcc-4.8.2/gcc-build-4.8.2/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.18
./gcc-4.8.2/gcc-build-4.8.2/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
./gcc-4.8.2/gcc-build-4.8.2/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so
./gcc-4.8.2/gcc-build-4.8.2/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.18
./gcc-4.8.2/gcc-build-4.8.2/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
./gcc-4.8.2/gcc-build-4.8.2/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so
./gcc-4.8.2/gcc-build-4.8.2/stage1-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.18
./gcc-4.8.2/gcc-build-4.8.2/stage1-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
./gcc-4.8.2/gcc-build-4.8.2/stage1-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so

建立软链接(用搜索结果的第一条)

1
cp ./gcc-4.8.2/gcc-build-4.8.2/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.18 /usr/lib64

切换目录至/usr/lib64

1
cd /usr/lib64

删除原软链接

1
rm -rf libstdc++.so.6

将默认库的软连接指向最新动态库

1
ln -s libstdc++.so.6.0.18 libstdc++.so.6

默认动态库升级完成。重新运行以下命令检查动态库:

1
strings /usr/lib64/libstdc++.so.6 | grep GLIBC

如果含GLIBCXX_3.4.18,成功。

再回到测试目录执行node test,又报了另一个错

1
libc.so.6: version GLIBC_2.14 not found

一查,缺少glibc2.14这个库,原来还要更新glibc这个库

更新glibc库

先查询现有的glibc库

1
strings /lib64/libc.so.6 |grep GLIBC_

返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_PRIVATE

找个目录下载安装源

1
2
wget http://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz 
wget http://ftp.gnu.org/gnu/glibc/glibc-ports-2.14.tar.gz

解压

1
2
tar -xvf  glibc-2.14.tar.gz 
tar -xvf glibc-ports-2.14.tar.gz

合并

1
mv glibc-ports-2.14 glibc-2.14/ports

建立一个目录供编译出的文件存放

1
2
mkdir glibc-2.14/build
cd glibc-2.14/build

生成Makefile文件(可能要几分钟)

1
../configure  --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin

编译(可能要好几十分钟)

1
make

安装

1
sudo make install

查看/lib64/libc.so.6软链接指向

1
ll /lib64/libc.so.6

结果

1
/lib64/libc.so.6 -> /lib64/libc-2.14.so

说明指向对了,再看glibc的安装版本

1
strings /lib64/libc.so.6 |grep GLIBC_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.14
GLIBC_PRIVATE

装好了。

废了半条命,再回到之前node项目的测试目录,执行

node test

没报错,看了下目录里也有个test.png且显示正常。总算是可以正常用了。。。踩坑结束

我还遇到了canvas包半天装不上的情况,感觉用cnpm多装几次才成功。