Gtk.jlの準備

JuliaでGUIを作りたいと思ってJulia Observerに行くと、いくつかの選択肢が掲載されています。掲載されているものの他にもWebIO.jlGtk.jlもありますし、以前はFLTKバインディングがあったような気もします。また、SDLを使うためのSimpleDirectMediaLayer.jlもあります。その中でも、ImageView.jlなどで使用されているGtk.jlを試してみたいと思います。

まずはインストールできなくてハマったところです。

Gtk.jlを動かすためにはCairo.jlが必要なのですが、macOS 10.14.5でCairo.jlがインストールできないという問題が発生しました。このことについてはGitHubの以下のIssueに報告されていますが、日本語でなく、また結構長いので、このエントリにも書き残しておきたいと思います。

github.com

僕の環境はmacOS 10.14.5、Julia 1.1.1で、Homebrewを使って様々なソフトを入れています。PkgモードでCairo.jlをaddするところまでは行ったものの、以下のような(上記Issueのここからコピペ)エラーが出てビルドができない状態でした。Cairo.jlがインストールできないのでGtk.jlも使えず、それに依存するImageView.jlもMakie.jlもprecompileできない状態です。

(v1.1) pkg> build Cairo
  Building LibCURL ─→ `~/.julia/packages/LibCURL/khRkY/deps/build.log`
  Building WinRPM ──→ `~/.julia/packages/WinRPM/Y9QdZ/deps/build.log`
  Building Homebrew → `~/.julia/packages/Homebrew/s09IX/deps/build.log`
  Building Cairo ───→ `~/.julia/packages/Cairo/CXPG1/deps/build.log`
┌ Error: Error building `Cairo`:
│
│ signal (11): Segmentation fault: 11
│ in expression starting at ~/.julia/packages/Cairo/CXPG1/deps/build.jl:165
│ _platform_strcmp at /usr/lib/system/libsystem_platform.dylib (unknown line)
│ Allocations: 19355595 (Pool: 19352771; Big: 2824); GC: 43
└ @ Pkg.Operations /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.1/Pkg/src/Operations.jl:1075

Issue上では原因究明のためにいろいろな試行錯誤がされていましたが、その結果、Cairo.jl 0.5.6やCairo.jl 0.6.0はglib 2.60とは相性が悪いというのが直接の原因だと判明しました。解決策としては、使用しているglibを0.58.3にすればよいとのこと。ただ、僕の環境ではすでにシステム側にもHomebrewが入っているので、Juliaが.juliaディレクトリ内にインストールするHomebrewと両方のglibのバージョンを下げる必要がありました。

https://github.com/JuliaGraphics/Cairo.jl/issues/271#issuecomment-480203117に書いてあるとおり、まずはJulia内Homebrewにglib 2.58.3が入っているか確認します。

julia> using Homebrew
julia> Homebrew.brew(`switch glib 2.58.3`)

ここで「Error: glib does not have a version "2.58.3" in the Cellar.(2.58.3はないよ)」と言われたので、2.58.3のソースコードをダウンロードしてコンパイル&インストールします。

julia> Homebrew.brew(`install --verbose --build-from-source https://raw.githubusercontent.com/Homebrew/homebrew-core/05871cb0394f78ef25a5c1c071456d0f1e4be4fe/Formula/glib.rb`)
julia> Homebrew.brew(`switch glib 2.58.3`)

すると、以下のように2.58.3がデフォルトで使用されるバージョンに指定されていることが確認できました。

julia> Homebrew.brew(`info glib`)
glib: stable 2.60.3
Core application library for C
https://developer.gnome.org/glib/
/Users/xxxxx/.julia/packages/Homebrew/s09IX/deps/usr/Cellar/glib/2.58.3 (451 files, 18.8MB) *
  Built from source on 2019-06-01 at 11:24:55
/Users/xxxxx/.julia/packages/Homebrew/s09IX/deps/usr/Cellar/glib/2.60.3 (429 files, 15.3MB)
  Poured from bottle on 2019-06-01 at 11:12:15
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/glib.rb
==> Dependencies
Build: meson ✘, ninja ✘, pkg-config ✔
Required: gettext ✔, libffi ✔, pcre ✔, python ✔
Process(`/Users/xxxxx/.julia/packages/Homebrew/s09IX/deps/usr/bin/brew info glib`, ProcessExited(0))

これでglibバージョンについては解決したと思いきや、さらにシステム側のHomebrewにインストールされているglib 2.60.3からも影響があるようで、まだビルドが通りません。そこでターミナルからも上記と同様のことをやります。

$ brew install --verbose --build-from-source https://raw.githubusercontent.com/Homebrew/homebrew-core/05871cb0394f78ef25a5c1c071456d0f1e4be4fe/Formula/glib.rb
$ brew switch glib 2.58.3

無事にシステム側のHomebrewでもglib 0.58.3が使える状態になりました。

$ brew info glib
glib: stable 2.60.3 (bottled)
Core application library for C
https://developer.gnome.org/glib/
/usr/local/Cellar/glib/2.58.3 (451 files, 18.8MB) *
  Built from source on 2019-06-01 at 11:38:14
/usr/local/Cellar/glib/2.60.3 (429 files, 15.3MB)
  Poured from bottle on 2019-05-22 at 16:33:03
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/glib.rb
==> Dependencies
Build: meson ✘, ninja ✘, pkg-config ✔
Required: gettext ✔, libffi ✔, pcre ✔, python ✔
==> Analytics
install: 267,265 (30 days), 780,837 (90 days), 2,035,504 (365 days)
install_on_request: 12,612 (30 days), 36,289 (90 days), 89,127 (365 days)
build_error: 0 (30 days)

その後、Julia上で(v1.1) pkg> build Cairoを行うと無事にCairoのインストールが完了し、次いでGtk.jlもインストールできました。

Juliaプロンプト上でGtk.jlのGetting Startedにあるサンプルを実行すると、無事にウィンドウとボタンが表示されました。よかった。

using Gtk
win = GtkWindow("My First Gtk.jl Program", 400, 200)
b = GtkButton("Click Me")
push!(win, b)
showall(win)

f:id:amarui:20190608132252p:plain