概要
Ubuntu 16.04 の上で Pharo Zeroconf Script から取得した Pharo VM とイメージの組み合わせを動作させます。
なるべくパッケージでインストールできるものはパッケージに頼って、コンパイルの必要が発生しないように気をつけてまとめました。
VM とイメージの取得
get.pharo.org から取得します。
$ mkdir pharo
$ cd pharo/
$ curl get.pharo.org | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 12445 100 12445 0 0 19426 0 --:--:-- --:--:-- --:--:-- 19414
Downloading the latest 50 Image:
http://files.pharo.org/get-files/50/pharo.zip
Pharo.image
Downloading the latest pharoVM:
http://files.pharo.org/get-files/50/pharo-linux-stable.zip
pharo-vm/pharo
Downloading PharoV50.sources:
http://files.pharo.org/get-files/50/sources.zip
Creating starter scripts pharo and pharo-ui
On a 64-bit system? You must install the 32-bit libraries
Try `sudo aptitude install ia32-libs` or see http://pharo.org/gnu-linux-installation#64-bit-System-Setup for more info
取得できたものを確認してみます。
$ ls
Pharo.changes Pharo.image pharo pharo-ui pharo-vm
中身は以下のような内容となっています。
- Pharo.changes
- Pharo.image イメージに対応する changes ファイル
- Pharo.image
- Pharo 5.0 向けのイメージ
- pharo
- バイナリを実行するラッパースクリプト
- ヘッドレスで動作させるためのオプション付き
- pharo-ui
- バイナリを実行するラッパースクリプト
- X11 環境などがないと使えません
- pharo-vm
- ラッパースクリプトが実行するバイナリや
*.so
などのランタイムが格納されています
- ラッパースクリプトが実行するバイナリや
実行
ラッパースクリプトの内容を確認してみます。
$ tail pharo
# some magic to find out the real location of this script dealing with symlinks
DIR=`readlink "$0"` || DIR="$0";
DIR=`dirname "$DIR"`;
cd "$DIR"
DIR=`pwd`
cd - > /dev/null
# disable parameter expansion to forward all arguments unprocessed to the VM
set -f
# run the VM and pass along all arguments as is
"$DIR"/"pharo-vm/pharo" --nodisplay "$@"
pharo
と pharo-ui
はオプションを切り替えてバイナリを起動するスクリプトであることがわかります。
バイナリを実行してみます。引数なしで実行すればオプション引数にイメージ名が必要であるメッセージがでるはずです。
$ ./pharo-vm/pharo
-bash: ./pharo-vm/pharo: No such file or directory
なん…だと…
$ file ./pharo-vm/pharo
./pharo-vm/pharo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=48578da2df9b12949b98afcc92c361518ee317b8, not stripped
$ uname -a
Linux helium 4.4.0-47-generic #68-Ubuntu SMP Wed Oct 26 19:39:52 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
バイナリが32ビットでカーネルが64ビットなので認識できていないみたいです。
32ビット環境の作成
ダウンロードのときのメッセージを確認してみます。
On a 64-bit system? You must install the 32-bit libraries
Try `sudo aptitude install ia32-libs` or see http://pharo.org/gnu-linux-installation#64-bit-System-Setup for more info
ia32-libs
というパッケージをインストールすれば、32ビットのバイナリが動くようになるよ、みたいなことが書いてあります。
しかし、これは Ubuntu 14.04 のときに存在していたパッケージで Ubuntu 16.04 からは ia32-libs
というパッケージが存在しない1ので、インストールできないです。
64 bit - How to run 32-bit app in Ubuntu 64-bit? - Ask Ubuntu を参考にアーキテクチャの追加と必要なパッケージのインストールを行いましょう。
$ sudo dpkg --add-architecture i386
$ sudo apt-get update
$ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
実行してみます。
$ ./pharo-vm/pharo
pharo: could not find any display driver
Aborted (core dumped)
あっ、刺さるようになった。
なんかとてもダメな気がしますが、見なかった事にします。
X11 環境を用意すればいいんですが、今回は動かすのが目的なので無視します。--nodisplay
でヘッドレスで動くのか確認します。
Transcript show: 'hoge'.
の実行
$ ./pharo-vm/pharo --nodisplay Pharo.image eval "Transcript show: 'hoge'."
ioLoadModule(/home/ubuntu/pharo/pharo-vm/libFT2Plugin.so):
libfreetype.so.6: cannot open shared object file: No such file or directory
ioLoadModule(/home/ubuntu/pharo/pharo-vm/libFT2Plugin.so):
libfreetype.so.6: cannot open shared object file: No such file or directory
ioLoadModule(/home/ubuntu/pharo/pharo-vm/libFT2Plugin.so):
libfreetype.so.6: cannot open shared object file: No such file or directory
Freetype2 primitive failed [error -1][can't get error string]
FreeTypeExternalMemory(FT2Handle)>>primitiveFailed:
FreeTypeExternalMemory(FT2Handle)>>primitiveFailed
FreeTypeExternalMemory>>primCopyToExternalMemory:
FreeTypeExternalMemory>>validate
EmbeddedFreeTypeFontInstaller>>addFromFileContents:baseName:
SourceCodeProRegular class(EmbeddedFreeTypeFontFontDescription class)>>installFontsIn:
[ :each | each installFontsIn: provider ] in EmbeddedFreeTypeFontFontDescription class>>installAllFontsIn: in Block: [ :each | each installFontsIn: provider ]
OrderedCollection>>do:
EmbeddedFreeTypeFontFontDescription class>>installAllFontsIn:
EmbeddedFreeTypeFontInstaller>>installAllFontsIn:
[ :each | each installAllFontsIn: self ] in FreeTypeFontProvider>>updateEmbeddedFreeTypeFonts in Block: [ :each | each installAllFontsIn: self ]
OrderedCollection>>do:
FreeTypeFontProvider>>updateEmbeddedFreeTypeFonts
FreeTypeSettings class>>updateFreeType
FreeTypeSettings class>>startUp:
ClassSessionHandler>>startup:
[ :each | each startup: isImageStarting ] in WorkingSession>>runStartup: in Block: [ :each | each startup: isImageStarting ]
[ aBlock value: each ] in [ :each |
[ aBlock value: each ]
on: Exception
do: [ :error | self errorHandler handleError: error ] ] in WorkingSession>>runList:do: in Block: [ aBlock value: each ]
BlockClosure>>on:do:
[ :each |
[ aBlock value: each ]
on: Exception
do: [ :error | self errorHandler handleError: error ] ] in WorkingSession>>runList:do: in Block: [ :each | ...
Array(SequenceableCollection)>>do:
WorkingSession>>runList:do:
WorkingSession>>runStartup:
WorkingSession>>start:
SessionManager>>snapshot:andQuit:
SmalltalkImage>>snapshot:andQuit:
ImageCleanerCommandLineHandler>>activate
ImageCleanerCommandLineHandler class(CommandLineHandler class)>>activateWith:
[ aCommandLinehandler activateWith: commandLine ] in PharoCommandLineHandler(BasicCommandLineHandler)>>activateSubCommand: in Block: [ aCommandLinehandler activateWith: commandLine ]
BlockClosure>>on:do:
hogeTranscript
なんかキッツい感じで中途半端に動いてますね。
じつはこのまま動かしていると運用に耐えられるようなものではありません。
ネタばらしするとさまざまな *.so
が不足しているんですよね。
ioLoadModule(/home/ubuntu/pharo/pharo-vm/libFT2Plugin.so):
libfreetype.so.6: cannot open shared object file: No such file or directory
ioLoadModule(/home/ubuntu/pharo/pharo-vm/libFT2Plugin.so):
libfreetype.so.6: cannot open shared object file: No such file or directory
ioLoadModule(/home/ubuntu/pharo/pharo-vm/libFT2Plugin.so):
libfreetype.so.6: cannot open shared object file: No such file or directory
ここのログが足がかりになります。
足りない *.so
を調べる
ちょっと強引なんですが、バイナリが格納されているディレクトリで ldd(1)
を使って足りない *.so
を探します。
$ cd pharo-vm/
$ ls
PharoV50.sources libJPEGReadWriter2Plugin.so libSDL2-2.0.so.0.2.1 libgit2.so.0 vm-display-null
libB3DAcceleratorPlugin.so libJPEGReaderPlugin.so libSDL2DisplayPlugin.so libssh2.so.1 vm-sound-ALSA
libFT2Plugin.so libRePlugin.so libSqueakSSL.so pharo vm-sound-null
libInternetConfigPlugin.so libSDL2-2.0.so.0 libSurfacePlugin.so vm-display-X11
$ ldd * | grep 'not found'
libfreetype.so.6 => not found
libSDL2-2.0.so.0 => not found
libssl.so.1.0.0 => not found
libz.so.1 => not found
libssl.so.1.0.0 => not found
libcrypto.so.1.0.0 => not found
libcrypto.so.1.0.0 => not found
libz.so.1 => not found
libcrypto.so.1.0.0 => not found
libz.so.1 => not found
libGL.so.1 => not found
libX11.so.6 => not found
libasound.so.2 => not found
こんなに…あるの…
これらのうち、ないとヤバそうなものを入れていきます。
具体的には libssl.so
とか libz.so
とか libfreetype.so
とか libcrypto.so
あたりですね。
最近の通信はすぐに SSL を使いますので Zinc とかが刺さりまくります。
足りない *.so
のパッケージを探す
インチキっぽいんですが、公式のレポジトリから Pharo をインストールした Ubuntu 14.04 を用意して do-release-upgrade(8)
で Ubuntu 16.04 に上げます。
その Ubuntu 16.04 マシンで dpkg(1)
を使って探していきます。
$ dpkg -S libfreetype.so.6
libfreetype6:amd64: /usr/lib/x86_64-linux-gnu/libfreetype.so.6.12.1
libfreetype6:i386: /usr/lib/i386-linux-gnu/libfreetype.so.6
libfreetype6:amd64: /usr/lib/x86_64-linux-gnu/libfreetype.so.6
libfreetype6:i386: /usr/lib/i386-linux-gnu/libfreetype.so.6.12.1
$ dpkg -S libSDL
dpkg-query: no path found matching pattern *libSDL*
$ dpkg -S libssl.so.1.0.0
libssl1.0.0:amd64: /lib/x86_64-linux-gnu/libssl.so.1.0.0
libssl1.0.0:i386: /lib/i386-linux-gnu/libssl.so.1.0.0
$ dpkg -S libz.so.1
zlib1g:i386: /lib/i386-linux-gnu/libz.so.1.2.8
zlib1g:amd64: /lib/x86_64-linux-gnu/libz.so.1
zlib1g:i386: /lib/i386-linux-gnu/libz.so.1
zlib1g:amd64: /lib/x86_64-linux-gnu/libz.so.1.2.8
$ dpkg -S libcrypto.so.1.0.0
libssl1.0.0:i386: /lib/i386-linux-gnu/libcrypto.so.1.0.0
libssl1.0.0:amd64: /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
$ dpkg -S libGL.so.1
libgl1-mesa-glx:i386: /usr/lib/i386-linux-gnu/mesa/libGL.so.1
libgl1-mesa-glx:amd64: /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
libgl1-mesa-glx:amd64: /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0
libgl1-mesa-glx:i386: /usr/lib/i386-linux-gnu/mesa/libGL.so.1.2.0
$ dpkg -S libX11.so.6
libx11-6:i386: /usr/lib/i386-linux-gnu/libX11.so.6.3.0
libx11-6:amd64: /usr/lib/x86_64-linux-gnu/libX11.so.6
libx11-6:amd64: /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
libx11-6:i386: /usr/lib/i386-linux-gnu/libX11.so.6
$ dpkg -S libasound.so.2
libasound2:amd64: /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
libasound2:i386: /usr/lib/i386-linux-gnu/libasound.so.2.0.0
libasound2:amd64: /usr/lib/x86_64-linux-gnu/libasound.so.2
libasound2:i386: /usr/lib/i386-linux-gnu/libasound.so.2
これらのうち、i386 のパッケージを入れていけばいいのです。
libSDL
が見つかりませんでしたが、まあ、普通は使わないと思うので今回はパスです。
足りない *.so
のパッケージをインストール
必要なパッケージは以下のものだということが分かりました。
libfreetype6:i386
libssl1.0.0:i386
zlib1g:i386
libgl1-mesa-glx:i386
libx11-6:i386
libasound2:i386
というわけで、一撃必殺。
$ sudo apt install -y libfreetype6:i386 libssl1.0.0:i386 zlib1g:i386 libgl1-mesa-glx:i386 libx11-6:i386 libasound2:i386
入った。
帰ってきた Transcript show: 'hoge'.
の実行
$ ./pharo-vm/pharo --nodisplay Pharo.image eval "Transcript show: 'hoge'."
hogeTranscript
スッと何も文句なしに動くようになりました。
Transcript
って出てるのは何なんですかね… eval
すると戻り値が print it されるのかな?
まとめ
Pharo Zeroconf Script で取得した VM を動かすには32ビットのランタイムがいろいろと必要になります。
多く分けてふたつのステップをこなせば64ビットの Ubuntu 16.04 環境をなるべく汚さずに Pharo で生活できるようになります。
- アーキテクチャの追加とランタイムのインストール
$ sudo dpkg --add-architecture i386
$ sudo apt-get update
$ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
- 不足している
*.so
のインストール
$ sudo apt install -y libfreetype6:i386 libssl1.0.0:i386 zlib1g:i386 libgl1-mesa-glx:i386 libx11-6:i386 libasound2:i386
これくらい入っていれば ALLSTOCKER2 も動作するくらいのランタイムは揃います。
それではみなさんも Ubuntu 16.04 と Pharo 5 で快適な Smalltalk 生活をお送り下さい。
ではまた。