LoginSignup
0
0

mesonかcmakeでGTKプログラムをビルドする(リソースもね)

Posted at

自分は、GTKのプログラミングをする際には主にPythonを使っているのですが、たまにC言語で書いてみようか、と思う時があるのですよ。
まぁそれも仕事ではなく私事だし、その上気分転換的な感じなので、惰性的にビルド環境にcmakeを使っていたのですが、GTK的にはmeson推しのようなので、この度mesonを使ってみようかと思います。

あと、リソースを使うことを前提とします。
GTKのリソースについては、以前書いた記事を参考にしてください。

以下、ubuntu23.10での作業を前提としています。

ソースコードの作成

まずは、ソースコードを用意します。
適当なディレクトリに、以下のファイルを用意します。

  • main.c
  • main.ui
  • app.gresource.xml
main.c
#include <gtk/gtk.h>

static void on_activate(GApplication *app, gpointer cb_data)
{
	GtkBuilder *builder;
	GtkWidget *window;

	builder = gtk_builder_new();
	gtk_builder_add_from_resource(builder, "/com/example/example01/main.ui", NULL);

	window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
	gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
	gtk_widget_set_visible(window, TRUE);

	g_object_unref(G_OBJECT(builder));
}

int main(int argc, char *argv[])
{
	GtkApplication *app;

	app = gtk_application_new(NULL, 0);
	g_signal_connect(G_OBJECT(app), "activate", G_CALLBACK(on_activate), NULL);
	return g_application_run(G_APPLICATION(app), argc, argv);
}
main.ui
<?xml version="1.0" encoding="utf-8"?>
<interface>
	<object class="GtkWindow" id="window">
		<property name="default-width">300</property>
		<child>
			<object class="GtkLabel">
				<property name="label">Hello, world!</property>
			</object>
		</child>
	</object>
</interface>
app.gresource.xml
<?xml version="1.0" encoding="utf-8"?>
<gresources>
	<gresource prefix="/com/example/example01">
		<file preprocess="xml-stripblanks">main.ui</file>
	</gresource>
</gresources>

まずは、これらをmesonもcmakeも使わずにビルドしてみます。
ubuntuであれば、以下のコマンドで必要なパッケージをインストールします。

sudo apt install -y build-essential libgtk-4-dev libxml2-utils

以下のコマンドでビルドします。

glib-compile-resources app.gresource.xml --target resource.c --generate-source && \
  gcc main.c resource.c $(pkg-config --cflags --libs gtk4)

ビルドが成功すると、「a.out」という実行ファイルが作成されるので、実行してみます。

./a.out

とりあえず確認が取れたら、今回のビルドで作られた「resource.c」と「a.out」は削除しておきましょう。

mesonでビルドする。

mesonでビルドしてみます。
まずは、mesonをインストールしなければなりません。
「aptを使ってインストールする」方法と「pipを使ってインストールする」方法がありますが、今回はaptを使います。

sudo apt install -y meson

mesonでビルドするには、「meson.build」というファイルを作成します。
以下の内容にします。

meson.build
# 「プロジェクト名」と「言語」を指定します。
# 「プロジェクト名」はご自由に。
project('example01', 'c')

# 依存しているライブラリを指定します。
# ライブラリ名は、pkg-configで指定するライブラリ名です。
# また、複数ある場合には、「`gtk4 gmodule-2.0`」というように、文字列でスペース区切りで指定します。
libs = dependency('gtk4')

# リソースをビルドするための指定をします。
# 「dependencies」に、「app.gresource.xml」で含まれているファイルを指定します。
gnome = import('gnome')
resources = gnome.compile_resources('resources', 'app.gresource.xml',
  dependencies: [files('main.ui')],
  source_dir: [meson.source_root()])

# ビルドする実行ファイルを指定します。
# 実行ファイル名は、今回は先に指定したプロジェクト名と同じ「example01」にしていますが、
# 必ず同じにする必要はありません。
executable('example01', ['main.c', resources],
  dependencies: [libs])

リソースをビルドするためのgnome.compile_resourcesについては、ここに詳細が書かれています。

最初に一回、ビルド環境を構築します。

meson setup build

このコマンドにより、「build」というディレクトリが作成されます。
このディレクトリの名前は、別に何でも構いません。
このディレクトリに、ビルドの際に作成されるファイルが出力されます。
(一般的に、gitなどのバージョン管理をしないファイルです)

次に、ビルドを行います。

meson compile -C build

正常にビルドが行われれば、buildディレクトリに実行ファイル(今回はexecutableexample01と指定したので、example01というファイル)が作成されます。
これを実行して、動作を確認します。

./build/example01

ソースファイルを変更した際には、「meson compile」コマンドを実行してビルドすればよいです。

ついでに、cmakeでビルドする。

ついでなんで、今までやっていたcmakeでのビルドもしてみましょうか。
先のmesonでのビルドを行った場合は、一旦buildディレクトリを削除しておいてください。

cmakeでビルドするための、「CMakeLists.txt」ファイルを作成します。

CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)

PROJECT(example01)

FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(LIBS REQUIRED gtk4)

INCLUDE_DIRECTORIES(${LIBS_INCLUDE_DIRS})

ADD_CUSTOM_COMMAND(
	OUTPUT resource.c
	COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && glib-compile-resources app.gresource.xml --target ${CMAKE_CURRENT_BINARY_DIR}/resource.c --generate-source
	DEPENDS
		app.gresource.xml
		main.ui
)

ADD_EXECUTABLE(example01
	main.c
	resource.c
)
TARGET_LINK_LIBRARIES(example01 ${LIBS_LIBRARIES})

cmakeのパッケージをインストールします。

sudo apt install cmake

cmakeでビルドするためのセットアップを行います。
mesonと同様に、buildというディレクトリを作り、そこにビルドの際に作成されるファイルが出力されるようにします。

mkdir build && pushd build && cmake .. && popd

ビルドを行います。

make -C build

mesonと同じように実行ファイルは「example01」にしてありますので、実行します。

./build/example01

ハマりポイント

冒頭でも書いたとおり、GTKのリソースを使う点が今回の話のポイントなのですが、特に問題なのが glib-compile-resourcesコマンドを実行するにはapp.gresource.xmlがあるディレクトリで実行しなければならない点。
というのも、中に書かれているファイルパス(今回の例では、main.uiなど)は、app.gresource.xmlからの相対パスではなく、実行時のカレントディレクトリからの相対パスとして処理されてしまうのです。
なので、mesonもcmakeも、ソースディレクトリで実行するようにしています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0