julia in FreeBSD
前回だったか前々回だったか、FreeBSD 10.2にjuliaを入れようとして、あえなく撃沈した。 くやしいので、リベンジしてみる。
前回の失敗の原因は、コンパイル時間を短縮しようとして、llvmを備え付けのやつで流用 してしまった事にある。
膨大なコンパイル時間がかかる事を覚悟の上、llvmを気の済むように作ってもらった。 大体1.5時間ぐらいかかりましたかねぇ。
後はすんなり行くかと思ったら、blasもFreeBSDのpkgから持ってきたやつではお気にめさない よう。お前の好きにしろって指示したら、openblasを勝手に取って来てコンパイルを 始めたんだけど、途中でエラー。
ちゃんと記録を取っていなかったんで、うろ覚えだけどblas_server.cで、includeファイルの指定をしてる所で、 FreeBSDの宣言が抜けてて、すっとばされ、盛大にこけてた。そこを修正して、やはり待つ事、 1.5時間ぐらい。
これで行けるかと思ったら、悪夢が再現。
REPLCompletions.jl REPL.jl client.jl util.jl error during bootstrap: LoadError(at "sysimg.jl" line 238: LoadError(at "util.jl" line 234: ErrorException("error compiling blas_vendor: could not load library "libopenblas" /lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc48/libgfortran.so.3 not found"))) rec_backtrace at /usr/home/sakae/src/julia-0.4.3/usr/bin/../lib/libjulia.so (unknown line) jl_throw at /usr/home/sakae/src/julia-0.4.3/usr/bin/../lib/libjulia.so (unknownline) :
いい所まで来たんですがね。
gmake FC='gfortran48 -Wl,-rpath=/usr/local/lib/gcc48 '
このおまじないが効く範囲って限定的? これに気が付いたのは、fortran系のモジュールの configure中で、簡単な実行ファイルを作成出来るか試験してる部分があったんだけど、 それがこけてて、モジュール作成が出来なかった時に発見した裏技。
しょうがないので、 (Unix系OSの掟) LD_LIBRARY_PATHは最後の武器だから、濫用してはいけない とか ライブラリとは何なのか? なんてので、魔法の世界を再確認。
最後の砦の
$ export LD_LIBRARY_PATH=/usr/local/lib/gcc48
を発動。これで、やっとコンパイル完了。julia-0.4.3の作業Dir容量は、1.2Gになりましたよ。 そのうち依存関係者が入るdepsの容量が986M。出来上がったjulia群は170M(LLVMを含む) Make.incで節約したのは
USE_SYSTEM_LIBM=1 USE_SYSTEM_FFTW=1 USE_SYSTEM_GMP=1 USE_SYSTEM_MPFR=1
だけだった。
$ ./julia WARNING: Error during initialization of module LinAlg: ErrorException("could not load library "libopenblas" /lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc48/libgfortran.so.3 not found") WARNING: Error during initialization of module CHOLMOD: ErrorException("could not load library "libcholmod" Shared object "libcholmod" not found, required by "julia"") _ _ _ _(_)_ | A fresh approach to technical computing (_) | (_) (_) | Documentation: http://docs.julialang.org _ _ _| |_ __ _ | Type "?help" for help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 0.4.3 _/ |\__'_|_|_|\__'_| | |__/ | i386-portbld-freebsd10.1 julia>
LD_LIBRARY_PATHの設定をしなくても、警告が出て来るだけで、一応起動はする。 と思ったら、
julia> versioninfo() Julia Version 0.4.3 Platform Info: System: FreeBSD (i386-portbld-freebsd10.1) CPU: Intel(R) Celeron(R) CPU 900 @ 2.20GHz WORD_SIZE: 32 ERROR: could not load library "libopenblas" /lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc48/libgfortran.so.3 not found in openblas_get_config at ./util.jl:239 in versioninfo at interactiveutil.jl:188 in versioninfo at interactiveutil.jl:158
案の定、まともに動かない。しょうがないので、
alias julia='LD_LIBRARY_PATH=/usr/local/lib/gcc48 /home/sakae/src/julia-0.4.3/julia'
こんなエイリアスを設定、
julia> versioninfo() Julia Version 0.4.3 Platform Info: System: FreeBSD (i386-portbld-freebsd10.1) CPU: Intel(R) Celeron(R) CPU 900 @ 2.20GHz WORD_SIZE: 32 BLAS: libopenblas (DYNAMIC_ARCH NO_AFFINITY Penryn) LAPACK: libopenblas LIBM: libm LLVM: libLLVM-3.3
ちゃんとFreeBSD印も押してあるし、まずは目出度い。あれ? juliaを普通の言語系として 使わないの? ええ、replから使うものだと割り切りました。だって、スクリプトを実行 させるのにやれJITとかやらかしてくれると、イライラが募りますから。
FreeBSDでLinuxのエミュレーション
もう一つリベンジが残っていた。過去にOpenBSDやらNetBSDのLinuxエミュレーションを使って、 gdbserverが動くかやった。結果、あえなく撃沈。あれは特殊なアプリだっから?
今回は普通のアプリ、Linux側のJuliaをFreeBSD側に持ってきて動くか、確認してみたい。 ええ、Julia開発陣の気まぐれで、FreeBSDの対応が打ち切られても、あたふたしないように 、逃げ道を確認しておきたいと思って。。。
man linuxすればあらかたの事が分かる。最初juliaだけを持ってきて試そうかと思ったけど、 素直にLinuxのBedを用意する事にした。どんなのがあるか、取りあえず確認。
$ pkg search linux_base linux_base-c6-6.6_6 Base set of packages needed in Linux mode for i386/amd64 (Linux CentOS 6) linux_base-f10-10_9 Base set of packages needed in Linux mode for i386/amd64 (Linux Fedora 10)
Cent6の方が新しいだろうって理由で選んだら、約170MぐらいDisk容量が必要との事。 忘れずにkldload linuxしておく。
$ kldstat Id Refs Address Size Name 1 12 0xc0400000 13ed81c kernel 2 1 0xc4b9e000 4000 fdescfs.ko 3 1 0xc4d28000 4000 uhid.ko 4 1 0xc5fa1000 4a000 linux.ko
後は、Fedoraからlibを持ってきて、/compat/linux/usr/libの下に入れる。念のためLinuxの 儀式を行う。
$ /compat/linux/sbin/ldconfig -r /compat/linux
そして実行。
$ /compat/linux/usr/bin/julia /compat/linux/usr/bin/julia: relocation error: /usr/lib/libc.so.6: symbol _dl_starting_up, version GLIBC_PRIVATE not defined in file ld-linux.so.2 with link time reference
おかしいなってんで、 10.2. インストール を見直し。
$ ldd /compat/linux/usr/bin/julia /compat/linux/usr/bin/julia: libjulia.so => /usr/lib/libjulia.so (0x2806f000) libdl.so.2 => /lib/libdl.so.2 (0x2820f000) librt.so.1 => /lib/librt.so.1 (0x28214000) libpthread.so.0 => /lib/libpthread.so.0 (0x2821d000) libunwind-x86.so.8 => /usr/lib/libunwind-x86.so.8 (0x28238000) libunwind.so.8 => /usr/lib/libunwind.so.8 (0x28251000) libz.so.1 => /lib/libz.so.1 (0x28267000) libffi.so.6 => /usr/lib/libffi.so.6 (0x2827b000) libLLVM-3.3.so => /usr/lib/libLLVM-3.3.so (0x28283000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x29889000) libm.so.6 => /lib/libm.so.6 (0x29a03000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x29a2d000) libc.so.6 => /usr/lib/libc.so.6 (0x29a4c000) libutf8proc.so.1 => /usr/lib/libutf8proc.so.1 (0x29c19000) /lib/ld-linux.so.2 (0x2804c000)
ちなみにFreeBSDの方は、
$ ldd src/julia-0.4.3/usr/bin/julia src/julia-0.4.3/usr/bin/julia: libjulia.so => /usr/home/sakae/src/julia-0.4.3/usr/bin/../lib/libjulia.so (0x28400000) libelf.so.1 => /usr/lib/libelf.so.1 (0x28078000) libkvm.so.6 => /lib/libkvm.so.6 (0x2808e000) librt.so.1 => /usr/lib/librt.so.1 (0x28097000) libstdc++.so.6 => /usr/local/lib/gcc48/libstdc++.so.6 (0x2809d000) libm.so.5 => /lib/libm.so.5 (0x28189000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281b0000) libc.so.7 => /lib/libc.so.7 (0x281bc000) libz.so.6 => /lib/libz.so.6 (0x28331000) libthr.so.3 => /lib/libthr.so.3 (0x28345000)
構成が違うね。FreeBSDでちゃんとJITが効いてくれるか、思わず確かめちゃったぞ。
それはいいとして、ここに至るまで、
$ /compat/linux/usr/bin/julia FATAL: kernel too old
とか言われたので、
$ sudo sysctl -w compat.linux.osrelease=2.6.32 compat.linux.osrelease: 2.6.18 -> 2.6.32
無理してLinuxのバージョンを上げた。で、上の結果になった。諦めきれないオイラーは、 ld-linux.so.2をヒントに、
$ ls -l /compat/linux/lib/ld-* -rwxr-xr-x 1 root wheel 141144 Jan 31 10:16 /compat/linux/lib/ld-2.12.so* -rwxr-xr-x 1 sakae wheel 159928 Mar 4 16:11 /compat/linux/lib/ld-2.22.so* lrwxr-xr-x 1 root wheel 10 Mar 4 16:26 /compat/linux/lib/ld-linux.so.2@ -> ld-2.12.so lrwxr-xr-x 1 root wheel 13 Feb 22 2013 /compat/linux/lib/ld-lsb.so.3@ -> ld-linux.so.2
で、ld-linux.so.2のリンク先を、Fedoraのそれ、ld-2.22.soに付け替えたんだ。そしたら、
$ /compat/linux/usr/bin/julia Segmentation fault (core dumped) $ ldd /compat/linux/usr/bin/julia /compat/linux/usr/bin/julia: /compat/linux/usr/bin/julia: signal 11
状況は悪化しましたよ。Fedora23なんて、時代の最先端な実験Linux(そうさ、オイラーは赤帽 さんのモルモットを喜んで務めております)、そして実用のRedHat版のLinxuが出て、それの クローンがCentOS。だから、無理はきかないのね。討ち死にじゃーー。 まあ、LinuxのBedにしたやつは、Linux CentOS 6.5 meta port. らしいですから。
file julia
と、まあ無駄骨でしたねぇ。結局エミュレーション関連は綺麗さっぱりと削除しました。 この環境で、fedoraから持ってきたjuliaは、FreeBSDにはどう映るか確認。
$ ./julia ELF binary type "0" not known. ./julia: Exec format error $ file julia julia: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ea81d90f90b6a7dd581f6cce55f07d613433bb2d, stripped
実行しようとすると、そんな異物は知らんと免疫機能が働いています(当然)。でも、fileコマンドで 相手の素性を調査してみると、ちゃんとどのLinuxバージョン上でコンパイルされたかを 含めて、DNAが残っているようです。あれ? ELFファイルにOSのバージョン番号なんて付与 されてたっけ? 調べてみれって事で、まずは file コマンドを参照。 続いて、ソース嫁。
たまたまNetBSDが立ち上がっているので、 /usr/src/external/bsd/file/dist/srcを参照。多分見るべきファイルはreadelf.c。
472private size_t 473donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, 474 int clazz, int swap, size_t align, int *flags) : 541 if (file_printf(ms, ", for GNU/") == -1) 542 return size; 543 switch (elf_getu32(swap, desc[0])) { 544 case GNU_OS_LINUX: 545 if (file_printf(ms, "Linux") == -1) 546 return size; 547 break; : 568 if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]), 569 elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1 ) 570 return size;
どうも関数名、donoteなんて言う名前が怪しい。readelf.hを見たら
typedef struct elf_note { Elf32_Word n_namesz; /* Name size */ Elf32_Word n_descsz; /* Content size */ Elf32_Word n_type; /* Content type */ } Elf32_Nhdr; /* * GNU executables (name = "GNU") * word[0]: GNU OS tags * word[1]: major version * word[2]: minor version * word[3]: tiny version */
次はは、readelfの出番だ。
Notes at offset 0x00000168 with length 0x00000020: Owner Data size Description GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) OS: Linux, ABI: 2.6.32 Notes at offset 0x00000188 with length 0x00000024: Owner Data size Description GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: ea81d90f90b6a7dd581f6cce55f07d613433bb2d
readelf.cには、FreeBSD用のdonote表示コードも掲載されてたけど、version4から5の頃は、 がたがたしてたみたいで、それを吸収するコードが無様に組み込んであった。fileの作者さん、 どうもスマソ。
乗り掛けた船なんで、もうちょっと調べてみる。そもそもfileコマンドは寄贈ソフトを FreeBSDもNetBSDも採用してる。OpenBSDにはソース上言及していない。 ならば、fileコマンドはOpenBSDの事をほとんど知らないはず。
例としてOpenBSD用のfileコマンドをFreeBSDに持ってきて、どういう報告をするか確認。
$ file file file: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /usr/libexec/ld.so, for OpenBSD, stripped $ readelf -a file : No version information found in this file. Displaying notes found at file offset 0x000001e8 with length 0x00000030: Owner Data size Description OpenBSD 0x00000004 NT_VERSION (version) OpenBSD 0x00000004 NT_VERSION (version)
やはり、OpenBSDなんて、オラ白根って言ってきた。
FreeBSDに持って行ったjuliaは
[ob: ~]$ file julia julia: ELF 32-bit LSB executable, Intel 80386, version 1, for GNU/Linux 2.6.32, dynamically linked (uses shared libs), stripped
ちゃんと表示してくれた。
OpenBSDのfileコマンドソースは、正統な場所(/usr/src/usr.bin/file)に収められている。 READMEを読むと、freeware扱いのソースを取ってきて、OpenBSD用に改変したよって書いてる。 面白いな。
julia in NetBSD
無謀にもjuliaがNetBSDに入るか挑戦してみた。まずは下準備って事で、 gtar,cmake,gcc48(for gfortran)を入れてあげる。設定はFreeBSDのそれを継承する。
nb7$ gmake FC=gfortran CC src/unix/libuv_la-netbsd.lo src/unix/netbsd.c: In function 'uv_get_free_memory': src/unix/netbsd.c:104:17: error: storage size of 'info' isn't known struct uvmexp info; ^ Makefile:1915: recipe for target 'src/unix/libuv_la-netbsd.lo' failed gmake[3]: *** [src/unix/libuv_la-netbsd.lo] Error 1 Makefile:830: recipe for target 'all' failed gmake[2]: *** [all] Error 2 Makefile:757: recipe for target 'libuv-efb40768b7c7bd9f173a7868f74b92b1c5a61a0e/.libs/libuv.la' failed gmake[1]: *** [libuv-efb40768b7c7bd9f173a7868f74b92b1c5a61a0e/.libs/libuv.la] Error 2 Makefile:51: recipe for target 'julia-deps' failed gmake: *** [julia-deps] Error 2
ぐぐったら、こんなのを入れるといいよってのが遭った。
#include <uvm/uvm_extern.h>
ここまではいいんだけど、llvmのインストールの所でコケル。ぐぐる先生に聞いてみても、 エラー報告は有るものの解決策は全く無い。そんじゃ、NetBSDのpkgになってるllvmはどうやってるか 調べてみるか。こういう時はpatch集を見るに限るな。
2つのMakefileにパッチが当っていた。内容はNetBSDは蚊帳の外だからFreeBSDと同様に扱って くれよなーって物。同等のpatchを手で当ててみたけど、やはりエラー。
だったら、pkgのllvmを使ってあげればいいじゃんって事にしたよ。えっちらおっちらと巨大な clangパッケージをインストール。そしてコンパイルを再回。
今度は、openblsaの所でコケタ。エラー内容は、リンクが解決出来ないってやつ。これもぐぐる 先生に聞いてみた。やはりエラーの報告は有るものの、使い方を限定しろってもの。 そうしたら、多分juliaとしては成り立たなくなるんで、潔く撤退する事にした。
後に残るはclangよ。これはきっと、llvmに手を出してみろって事なんだろうな。
etc
わずか600円台のコンピューター「Raspberry Pi Zero」が登場
Rustで書いた自作OSをRaspberry Pi Zeroで動かす
何、64Bitで4コアだって! 何と言う凄まじさ。オイラーの所の旧石器は、もう暫く 寝かせておくと、何でも鑑定団に出品出来るぞ。32Bit、シングルコア、昔の人は こういう石器で頑張っていたんですねぇ。大切に保存しておきましょう。 そのうちに、国立科学博物館から高値で引き取りたいと言ってきますから。