$ uname -a
Linux ****** 4.4.184.alpine.1 #1 SMP Thu Sep 5 02:32:14 UTC 2019 armv7l GNU/Linux
armv71.CPUの分類が判ったので、
公式サイトからArmV71用をダウンロード。
インストール方法を見ながら、やってみたものの。結果は
# node
-bash: /usr/local/lib/nodejs/node-v12.13.0-linux-armv7l/bin/node: No such file or directory
Ubuntu(for Armv7l)のリポジトリィを漁ってみると
# apt-get update
# apt-get install nodejs npm
# nodejs -v
v0.10.29
さすがにコレは古いが、開発キットをインストしてみると、
# apt-get install build-essential
# gcc --version
gcc (Debian 4.9.2-10+deb8u2) 4.9.2
# g++ --version
g++ (Debian 4.9.2-10+deb8u2) 4.9.2
# make --version
GNU Make 4.0
# apt-get install openjdk*
# java -version
java version "1.7.0_231"
# python --version ※これは管理画面からインスト
Python 2.7.9
32ビットCPUなんで全てが古いらしい。
Node.jsのソースからビルドする際に要求に
gcc
and g++
>= 6.3 or newer, or
があるので致命的。
しかも、ie同様にarrow関数が使えないから全部function()で書かないといけないのは辛いので「パッケージマネージャを利用した Node.js のインストール」から「 Node.js 公式のバイナリディストリビューション 」の「Manual installation」を読んでみたが失敗。
armel で、引っかかってしまう。
Available architectures: を見ると未サポートで、
ラズパイの様にarmhf(ハードウェアFPU付)だったら良かったらしい。
キモは、
export でCCFLAGSとCXXFLAGSを指定することだった。
Rasbery-Pi/Zeroなら
# export CCFLAGS='-march=armv6'
# export CXXFLAGS='-march=armv6'
とするらしい。
gccが9.2.0でもコレは同じ。
しかし、ReadyNAS212のCPUは ARM Cortex A15。
Wikiによれば、
ファミリー : Cortex-A
アーキテクチャ: v7-A
コア : Cortex A15
と云うことで、
こんぱいらの ターゲットアーキテクチャの指定 から
CCFLAGSは、 ‘-march=armv7-a’ なのだそうだ。
Node.jsのコミュニティを眺めてたら、
ん~な古いCPUの需要あるの?あるならやるかも。と、書いてあったので、
新しいVerで試してみた。
※wgetしたので、git-coreは要らない。
なお、コンパイルに要した時間は3時間を超えており、make install もログが長い。
最終的にはこれでOK。
$ sudo apt-get install git-core build-essential libssl-dev
$ # sudo wget https://nodejs.org/dist/v12.13.1/node-v12.13.1.tar.gz
$ # sudo tar xvzf node-v12.13.1.tar.gz
$ # cd node-v12.13.1
$ sudo wget https://nodejs.org/dist/v12.18.3/node-v12.18.3.tar.gz
$ sudo tar xvzf node-v12.18.3.tar.gz
$ cd node-v12.18.3
$ export CCFLAGS='-march=armv7-a'
$ export CXXFLAGS='-march=armv7-a'
$ sudo -E ./configure
$ sudo -E make -j8
$ sudo -E make install
$ node --version
v12.13.1
$ npm --version
6.12.1
-j8は8スレッド使用かな?付けない時よりはログの流れが速いし、topコマンドで見る限り、指定有:97%、無:24%。8コアじゃないから-j4で十分。
かかった時間も 指定有:1時間半、無:3時間だから -j2で良かったかも。
以下は、トラブル履歴。
トラブル 1.一般ユーザからsudoを使ってビルドすると古いgccが使われてしまう。
-Eを付けてもPATHだけは置き換えられてしまうので、
/etc/sudoers のパスに/usr/local/gcc-9.2.0/binを追加。
# cd node-v12.13.1
# ./configure ※要python
WARNING: C++ compiler too old, need g++ 6.3.0 or clang++ 8.0.0 (CXX=g++)
INFO: Using floating patch "tools/icu/patches/64/source/common/putil.cpp" from "tools/icu"
INFO: Using floating patch "tools/icu/patches/64/source/i18n/dtptngen.cpp" from "tools/icu"
WARNING: warnings were emitted in the configure phase
INFO: configure completed successfully
※gcc 9.2.0の場合
INFO: Using floating patch "tools/icu/patches/64/source/common/putil.cpp" from "tools/icu"
INFO: Using floating patch "tools/icu/patches/64/source/i18n/dtptngen.cpp" from "tools/icu"
INFO: configure completed successfully
しかし、うまくいかない。
Error: selected processor does not support ARM mode `bkpt 0'
この直後にrootでログインしても
libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by
apt-get install libstdc++6
はインスト済みだが、リポジトリィのものはかなり古いようだ。
gcc-9.2.0のターゲットは /usr/local/gcc-9.2.0 だったので、
export LD_LIBRARY_PATH=/usr/local/gcc-9.2.0/lib:$LD_LIBRARY_PATH
でやり過ごそうとしたが
無駄。
やはり古いのを見てしまう。
というか仕様になっていた。
一般のユーザの~/.bash_profileなどに書くとうまくいく場合もあるらしいが
$ echo $LD_LIBRARY_PATH
/usr/local/gcc-9.2.0/lib:
トラブル2. LD_LIBRARY_PATH は効かない。
LD_LIBRARY_PATHが空っぽの時点で察する必要があった。
このNASのLinuxでは、LD_LIBRARY_PATH環境変数は一般の環境変数でしかないのだった。
どうやら、ldconfigの出番の様だ。gcc-9.2.0と心中するつもりで取り掛かるしかないのだ。
しかし、今は/etc/ld.so.confに直書きするのではなく、
/etc/ld.so.conf.dにgcc-9.2.9.confを追加するのが通らしい。
# gcc-9.2.0 configuration
/usr/local/gcc-9.2.0/lib
そして、共有ライブラリィのリンクを入れ替える
# ldconfig
/sbin/ldconfig.real: /usr/local/gcc-9.2.0/lib/libstdc++.so.6.0.27-gdb.py is not an ELF file - it has the wrong magic bytes at the start.
/sbin/ldconfig.real: /usr/lib/libreadycloud.so.1 is not a symbolic link
これでも、
$ sudo -E ldconfig -p | grep libstdc++.so.6
libstdc++.so.6 (libc6,soft-float) => /usr/lib/arm-linux-gnueabi/libstdc++.so.6
libstdc++.so.6 (libc6,soft-float) => /usr/local/gcc-9.2.0/lib/libstdc++.so.6
となって古いものを見てしまう。
/etc/ld.so.conf の中身が
include /etc/ld.so.conf.d/*.conf
なので、arm-linux-gnueabi.conf より文字コードが前になりそうな
__ gcc-9.2.9.conf に名を変えたが無駄足で、
結局 ls -l /etc/ld.so.conf.d/*.conf の結果 を見ながらファイル名を変えて、
arm-gcc-9.2.9.conf が正解!
奥が深いというより、
デフォのgccのファイル名が linux-gnueabi.conf ならOKだが、
arm- linux-gnueabi.conf なら誰もが失敗する。
こんな設定ファイルの読込み順で、共有ライブラリィのパスが決まるのって
間抜けとしか云いようがない
否、今は
include *****/*.conf
が普通なのだから、昨今のlinuxのノウハウの半分を占めている可能性が高い。
※とっても低レベルだが、
決して、侮れないノウハウだ。
ファイル名を linux-arm-gnueabi.conf に変えるだけで誰もが幸せになれるのにね?でも、ダレもそんなことはしないのが世の常。
$ sudo -E ldconfig -p | grep libstdc++.so.6
libstdc++.so.6 (libc6,soft-float) => /usr/local/gcc-9.2.0/lib/libstdc++.so.6
libstdc++.so.6 (libc6,soft-float) => /usr/lib/arm-linux-gnueabi/libstdc++.so.6
とりあえず、バイトコード生成をコメントアウトしなくて済むようになったので、リモートデバッグもできるようになるだろう。
※ソースをNFSの共有フォルダに配置しなければいけない問題はあるけど。
そして、長いコンパイルはまだまだ3時間くらい続くはずだ。
sudo make test
=== release test-perf-hooks ===
Path: sequential/test-perf-hooks
{
name: 'node',
entryType: 'node',
startTime: 0,
duration: { around: 144.90792298316956 },
nodeStart: { around: 0 },
v8Start: { around: 0 },
bootstrapComplete: { around: 135.9222869873047, delay: 2500 },
environment: { around: 0 },
loopStart: -1,
loopExit: -1
}
{
name: 'node',
entryType: 'node',
startTime: 0,
duration: { around: 1163.1746279895306 },
nodeStart: { around: 0 },
v8Start: { around: 0 },
bootstrapComplete: { around: 135.9222869873047, delay: 2500 },
environment: { around: 0 },
loopStart: { around: 135.9222869873047, delay: 2500 },
loopExit: -1
}
{
name: 'node',
entryType: 'node',
startTime: 0,
duration: { around: 1165.5776199996471 },
nodeStart: { around: 0 },
v8Start: { around: 0 },
bootstrapComplete: { around: 135.9222869873047, delay: 2500 },
environment: { around: 0 },
loopStart: { around: 135.9222869873047, delay: 2500 },
loopExit: { around: 1165.6191799938679 }
}
assert.js:374
throw err;
^
AssertionError [ERR_ASSERTION]: duration: 389.13076999783516 >= 250
at checkNodeTiming (/home/****/node-v12.13.1/test/sequential/test-perf-hooks.js:67:7)
at process.<anonymous> (/home/****/node-v12.13.1/test/sequential/test-perf-hooks.js:108:3)
at process.emit (events.js:215:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}
Command: out/Release/node /home/****/node-v12.13.1/test/sequential/test-perf-hooks.js
[09:26|% 100|+ 2776|- 1]: Done
Makefile:296: recipe for target 'jstest' failed
make[1]: *** [jstest] Error 1
Makefile:316: recipe for target 'test' failed
make: *** [test] Error 2
ダメっぽいが、何がダメなのか判らないので、インストして終了。
OpenSSLの指定方法が不明だったので、
apt-get でインストした libssl-dev(1.0.1t-1+deb8u12)を使うことになる。
$ openssl version
OpenSSL 1.0.1t 3 May 2016
/etc/sudoersにコンパイルしたOpenSSLのパスを追加すればいいかな
Defaults secure_path=”/usr/local/openssl-1.0.2t/bin:
にすると
$ sudo openssl version
OpenSSL 1.0.2t 10 Sep 2019
やっぱりもっと新しい方がいいような
Defaults secure_path=”/usr/local/openssl-1.1.1d/bin:
OpenSSL 1.1.1d 10 Sep 2019
にしておこう。
ldconfigで書き換えてるし、rootも設定しておくか
export PATH=/usr/local/openssl-1.1.1d/bin:/usr/local/gcc-9.2.0/bin:$PATH