2009-01-03

GTK+ でクロスコンパイル

SourceForge.net Logo

Features/Windows cross compiler の Release Notes によると、Fedora 11 で、MinGW Cross Compile 環境が提供されるようになるとのことです。

SourceForge.net に開設している MinGW Cross Compiler のプロジェクトの役割は、今後は前述のプロジェクトがカバーしていない、ニッチな分野のパッケージが対象になりそうです。しかし、短期的には Fedora 11 用のレポジトリから spec ファイルを持ってきて Fedora 10 でリビルドしたパッケージを公開しようとコンパイル作業に明け暮れています。

その中で、GTK+ のパッケージをアップしましたので、動作確認として簡単なプログラムをコンパイルしてみました。サンプルは、以下の GTK+ プロジェクトのサイトで公開されている Tutorial に掲載されているサンプルを流用しました。

[1] GTK+ 2.0 Tutorial/Getting Started


#include <gtk/gtk.h>

/*
* This is a callback function. The data arguments are ignored in this example.
* More on callbacks below.
*/

static void
hello (GtkWidget * widget, gpointer data)
{
g_print ("Hello World!\n");
}

static gboolean
delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
{
/*
* If you return FALSE in the "delete_event" signal handler, GTK will emit
* the "destroy" signal. Returning TRUE means you don't want the window to be
* destroyed.
* This is useful for popping up 'are you sure you want to quit?' type
* dialogs.
*/

g_print ("delete event occurred\n");

/*
* Change TRUE to FALSE and the main window will be destroyed with a
* "delete_event".
*/

return TRUE;
}

/* Another callback */
static void
destroy (GtkWidget * widget, gpointer data)
{
gtk_main_quit ();
}

int
main (int argc, char *argv[])
{
/* GtkWidget is the storage type for widgets */
GtkWidget *window;
GtkWidget *button;

/*
* This is called in all GTK applications. Arguments are parsed from the
* command line and are returned to the application.
*/

gtk_init (&argc, &argv);

/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

/*
* When the window is given the "delete_event" signal (this is given by the
* window manager, usually by the "close" option, or on the titlebar), we ask
* it to call the delete_event () function as defined above. The data passed
* to the callback function is NULL and is ignored in the callback function.
*/

g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);

/*
* Here we connect the "destroy" event to a signal handler.
* This event occurs when we call gtk_widget_destroy() on the window, or if
* we return FALSE in the "delete_event" callback.
*/

g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);

/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);

/* Creates a new button with the label "Hello World!". */
button = gtk_button_new_with_label ("Hello World!");

/*
* When the button receives the "clicked" signal, it will call the function
* hello() passing it NULL as its argument.
* The hello() function is defined above.
*/

g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello), NULL);

/*
* This will cause the window to be destroyed by calling
* gtk_widget_destroy(window) when "clicked". Again, the destroy signal
* could come from here, or the window manager.
*/

g_signal_connect_swapped (G_OBJECT (button), "clicked",
G_CALLBACK (gtk_widget_destroy),
G_OBJECT (window));

/* This packs the button into the window (a gtk container). */
gtk_container_add (GTK_CONTAINER (window), button);

/* The final step is to display this newly created widget. */
gtk_widget_show (button);

/* and the window */
gtk_widget_show (window);

/*
* All GTK applications must have a gtk_main(). Control ends here and waits
* for an event to occur (like a key press or mouse event).
*/

gtk_main ();

return 0;
}

動作チェックは、一次評価として Fedora の wine 上で行っています。以下は bash 上で必要なパスを設定してコンパイル、実行した結果です。バイナリの実行では、もちろん wine が起動しています。

$ export PKG_CONFIG_PATH=/usr/i686-pc-mingw32/sys-root/mingw/lib/pkgconfig
$ i686-pc-mingw32-gcc -Wall -g hello.c -o hello.exe `pkg-config gtk+-2.0 --cfl
ags` `pkg-config gtk+-2.0 --libs`

$ ./hello.exe


Windows 上で実行する場合は、コンパイルしたプログラム hello.exe が参照しているランタイムライブラリ (DLL) もコピーしなければなりません。直接参照している DLL をチェックするには次のようにします。

$ i686-pc-mingw32-objdump -p hello.exe | grep "DLL Name"
DLL Name: libglib-2.0-0.dll
DLL Name: libgobject-2.0-0.dll
DLL Name: libgtk-win32-2.0-0.dll
DLL Name: KERNEL32.dll
DLL Name: msvcrt.dll

このうち、KERNEL32.dllmsvcrt.dll は、Windows ではシステム側の DLL ですので、コピーする必要はありません。と言っても MinGW 上では同名の DLL は存在しません。さらに libglib-2.0-0.dll などが参照している DLL も Windows 側にコピーする必要があります。wbc を利用すると、参照している DLL を簡単にチェックできます。大文字のファイル名の DLL がシステム DLL ですので、それ以外の DLL がコピーの対象になります(ただし、msvcrt.dll は除きます)。

0 件のコメント: