C++ Docker Linux

Dockerを使用した簡単なC++実行環境の構築

投稿日:

今回は、C++の機能を調査するための簡単なテスト環境を、Dockerを用いて構築する手順を解説します。

要件

  • 単一のソースファイルをg++を用いてコンパイルできること
  • 上記g++で生成された実行ファイルを実行できること
  • コンパイル及び実行について、それを行う環境に依存しないこと
    • Linuxであれば、どの環境でも実行可能なこと
  • C++11を使用できること

仕様

  • Dockerを用いて、g++コンパイル環境を作成する
  • Dockerを用いて、上記コンパイル成果物の実行環境を作成する
  • Dockerイメージを作成して、DockerをインストールしてあるLinuxPCへのポータビリティを確保する
  • g++は-std=c++11オプションが使用できるものを使用する

実装

元になるイメージ

Dockerhubにある公式のgcc用イメージを使用します。

このイメージは、buildpack-deps(ビルド環境用基本イメージ)内に、特定のバージョンのgccをインストールしています。
どのアーキテクチャ用のgccをインストールするかは、イメージをビルドするときの環境から自動で選択されます。i386やamd64のほか、arm32v7やarm64v8など、一般的に使用されるARMアーキテクチャにも対応しています。

Dockerfileの作成

上記gccイメージを使用して、g++のコンパイル・実行環境としてのイメージを作成するためのDockerfileを記述します。
DockerhubのgccイメージのページにあるC言語のコンパイル・実行環境作成用Dockerfileを改造するだけで作成できます。

FROM gcc:4.9
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN g++ -o myapp main.cpp -std=c++11 -lpthread
CMD ["./myapp"]

動作としては、docker run時にカレントディレクトリをコピーし、カレントディレクトリに存在しているmain.cppをコンパイルして実行します。
マウントではなくコピーを用いているのは、ゲスト環境であるDockerコンテナ内部のプログラムの異常動作がマウントされたホスト環境に影響を与えないようにする配慮だと考えられます。

Dockerhub掲載のものとの変更点は以下です。

  • gccではなく、g++を使用するように変更しています。
  • -std=c++11オプションを追加することでC++11の機能を使用できるようにします。
  • 末尾に-lpthreadを追加しています。
    • (私が頻繁に使用するマルチスレッドプログラミングのテストを行うため)

実行方法

使用時にはイメージのビルド、コンテナ起動(及びイメージの削除)が必要になります。今回は簡単なシェルスクリプトを作成しました。

#!/bin/bash

set -eu

if [ ! -e myapp/main.cpp ]; then
  echo "Error:main.cpp not exists."
  exit 1
fi

eval docker build -t my-gcc-app . >/dev/null
eval docker run -it --rm --name my-running-app my-gcc-app
eval docker rmi my-gcc-app >/dev/null

本シェルスクリプトを以下のようなディレクトリ構成下で実行してください。

/test_dir/      # テストディレクトリのルート
|--dg++.sh      # シェルスクリプト
|--Dockerfile
|--myapp
|  |--main.cpp  # テスト対象

サンプル実行例

例として、Hello, Worldを実行した場合の結果を記述します。

user@hostname:~/test_dir$ ls
dg++.sh  Dockerfile  myapp
user@hostname:~/test_dir$ ls myapp/
main.cpp
user@hostname:~/test_dir$ cat myapp/main.cpp 
#include <iostream>

int main() {
  std::cout << "Hello, World." << std::endl;
  return 0;
}
user@hostname:~/test_dir$ ./dg++.sh 
Hello, World.
user@hostname:~/test_dir$

終わりに

Dockerを用いることで、作成したC++ソースを完全に独立した環境でテストする事ができるようになりました。Jenkins等のCIツールに自動テスト環境として組み込んだりすると面白いかもしれません。

-C++, Docker, Linux
-, ,

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

関連記事

no image

cmakeでのDEBUG/RELEASEモード別・サブディレクトリ別のコンパイルオプションの分け方

仕事で使うので備忘録として。 対象となるソースコードツリーは、拙作のcppのプロジェクトのテンプレートで行う shinjikirino/cpp_project_templatehttps://gith …

pthread_cancelすると何が行われるのか

仕事でのメモ。 目次1 pthread_cancel2 pthread_cancelで何が行われるのか2.1 シグナル送出2.2 注意2.3 ソースコードを読む2.4 pthread_cancel時の …

cmake, googletestを利用したC++開発環境の構築テスト

自学用メモ。 業務で使用しているcmakeの勉強がてら、業務に近いソースツリーを作成した。 googletestを用いた単体テストも合わせて書けるような構成になっている。 テンプレートとして、今後のC …

Docker上でnginx-proxy他を使ってSSL対応マルチドメインサーバ環境の構築

今回は、nginx-proxyを使用し、SSLに対応したマルチドメイン環境を構築します。 追記(2017/10/08):作成したdocker-compose.ymlをGithubに公開しました。目次の …

Ubuntu 16.04 LTS でのDocker実行環境(docker-engine + docker-compose)の構築

今回は、Ubuntu 16.04 LTS でのDocker実行環境の構築を行います。 目次1 背景2 注意3 docker-engineのインストール4 docker-composeのインストール5 …