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://stackoverflow.com/questions/72571235/can-i-install-node-js-18-on-centos-7-and-do-i-need-python-3-install-too#:~:text=Starting v18%2C Node.,due to glibc version incompatibility.

image-20231024213204595

NodeJS 18 revert to building on CentOS 7, RHEL 7, Ubuntu Bionic 18.04, other other LTS distros · Issue #43246 · nodejs/node · GitHub

吵得还是挺厉害。我觉得也是比较坑的是,下载的时候,文档也没个提示,比如是否在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库,官网:The GNU C Library- GNU Project - Free Software Foundation

这个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的包:

glibc-2.17-326.el7_9.x86_64 RPM

可以看到,它其实包含了非常多文件,其中就有/lib64/libm.so.6:

image-20231025220044115

那我意思其实就是,/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 

我找到了一个绝好的回答:

shared library - What do the multiple GLIBC versions mean in the output of ldd? - Unix & Linux Stack Exchange

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#

这里参考了文章:

【我用鲲鹏做开发】CentOS7安装NodeJS18

跟我遇到的坑差不多。文章里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 

按照官方文档来的:

InstallingGCC - GCC Wiki

安装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个半小时:

image-20231025225356657

从4点20:

image-20231025225415970

跑到6点40了:

image-20231025225433610

搞完这些,再去用node,应该就没啥问题了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/253936.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何做搜索?如何做搜索优化?如何在搜索领域快速成长?

三年多的搜索研发经历&#xff0c;万亿级集群管理经历&#xff0c;集群优化搜索优化经历。将生产环境的集群&#xff0c;检索性能提升了数十倍。也遇到过大大小小的生产事故。在工作中有幸能够得到前谷歌中国首席架构陈老师的指导。在搜索方面&#xff0c;自己也积累了蛮多的经…

最具挑战的骑行路线

1&#xff0c;318川藏线 2&#xff0c;独库公路 - 561公里 3&#xff0c;珠峰尼泊尔 1000公里 4&#xff0c;沙漠公路 1800公里 5&#xff0c;219新藏线 2500公里 下面是一些别人的骑行记录、证书或奖牌。 参考&#xff1a; 1&#xff0c;抖音 - Max骑行玩家 https://v.douy…

链路聚合 (hcia)

原理 采用链路聚合技术可以在不进行硬件升级的条件下&#xff0c;通过将多个物理接口捆绑为一个逻辑接 口&#xff0c;达到增加链路带宽的目的。在实现增大带宽目的的同时&#xff0c;链路聚合采用备份链路的机制&#xff0c; 可以有效的提高设备之间链路的可靠性 &#x…

Chrome2023新版收藏栏UI改回旧版

版本 120.0.6099.109&#xff08;正式版本&#xff09;Chrome浏览器菜单新版、旧版的差异 想要将书签、功能内容改回旧版的朋友可以网址栏输入&#xff1a;「chrome://flags」&#xff0c;接着搜寻「Chrome Refresh 2023」。 最后将 Chrome Refresh 2023、Chrome Refresh 2023…

如何使用JavaScript 将数据网格绑定到 GraphQL 服务

前言 作为一名前端开发人员&#xff0c;GraphQL对于我们来说是令人难以置信的好用。它可以用来简化数据访问&#xff0c;这让我们的工作变得更加容易。 什么是 GraphQL&#xff1f;它是一个抽象层&#xff0c;位于任意数量的数据源之上&#xff0c;并为您提供一个简单的 API …

学网安:先来学学Python之Excel

在 Python 中&#xff0c;exec 是一个内置函数&#xff0c;允许在运行时动态执行 Python 代码。虽然 exec 的使用需要谨慎&#xff0c;因为它可以导致安全问题和难以调试的代码&#xff0c;但它也提供了一些非常强大的功能。 本文将详细介绍 Python exec 函数的高级用法&#…

GZ015 机器人系统集成应用技术样题5-学生赛

2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书&#xff08;学生赛&#xff09; 样题5 选手须知&#xff1a; 本任务书共 24页&#xff0c;如出现任务书缺页、字迹不清等问题&#xff0c;请及时向裁判示意&#xff0c;并进行任务书的更换。参赛队…

基于linux系统的Tomcat+Mysql+Jdk环境搭建(一)vmare centos7 设置静态ip和连接MobaXterm

特别注意&#xff0c;Windows10以上版本操作系统需要下载安装VMware Workstation Pro16及以上版本&#xff0c;安装方式此处略。 (可忽略 my*** 记录设置的vamare centos7 账号root/aaa 密码&#xff1a;Aa123456 ) 1、命令行和图形界面切换 如果使用的是VMware虚拟机&…

Activiti工作流框架学习笔记(一)之通用数据表详细介绍

文/朱季谦 Activiti工作流引擎自带了一套数据库表&#xff0c;这里面有一个需要注意的地方&#xff1a; 低于5.6.4的MySQL版本不支持时间戳或毫秒级的日期。更糟糕的是&#xff0c;某些版本在尝试创建此类列时将引发异常&#xff0c;而其他版本则不会。执行自动创建/升级时&a…

C/C++ STL提供的关联式容器之unordered_set

unordered_set 容器&#xff0c;直译为[无序set容器]。 unordered_set容器和set容器很像&#xff0c;唯一的区别就在于 set 容器会自行对存储的数据进行排序&#xff0c;而unordered_set容器不会。 unordered_set的几个特性&#xff1a; 1. 不再以键值对的形式存储数据&#x…

数据科学知识库

​ 我的博客是一个技术分享平台&#xff0c;涵盖了机器学习、数据可视化、大数据分析、数学统计学、推荐算法、Linux命令及环境搭建&#xff0c;以及Kafka、Flask、FastAPI、Docker等组件的使用教程。 在这个信息时代&#xff0c;数据已经成为了一种新的资源&#xff0c;而机…

基于.NetCore开发评论系统(转)

博客前台以及后端涉及的代码主要在以下文件&#xff1a; StarBlog.Web/Services/CommentService.csStarBlog.Web/Apis/Comments/CommentController.csStarBlog.Web/Views/Blog/Widgets/Comment.cshtmlStarBlog.Web/wwwroot/js/comment.js 管理后台的代码在以下文件&#xff1…

Linux学习教程(第十三章 Linux数据备份与恢复)

第十三章 Linux数据备份与恢复 不知道大家有没有丢失过重要的数据呢&#xff1f; 丢失数据的理由是多种多样的&#xff0c;有人是因为重装系统时&#xff0c;没有把加密文件的密钥导出&#xff0c;重装系统后密钥丢失&#xff0c;导致所有的加密数据不能解密&#xff1b;也有人…

C语言—小小圣诞树

这个代码会询问用户输入圣诞树的高度&#xff0c;然后根据输入的高度在控制台上显示相应高度的圣诞树。 #include <stdio.h>int main() {int height, spaces, stars;printf("请输入圣诞树的高度: ");scanf("%d", &height);spaces height - 1;st…

使用Halcon实现模板匹配

图片: 代码: read_image (Image, C:/Users/14348/Desktop/mobanpipei.jpg) get_image_size (Image, Width, Height) dev_close_window() dev_open_window (0, 0, Width, Height, black, WindowHandle) dev_display (Image) draw_rectangle1 (WindowHandle, Row1, Column1, Ro…

字符设备驱动框架的编写

一. 简介 我们在学习裸机或者 STM32 的时候关于驱动的开发就是初始化相应的外设寄存器&#xff0c;在 Linux 驱动开发中&#xff0c;肯定也是要初始化相应的外设寄存器。 只是在 Linux 驱动开发中&#xff0c; 我们需要按照其规定的框架来编写驱动&#xff0c;所以说学 …

Docker介绍,Docker安装

docker镜像仓库官网 一、Docker的基本概念 1.Docker的三大核心组件 docker 镜像 --------docker images docker 仓库---------docker registeries docker 容器---------docker containers 2.Docker 镜像 Docker镜像是运行docker容器时的只读模板&#xff0c;每一个镜像由一…

设计模式——迭代器模式

引言 迭代器模式是一种行为设计模式&#xff0c; 让你能在不暴露集合底层表现形式 &#xff08;列表、 栈和树等&#xff09; 的情况下遍历集合中所有的元素。 问题 集合是编程中最常使用的数据类型之一。 尽管如此&#xff0c; 集合只是一组对象的容器而已。 大部分集合使用…

springboot221酒店管理系统

springboot221酒店管理系统 源码获取&#xff1a; https://docs.qq.com/doc/DUXdsVlhIdVlsemdX

CentOS7安装教程

1.准备工作 安装虚拟机软件 VMware Workstation 17 Player下载CentOS7 镜像 2. 安装VMware Workstation 17 Player 官网 下载链接 下载好了安装包&#xff0c;双击安装包&#xff0c;傻瓜式安装一直下一步&#xff0c;安装即可。 3. 安装CentOS7 官网 推荐下载地址&…
最新文章