MSYS2 MinGW GCC環境をつくる(その4)

MinGW GCC 環境をつくる その 4 です。今回は Eclipse CDT からアプリケーションをデバッグ実行する方法を説明します。

MSYS2 環境を構築して MinGW gcc コンパイラをインストールする方法 Eclipse CDT をインストールして MinGW gcc コンパイラを使用する方法については 過去の記事を参照してください。

サンプルコード

MSYS2 MinGW GCC 環境をつくる その 2 を参考にして 簡単なサンプルコードを用意してください。

sample1.cpp
#include <iostream> int main(int argc, char* argv[]) { std::cout << "Hello, World!!" << std::endl; std::string name = "taro"; std::cout << "Hello, " << name << std::endl; return 0; }
Makefile
TARGET=sample1 SRC_DIR=./src OBJ_DIR=./obj BIN_DIR=./bin CC = gcc CXX = g++ CPPFLAGS = CXXFLAGS = LDFLAGS = LOADLIBES = LDLIBS = -lstdc++ EXTENSION:=.cpp SRC:=$(wildcard $(SRC_DIR)/**/*$(EXTENSION)) $(wildcard $(SRC_DIR)/*$(EXTENSION)) SRC_WITHOUT_PREFIX:=$(patsubst $(SRC_DIR)%,%,$(SRC)) OBJ:=$(addprefix $(OBJ_DIR),$(SRC_WITHOUT_PREFIX:$(EXTENSION)=.o)) $(BIN_DIR)/$(TARGET) : $(OBJ) @if [ ! -d $(BIN_DIR) ]; then mkdir $(BIN_DIR); fi $(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(OBJ_DIR)/%.o : $(SRC_DIR)/%$(EXTENSION) @if [ ! -d $(OBJ_DIR) ]; then mkdir $(OBJ_DIR); fi $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< .PHONY: all clean all: $(BIN_DIR)/$(TARGET) clean: @if [ -d $(OBJ_DIR) ]; then rm -fr $(OBJ_DIR); fi @if [ -d $(BIN_DIR) ]; then rm -fr $(BIN_DIR); fi

デバッグ実行 1 回目

まだ何も準備をしていませんが デバッグ実行をするとどうなるのか試してみましょう。

Project Explorer sample1 プロジェクトを選択して 右クリック Debug AsLocal C/C++ Application をクリックします。

Error with command: gdb --version というエラーが表示されてしまいました。

gdb がインストールされていないと このようなエラーが表示されてアプリケーションの起動に失敗してしまいます。

gdb をインストールする

プログラムのデバッグ実行には gdb が必要になります。いつものように MSYS2 のパッケージマネージャー pacman を使って gdb をインストールしていきます。

C:¥msys64¥mingw64.exe を起動して gdb を含むパッケージを検索します。

gdbを含むパッケージを検索するコマンド
$ pacman -Ssq gdb

MinGW 64 ビット版 パッケージである mingw-w64-x86_64-gdb をインストールします。

mingw-w64-x86_64-gdbパッケージをインストールするコマンド
$ pacman -S mingw-w64-x86_64-gdb

インストールを行いますか? と確認メッセージが表示されるので Y を入力してから Enter を押します。

デバッグ実行 2 回目

gdb のインストールが完了したら Eclipse CDT に戻って再びデバッグ実行をしてみます。

先程とはエラーメッセージの内容が変わりましたが またしても起動に失敗してしまいました。

Error in final launch sequence  
Failed to execute MI command: -exec-run

このようなエラーメッセージが出てしまう場合には Eclipse を管理者権限で起動すると問題が解決するようです。Eclipse を管理者権限で起動し直してみましょう。

デバッグ実行 3 回目

Eclipse を管理者権限で起動したら もう一度 デバッグ実行に挑戦です。

何やら長い英語のメッセージが表示されました。

This kind of launch is configured to open the Debug perspective when it suspends.

This Debug perspective is designed to support application debugging. It incorporates view for displaying the debug stack, variables and breakpoint management.

Do you want to open this perspective now ?"

日本語に翻訳すると以下のような意味になります。

この種類の起動はデバッグ・パースペクティブを開くように構成されています。

デバッグ・パースペクティブはアプリケーションのデバッグをサポートするために設計されています。スタック、変数、ブレークポイント管理を表示するビューが組み込まれています。

このパースペクティブを開きますか?

Yes をクリックして デバッグ パースペクティブに切り替えましょう。次回以降 このダイアログを表示しないようにする場合は Remember my decision にチェックを入れます。

ようやくデバッグ実行を開始することができました。

しかし よく見ると No source available for "main() at 0x40156e main 関数のソースコードが見つからない というメッセージが出ていますね。

実はデバッグ実行するためには ビルド時にデバッグ用のオプションを指定してデバッグ用の実行ファイルを作成しておく必要があります。これをデバッグ ビルドと呼びます

停止ボタンをクリックして 一旦 デバッグを終了してください。元の C/C++パースペクティブに戻すには Eclipse のメニュー右上に表示されている C と書かれているアイコンをクリックします。

Makefile を変更してデバッグビルド構成にする

アプリケーションをデバッグ用にビルドするには コンパイル時のオプションに -g3 ジースリー -O0 オーゼロ を指定します。

  • -g3 ジースリー 最大限のデバッグ情報を付加します。
  • -O0 オーゼロ コンパイル時の最適化を無効にします。

Makefile CXXFLAGS= に上記オプションを指定します。

デバッグ用のオプション
CXXFLAGS = -g3 -O0

Makefile にオプションを追加して保存したら Eclipse のメニューバーから ProjectClean... を実行します。これで make clean が実行され実行ファイルが削除されます

続いて Eclipse のメニューバーから ProjectBuild Project を実行してアプリケーションをビルドします。これで デバッグ情報の付いた実行ファイルが出来ます。

デバッグ実行 4 回目

4 回目のデバッグ実行です。Project Explorer から sample1 プロジェクトを選択して 右クリック Debug AsLocal C/C++ Application をクリックします。

今度こそデバッグ実行成功です!

main 関数が実行されて最初の行でプログラムが停止状態になっています。

  • F6 1 行ずつステップ実行できます。
  • F8 でブレークポイントで停止するまで一気に実行できます。

詳しくは Eclipse のメニューバーにマウスカーソルを当ててツールチップを確認してみてください。機能名とショートカットキーを確認することができます。

Variables ビューでは変数の値を確認することができます。

いろいろと触っていれば次第に分かってくると思います。

Makefile を改善する

Makefile を編集して CXXFLAGS = -g3 -O0 としましたが これでは常にデバッグ情報が付加された実行ファイルが出来てしまいます。

Makefile を改善して デバッグ ビルドとリリース ビルドを切り替えられるようにしたいと思います。make には変数の値によって条件分岐する機能があります。以下の例では環境変数 CONFIG_NAME Debug が設定されている場合は CXXFLAGS -g3 -O0 を追加します。そうでなければ CXXFLAGS -O2 を追加します。-O2 はリリース用の標準的な最適化オプションです

環境変数CONFIG_NAMEにDebugが設定されているときはデバッグ情報を付加する
ifeq ($(CONFIG_NAME), Debug) CXXFLAGS += -g3 -O0 else CXXFLAGS += -O2 endif

先程までの CXXFLAGS = -g3 -O0 は元の CXXFLAGS = に戻しておきます。

Makefile 全体は以下のようになります。

Makefile
TARGET=sample1 SRC_DIR=./src OBJ_DIR=./obj BIN_DIR=./bin CC = gcc CXX = g++ CPPFLAGS = CXXFLAGS = LDFLAGS = LOADLIBES = LDLIBS = -lstdc++ ifeq ($(CONFIG_NAME), Debug) CXXFLAGS += -g3 -O0 else CXXFLAGS += -O2 endif EXTENSION:=.cpp SRC:=$(wildcard $(SRC_DIR)/**/*$(EXTENSION)) $(wildcard $(SRC_DIR)/*$(EXTENSION)) SRC_WITHOUT_PREFIX:=$(patsubst $(SRC_DIR)%,%,$(SRC)) OBJ:=$(addprefix $(OBJ_DIR),$(SRC_WITHOUT_PREFIX:$(EXTENSION)=.o)) $(BIN_DIR)/$(TARGET) : $(OBJ) @if [ ! -d $(BIN_DIR) ]; then mkdir $(BIN_DIR); fi $(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(OBJ_DIR)/%.o : $(SRC_DIR)/%$(EXTENSION) @if [ ! -d $(OBJ_DIR) ]; then mkdir $(OBJ_DIR); fi $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< .PHONY: all clean all: $(BIN_DIR)/$(TARGET) clean: @if [ -d $(OBJ_DIR) ]; then rm -fr $(OBJ_DIR); fi @if [ -d $(BIN_DIR) ]; then rm -fr $(BIN_DIR); fi

環境変数 CONFIG_NAME を設定する

sample1 プロジェクトに環境変数を設定するために以下の手順を実施します。

Project Explorer から sample1 プロジェクトを選択して 右クリック Properties をクリックします。プロパティが表示されたら C/C++ BuildEnvironment を開きます。

Add... ボタンをクリックします。

新しい環境変数を設定するダイアログが表示されるので Name CONFIG_NAME Value Debug と入力して OK をクリックします。

Apply and Close をクリックしてプロパティを閉じます。

これで 環境変数 CONFIG_NAME の値が Debug に設定されたので ビルドを実行するとデバッグ情報付きの実行ファイルが出来上がります。リリース用の実行ファイルを出力したい場合は環境変数 CONFIG_NAME の値を Debug 以外の値 たとえば Release に変更します。

構成 Configuration と連動させることもできる

環境変数 CONFIG_NAME の値を書き換えるのではなく Eclipse CDT の構成 Configuration 切替と連動させることもできます。

環境変数 CONFIG_NAME を選択した状態で Edit... をクリックします。

環境変数の値を編集するダイアログが表示されるので Value の値を ${ConfigName} に変更して OK をクリックします。

環境変数 CONFIG_NAME の値が ${ConfigName} に変わりました。${ConfigName} は構成名が設定される Eclipse CDT のビルトイン変数です。構成を追加するために Manage Configurations... をクリックします。

構成を管理するダイアログが表示されるので New... をクリックします。

新しい構成を作成するダイアログが表示されます。Name Debug と入力して OK をクリックします。

新しい構成 Debug が作成されました。Debug 行を選択した状態で Set Active をクリックして Debug 構成をアクティブにしておきましょう。OK をクリックしてダイアログを閉じます。

構成として Debug を選択できるようになりました。

ビルトイン変数 ${ConfigName} にはアクティブになっている構成の名前が設定されます。そして環境変数 CONFIG_NAME にはビルトイン変数 ${ConfigName} の値が設定されます。

つまり Debug 構成をアクティブにすると環境変数 CONFIG_NAME Debug が設定され Makefile の分岐条件で -g3 -O0 オプションが指定されるようになったわけです。

デバッグ実行をエントリーポイントで停止させない

デフォルトではブレークポイントの有無に関わらず エントリーポイント 通常は main 関数 でデバッガが停止するようになっています。

F8 1 回押せば済む話ですが それでもなんとなく面倒です。デバッグ構成を変更して エントリーポイントでデバッガが停止しないように変更してみましょう。

Project Explorer sample1 プロジェクトを選択して 右クリック Debug AsDebug Configurations... をクリックします。

Debugger タブに切り替えて Stop on start up at: main のチェックを外します。Apply をクリックします。これで エントリーポイントでデバッガが停止しないようになります。

Eclipse CDT + gdb でのデバッグ実行手順の説明は以上になります。

この記事を共有しませんか?