LoginSignup
6
6

More than 5 years have passed since last update.

c++14 with openmp + gtest-1.8のcmake環境を整備する

Last updated at Posted at 2016-11-11

目標

  • c++14の並列計算(openmp)プログラムを書く
  • g++-5で動けばよい(他のコンパイラだと手直しが必要)
  • openmpが含まれているテストをgtestで書く
  • とりあえず手元のPC(Ubuntu)で動くまで検証する(Macなど環境が違うとうまくいかないかもしれません)
  • 参考

利用するソフト

  • gtest-1.8
  • gmock(gtest-1.8に統合されたので不要)
  • cmake
  • g++-5 (c++14 and openmp)

環境

  • 環境1
    • Ubuntu 16.04
    • cmake 3.5
    • g++5.4 (system default)
  • 環境2
    • Ubuntu 14.04
    • cmake 2.8
    • g++5.4 (sudo apt-get install g++-5)

使い方

コンパイル

git clone https://takeshi-uchitane@bitbucket.org/takeshi-uchitane/cmake_c-14_openmp_gtests.git
cd cmake_c-14_openmp_gtests
mkdir build
cd build
cmake .. # if you have another version of g++, you should set CXX=g++-5
make

実行

  • OpenMPを利用するプログラムのテストができた
$ ./utest/tests/Foo/foo-test 
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Foo
[ RUN      ] Foo.constractor
thread 3
thread 1
thread thread 2
0
[       OK ] Foo.constractor (53 ms)
[----------] 1 test from Foo (53 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (53 ms total)
[  PASSED  ] 1 test.

ソースコード

Foo class

  • OPM並列プログラムとそのテスト
src/Foo.cpp
#include "Foo.hpp"
#include <omp.h>
#include <iostream>

Foo::Foo() { for(unsigned int i=0u;i<4u;i++) { v.push_back(i); } }

std::vector<double> Foo::calc() {
  std::vector<double> array(v.size());
#pragma omp parallel for
  for(unsigned int i=0u;i<v.size();i++) {
    array[i]=double(v[i]);
    std::cout << "thread " << omp_get_thread_num() << std::endl;
  }
  sort(array.begin(), array.end());
  return std::move(array);
}
utest/tests/Foo/main.cpp
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "Foo.hpp"

TEST(Foo, constractor) {
  Foo foo;
  EXPECT_THAT(foo.v, testing::ElementsAre(0,1,2,3));
  EXPECT_THAT(foo.calc(), testing::ElementsAre(0.0,1.0,2.0,3.0));
}

CmakeLists.txt

  • CMakeLists.txtはプロジェクト用とテスト用の2つ
  • OPENMPのフラグ(OpenMP_CXX_FLAGS)はテストを追加する前に見つけておく
CmakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

#if you use special compiler, set the compiler
#SET(CMAKE_CXX_COMPILER  "g++-5")
#or
#set option -DCMAKE_CXX_COMPILER="g++-5"

PROJECT(hoge CXX)
include_directories(${PROJECT_SOURCE_DIR}/include)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SOURCES)

ADD_EXECUTABLE(hoge.out main.cpp ${SOURCES})

if (NOT DEFINED ${CMAKE_CXX_FLAGS})
  SET (CMAKE_CXX_FLAGS "-Wall -O3 -std=c++14")
  find_package(OpenMP)
  if (OPENMP_FOUND)
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
  endif()
endif ()
MESSAGE( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )

#gtest
if(NOT without-test)
  enable_testing()
  include(${PROJECT_SOURCE_DIR}/utest/include/gtest.cmake)
  add_subdirectory(${PROJECT_SOURCE_DIR}/utest/tests)
endif()
utest/test/Foo/CmakeLists.txt
cmake_minimum_required(VERSION 2.8)

add_executable(foo-test main.cpp ${SOURCES})
target_link_libraries(foo-test
  gtest
  gtest_main
  gmock
  gmock_main
  pthread
)
add_test(
  NAME foo
  COMMAND $<TARGET_FILE:foo-test>
  )

# run with: ctest -L lib
set_property(
  TEST foo
  PROPERTY LABELS lib foo
  )

gtest.cmake

  • ダウンドーロ先のURLをgtest-1.8用に変更
  • gmockはgtest1.8からgtestに統合された(gmockを別途インストールする必要は無い)
  • 統合によりincludeファイルのパスが変更された
    • ${source_dir}/googletest/include
    • ${source_dir}/googlemock/include
  • 静的ライブラリの作成されるパスが微妙(なんでこんなパスにしたんでしょう)
    • ${binary_dir}/googlemock/gtest/libgtest.a
    • ${binary_dir}/googlemock/gtest/libgtest_main.a
    • ${binary_dir}/googlemock/libgmock.a
    • ${binary_dir}/googlemock/libgmock_main.a
utest/include/gtest.cmake
cmake_minimum_required(VERSION 2.8)

# Google Test settings
include(ExternalProject)

ExternalProject_Add(
    GoogleTest
    URL https://github.com/google/googletest/archive/release-1.8.0.zip
    CMAKE_ARGS -DCMAKE_CXX_COMPILER=g++-5;-DCMAKE_C_COMPILER=gcc-5
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/lib
    INSTALL_COMMAND ""
    LOG_DOWNLOAD ON
    LOG_CONFIGURE ON
    LOG_BUILD ON
    )

ExternalProject_Get_Property(GoogleTest source_dir)
include_directories(${source_dir}/googletest/include)
include_directories(${source_dir}/googlemock/include)

ExternalProject_Get_Property(GoogleTest binary_dir)
add_library(gtest STATIC IMPORTED)
set_property(
    TARGET gtest
    PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/gtest/libgtest.a
    )
add_library(gtest_main STATIC IMPORTED)
set_property(
    TARGET gtest_main
    PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/gtest/libgtest_main.a
    )
add_library(gmock STATIC IMPORTED)
set_property(
    TARGET gmock
    PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/libgmock.a
    )
add_library(gmock_main STATIC IMPORTED)
set_property(
    TARGET gmock_main
    PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/libgmock_main.a
    )

所感

  • 自分のメモ用に初投稿
  • 以下のニーズを満たした開発環境が欲しかった
    • c++-14で書きたい
    • 並列計算プログラムが必要
    • TDDしたい
    • cmake使いたい
  • 探したけど,上記が統合されている開発環境は落ちていなかった
    • きっとニッチな要求なんだろう
    • じゃあ,作ろう
  • gtest1.7とgmock1.7用に作っていたがダウンロードURLが変更になったり,仕様が変わっていたりで手間取ったのでメモを共有
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6