C++でHelloWorld&ビルド&デバッグの画像
芽萌丸プログラミング部 @programming
投稿日 2021/01/22

C++

C++でHelloWorld&ビルド&デバッグ

C++プロジェクトのHelloWorldのメモです。 C++ソースコードのビルドと簡単なデバッグの方法も載せておきます。 今回の必要となるものは、コンパイラ(g++)、デバッガ(gdb), そしてお好きなテキストエディタだけです。

目次:

前提

  • OS: Ubuntu 16.04 LTS
  • コンパイラ: g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
  • デバッガ: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
  • GNU Make 4.1

コンパイラ&デバッガその他のインストール

g++等をまとめてインストール:

$ sudo apt-get install build-essential

サンプルC++コード

src/helloworld.cpp

#include<iostream>

using namespace std;

int main() {
    string s1 = "Hello";
    string s2 = "World!";
    cout << s1 << s2 << endl;
}

ビルド

g++コマンドでビルドする方法

$ g++ src/helloworld.cpp -o a.out

makeコマンドでビルドする方法

プロジェクト内に以下の Makefile を作ります。

Makefile

#
# 汎用的に使えるMakefile
# 
# Usage:
# 
# プロダクションビルド:
# $ make
# 
# デバッグビルド:
# $ make debug
# 
# 中間ファイルを削除:
# $ make clean
# 
TARGET = a.out
CC = g++
# ソースフォルダ:
SRC_DIR := ./src
# 中間ファイルフォルダ:
OBJ_DIR := ./obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := 
# CPPFLAGSオプション:
# - 潜在的ミスを警告: -Wall 
# - c++14の機能を利用: -std=c++14 
# - バイナリサイズ削減: -Os -ffunction-sections -fdata-sections 
CPPFLAGS := -Wall -std=c++14 -Os -ffunction-sections -fdata-sections 
# CXXFLAGSオプション:
# - 依存ライブラリ pthread & libcurl をリンクする例:
# CXXFLAGS := -pthread $$(pkg-config --libs libcurl)
CXXFLAGS :=

ALL: exectable

# デバッグビルド: -g 
debug: CPPFLAGS += -DDEBUG -g
debug: CXXFLAGS += -DDEBUG -g
debug: exectable

exectable: $(OBJ_FILES)
    $(CC) $(LDFLAGS) -o $(TARGET) $^ $(CXXFLAGS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    $(CC) $(CPPFLAGS) -c -o $@ $<


.PHONY: clean
clean:
    rm -rf $(OBJ_DIR)/*.o
    @mkdir -p $(OBJ_DIR)

TIP: 上記の Makefile ファイルは汎用的にコピペで使えます!

Makefileと同じ階層でmakeを実行:

## プロダクション用ビルド:
$ make clean && make

実行

$ ./a.out 

HelloWorld!

デバッグ

gdbコマンドで簡単にデバッグを行うことができます。

まず-gオプションを付けてデバッグ用にビルドしておきます:

## g++でデバッグビルド:
$ g++ src/helloworld.cpp -o a.out -g

もしくは前述の Makefile で make debug します:

## make debug でデバッグビルド:
$ make clean && make debug

デバッグビルドができたらgdbデバッガを起動します:

$ gdb -tui ./a.out

上記のコマンドでは-tuiオプションでCUIベースの簡易GUIデバッガを起動しています。 これは開発環境のEclipse等とは毛色の違う非常に簡易的なデバッグツールですが、動作がとても軽いので個人的には重宝しています。

gdbの使い方

gdb内でよく使うコマンド:

  • r: プログラムを実行
  • b <行番号>: ブレークポイントをセット
  • i breakpoints: 全てのブレークポイントを表示
  • i locals: 全てのローカル変数を表示
  • i args: 全ての引数を表示
  • d <行番号>: ブレークポイントを削除
  • c: 次のブレークポイントまで実行
  • p <変数名>: 変数の中身を表示
  • s: ステップ・イン実行
  • bt: バックトレース(関数呼出履歴)を表示
  • print <コード>: コードを実行して表示
  • what <コード>: コードの型を表示
  • call <変数名>.assign("hoge"): 文字列な変数の中身を書き換え
  • q: デバッガを終了

gdbでのデバッグ実行例:

$ gdb -tui ./a.out

## 8行目にブレークポイントをセット:
(gdb) b 8

## プログラムを実行:
(gdb) r

## ここで8行目のブレークポイントでカーソルが停止

## 全てのブレークポイントを表示:
(gdb) i breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400c08 in main() at helloworld.cpp:8
        breakpoint already hit 1 time
## 上記一覧から1番のブレークポイントを解除:
(gdb) d 1

## 変数s1の内容を表示:
(gdb) p s1
$2 = "Hello"

## 変数s2の内容を書き換え:
(gdb) call s2.assign("Japan")
$2 = "Japan"

## 次のブレークポイントまで実行:
(gdb) c
Continuing.
HelloJapan ## <=== 書き換えた内容で標準出力されました!

## デバッガを終了:
(gdb) q

以上です。


芽萌丸プログラミング部
芽萌丸プログラミング部 @programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。