環境
- Ubuntu 18.04
- Nodejs18
問題
Ubuntu 18.04にNodejs18がインストールしようとしたが、エラーでインストールできない。
# apt install nodejs Reading package lists... Done Building dependency tree Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: nodejs : Depends: libc6 (>= 2.28) but 2.27-3ubuntu1.6 is to be installed E: Unable to correct problems, you have held broken packages.
調べてみるとそもそも公式サイトでも対応してないとのこと。 Ubuntu 18.04なら同じバージョン対応してくれよ
で、なんとかしてインストールしたい
原因
Ubuntu 18.04の標準glibcはバージョン2.27だ。Node.js 18はglibc 2.28以上を要求する。つまり、システムのglibcが古すぎてNode.js 18が依存する関数が無いからエラーになる。
dpkg -l | grep libc6 ii libc6:amd64 2.27-3ubuntu1.6 amd64 GNU C Library: Shared libraries
手順
glibcのバージョンが古いため、新しいNode.jsが要求するライブラリ関数が見つからないというエラーが出ている。パッチを当ててNode.jsがそれを使えるように設定する必要がある。
aptでは依存解決上インストールできないのでまずはnodenv等で無理矢理バイナリインストールする。ここでは割愛する。
もちろん当然エラーになって実行できない。これを修正していく。
$ node -v /root/.nodenv/versions/18.20.4/bin/node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by /root/.nodenv/versions/18.20.4/bin/node)
必要なパッケージのインストール
apt install gawk patchelf bison build-essential
gawk
: GNU Awkのことで、テキスト処理に使う強力なツール。glibcのビルドプロセスの一部で使われている。patchelf
: ELF形式の実行ファイルのヘッダ情報を変更するためのツール。今回は新しくインストールしたglibcを使うようにNode.jsのバイナリを修正するために必要。bison
: パーサジェネレータ。glibcのビルドに使われている。build-essential
: 多くのソフトウェアをビルドするのに必要なパッケージ群。gcc, makeなど基本的なツールが含まれている。
curl -O https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz tar zxf glibc-2.28.tar.gz cd glibc-2.28 mkdir glibc-build cd glibc-build ../configure --prefix=/opt/glibc-2.28
いざビルド めちゃくちゃ時間かかるので注意
make -j
make install
patchelfコマンドでNode.jsバイナリを修正する。
patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ ~/.nodenv/versions/18.20.4/bin/node
--set-interpreter
オプションで、Node.jsが使用するインタプリタ(動的リンカ)を新しくインストールしたglibcのものに設定する。--set-rpath
オプションで、Node.jsがライブラリを検索するパスを指定する。これにより、Node.jsはシステムの古いglibcではなく、新しくインストールしたglibcを使うようになる。
これで無事にNodejs18が実行できるようになる。
$ node -v v18.20.4
当然npmなどのコマンドも実行できるようになってる。
$ npm -v 10.7.0 $ npx -v 10.7.0