CMake モジュール: CheckCXXSourceRuns - C++ ソースコードのコンパイル・実行を確認する


CheckCXXSourceRuns は CMake モジュールの一つで、C++ ソースコードがコンパイルおよび実行できるかどうかを確認するために使用されます。このモジュールは、特定のライブラリや機能が使用可能かどうかを検証する際に役立ちます。

使用方法

CheckCXXSourceRuns モジュールを使用するには、以下のコマンドを使用します。

CHECK_CXX_SOURCE_RUNS(<var>)

このコマンドは、以下の引数を受け取ります。

  • <var>: ソースコードを格納する変数の名前。この変数は、std::string 型である必要があります。

オプション

以下のオプションを設定することで、CheckCXXSourceRuns モジュールの動作を変更できます。

  • CMAKE_REQUIRED_LIBRARIES: リンクするライブラリのリスト。この変数は、ライブラリ名のリストである必要があります。
  • CMAKE_REQUIRED_INCLUDES: インクルードディレクトリのリスト。この変数は、ディレクトリパスのリストである必要があります。
  • CMAKE_REQUIRED_DEFINITIONS: 定義するマクロのリスト。この変数は、-DFOO=bar 形式の文字列のリストである必要があります。
  • CMAKE_REQUIRED_FLAGS: コンパイラに渡される追加フラグ。この変数は、スペース区切りの文字列である必要があります。

以下の例では、main.cpp という名前のソースコードがコンパイルおよび実行できるかどうかを確認します。

set(SOURCE_CODE "
#include <iostream>

int main() {
  std::cout << \"Hello, world!\" << std::endl;
  return 0;
}
")

CHECK_CXX_SOURCE_RUNS(RESULT ${SOURCE_CODE})

if(RESULT)
  message(STATUS "ソースコードがコンパイルおよび実行されました。")
else()
  message(STATUS "ソースコードがコンパイルまたは実行できませんでした。")
endif()

プログラミングへの応用例

CheckCXXSourceRuns モジュールは、以下のプログラミングタスクに役立ちます。

  • コードの移植性確認
  • 依存関係のチェック
  • ライブラリや機能の可用性を検証する


例 1: ライブラリの可用性を検証する

この例では、boost ライブラリが使用可能かどうかを確認します。

CHECK_CXX_SOURCE_RUNS(RESULT "
#include <boost/thread.hpp>

int main() {
  boost::thread t([]() {
    std::cout << \"Hello, world!\" << std::endl;
  });
  t.join();
  return 0;
}
")

if(RESULT)
  message(STATUS "Boost ライブラリが使用可能です。")
else()
  message(STATUS "Boost ライブラリが使用できません。")
endif()

例 2: 依存関係のチェック

この例では、libfoo ライブラリが使用可能かどうかを確認し、libfoo ライブラリが使用可能な場合のみ libfoo を使用するようにビルドシステムを設定します。

CHECK_CXX_SOURCE_RUNS(RESULT "
#include <libfoo.h>

int main() {
  foo();
  return 0;
}
")

if(RESULT)
  target_link_libraries(myprogram libfoo)
endif()

例 3: コードの移植性確認

この例では、ソースコードが #ifdef ディレクティブで囲まれたコードセクションを含むかどうかを確認します。このコードセクションは、特定のプラットフォームでのみ使用される場合に役立ちます。

CHECK_CXX_SOURCE_RUNS(RESULT "
#ifdef __linux__
  std::cout << \"Linux\" << std::endl;
#elif defined(_WIN32)
  std::cout << \"Windows\" << std::endl;
#else
  std::cout << \"Unknown platform\" << std::endl;
#endif
")


手動のコンパイルと実行

最も単純な代替方法は、手動でソースコードをコンパイルして実行することです。これには、以下の手順が必要です。

  1. ソースコードをファイルに保存します。
  2. コンパイラを使用してソースコードをコンパイルします。
  3. 生成された実行可能ファイルをを実行します。

この方法は、単純で理解しやすいですが、時間のかかる作業です。

CMake の try_compile コマンド

CMake には、try_compile コマンドという別の方法があります。このコマンドは、ソースコードがコンパイルできるかどうかを確認するために使用できます。

try_compile(RESULT ${SOURCE_CODE}
  COMPILE_FLAGS "${CMAKE_REQUIRED_FLAGS}"
  LINK_FLAGS "${CMAKE_REQUIRED_LINK_FLAGS}"
  INCLUDES "${CMAKE_REQUIRED_INCLUDES}"
  LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}"
)

このコマンドは、CheckCXXSourceRuns モジュールとほぼ同じ引数を受け取ります。

Boost.Test フレームワーク

Boost.Test フレームワークは、C++ テストを書くためのライブラリです。このフレームワークには、ソースコードがコンパイルおよび実行できるかどうかを確認するためのテストケースを作成できるアサーションが含まれています。

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(test_source_code) {
  BOOST_CHECK_EQUAL(system("g++ -o test main.cpp && ./test"), 0);
}

この方法は、よりテスト駆動型の開発アプローチを提供します。

Catch2 テストフレームワーク

Catch2 は、Boost.Test に似たもう 1 つのテストフレームワークです。Catch2 は、より軽量で使いやすいフレームワークとして知られています。

#include <catch2/catch.hpp>

TEST_CASE("test source code") {
  REQUIRE(system("g++ -o test main.cpp && ./test") == 0);
}

Google Test フレームワーク

Google Test は、Google によって開発されたテストフレームワークです。このフレームワークは、C++ と C の両方のテストをサポートしています。

#include "gtest/gtest.h"

TEST(TestSourceCode, CompileAndRun) {
  EXPECT_EQ(system("g++ -o test main.cpp && ./test"), 0);
}