linux 安装node-canvas "version GLIBC_2.18 not found"

2,045 阅读3分钟

背景

在服务端给图片增加水印,输入一张图片和文字,服务端返回一张带水印图片。

技术选项

  1. dom+css:编辑器开发成本低,是云端图像输出依赖截屏,性能较差。
  2. node-canvas:基于很多c++库在node端的实现,虽然和浏览器端API保持一致,但实际渲染效果会有差异。
  3. phantomjs:puppeteer发布后这个项目已经停止维护。
  4. skia:相比puppeteer+canvas,skia绘制效率会比高不少,并且浏览器端可以使用skia+wasm的方案同构开发编辑器。

node-canvas

canvas api 官方网站

node-canvas 官方仓库

Linux 服务器安装 canvas 遇到问题?

一、/lib64/libc.so.6: version GLIBC_2.18 not found

1、产生原因: 由于Linux系统的glibc版本太低,而软件编译时使用了较高版本的glibc引起的。

查看软链接指向的版本
[root@localhost ~]$ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Aug  2  2021 /lib64/libc.so.6 -> libc-2.17.so

查看使用的glibc版本
[root@localhost ~]$ ldd --version
ldd (GNU libc) 2.17
Copyright (C) 2012 Free Software Foundation, Inc.

查看系统glibc支持的版本
[root@localhost ~]$ strings /lib64/libc.so.6 |grep GLIBC_
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.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
GLIBC_PRIVATE

[root@localhost ~]$ rpm -qa |grep glibc
glibc-2.17-307.1.alios7.1.x86_64
glibc-common-2.17-307.1.alios7.1.x86_64

可以看到最高支持到2.17版本。因为yum安装只能安装到2.17版本,所有只能采用源码升级的方式进行。

2、linux 升级glibc支持的版本到GLIBC_2.18

#下载
wget http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
#解压缩
tar zxvf glibc-2.18.tar.gz
#创建文件夹
cd glibc-2.18
mkdir build
cd build
#预编译glibc-2.18,生成 makefile 文件
../configure --prefix=/opt/glibc-2.18
#编译glibc-2.18,-j表示使用4核
make -j4
#安装glibc-2.18
sudo make install
#环境变量设置,在原有环境变量上拼接
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/glibc-2.18/lib
#检查软链接,编译成功后,build文件下会生成一个新的libc.so.6,这是一个软连接,而真实的lib文件是此目录下的libc.so。ll是ls -l的别名
$ll libc.so.6
lrwxrwxrwx 1 root root 12 Aug 25 17:06 libc.so.6 -> libc-2.18.so
#查看库文件 可以看到2.17的旧库文件还在,多了2.18版本的库文件,而且软链接文件全部指向了2.18版本才正确
ll /lib64/libc*
#验证glibc-2.18版本
strings /lib64/libc.so.6 |grep GLIBC
#解决中文乱码问题
make localedata/install-locales

#验证 node canvas 是否可用

mkdir canvastest
cd canvastest
npm init -y
npm i -D canvas
touch index.js
vim index.js 
#编辑 index.js 

let Canvas = require('canvas');

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

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

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

stream.pipe(out)

在当前目录下有一个test.png图片就是成功了。

二、安装过程的坑

1、执行 ../configure --prefix=/opt/glibc-2.18 出错

configure: WARNING:
*** These auxiliary programs are missing or incompatible versions: makeinfo autoconf
*** some features will be disabled.
*** Check the INSTALL file for required versions.
checking LD_LIBRARY_PATH variable... contains current directory
configure: error:
*** LD_LIBRARY_PATH shouldn't contain the current directory when
*** building glibc. Please change the environment variable
*** and run configure again.

原因:LD_LIBRARY_PATH不能包含当前目录,请修改环境变量并重新执行configure

1、查看 LD_LIBRARY_PATH
$echo $LD_LIBRARY_PATH
:/opt/glibc-2.18/lib

2、清空 LD_LIBRARY_PATH
$export LD_LIBRARY_PATH=

3、重新执行 ../configure --prefix=/opt/glibc-2.18
$../configure --prefix=/opt/glibc-2.18

4、重设 LD_LIBRARY_PATH
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/glibc-2.18/lib

当然也可以重设文件
$vim /etc/profile
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/glibc-2.18/lib:/opt/glibc-2.17/lib(可以多个)
// i 文件输入, wq 保存退出,q 不保存退出
$source /etc/profile
// 运行重新生效

2、执行 make -j4 出错(一)

No rule to make target `/home/admin/glibc-2.18/build/bits/stdio_lim.st', needed by `/home/admin/glibc-2.18/build/bits/stdio_lim.h'.  Stop.

#很无解,把一些库都装上。安装一些库,后面仔细研究下都是干什么的。
yum install pixman pkgconfig cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel giflib-devel texinfo glibc-headers gcc-c++ -y
yum install texinfo glibc-headers gcc-c++ -y

3、执行 make -j4 出错(二)

/home/admin/glibc-2.18/build/elf/ldconfig: Warning: ignoring configuration file that cannot be opened: /opt/glibc-2.18/etc/ld.so.conf: No such fileor directory

就是缺少了必要的编译文件ld.so.conf。通过find命令找到对应的文件位置。

$find / -name "ld.so.conf"
/etc/ld.so.conf

$sudo cp /etc/ld.so.conf /opt/glibc-2.18/etc/

4、执行 make install 出错

/home/admin/glibc-2.18/build/elf/ldconfig: Warning: ignoring configuration file that cannot be opened: /opt/glibc-2.18/etc/ld.so.conf: No such fileor directory
make[1]: Leaving directory `/home/admin/glibc-2.18'

sudo ldconfig -p

#执行make install 会报错 sudo cp /etc/ld.so.conf /opt/glibc-2.18/etc/

5、执行 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/glibc-2.18/lib 后查看 glibc 库出错


查看 INSTALL 文件我们可以知道安装glibc2.18的要求,需要gcc版本4.4以上,make版本3.79以上
[/home/admin/glibc-2.18]$cat INSTALL | grep -E "newer|later"

ls: relocation error: libc.so.6: symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference

$export LD_LIBRARY_PATH=

6、安装/升级 make

#yum安装只能安装 3.82 版本
yum install make  

#手动安装 4.3 版本
wget http://ftp.gnu.org/gnu/make/make-4.3.tar.gz
tar -zxf make-4.3.tar.gz
cd make-4.3/
mkdir build
cd build
../configure --prefix=/usr
make
make install
make -v

#执行 make 出错
checking whether the C compiler works... no
configure: error: in `/home/admin/make-4.3/build':
configure: error: C compiler cannot create executables
See `config.log' for more details

#如果提高编译并发数
-j4中的数字为cpu核数,及并发工作任务数量,可以提高编译效率
make -j4

查看cpu核数(此命令待考究)
cat /proc/cpuinfo| grep "processor" | wc -l

查看动态库版本有哪些
$strings /usr/lib64/libstdc++.so.6 | grep GLIBC

总结:根据安装的坑,博主的安装命令如下。可以将此代码放到glb218.sh文件脚本中,用bash glb218.sh进行执行。

#优先安装make,其中 -y 表示自动执行yes
sudo yum install make -y
#安装各种依赖
sudo yum install pixman pkgconfig cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel giflib-devel texinfo glibc-headers gcc-c++ -y
#下载
sudo wget http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
#解压缩
tar zxvf glibc-2.18.tar.gz
#创建文件夹
cd glibc-2.18
mkdir build
cd build
#预编译glibc-2.18,生成 makefile 文件,glibc库包含了ls等命令 --with-binutils 不会引起ls命令失效
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
#编译glibc-2.18
make -j8
#安装glibc-2.18
sudo make install

参考资料

解决'GLIBC_2.14' not found问题时遇到的坑

参考链接

参考资料

# relocation error: /usr/lib64/libc.so.6: symbol _dl_starting_up, version GLIBC_PRIVATE not define