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;
}
MakefileTARGET=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 As → Local 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 のメニューバーから Project → Clean... を実行します。(これで make clean
が実行され実行ファイルが削除されます。)
続いて、 Eclipse のメニューバーから Project → Build Project を実行してアプリケーションをビルドします。これで、 デバッグ情報の付いた実行ファイルが出来ます。
デバッグ実行(4回目)
4 回目のデバッグ実行です。Project Explorer から sample1
プロジェクトを選択して、 右クリック、 Debug As → Local 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
全体は以下のようになります。
MakefileTARGET=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++ Build
→ Environment
を開きます。
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 As → Debug Configurations... をクリックします。
Debugger
タブに切り替えて、 Stop on start up at: main
のチェックを外します。Apply をクリックします。これで、 エントリーポイントでデバッガが停止しないようになります。
Eclipse CDT + gdb でのデバッグ実行手順の説明は以上になります。