centos7安装node-v18版本真是难呢
背景
背景就是上一篇文章提到的,部署gitbook这个文档中心的话,是需要先安装node,然后,如果你的node版本过高的话,一般会报错,此时,网上很多文章就是降node版本解决,但其实用高版本也是有办法的,只是麻烦点,要改改代码;但是,我下载了高版本的node安装时,发现在centos7上还装不了,可谓一波未平一波又起。
报错的nodejs版本:v18,我这边具体的是node-v18.18.2-linux-x64.tar.xz
服务器版本是centos 7.6,centos 7.9(两个都试了)
下面这个问题可以看下:

https://github.com/nodejs/node/issues/43246
吵得还是挺厉害。我觉得也是比较坑的是,下载的时候,文档也没个提示,比如是否在centos7上可用,等到弄下来搞出一堆问题了上网去找才知道版本不兼容。
下面具体说下这个问题。
问题原因分析
tar -xvf node-v18.18.2-linux-x64.tar.xz
cd node-v18.18.2-linux-x64/
[root@VM-0-6-centos node-v18.18.2-linux-x64]# bin/node
bin/node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by bin/node)
bin/node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by bin/node)
bin/node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by bin/node)
bin/node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by bin/node)
bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by bin/node)
bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by bin/node)
这个报错,是这个意思,node在执行的时候,是依赖了一些动态库的,依赖了哪些呢:
[root@VM-0-6-centos node-v18.18.2-linux-x64]# ldd bin/node
linux-vdso.so.1 => (0x00007fff34927000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fd57af20000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fd57ac19000)
libm.so.6 => /lib64/libm.so.6 (0x00007fd57a917000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd57a701000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd57a4e5000)
libc.so.6 => /lib64/libc.so.6 (0x00007fd57a117000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd57b124000)
在 => 这个符号左侧,就是依赖的动态库名字,右侧,就是根据这个名字,在环境变量LD_LIBRARY_PATH指定的路径下查找,最终解析到的动态库全路径。
那我们再来看第一行报错:
[root@VM-0-6-centos node-v18.18.2-linux-x64]# bin/node
bin/node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by bin/node)
/lib64/libm.so.6这个是全路径,看起来找到了,但是还是报错,好像说要在GLIBC_2.27这个版本没找到。
我们可以这样,在执行ldd时打个详细日志:
[root@VM-0-6-centos]# ldd -v bin/node
Version information:
bin/node:
...
libm.so.6 (GLIBC_2.27) => not found
libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6
看起来,它是找libm.so.6(GLIBC_2.27)没找到,但找到了libm.so.6 (GLIBC_2.2.5)。
这块其实是这样,内核提供给用户的是系统调用(system call),但是,在我们编写c语言代码时,一般不是直接去调用这些系统调用,而是会include一些头文件,如include <stdio.h>,这些头文件算是接口,这些接口包括其实现,最终编译成二进制打成一个库,供用户使用。最早是标准的libc库,后来逐渐被glibc这个取代,glibc是GNU发布的libc库,官网:https://www.gnu.org/software/libc/libc.html
这个glibc库,比如在我的centos7.6上,到底在啥位置呢?
我先看了下本机的glibc版本是2.17:
https://lindevs.com/check-glibc-version-in-linux
方法1:
[root@VM-0-6-centos lib64]# ldd --version
ldd (GNU libc) 2.17
方法2:
[root@VM-0-6-centos lib64]# ldd `which cat` | grep libc
libc.so.6 => /lib64/libc.so.6 (0x00007f27331c8000)
[root@VM-0-6-centos lib64]# /lib64/libc.so.6
GNU C Library (GNU libc) stable release version 2.17, by Roland McGrath et al.
glibc一般也是有rpm包的,我在这个网站上找到了2.17版本的x86-64的glibc的包:
可以看到,它其实包含了非常多文件,其中就有/lib64/libm.so.6:

那我意思其实就是,/lib64/libm.so.6就是glibc的一部分,那这个2.17版本的glibc,包含的/lib64/libm.so.6报的这个错到底啥意思啊?
[root@VM-0-6-centos]# ldd -v bin/node
Version information:
bin/node:
...
libm.so.6 (GLIBC_2.27) => not found
libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6
我找到了一个绝好的回答:
GLIBC_..., GLIBCXX_... etc. are version symbols, which are used in some libraries (including the GNU C library and the GCC libraries) to identify required versions and to manage backward compatibility. A binary (executable or library) will usually end up requiring multiple versions, based on the symbols it really uses from the target library. To satisfy the requirements of a given binary, you need to provide a library which supports all the required versions — i.e. a library matching at least the highest version symbol in the list of requirements.
翻译过来是,GLIBC_...等GLIBCXX_...是版本符号,在某些库(包括GNU C库和GCC库)中使用它们来标识所需的版本并管理向后兼容性。二进制文件(可执行文件或库)通常最终需要多个版本,具体取决于它实际使用的目标库中的符号。为了满足给定二进制文件的要求,您需要提供一个支持所有所需版本的库 -即至少匹配要求列表中最高版本符号的库。
The reason multiple versions can end up being required, is that each imported object (function etc.) can have a version, and a given binary can link against multiple versions across all the functions it uses.
翻译:最终可能需要多个版本的原因是每个导入的对象(函数等)都可以有一个版本,并且给定的二进制文件可以链接到它使用的所有函数的多个版本。
我这里也只截取了一部分,大家还是去看原文吧,反正意思就是,比如node这个程序,它就是会用到/lib64/libm.so.6里面不同version symbol的函数,你需要做的,就是满足它,否则,它就报错。
怎么满足它呢,就是把/lib64/libm.so.6的版本升上去,直到包含GLIBC_2.27这个version symbol。
那怎么才能升/lib64/libm.so.6上去呢,那它既然是glibc的一部分,自然是只能整体升级glibc到指定版本,比如这里的GLIBC_2.27。
解决-升级GLIBC
这里参考了文章:
https://mp.weixin.qq.com/s/Xhm_BmMH2EoVWMPRWfCnaw
跟我遇到的坑差不多。文章里1、安装编译环境devtoolset-8那部分应该不需要特别关注,我觉得也不用操作,因为这种偷懒方式安装的gcc,是解决不了node安装报错的问题的,往下看就知道了。
开始升级glibc,值得注意的是,大家最好是虚拟机、个人的云主机先玩一玩,不要拿着有其他人在用的环境搞这些,很容易把机器彻底搞到不能收场的地步;玩之前也记得备份,比如先复制一个虚拟机出去
慢的话,可以自己手动下载再上传
wget https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz --no-check-certificate
tar -xzvf glibc-2.28.tar.gz
cd glibc-2.28
mkdir build && cd build (一定要单独建个文件夹来build)
在编译开始前,修改 scripts/test-installation.pl 128行,增加 && $name ne "nss_test2" ,以避免编译错误 nss_test2报错,反正就是照着加一行。
接下来,是configure命令,尤其注意加--enable-obsolete-nsl,解决undefined reference to '_nsl_default_nss@GLIBC_PRIVATE' ,其他选项用他文章的也行,我的那个命令搞丢了(虚拟机后来搞别的搞坏了)
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin --enable-obsolete-nsl
然后就是:
make 或者 make -j4 (4个线程并发跑)
我记得我这边大概耗时半小时或一小时内,忘了,还是虚拟机这种性能差的
make install
检查里面的version symbol:
strings /lib64/libc.so.6 | grep GLIBC
解决gcc问题--升级gcc
解决上面的问题后,继续执行node,还是报错,大概如下:
bin/node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by bin/node)
bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by bin/node)
bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by bin/node)
查看这个里面的symbol version,最新到1.3.7,不满足1.3.9的要求:
[root@VM-0-6-centos node-v18.18.2-linux-x64]# strings /lib64/libstdc++.so.6 |grep CXXABI_
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.2
CXXABI_1.3.3
CXXABI_1.3.4
CXXABI_1.3.5
CXXABI_1.3.6
CXXABI_1.3.7
最新到3.4.19,不满足3.4.20和3.4.21的要求:
[root@VM-0-6-centos node-v18.18.2-linux-x64]# strings /lib64/libstdc++.so.6 |grep GLIBCXX
...
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
按照官方文档来的:
https://gcc.gnu.org/wiki/InstallingGCC
安装gcc前,需要先安装依赖的gmp-devel mpfr-devel libmpc-devel,好多文章是说yum安装,我觉得也可以,但我就怕gcc版本和yum安装的这些依赖的版本不太匹配,建议还是按照如下方式来安装:
wget https://ftp.gnu.org/gnu/gcc/gcc-8.5.0/gcc-8.5.0.tar.gz --no-check-certificate
cd gcc-8.5.0
./contrib/download_prerequisites
这一步就会去下载对应的源码,需要互联网:
[root@VM-0-6-centos gcc-8.5.0]# ./contrib/download_prerequisites
2023-10-22 15:40:49 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 [2383840] -> "./gmp-6.1.0.tar.bz2" [1]
2023-10-22 15:42:05 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2 [1279284] -> "./mpfr-3.1.4.tar.bz2" [1]
2023-10-22 15:42:42 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz [669925] -> "./mpc-1.0.3.tar.gz" [1]
2023-10-22 15:44:31 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2 [1658291] -> "./isl-0.18.tar.bz2" [1]
gmp-6.1.0.tar.bz2: OK
mpfr-3.1.4.tar.bz2: OK
mpc-1.0.3.tar.gz: OK
isl-0.18.tar.bz2: OK
All prerequisites downloaded successfully.
下完后,就保存到了当前目录下,几个tar包。
mkdir build
cd build/
我是不需要gcc支持编译go,需要的话,可以加上
../configure --disable-multilib --enable-languages=c,c++ --prefix=$HOME/local
接下来就是make,我一开始求快,搞得是:
nohup make -j4 2>&1 &
结果后面等了好久,报错了。。。抱着试试看心理,改成make,结果成功了
nohup make 2>&1 &
tailf nohup.out
make install
export LD_LIBRARY_PATH=$HOME/local/lib64
这里这个make,要执行很久很久,反正我的云主机是这样,1核2g,cpu一直是100%,跑了2个半小时:

从4点20:

跑到6点40了:

搞完这些,再去用node,应该就没啥问题了。哎,你说你官网文档,就不能好好提示下我,支持centos7的最新版本是哪个,搞到一半报错,然后一个版本一个版本地往下降,直到不报错,网上社区也是一堆吐槽,服。
centos7安装node-v18版本真是难呢的更多相关文章
- centos7安装node
centos7安装node 二进制文件安装 node=v10.13.0 file=node-${node}-linux-x64 wget https://nodejs.org/dist/${node} ...
- centos7安装较高版本python3.5/3.6
应用环境: Centos7或者RHEL7下默认安装的python版本为2.7.x,更新不够及时,现在很多时候需要额外安装较高版本的python环境, 网上搜罗一圈总结记录一下常用两种方式: ① 源码编 ...
- centos7 安装gitlab任意版本
主要还是根据官网:https://www.gitlab.cc/installation/#centos-7 1.安装依赖: sudo yum install curl policycoreutils ...
- centos7 安装Node.js并配置为全局可用
本文Node.js版本为5.12.0,登录 https://nodejs.org/dist/v5.12.0/,需指定其他版本的话可以直接修改版本号进行登录. 为了方便使用tar命令对文件进行解压,我们 ...
- CentOS7 安装 Node.js
1.首先安装node.js 的版本管理工具 NVM,执行以下命令: curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/ ...
- linux服务器CentOS7安装node.js
方维一元夺宝2.0版本,很多用户面临机器人自动执行任务.采集计划一直无法开启的问题. 这个需要开启node.js分享给大家. 1.获取node.js资源 V5.x: curl --silent --l ...
- Centos7 安装node(8版本)
最简洁的命令 yum -y update yum -y install gcc make gcc-c++ openssl-devel wget vim(后面两个如果没有再选择安装) cd /usr/l ...
- centos7安装node.js
安装版本:node-v10.15.3 一.安装必要的编译软件包 # yum install gcc gcc-c++ -y 二.从源码下载Nodejs 进入官网选择自己需要的版本 https://nod ...
- centos7 安装 mysql5.7 版本(全)
centos 安装 版本说明 :centos7,mysql5.7 ,不是 centos7 可能有些命令不兼容 安装 mysql-server # 下载并安装 mysql yum wget -i -c ...
- Linux Centos7安装Oracle12c第二版本
环境: CentOS7@VMware12,分配资源:CPU:2颗,内存:4GB,硬盘空间:30GB Oracle12C企业版64位 下载地址:http://www.oracle.com/technet ...
随机推荐
- Python copy & deeocopy 探究
简单来说,copy 复制创建新的容器,而引用容器内元素的地址不变.而 deepcopy 也对容器内的容器元素进行复制. 但是这种复制具体是什么体现呢?是否只是对第一层容器元素进行了复制?写了一段代码验 ...
- 4.5 x64dbg 探索钩子劫持技术
钩子劫持技术是计算机编程中的一种技术,它们可以让开发者拦截系统函数或应用程序函数的调用,并在函数调用前或调用后执行自定义代码,钩子劫持技术通常用于病毒和恶意软件,也可以让开发者扩展或修改系统函数的功能 ...
- Python中 sys.argv[]用法详解
sys.argv[0]表示代码本身文件路径. sys.argv[]是一个从程序外部获取参数的桥梁,从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一 ...
- Code Generate V2.0 代码生成器
Code Generate 代码生成器 系统首页 使用说明 系统默认会根据SQL生成字段信息 className.fieldList.classComment 如下所示: 建表语句 CREATE TA ...
- 《最新出炉》系列入门篇-Python+Playwright自动化测试-7-浏览器的相关操作
1.简介 上一篇已经将playwright的元素定位大法基本介绍的差不多了,但是在Web的UI自动化的测试中,我们通常需要使用一些方法来操作浏览器,今天就跟随学习了解一下.这一篇宏哥主要是介绍一下,在 ...
- [译]使用Python和Dash 创建一个仪表盘(上)
介绍 在数据科学和分析的领域,数据能力的释放不仅是通过提取见解的方式, 同时也要能通过有效的方式来传达见解.这就是数据可视化发挥见解的地方. 数据可视化是信息和数据的可视化呈现. 它使用可视化元素,如 ...
- kafka分区分配策略
前言 现有主流消息中间件都是生产者-消费者模型,主要角色都是:Producer -> Broker -> Consumer,上手起来非常简单,但仍有需要知识点需要我们关注,才能避免一些错误 ...
- ubuntu server安装图形化界面
只需一个命令,然后重启即可: # apt-get install ubuntu-desktop # 查看下一次启动的设置 systemctl get-default # reboot
- React: 路由重定向
解决方案 参考链接 https://v5.reactrouter.com/web/example/route-config
- 华为ensp配置静态路由,三路由,三pc
华为ensp配置静态路由 目的:使pc1,pc2,pc3能相互ping通 1,tuop图的搭建 1,如图所示:先搭建好设备的通讯关系,在标记好每台设备对应的,ip地址和网关. 2,pc的网关,与ip地 ...