背景
今天安装某个npm库,但是安装失败了。日志里看看到是安装leveldown包失败了,于是单独安装leveldown进行测试。
问题排查
[duser@hy-docker02 tmp]$ npm i leveldown
> leveldown@5.6.0 install /tmp/node_modules/leveldown
> node-gyp-build
make: Entering directory `/tmp/node_modules/leveldown/build'
CXX(target) Release/obj.target/leveldb/deps/leveldb/leveldb-1.20/db/builder.o
cc1plus: error: unrecognized command line option "-std=gnu++1y"
make: *** [Release/obj.target/leveldb/deps/leveldb/leveldb-1.20/db/builder.o] Error 1
make: Leaving directory `/tmp/node_modules/leveldown/build'
从cc1plus: error: unrecognized command line option "-std=gnu++1y"
可以看出是调用g++编译时使用了不支持的参数。
因为另外有台机器(机器B)是可以将这个库安装成功的,所以我到那台机器执行 g++ -std=gnu++1y 1.c
,但也是报一样的错误。并且这台机器的g++版本和我失败的那台是一致的,甚至操作系统版本也比较低。为什么机器B能够安装成功呢,一时想不出头绪来。
到安装成功的node_module/leveldown/里看了下,有个prebuilds目录引起了我的注意,发现里边放了各主流平台的预编译好的文件。再结合README,里边说了,如果预编译好的文件不存在(应该还做了检查)才会 fallback to a compile step
。
这就能够解释为什么同样的g++版本,机器B能够成功安装了。大概就是机器B使用了预编译库,没有触发重新编译。
从github下载源码,打算跟踪下为什么当前机器没有用预编译好的包。下载后发现package.json文件有个test-prebuild
命令用于测试预编译包。于是先npm install先安装一些包,然后执行download-prebuilds
把编译好的包先下载下来。
[duser@hy-docker02 /tmp/foamzou/leveldown-master]$ npm run test-prebuild
> leveldown@5.6.0 test-prebuild /tmp/foamzou/leveldown-master
> cross-env PREBUILDS_ONLY=1 npm t
> leveldown@5.6.0 test /tmp/foamzou/leveldown-master
> standard && (nyc -s tape test/*-test.js | faucet) && nyc report
standard: Node 10.12.0 or greater is required. `standard` did not run.
module.js:664
return process.dlopen(module, path._makeLong(filename));
^
Error: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /tmp/foamzou/leveldown-master/prebuilds/linux-x64/node.napi.glibc.node)
at Object.Module._extensions..node (module.js:664:18)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Module.require (module.js:579:17)
at require (internal/module.js:11:18)
at load (/tmp/foamzou/leveldown-master/node_modules/node-gyp-build/index.js:21:10)
at Object.<anonymous> (/tmp/foamzou/leveldown-master/binding.js:2:153)
at Module._compile (module.js:635:30)
at Module.replacementCompile (/tmp/foamzou/leveldown-master/node_modules/append-transform/index.js:60:13)
然后发现上面这个GLIBC_2.14' not found
,原来是glibc的问题。执行 strings /lib64/libc.so.6|grep GLIBC
查看本机glibc版本,最高到GLIBC_2.12,而机器B是GLIBC_2.17。所以接下来升级glibc即可。由于是测试机器,并且版本更新不大,不是很担心升级后大量软件挂掉的问题。
安装Glibc2.17
wget http://ftp.gnu.org/pub/gnu/glibc/glibc-2.17.tar.gz
tar -zxvf glibc-2.17.tar.gz
cd glibc-2.17
mkdir build
cd build
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
make
sudo make install
执行 strings /lib64/libc.so.6|grep GLIBC
。OK,看到2.17了
问题解决
再次尝试 npm i leveldown
,成功安装,至此问题解决。