C言語GUI入門|よくあるエラーに対応する

GTK 4プログラムを作成していると、ヘッダーファイルが見つからない、pkg-configが実行できない、GTK 4が認識されない、DLLが見つからないといったエラーが発生することがあります。

このようなエラーは、ソースコードだけが原因とは限りません。使用しているターミナル、現在のディレクトリ、インストールしたパッケージ、コンパイルコマンドなども確認する必要があります。

この記事では、次の代表的なエラーへの対処方法を解説します。

  • gtk/gtk.hが見つからない
  • pkg-configが見つからない
  • gtk4が見つからない
  • GTK 4の関数をリンクできない
  • 実行時にDLLが見つからない
  • UCRT64以外のターミナルを使用している
  • PowerShellでBash用のコマンドを実行している
  • hello_gtk.cやhello_gtk.exeが見つからない
  • 実行中のhello_gtk.exeを上書きできない

エラーが表示されたときは、メッセージをよく読み、どの段階で問題が発生したのかを確認することが大切です。

エラーが発生する段階を確認する

GTK 4プログラムの作成から実行までは、大きく分けて次の段階があります。

ソースコードを作成
        ↓
pkg-configで設定を取得
        ↓
コンパイル
        ↓
リンク
        ↓
実行ファイルを作成
        ↓
プログラムを実行

エラーメッセージを見ると、どの段階で問題が発生しているのかを判断できます。

エラーの例発生している段階
gtk/gtk.hが見つからないコンパイル
pkg-configが見つからない設定の取得
gtk4が見つからない設定の取得
undefined referenceが表示されるリンク
DLLが見つからない実行
hello_gtk.cが見つからないファイルの指定
hello_gtk.exeを作成できない出力または上書き

最初にエラーの発生段階を確認すると、調べる範囲を絞り込めます。

図1:GTK 4プログラムでエラーが発生する場所

この図から分かること

GTK 4プログラムでは、ソースコードのコンパイルだけでなく、pkg-configによる設定取得、ライブラリとのリンク、実行時のDLL読み込みでもエラーが発生します。

表示されたメッセージから、どの段階で処理が止まったのかを確認することが、問題解決の第一歩です。

最初のエラーから確認する

コンパイル時には、複数のエラーメッセージが続けて表示されることがあります。

たとえば、最初の文法エラーが原因となり、その後の行でも関連するエラーが発生する場合があります。

最初のエラー
    ↓
後続の処理を正しく解釈できない
    ↓
関連するエラーが続けて表示される

すべてのエラーを同時に直そうとせず、最初に表示されたエラーから確認してください。

最初のエラーを修正して再コンパイルすると、後に続いていたエラーもまとめて消えることがあります。

動作確認に使用するプログラム

エラーの原因がソースコードにあるのか、開発環境にあるのか分からない場合は、次のプログラムで確認できます。

ボタンをクリックするとメッセージを表示するプログラム

ファイル名:hello_gtk.c

#include <gtk/gtk.h>

static void on_button_clicked(
    GtkButton *button,
    gpointer user_data
)
{
    (void)button;
    (void)user_data;

    g_print("ボタンが押されました\n");
}

static void on_activate(
    GtkApplication *app,
    gpointer user_data
)
{
    GtkWidget *window;
    GtkWidget *box;
    GtkWidget *button;

    (void)user_data;

    window = gtk_application_window_new(app);

    gtk_window_set_title(
        GTK_WINDOW(window),
        "ボタンのクリック処理"
    );

    gtk_window_set_default_size(
        GTK_WINDOW(window),
        640,
        480
    );

    box = gtk_box_new(
        GTK_ORIENTATION_VERTICAL,
        10
    );

    gtk_widget_set_halign(
        box,
        GTK_ALIGN_CENTER
    );

    gtk_widget_set_valign(
        box,
        GTK_ALIGN_CENTER
    );

    gtk_window_set_child(
        GTK_WINDOW(window),
        box
    );

    button = gtk_button_new_with_label(
        "クリックしてください"
    );

    g_signal_connect(
        button,
        "clicked",
        G_CALLBACK(on_button_clicked),
        NULL
    );

    gtk_box_append(
        GTK_BOX(box),
        button
    );

    gtk_window_present(GTK_WINDOW(window));
}

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

    app = gtk_application_new(
        "com.example.hellogtk",
        G_APPLICATION_DEFAULT_FLAGS
    );

    g_signal_connect(
        app,
        "activate",
        G_CALLBACK(on_activate),
        NULL
    );

    status = g_application_run(
        G_APPLICATION(app),
        argc,
        argv
    );

    g_object_unref(app);

    return status;
}

プログラムを入力したら、hello_gtk.cをUTF-8で保存してください。

基本的な確認手順

個別のエラーを調べる前に、次の項目を順番に確認します。

  1. MSYS2 UCRT64 Bashを使用しているか
  2. chap04ディレクトリへ移動しているか
  3. hello_gtk.cが保存されているか
  4. GCCが実行できるか
  5. pkg-configが実行できるか
  6. pkg-configがGTK 4を認識しているか
  7. 正しいコンパイルコマンドを使用しているか
  8. hello_gtk.exeが作成されたか
  9. 実行時にDLLが見つかっているか

この順番で確認すると、原因を見つけやすくなります。

UCRT64環境を確認する

使用中のMSYS2環境は、次のコマンドで確認できます。

echo $MSYSTEM

正しい場合は、次のように表示されます。

UCRT64

MSYS、MINGW64、CLANG64などが表示された場合は、使用している環境が異なります。

現在のターミナルを閉じ、VSCodeからMSYS2 UCRT64 Bashを開き直してください。

GCCの場所も確認します。

which gcc

UCRT64用のGCCを使用している場合は、次の場所が表示されます。

/ucrt64/bin/gcc

pkg-configの場所は、次のコマンドで確認できます。

which pkg-config

UCRT64用のpkg-configを使用している場合は、ucrt64を含む場所が表示されます。

MSYS2 UCRT64環境では、PATHの先頭に/ucrt64/binが追加されます。そのため、UCRT64用のGCCやライブラリが優先して使用されます。

図2:UCRT64環境を確認する手順

この図から分かること

GTK 4プログラムを正しくコンパイルするには、GCC、pkg-config、GTK 4をUCRT64環境でそろえる必要があります。

最初にecho $MSYSTEMを実行し、UCRT64と表示されることを確認します。その後、GCC、pkg-config、GTK 4の順に確認すると、環境の混在を見つけやすくなります。

現在のディレクトリを確認する

hello_gtk.cは、次のディレクトリに保存しています。

C:\cgui\chap04

MSYS2 UCRT64 Bashでは、次のように表します。

/c/cgui/chap04

次のコマンドでchap04へ移動します。

cd /c/cgui/chap04

現在の場所を確認します。

pwd

正しい場合は、次のように表示されます。

/c/cgui/chap04

ファイルの一覧も確認します。

ls

hello_gtk.cが表示されることを確認してください。

gtk/gtk.hが見つからない

コンパイル時に、次のようなエラーが表示されることがあります。

fatal error: gtk/gtk.h: No such file or directory

このエラーは、GCCがgtk/gtk.hを見つけられないことを表しています。

主な原因

  • コンパイルコマンドに--cflagsが含まれていない
  • pkg-configの指定が間違っている
  • GTK 4がインストールされていない
  • UCRT64以外のターミナルを使用している
  • gtk/gtk.hの記述が間違っている
  • UCRT64用ではないGCCを使用している

gtk/gtk.hの記述を確認する

正しい記述は、次のとおりです。

#include <gtk/gtk.h>

次のような記述ではありません。

#include <gtk.h>
#include <gtk4/gtk.h>

GTK 4の公式ドキュメントでも、GTKアプリではgtk/gtk.hを読み込み、コンパイラへヘッダーファイルの場所を知らせるためにpkg-configを使用すると説明されています。

--cflagsの出力を確認する

次のコマンドを実行します。

pkg-config --cflags gtk4

正しく認識されている場合は、-Iから始まるヘッダーファイルの検索場所が表示されます。

-I/ucrt64/include/gtk-4.0
-I/ucrt64/include/glib-2.0
...

実際の表示内容は、GTK 4のバージョンや環境によって異なります。

何も表示されない場合やエラーになる場合は、GTK 4のインストールと使用中の環境を確認してください。

正しいコマンドでコンパイルする

短いコマンドは、次のとおりです。

gcc hello_gtk.c -o hello_gtk.exe $(pkg-config --cflags --libs gtk4)

警告を有効にする推奨コマンドは、次のとおりです。

gcc -std=c17 -Wall -Wextra $(pkg-config --cflags gtk4) hello_gtk.c -o hello_gtk.exe $(pkg-config --libs gtk4)

どちらのコマンドにも、GTK 4のヘッダーファイルを検索するための情報が含まれています。

pkg-configが見つからない

次のようなエラーが表示される場合があります。

bash: pkg-config: command not found

このエラーは、Bashがpkg-configを見つけられないことを表しています。

pkg-configの場所を確認する

次のコマンドを実行します。

which pkg-config

何も表示されない場合は、pkg-config互換ツールがインストールされていないか、UCRT64環境のPATHが正しく設定されていない可能性があります。

UCRT64用のpkgconfをインストールする

MSYS2 UCRT64 Bashで、次のコマンドを実行します。

pacman -S mingw-w64-ucrt-x86_64-pkgconf

mingw-w64-ucrt-x86_64-pkgconfは、pkg-configと互換性のあるツールです。MSYS2パッケージ情報:pkgconf

インストール後は、ターミナルを開き直して確認します。

pkg-config --version

バージョン番号が表示されれば、pkg-configを実行できます。

gtk4が見つからない

pkg-configは実行できても、次のようなエラーが表示される場合があります。

Package gtk4 was not found in the pkg-config search path.
Package 'gtk4', required by 'virtual:world', not found

このエラーは、pkg-configがGTK 4の設定情報を見つけられないことを表しています。

主な原因

  • GTK 4がインストールされていない
  • UCRT64用ではないGTK 4をインストールしている
  • UCRT64以外のターミナルを使用している
  • GTK 3を指定している
  • パッケージ名を間違えている

GTK 4のバージョンを確認する

次のコマンドを実行します。

pkg-config --modversion gtk4

正しく認識されている場合は、GTK 4のバージョンが表示されます。

4.x.x

実際の数字は、インストールされているバージョンによって異なります。

GTK 4パッケージを確認する

次のコマンドで、UCRT64用のGTK 4がインストールされているか確認できます。

pacman -Q mingw-w64-ucrt-x86_64-gtk4

インストールされている場合は、パッケージ名とバージョンが表示されます。

パッケージが見つからない場合は、次のコマンドでインストールします。

pacman -S mingw-w64-ucrt-x86_64-gtk4

このパッケージは、MSYS2のUCRT64リポジトリから提供されています。

インストール後は、もう一度確認します。

pkg-config --modversion gtk4

gtk4の指定を確認する

pkg-configへ指定する名前はgtk4です。

正しいコマンドは、次のとおりです。

pkg-config --cflags --libs gtk4

次のようにGTKと4の間へハイフンや空白を入れないでください。

pkg-config --cflags --libs gtk-4
pkg-config --cflags --libs gtk 4

また、gtk+-3.0を指定するとGTK 3の情報を探すことになります。

pkg-config --cflags --libs gtk+-3.0

この教材で使用しているのはGTK 4なので、gtk4を指定します。

GTK 4の関数をリンクできない

gtk/gtk.hは読み込めても、次のようなエラーが表示される場合があります。

undefined reference to `gtk_application_new'
undefined reference to `gtk_application_window_new'
undefined reference to `gtk_window_present'

このエラーは、ソースコードのコンパイルは進んだものの、GTK 4の関数が含まれるライブラリをリンクできなかったことを表しています。

主な原因

  • コンパイルコマンドに--libsが含まれていない
  • pkg-configの指定が間違っている
  • GTK 4のライブラリを正しく認識できていない
  • ライブラリ指定の位置が適切でない
  • 異なるMSYS2環境のライブラリが混在している

--libsの出力を確認する

次のコマンドを実行します。

pkg-config --libs gtk4

正しく認識されている場合は、次のようなライブラリ情報が表示されます。

-L/ucrt64/lib
-lgtk-4
-lgobject-2.0
-lglib-2.0
...

実際の内容や順番は、環境によって異なります。

ライブラリ指定を含めてコンパイルする

短いコマンドは、次のとおりです。

gcc hello_gtk.c -o hello_gtk.exe $(pkg-config --cflags --libs gtk4)

警告を有効にする推奨コマンドは、次のとおりです。

gcc -std=c17 -Wall -Wextra $(pkg-config --cflags gtk4) hello_gtk.c -o hello_gtk.exe $(pkg-config --libs gtk4)

推奨コマンドでは、pkg-config --libs gtk4をhello_gtk.cより後ろに配置しています。ライブラリの指定は、リンクするソースファイルやオブジェクトファイルより後ろに置くと安全です。

DLLが見つからない

コンパイルには成功しても、hello_gtk.exeの実行時にDLLが見つからないというメッセージが表示されることがあります。

たとえば、Windowsから次のようなメッセージが表示されます。

libgtk-4-1.dllが見つからないため、コードの実行を続行できません。

表示されるDLL名は、環境や不足しているファイルによって異なります。

主な原因

  • PowerShellから実行している
  • エクスプローラーから直接実行している
  • UCRT64のbinディレクトリがPATHに含まれていない
  • UCRT64用のGTK 4が正しくインストールされていない
  • hello_gtk.exeだけを別のディレクトリへコピーした
  • 必要なDLLを削除または移動した

MSYS2 UCRT64 Bashから実行する

開発中は、MSYS2 UCRT64 Bashから実行してください。

cd /c/cgui/chap04
./hello_gtk.exe

UCRT64環境では、GTK 4のDLLが保存されている/ucrt64/binがPATHに含まれています。

PATHは、次のコマンドで確認できます。

echo $PATH

表示内容に/ucrt64/binが含まれていることを確認してください。

GTK 4のDLLを確認する

GTK 4の主要なDLLは、/ucrt64/binに保存されています。

次のコマンドで確認できます。

ls /ucrt64/bin/libgtk-4*.dll

GTK 4が正しくインストールされていれば、該当するDLLが表示されます。

実行ファイルが必要とするDLLは、次のコマンドでも確認できます。

ldd hello_gtk.exe

依存するDLLが見つからない場合は、その行にnot foundが表示されることがあります。

開発中は、DLLをchap04へ手作業でコピーする必要はありません。MSYS2 UCRT64 Bashから実行し、UCRT64環境のDLLを使用します。

開発環境のないWindowsへ配布するときのDLL配置は、第7章で解説します。

UCRT64以外のターミナルを使用している

MSYS2には、複数のターミナル環境があります。

環境この教材での使用
UCRT64使用する
MSYS使用しない
MINGW64使用しない
CLANG64使用しない

見た目が似ていても、使用するGCC、ライブラリ、PATHなどが異なります。

UCRT64以外のターミナルでは、次のような問題が発生する可能性があります。

  • gccが見つからない
  • pkg-configが見つからない
  • gtk4が見つからない
  • gtk/gtk.hが見つからない
  • 異なる環境のライブラリが使われる
  • 実行時にDLLが見つからない

必ず次のコマンドで確認してください。

echo $MSYSTEM
UCRT64

UCRT64と表示されない場合は、ターミナルを開き直します。

GCCとGTK 4の環境をそろえる

次のコマンドでGCCの場所を確認します。

which gcc
/ucrt64/bin/gcc

GTK 4のインストール先は、次のコマンドで確認できます。

pkg-config --variable=prefix gtk4

環境によって、次のような場所が表示されます。

/ucrt64

または、次のようなWindows形式の場所が表示される場合があります。

C:/msys64/ucrt64

どちらの場合も、ucrt64を含む場所を指していれば、UCRT64用のGTK 4が認識されています。

GCCは/ucrt64、GTK 4は/mingw64というように異なる環境を指している場合は、ターミナルを開き直してください。

PowerShellでBash用コマンドを実行している

この教材で使用しているコンパイルコマンドは、MSYS2 UCRT64 Bashを前提としています。

gcc hello_gtk.c -o hello_gtk.exe $(pkg-config --cflags --libs gtk4)

このコマンドには、Bashのコマンド置換が含まれています。

$(pkg-config --cflags --libs gtk4)

PowerShellにも似た表記がありますが、外部コマンドの出力を引数として渡す方法やPATHの設定がBashとは異なります。そのため、同じコマンドをPowerShellで実行しても、期待どおりに動作しない場合があります。

また、PowerShellでは、UCRT64用のGCCやGTK 4がPATHに含まれていない可能性があります。

使用中のターミナルを確認する

VSCodeのターミナルに、次のような表示がある場合はPowerShellです。

PS C:\cgui\chap04>

MSYS2 UCRT64 Bashでは、次のようにドル記号を含むプロンプトが表示されます。

ユーザー名@コンピューター名 UCRT64 /c/cgui/chap04
$

表示形式は環境によって多少異なりますが、UCRT64と表示されていることを確認してください。

MSYS2 UCRT64 Bashへ切り替える

VSCodeでは、次の手順で切り替えます。

  1. 現在のPowerShellターミナルを閉じる
  2. ターミナルメニューを開く
  3. 新しいターミナルを選択する
  4. ターミナル右上の選択メニューを開く
  5. MSYS2 UCRT64 Bashを選択する
  6. echo $MSYSTEMでUCRT64を確認する

この教材のBash用コマンドは、MSYS2 UCRT64 Bashで実行してください。

hello_gtk.cが見つからない

コンパイル時に、次のようなエラーが表示されることがあります。

cc1.exe: fatal error: hello_gtk.c: No such file or directory

このエラーは、現在のディレクトリにhello_gtk.cが存在しないことを表しています。

現在のディレクトリを確認する

pwd
/c/cgui/chap04

ファイルの一覧を確認します。

ls

hello_gtk.cが表示されない場合は、次の点を確認してください。

  • VSCodeでhello_gtk.cを保存しているか
  • C:\cgui\chap04へ保存しているか
  • ファイル名のスペルが正しいか
  • hello_gtk.c.txtになっていないか
  • 別の章のディレクトリへ保存していないか

ファイル名は、大文字と小文字も含めて正確に指定してください。

hello_gtk.exeが見つからない

実行時に、次のようなエラーが表示される場合があります。

bash: ./hello_gtk.exe: No such file or directory

このエラーは、現在のディレクトリにhello_gtk.exeが存在しないことを表しています。

次のコマンドで確認します。

ls hello_gtk.exe

ファイルがない場合は、hello_gtk.cをコンパイルします。

短いコマンドは、次のとおりです。

gcc hello_gtk.c -o hello_gtk.exe $(pkg-config --cflags --libs gtk4)

警告を有効にする推奨コマンドは、次のとおりです。

gcc -std=c17 -Wall -Wextra $(pkg-config --cflags gtk4) hello_gtk.c -o hello_gtk.exe $(pkg-config --libs gtk4)

コンパイルに失敗している場合は、hello_gtk.exeが作成されません。コンパイル時に表示された最初のエラーから確認してください。

hello_gtk.exeを上書きできない

再コンパイル時に、次のようなエラーが表示されることがあります。

cannot open output file hello_gtk.exe: Permission denied

このエラーは、hello_gtk.exeが実行中で、Windowsがファイルを使用しているときに発生することがあります。

対処方法

  1. 表示中のGTK 4ウィンドウを閉じる
  2. ターミナルへプロンプトが戻ったことを確認する
  3. hello_gtk.cを保存する
  4. もう一度コンパイルする

短いコマンドは、次のとおりです。

gcc hello_gtk.c -o hello_gtk.exe $(pkg-config --cflags --libs gtk4)

推奨コマンドは、次のとおりです。

gcc -std=c17 -Wall -Wextra $(pkg-config --cflags gtk4) hello_gtk.c -o hello_gtk.exe $(pkg-config --libs gtk4)

実行中のウィンドウが見つからない場合は、タスクバーに最小化されていないか確認してください。

ウィンドウは表示されるがメッセージが出ない

ボタンをクリックしても、ターミナルにメッセージが表示されない場合は、次の部分を確認します。

コールバック関数を確認する

static void on_button_clicked(
    GtkButton *button,
    gpointer user_data
)
{
    (void)button;
    (void)user_data;

    g_print("ボタンが押されました\n");
}

g_signal_connectを確認する

g_signal_connect(
    button,
    "clicked",
    G_CALLBACK(on_button_clicked),
    NULL
);

主な確認項目は、次のとおりです。

  • シグナル名がclickedになっているか
  • clickedがすべて小文字になっているか
  • on_button_clickedのスペルが一致しているか
  • G_CALLBACKの中で関数を指定しているか
  • g_printの文字列に\nが含まれているか
  • 修正後にhello_gtk.cを保存したか
  • 修正後に再コンパイルしたか
  • 古いhello_gtk.exeを実行していないか

ソースコードを修正しただけでは、hello_gtk.exeの内容は更新されません。保存後に再コンパイルしてください。

図3:エラーを確認して解決する流れ

この図から分かること

エラーが発生したときは、最初に表示されたメッセージを確認し、コンパイル、リンク、実行のどこで止まったのかを判断します。

次に、UCRT64環境、現在のディレクトリ、ファイル、pkg-config、GTK 4の順番で確認します。

修正後はhello_gtk.cを保存し、再コンパイルしてから実行します。エラーが残っている場合は、再び最初のエラーへ戻って確認します。

復旧後にコンパイルと実行を確認する

問題を修正したら、chap04ディレクトリへ移動します。

cd /c/cgui/chap04

短いコマンドでコンパイルします。

gcc hello_gtk.c -o hello_gtk.exe $(pkg-config --cflags --libs gtk4)

警告を有効にする場合は、推奨コマンドを使用します。

gcc -std=c17 -Wall -Wextra $(pkg-config --cflags gtk4) hello_gtk.c -o hello_gtk.exe $(pkg-config --libs gtk4)

コンパイル後にhello_gtk.exeを確認します。

ls hello_gtk.exe

次のように表示されれば、実行ファイルが作成されています。

hello_gtk.exe

続いて、プログラムを実行します。

./hello_gtk.exe

実行結果の例

ウィンドウの中央に「クリックしてください」と表示されたボタンが現れます。

ボタンをクリックすると、MSYS2 UCRT64 Bashへ次のメッセージが表示されます。

ボタンが押されました

複数回クリックすると、クリックした回数だけ表示されます。

ボタンが押されました
ボタンが押されました
ボタンが押されました

解決できない場合に記録する情報

エラーを調べても解決できない場合は、次の情報を記録しておくと、原因を確認しやすくなります。

  • 実行したコマンド
  • 最初に表示されたエラーメッセージ
  • エラーメッセージ全体
  • echo $MSYSTEMの結果
  • which gccの結果
  • which pkg-configの結果
  • pkg-config --modversion gtk4の結果
  • pwdの結果
  • lsの結果
  • 使用しているhello_gtk.cの内容
  • コンパイルは成功するか
  • hello_gtk.exeは作成されるか
  • ウィンドウは表示されるか
  • ターミナルに警告が表示されるか

エラーメッセージは、途中を省略せずに記録してください。特に、最初に表示されたエラーと、実行したコマンドの組み合わせが重要です。