いものやま。

雑多な知識の寄せ集め

FXRubyをMacにインストールしてみた。

ちょっとRubyGUIいじれないかなぁと思って、MacにFXRubyを入れてみたので、そのメモ。

FXRubyとは

FXRubyとは、FOX toolkitというクロスプラットフォームGUIツールキットの、Rubyバインディング

クロスプラットフォームGUIツールキットでRubyでも使えるものとなると、Tkとかも有名だけど、Tkはドキュメントが見つからなくて困るということが多かったので、別のものも試してみようかなと思って、インストールしてみた。

依存するライブラリのインストール

MacPortsを使えば、多分サクッとインストールできるのだけど、自分はパッケージシステムを使ってないので(どれを使ったらいいのか正直分からない・・・)、依存するライブラリをちまちまとインストールしていった。

参考にしたのは、以下のページ:

LibPNG

libpng.org: top levelからソースをダウンロードして、ビルド:

tar zxvf libpng-1.6.36.tar.gz
cd libpng-1.6.36
./configure
make
sudo make install

LibJPEG

Independent JPEG Groupからソースをダウンロードして、ビルド:

tar zxvf jpegsrc.v9c.tar.gz
cd jpeg-9c
./configure
make
sudo make install

LibTIFF

LibTIFF - TIFF Library and Utilitiesからソースをダウンロードして、ビルド:

tar zxvf tiff-4.0.10.tar.gz
cd tiff-4.0.10
./configure
make
sudo make install

FOX toolkitのインストール

ここまではすんなり上手くいったんだけど、FOX toolkitのインストールでいろいろつまずいた。

とりあえずはfox-toolkit.orgからソースをダウンロードして展開。

tar zxvf fox-1.6.57.tar.gz
cd fox-1.6.57

これをこのまま、参考にしたページの通りにビルド:

env CFLAGS="-I/usr/X11/include -I/usr/X11/include/freetype2 -DHAVE_XFT_H=1" CXXFLAGS="-I/usr/X11/include -I/usr/X11/include/freetype2 -DHAVE_XFT_H=1" LDFLAGS="-L/usr/X11/lib  -lXft -lfontconfig -lfreetype" ./configure --with-x --with-opengl --enable-cups --enable-release
make

すると、まずconfigureで以下の警告:

configure: WARNING: unrecognized options: --enable-cups

たぶん、--enable-cupsというオプションはなくなったのだと思う。

で、makeすると、以下のエラー:

In file included from FX88591Codec.cpp:1:
In file included from ../include/xincs.h:211:
/usr/X11/include/X11/Xft/Xft.h:39:10: fatal error: 'ft2build.h' file not found
#include <ft2build.h>
         ^~~~~~~~~~~~
1 error generated.

ft2build.hが見つからないというので、findしてみると、ちゃんと存在している。

$ find /usr/X11/include -name "ft2build.h" -print
/usr/X11/include/freetype2/ft2build.h

それに、CFLAGSCXXFLAGS-I/usr/X11/include/freetype2としているので、インクルードパスも通っているはず。
なので、ft2build.hが見つからないのは、おかしい・・・

で、いろいろ調べてみたら、なんと、configureの中でユーザの指定したCXXFLAGSを潰していやがった・・・
なので、configureを以下のように修正:

--- configure.org
+++ configure
@@ -3303,7 +3303,7 @@
 
 
 # Prevents setting flags.
-CXXFLAGS=""
+# CXXFLAGS=""
 
 # More secret source
 DEPDIR="${am__leading_dot}deps"

これで再度ビルドを実行。
すると、コンパイルは問題なく通ったのだけど、リンクで次のエラーが:

Undefined symbols for architecture x86_64:
  "_MPCreateSemaphore", referenced from:
      FX::FXSemaphore::FXSemaphore(int) in FXThread.o
      FX::FXSemaphore::FXSemaphore(int) in FXThread.o
  "_MPDeleteSemaphore", referenced from:
      FX::FXSemaphore::~FXSemaphore() in FXThread.o
      FX::FXSemaphore::~FXSemaphore() in FXThread.o
  "_MPSignalSemaphore", referenced from:
      FX::FXSemaphore::post() in FXThread.o
  "_MPWaitOnSemaphore", referenced from:
      FX::FXSemaphore::wait() in FXThread.o
      FX::FXSemaphore::trywait() in FXThread.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

MPCreateSemaphoreがない、といっているわけだけど、なんでだろうと調べてみたら、10.8 (Mountain Lion)で廃止されてた・・・

MPCreateSemaphore - Core Services | Apple Developer Documentation

じゃあ、最新(FOX toolkitの1.7系)だとどうしてるんだろうと調べてみたら、PthreadのAPIを叩くように修正されてた。
なので、これを取り込んでみた:

--- src/FXThread.cpp.org
+++ src/FXThread.cpp
@@ -155,32 +155,56 @@
   // of sizeof(MPSemaphoreID*) is supposed to be on your
   // machine and mail it to: jeroen@fox-toolkit.org!!
   //FXTRACE((150,"sizeof(MPSemaphoreID*)=%d\n",sizeof(MPSemaphoreID*)));
-  FXASSERT(sizeof(data)>=sizeof(MPSemaphoreID*));
-  MPCreateSemaphore(2147483647,initial,(MPSemaphoreID*)data);
+  // from 1.7.64
+  FXASSERT(sizeof(FXuval)*9 >= sizeof(pthread_cond_t));
+  FXASSERT(sizeof(FXuval)*6 >= sizeof(pthread_mutex_t));
+  data[0]=initial;
+  pthread_cond_init((pthread_cond_t*)&data[1],NULL);
+  pthread_mutex_init((pthread_mutex_t*)&data[10],NULL);
   }
 
 
 // Decrement semaphore
 void FXSemaphore::wait(){
-  MPWaitOnSemaphore(*((MPSemaphoreID*)data),kDurationForever);
+  // from 1.7.64
+  pthread_mutex_lock((pthread_mutex_t*)&data[10]);
+  while(data[0]==0){
+    pthread_cond_wait((pthread_cond_t*)&data[1],(pthread_mutex_t*)&data[10]);
+    }
+  data[0]-=1;
+  pthread_mutex_unlock((pthread_mutex_t*)&data[10]);
   }
 
 
 // Decrement semaphore but don't block
 FXbool FXSemaphore::trywait(){
-  return MPWaitOnSemaphore(*((MPSemaphoreID*)data),kDurationImmediate)==noErr;
+  // from 1.7.64
+  pthread_mutex_lock((pthread_mutex_t*)&data[10]);
+  if(data[0]==0){
+    pthread_mutex_unlock((pthread_mutex_t*)&data[10]);
+    return false;
+    }
+  data[0]-=1;
+  pthread_mutex_unlock((pthread_mutex_t*)&data[10]);
+  return true;
   }
 
 
 // Increment semaphore
 void FXSemaphore::post(){
-  MPSignalSemaphore(*((MPSemaphoreID*)data));
+  // from 1.7.64
+  pthread_mutex_lock((pthread_mutex_t*)&data[10]);
+  data[0]+=1;
+  pthread_cond_signal((pthread_cond_t*)&data[1]);
+  pthread_mutex_unlock((pthread_mutex_t*)&data[10]);
   }
 
 
 // Delete semaphore
 FXSemaphore::~FXSemaphore(){
-  MPDeleteSemaphore(*((MPSemaphoreID*)data));
+  // from 1.7.64
+  pthread_mutex_destroy((pthread_mutex_t*)&data[10]);
+  pthread_cond_destroy((pthread_cond_t*)&data[1]);
   }
 
 #else

これで再びmakeを実行。
今度はリンクも問題なくいき、無事ビルドが完了したので、sudo make installをして、インストール。

なお、参考にしたページだと、このあとFXScintillaをインストールしているのだけど、これはオプションで、自分はちょっと試してみたいだけだったので、スルー。

FXRubyのインストールと動作確認

あとはFXRubyのGemをインストールするだけ。

gem install fxruby

なお、自分はRVMを使っているので、sudoなしでGemのインストールを行なっているけど、そうでない場合、sudoが必要。

動作確認は、fxrubyのGitリポジトリをクローンしてきて、examples/以下に入っているサンプルを動かしてみるといい。

一例は、以下:

git clone https://github.com/lylejohnson/fxruby.git
cd fxruby/examples
ruby button.rb

上記のようにすると、X11が立ち上がって、以下のようなウィンドウが表示される:

f:id:yamaimo0625:20190224194629p:plain

うん、微妙・・・(^^;

もうちょいマシな見た目にならないのかなぁ・・・
まぁ、X11を使ってるなら、仕方ないか。

何はともあれ、インストールは出来たので、いろいろ試したりは出来るはず。
見た目が微妙すぎるので、やらないかもだけど。

今日はここまで!